From 28788a05a11d33ccf6d2419cc32224af27ffc900 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Tue, 19 Jan 2016 17:30:45 +0100 Subject: [PATCH 001/268] ohc function modified,allowing to compute the ohc in different Arctic regions --- common_ocean_post.txt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 0740662..1eeba07 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -930,11 +930,11 @@ cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt # # Input arguments # -if [ -z "$3" ] ; then - typeset var basin='Glob' -else - typeset var basin=$3 -fi +case $3 in +'') typeset var basin="Glob";; +'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3;; +*) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; ncrename -h -v $3,tmask mask.nc ;; +esac if [ -z "$4" ] ; then typeset var mxl=0 else @@ -983,6 +983,7 @@ case $basin in 'Anta') para="all $mxl 0 0 -90 -60" ; output='Ant_90S60S_'${output} ;; 'TInd') para="ind $mxl 0 0 -30 30" ; output='TInd_30S30N_'${output} ;; 'Glob') para="all $mxl 0 0 0 0" ;; + *) para="all $mxl 0 0 0 0; output=$3'_'${output} ;; esac case $mxl in @@ -1010,7 +1011,7 @@ for jt in $(seq 1 $ntime) ; do else cdfmxl tmpohc.nc mxl.nc fi - $exec tmpohc.nc $para $up $down > tmp.log + cdfheatc-cfu tmpohc.nc $para $up $down > tmp.log cat tmp.log thc=`cat tmp.log | grep "Total Heat content :" | awk '{print $5}'`; uhc=`cat tmp.log | grep "Total Heat content/volume" | awk '{print $5}'`; @@ -1024,6 +1025,11 @@ cdo cat $list ${output}$2 ncks -h -A -v time $1 ${output}$2 rm -f $list template_heatc.nc template_heatc.cdl depth.txt setminmax ${output}$2 thc uhc + +if [ ! -z "$3" ] && [ "$3" != 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' ]; then + ncrename -h -v tmask,$3 mask.nc + mv mask.nc mask_regions.nc + mv mask_tmp.nc mask.nc } ############################################################################### # # -- GitLab From 3a959d38653dc0c9c67772cb835252357f3c45e8 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Wed, 20 Jan 2016 15:18:35 +0100 Subject: [PATCH 002/268] Closed an if sentence that was opened-put fi --- common_ocean_post.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index a437ef6..ac488ba 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -1028,6 +1028,7 @@ if [ ! -z "$3" ] && [ "$3" != 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta ncrename -h -v tmask,$3 mask.nc mv mask.nc mask_regions.nc mv mask_tmp.nc mask.nc +fi } ############################################################################### # # -- GitLab From 1a436721b6d1106df7add233bf65b0691b1a7060 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Wed, 20 Jan 2016 15:39:48 +0100 Subject: [PATCH 003/268] Added space in a case conditional before ;; --- common_ocean_post.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index ac488ba..b8754f4 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -931,8 +931,8 @@ cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt # Input arguments # case $3 in -'') typeset var basin="Glob";; -'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3;; +'') typeset var basin="Glob" ;; +'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3 ;; *) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; ncrename -h -v $3,tmask mask.nc ;; esac if [ -z "$4" ] ; then -- GitLab From f5f524272b24ce8c29dc3f1f8b53671500d2532f Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Wed, 20 Jan 2016 16:07:56 +0100 Subject: [PATCH 004/268] Deleted a space --- common_ocean_post.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index b8754f4..a2862b3 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -933,7 +933,7 @@ cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt case $3 in '') typeset var basin="Glob" ;; 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3 ;; -*) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; ncrename -h -v $3,tmask mask.nc ;; +*) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; ncrename -h -v $3,tmask mask.nc ;; esac if [ -z "$4" ] ; then typeset var mxl=0 -- GitLab From f5c1c18c0b54e2bdb79e31ff3a1d33c794bf271b Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Thu, 21 Jan 2016 17:20:37 +0100 Subject: [PATCH 005/268] Put ; to close a sentence --- common_ocean_post.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index a2862b3..f204109 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -981,7 +981,7 @@ case $basin in 'Anta') para="all $mxl 0 0 -90 -60" ; output='Ant_90S60S_'${output} ;; 'TInd') para="ind $mxl 0 0 -30 30" ; output='TInd_30S30N_'${output} ;; 'Glob') para="all $mxl 0 0 0 0" ;; - *) para="all $mxl 0 0 0 0; output=$3'_'${output} ;; + *) para="all $mxl 0 0 0 0;; output=$3'_'${output} ;; esac case $mxl in -- GitLab From ecff6ee982cd4e768c9c8f2b6c8b9ee189cdc419 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Thu, 21 Jan 2016 17:45:27 +0100 Subject: [PATCH 006/268] Added double coma to close sentence --- common_ocean_post.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index f204109..983169e 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -981,7 +981,7 @@ case $basin in 'Anta') para="all $mxl 0 0 -90 -60" ; output='Ant_90S60S_'${output} ;; 'TInd') para="ind $mxl 0 0 -30 30" ; output='TInd_30S30N_'${output} ;; 'Glob') para="all $mxl 0 0 0 0" ;; - *) para="all $mxl 0 0 0 0;; output=$3'_'${output} ;; + *) para="all $mxl 0 0 0 0" ; output=$3'_'${output} ;; esac case $mxl in -- GitLab From 200791a98c28ef6c0d92efc2db94d270b86b4a31 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Fri, 22 Jan 2016 16:42:17 +0100 Subject: [PATCH 007/268] Changed documentation for ohc function and conditional if you make a mistake choosing the name of the Arctic region --- common_ocean_post.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 983169e..723b205 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -916,8 +916,12 @@ fi # # # $1 : input temperature file name # # $2 : output file name ( => 2D x-y ) # -# $3 : basin (NAtl, NPac, TAtl, TPac, TInd, Anta, Arct, Glob) Default : Glob # +# $3 : basin (NAtl, NPac, TAtl, TPac, TInd, Anta, Arct, Glob, or any basin # +# that is defined in ${CON_FILES}/mask.regions.${NEMOVERSION}.nc) # +# Default : Glob #) Default : Glob # # $4 = 0 if $3 = Glob # +# In all other cases, the heat content will be computed in the Arctic # +# regions # # $4 : mixed layer (1=only, 0=included, -1=without) Default : 0 # # $5 : upper level of the layer (optional) Default : top # # $6 : lower level of the layer (optional) Default : bottom # @@ -933,7 +937,7 @@ cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt case $3 in '') typeset var basin="Glob" ;; 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3 ;; -*) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; ncrename -h -v $3,tmask mask.nc ;; +*) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; typeset var lstvars=`cdo showvar mask.nc` ; if [[ ${lstvar/$3} != ${lstvar} ]] ; then ncrename -h -v $3,tmask mask.nc ; else echo 'This region does not exist, please choose another region' ; stop; fi ;; esac if [ -z "$4" ] ; then typeset var mxl=0 -- GitLab From 31cf65d256dead7b9e5447fba344a150c1abd2dc Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Tue, 1 Mar 2016 13:33:57 +0100 Subject: [PATCH 008/268] Corrected syntax errors --- common_ocean_post.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 0724753..931f932 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -935,7 +935,8 @@ cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt case $3 in '') typeset var basin="Glob" ;; 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3 ;; -*) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; typeset var lstvars=`cdo showvar mask.nc` ; if [[ ${lstvar/$3} != ${lstvar} ]] ; then ncrename -h -v $3,tmask mask.nc ; else echo 'This region does not exist, please choose another region' ; stop; fi ;; +exit +*) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; typeset var lstvars=`cdo showvar mask.nc` ; if [[ ${lstvars/$3} != ${lstvars} ]] ; then ncrename -h -v $3,tmask mask.nc ; else echo 'This region does not exist, please choose another region' ; exit; fi ;; esac if [ -z "$4" ] ; then typeset var mxl=0 -- GitLab From a72e7cf10fb772ceb90e5cc097dcff08a7162600 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Tue, 1 Mar 2016 13:35:18 +0100 Subject: [PATCH 009/268] Corrected syntax errors --- common_ocean_post.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 931f932..4441f00 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -935,7 +935,6 @@ cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt case $3 in '') typeset var basin="Glob" ;; 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3 ;; -exit *) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; typeset var lstvars=`cdo showvar mask.nc` ; if [[ ${lstvars/$3} != ${lstvars} ]] ; then ncrename -h -v $3,tmask mask.nc ; else echo 'This region does not exist, please choose another region' ; exit; fi ;; esac if [ -z "$4" ] ; then -- GitLab From 7f5addf551db64a9bb09b564831c644af3e7cdc0 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Tue, 1 Mar 2016 15:48:19 +0100 Subject: [PATCH 010/268] the same --- common_ocean_post.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 4441f00..7d6e987 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -1029,7 +1029,7 @@ ncks -h -A -v time $1 ${output}$2 rm -f $list template_heatc.nc template_heatc.cdl depth.txt setminmax ${output}$2 thc uhc -if [ ! -z "$3" ] && [ "$3" != 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' ]; then +if [ ! -z "$3" ] && [ "$3" != 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' ] ; then ncrename -h -v tmask,$3 mask.nc mv mask.nc mask_regions.nc mv mask_tmp.nc mask.nc -- GitLab From 0076c648814658e4924a1b0cd2720f405724cc85 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Tue, 1 Mar 2016 16:16:51 +0100 Subject: [PATCH 011/268] Fixed the last conditional of ohc function, there was a syntax problem with [[]] --- common_ocean_post.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 7d6e987..555d4d0 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -1029,7 +1029,7 @@ ncks -h -A -v time $1 ${output}$2 rm -f $list template_heatc.nc template_heatc.cdl depth.txt setminmax ${output}$2 thc uhc -if [ ! -z "$3" ] && [ "$3" != 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' ] ; then +if [[ ! -z "$3" ]] && [[ "$3" != NAtl ]] && [[ $3 != NPac ]] && [[ $3 != TAtl ]] && [[ $3 != TPac ]] && [[ $3 != TInd ]] && [[ $3 != Anta ]] && [[ $3 != Arct ]] && [[ $3 != Glob ]] ; then ncrename -h -v tmask,$3 mask.nc mv mask.nc mask_regions.nc mv mask_tmp.nc mask.nc -- GitLab From da2cb7da618a135046ba49874f53eec5564125c0 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Wed, 2 Mar 2016 12:23:04 +0100 Subject: [PATCH 012/268] Changed header info of ohc function and mask.regions.3d --- common_ocean_post.txt | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 555d4d0..a609831 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -64,7 +64,13 @@ cp -f ${CON_FILES}/mesh_mask_nemo.${NEMOVERSION}.nc mesh_zgr.nc cp -f ${CON_FILES}/mesh_mask_nemo.${NEMOVERSION}.nc mask.nc cp -f ${CON_FILES}/new_maskglo.${NEMOVERSION}.nc new_maskglo.nc -cp -f ${CON_FILES}/mask.regions.${NEMOVERSION}.nc mask_regions.nc +if [ -e ${CON_FILES}/mask.regions.${NEMOVERSION}.nc ] ; then +cp ${CON_FILES}/mask.regions.${NEMOVERSION}.nc mask_regions.nc +fi + +if [ -e ${CON_FILES}/mask.regions.3d.${NEMOVERSION}.nc ] ; then +cp ${CON_FILES}/mask.regions.3d.${NEMOVERSION}.nc mask_regions.3d.nc +fi if [[ ! -f mask.nc ]] ; then echo "No configuration files for cdftools" @@ -915,16 +921,16 @@ fi # $1 : input temperature file name # # $2 : output file name ( => 2D x-y ) # # $3 : basin (NAtl, NPac, TAtl, TPac, TInd, Anta, Arct, Glob, or any basin # -# that is defined in ${CON_FILES}/mask.regions.${NEMOVERSION}.nc) # -# Default : Glob #) Default : Glob # -# $4 = 0 if $3 = Glob # -# In all other cases, the heat content will be computed in the Arctic # -# regions # +# that is defined in ${CON_FILES}/mask.regions.3d.${NEMOVERSION}.nc) # +# Default : Glob) # # $4 : mixed layer (1=only, 0=included, -1=without) Default : 0 # # $5 : upper level of the layer (optional) Default : top # # $6 : lower level of the layer (optional) Default : bottom # # # # Created in May 2012 Author : vguemas@ic3.cat # +# Modified in March 2016 Author : ruben.cruzgarcia@bsc.es # +# Modifications for computing the ohc # +# in the Arctic regions # ############################################################################### module load CDO/1.5.3-foss-2015a function ohc { @@ -935,7 +941,7 @@ cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt case $3 in '') typeset var basin="Glob" ;; 'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3 ;; -*) mv mask.nc mask_tmp.nc ; mv mask_regions.nc mask.nc ; typeset var lstvars=`cdo showvar mask.nc` ; if [[ ${lstvars/$3} != ${lstvars} ]] ; then ncrename -h -v $3,tmask mask.nc ; else echo 'This region does not exist, please choose another region' ; exit; fi ;; +*) mv mask.nc mask_tmp.nc ; mv mask_regions.3d.nc mask.nc ; typeset var lstvars=`cdo showvar mask.nc` ; if [[ ${lstvars/$3} != ${lstvars} ]] ; then ncrename -h -v $3,tmask mask.nc ; else echo 'This region does not exist, please choose another region' ; exit; fi ;; esac if [ -z "$4" ] ; then typeset var mxl=0 @@ -1031,7 +1037,7 @@ setminmax ${output}$2 thc uhc if [[ ! -z "$3" ]] && [[ "$3" != NAtl ]] && [[ $3 != NPac ]] && [[ $3 != TAtl ]] && [[ $3 != TPac ]] && [[ $3 != TInd ]] && [[ $3 != Anta ]] && [[ $3 != Arct ]] && [[ $3 != Glob ]] ; then ncrename -h -v tmask,$3 mask.nc - mv mask.nc mask_regions.nc + mv mask.nc mask_regions.3d.nc mv mask_tmp.nc mask.nc fi } -- GitLab From be0cc4ec3457d77d86d3051796923f407e836f6a Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Thu, 3 Mar 2016 17:11:32 +0100 Subject: [PATCH 013/268] Modification in ohc function finished. Now you can calculate the ohc for each Arctic region --- common_ocean_post.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index a609831..cf9ce86 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -932,7 +932,6 @@ fi # Modifications for computing the ohc # # in the Arctic regions # ############################################################################### -module load CDO/1.5.3-foss-2015a function ohc { cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt # -- GitLab From 95b489fb246f6edc351d3b063f8354ee03880b08 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Mon, 7 Mar 2016 13:44:14 +0100 Subject: [PATCH 014/268] Added new function 'ohc_Arcticreg1' --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 805fa9b..68c8532 100644 --- a/README +++ b/README @@ -99,3 +99,4 @@ PATH=/cfu/software/cdftools2.1/:$PATH 'lArctohc' : Arctic (65-90N) lower (800m-bottom) ocean heat content 'temp_lev' : vertical mean of ocean temp (weighted) between level1 and level2 (in numbers, not in meters), specified in the config file 'sal_lev' : vertical mean of ocean sal (weighted) between level1 and level2 (in numbers, not in meters), specified in the config file +'ohc_Articreg1' : ocean heat content in the specified Arctic region (0-725m) -- GitLab From bd64f6c89c07a6397b0d8b8aa18cedf1c122123a Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Mon, 7 Mar 2016 13:45:09 +0100 Subject: [PATCH 015/268] Added 'raw_regions_ice' option --- config_file-ocean_pp.bash | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index ff51d3b..c683fac 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -2,12 +2,13 @@ # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). listpost=('temp_lev' 'sal_lev') - # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) + # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' 'ohc_Articreg1' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 level2=14 #If temp_lev or sal_lev is chosen on listpost, the lev1 and lev2 correspond to the levels between which the vertical mean has to be calculated. Lev1 and lev2 should be between 1,42 or 1,46, depending on the numbers of vertical levels on the original files. raw_vars_ocean=( '' ) # If listpost contains "ext_raw_oce" option, this is the list ocean variables you want to extract. If nothing is specified, all variables present in input file will be treated. If raw_vars_ocean='default', sosstsst, sosaline, somixhgt and somxl010 will be extracted. raw_vars_ice=( '' ) # If listpost contains "ext_raw_ice" option, this is the list of seaice variables you want to extract. If nothing is specified, all variables will be treated. If raw_vars_ice='default', isnowthi, iicethic, ileadfra, iicetemp, and ice_pres will be extracted. +raw_regions_ice=( '' ) # If listpost contains "ohc_Arcticreg1" or "siasiesivsit_Arcticreg1" option, this is the list of sea ice regions you want to compute expid=m02j # expid or nemovar_s4 / nemovar_combine / glorys2v1 mod='ecearth' # nemo / ecearth typeoutput='MMO' # diags / MMO -- GitLab From df91ecd76abd34c001368b1aae2c151313420c2e Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Mon, 7 Mar 2016 13:45:43 +0100 Subject: [PATCH 016/268] Added 'ohc_Arcticreg1' --- ocean_pp.bash | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/ocean_pp.bash b/ocean_pp.bash index ddabc08..13afee6 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -448,6 +448,32 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do done ;; + + 'ohc_Arcticreg1') + + case $typeoutput in + 'MMO' ) pref='grid_T' ;; + 'diags') pref='t3d' ;; + esac + + if [[ $raw_regions_ice == '' ]] ; then + lstseas=$( cdo showvar mask_regions.nc ) + else + if [[ $raw_regions_ice == 'default' ]] ; then + lstseas="Baffin_Bay Barents_Sea Beaufort_Sea Bering CanArch Chukchi_Sea East_Siberian_Sea Greenland_Sea Hudson Icelandic_Sea Kara_Sea Laptev_Sea Labrador_Sea Norwegian_Sea Okhotsk Central_Arctic" + else + lstseas=$( echo ${raw_regions_ice[@]} ) + fi + fi + + for sea in $lstseas ; do + + ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $basin 0 1 25 + + + done + ;; + esac @@ -534,6 +560,13 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do '3dsal') dirout='InterpS' ; files=('regular3dS') ;; 'TSec_ave190-220E') dirout='sections' ; files=('TSec_ave190-220E') ;; 'SSec_ave190-220E') dirout='sections' ; files=('SSec_ave190-220E') ;; + 'ohc_Arcticreg1') dirout=='heatc' ; + file=('heatc_Arctreg1') + for sea in $lstseas ; do + file='${sea}_'${file} + done + files=( $file ) ;; + esac case `echo $post|cut -c$((${#post}-2))-${#post}` in 'ohc') -- GitLab From 25c3ff0436f80cfb6c1dbed40b9970a8b8781ffe Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Mon, 7 Mar 2016 18:19:27 +0100 Subject: [PATCH 017/268] Added lstseas --- ocean_pp.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/ocean_pp.bash b/ocean_pp.bash index 13afee6..16b85e2 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -562,6 +562,7 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do 'SSec_ave190-220E') dirout='sections' ; files=('SSec_ave190-220E') ;; 'ohc_Arcticreg1') dirout=='heatc' ; file=('heatc_Arctreg1') + lstseas=$( cdo showvar mask_regions.nc ) for sea in $lstseas ; do file='${sea}_'${file} done -- GitLab From 37d425bc0489e980ec6c88809b3445bc907dd208 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Wed, 9 Mar 2016 17:27:16 +0100 Subject: [PATCH 018/268] Corrected --- ocean_pp.bash | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ocean_pp.bash b/ocean_pp.bash index 16b85e2..7632530 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -468,7 +468,7 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do for sea in $lstseas ; do - ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $basin 0 1 25 + ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ${sea}_heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $sea 0 1 24 done @@ -561,13 +561,10 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do 'TSec_ave190-220E') dirout='sections' ; files=('TSec_ave190-220E') ;; 'SSec_ave190-220E') dirout='sections' ; files=('SSec_ave190-220E') ;; 'ohc_Arcticreg1') dirout=='heatc' ; - file=('heatc_Arctreg1') - lstseas=$( cdo showvar mask_regions.nc ) - for sea in $lstseas ; do - file='${sea}_'${file} - done - files=( $file ) ;; - + for sea in ${lstseas[@]} ; do + file=${sea}_heatc + files=$( echo ${files[@]} $file) + done ;; esac case `echo $post|cut -c$((${#post}-2))-${#post}` in 'ohc') @@ -576,6 +573,7 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do case `echo $post | cut -c1` in 'x') mxl=1 ; start=2 ;; 'l') start=2 ; mxl=0 + ls case $NEMOVERSION in 'Ec2.3_O1L42'|'N3.2_O1L42'|'nemovar_O1L42') file='800-5350_'${file} ;; 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'N3.3_O1L46') file='855-5875_'${file} ;; -- GitLab From 3aa0d98adb29f341079673bce55b4b9ff81c1f69 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Wed, 9 Mar 2016 17:27:56 +0100 Subject: [PATCH 019/268] Modified --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 68c8532..0269da1 100644 --- a/README +++ b/README @@ -99,4 +99,4 @@ PATH=/cfu/software/cdftools2.1/:$PATH 'lArctohc' : Arctic (65-90N) lower (800m-bottom) ocean heat content 'temp_lev' : vertical mean of ocean temp (weighted) between level1 and level2 (in numbers, not in meters), specified in the config file 'sal_lev' : vertical mean of ocean sal (weighted) between level1 and level2 (in numbers, not in meters), specified in the config file -'ohc_Articreg1' : ocean heat content in the specified Arctic region (0-725m) +'ohc_Articreg1' : ocean heat content in the specified Arctic region (0-724m) -- GitLab From e34a6ea3a7fdb0ec1d597666a2203a3f2441fb3f Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Thu, 10 Mar 2016 18:25:10 +0100 Subject: [PATCH 020/268] Modified, but still has errors --- ocean_pp.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocean_pp.bash b/ocean_pp.bash index 7632530..b5bcb41 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -468,7 +468,7 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do for sea in $lstseas ; do - ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ${sea}_heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $sea 0 1 24 + ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $sea 0 1 24 done -- GitLab From b2f5a4e02f01039bf25c77b2952487bc7aeeaefe Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Thu, 10 Mar 2016 19:33:57 +0100 Subject: [PATCH 021/268] Corrected --- ocean_pp.bash | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ocean_pp.bash b/ocean_pp.bash index b5bcb41..0adad6c 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -468,7 +468,7 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do for sea in $lstseas ; do - ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $sea 0 1 24 + ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $sea 0 1 24 done @@ -560,9 +560,9 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do '3dsal') dirout='InterpS' ; files=('regular3dS') ;; 'TSec_ave190-220E') dirout='sections' ; files=('TSec_ave190-220E') ;; 'SSec_ave190-220E') dirout='sections' ; files=('SSec_ave190-220E') ;; - 'ohc_Arcticreg1') dirout=='heatc' ; + 'ohc_Arcticreg1') dirout='heatc' ; for sea in ${lstseas[@]} ; do - file=${sea}_heatc + file=${sea}_0-657_heatc files=$( echo ${files[@]} $file) done ;; esac -- GitLab From f1146b50bef48b9363c2f0f764931fc69a38300a Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Fri, 11 Mar 2016 12:15:04 +0100 Subject: [PATCH 022/268] Corrected --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 0269da1..53f509e 100644 --- a/README +++ b/README @@ -99,4 +99,4 @@ PATH=/cfu/software/cdftools2.1/:$PATH 'lArctohc' : Arctic (65-90N) lower (800m-bottom) ocean heat content 'temp_lev' : vertical mean of ocean temp (weighted) between level1 and level2 (in numbers, not in meters), specified in the config file 'sal_lev' : vertical mean of ocean sal (weighted) between level1 and level2 (in numbers, not in meters), specified in the config file -'ohc_Articreg1' : ocean heat content in the specified Arctic region (0-724m) +'ohc_Articreg1' : ocean heat content in the specified Arctic region (0-657m) -- GitLab From c5028d95034abf3e92c0291615a02a6ebe07f7b2 Mon Sep 17 00:00:00 2001 From: Ruben Cruz Garcia Date: Fri, 11 Mar 2016 12:15:48 +0100 Subject: [PATCH 023/268] Corrected version. It works fine and postprocesses the heat content in each Arctic region --- ocean_pp.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ocean_pp.bash b/ocean_pp.bash index 0adad6c..edefc68 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -560,7 +560,8 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do '3dsal') dirout='InterpS' ; files=('regular3dS') ;; 'TSec_ave190-220E') dirout='sections' ; files=('TSec_ave190-220E') ;; 'SSec_ave190-220E') dirout='sections' ; files=('SSec_ave190-220E') ;; - 'ohc_Arcticreg1') dirout='heatc' ; + 'ohc_Arcticreg1') dirout='heatc' ; + files=('') for sea in ${lstseas[@]} ; do file=${sea}_0-657_heatc files=$( echo ${files[@]} $file) @@ -573,7 +574,6 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do case `echo $post | cut -c1` in 'x') mxl=1 ; start=2 ;; 'l') start=2 ; mxl=0 - ls case $NEMOVERSION in 'Ec2.3_O1L42'|'N3.2_O1L42'|'nemovar_O1L42') file='800-5350_'${file} ;; 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'N3.3_O1L46') file='855-5875_'${file} ;; -- GitLab From 92ff93449bc70e9f645b44a32a4cb31a3fa4eb76 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 5 Apr 2016 14:39:07 +0200 Subject: [PATCH 024/268] First diagnostics converted (only MOC added from version in PyCompssTest) --- earthdiagnostics/__init__.py | 10 ++ earthdiagnostics/cdftools.py | 24 +++ earthdiagnostics/ocean/__init__.py | 1 + earthdiagnostics/ocean/circulation.py | 45 +++++ earthdiagnostics/ocean/heat.py | 96 ++++++++++ earthdiagnostics/ocean/salinity.py | 103 +++++++++++ earthdiagnostics/utils.py | 41 +++++ log.py | 246 ++++++++++++++++++++++++++ 8 files changed, 566 insertions(+) create mode 100644 earthdiagnostics/__init__.py create mode 100644 earthdiagnostics/cdftools.py create mode 100644 earthdiagnostics/ocean/__init__.py create mode 100644 earthdiagnostics/ocean/circulation.py create mode 100644 earthdiagnostics/ocean/heat.py create mode 100644 earthdiagnostics/ocean/salinity.py create mode 100644 earthdiagnostics/utils.py create mode 100644 log.py diff --git a/earthdiagnostics/__init__.py b/earthdiagnostics/__init__.py new file mode 100644 index 0000000..bab3e60 --- /dev/null +++ b/earthdiagnostics/__init__.py @@ -0,0 +1,10 @@ +from cdo import Cdo +from nco import Nco +from earthdiagnostics.utils import Utils +from earthdiagnostics.cdftools import CDFTools +import os + +cdo = Cdo() +nco = Nco() +cdftools = CDFTools('/home/Earth/jvegas/CDFTOOLS_3.0/bin') +DEVNULL = open(os.devnull, 'wb') diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py new file mode 100644 index 0000000..527a155 --- /dev/null +++ b/earthdiagnostics/cdftools.py @@ -0,0 +1,24 @@ +import subprocess +import os +from log import Log + + +class CDFTools: + + def __init__(self, path=''): + self.path = path + + def run(self, command, input, output=None, options=None): + line = [os.path.join(self.path, command)] + if input: + line.append(input) + if options: + for option in options: + line.append(option) + if output: + line.append('-o') + line.append(output) + + process = subprocess.Popen(line, stdout=subprocess.PIPE) + Log.log.log(Log.INFO, process.communicate()) + diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py new file mode 100644 index 0000000..61065a0 --- /dev/null +++ b/earthdiagnostics/ocean/__init__.py @@ -0,0 +1 @@ +from salinity import Salinity diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py new file mode 100644 index 0000000..f12f73c --- /dev/null +++ b/earthdiagnostics/ocean/circulation.py @@ -0,0 +1,45 @@ +from earthdiagnostics import Utils, cdftools +from log import Log +from nco import NCOException +import os +import shutil + + +def moc(input_file, output_file): + """ + Compute the MOC for oceanic basins + Created in March 2012 + Author : vguemas@ic3.cat + + :param input_file: input grid_V file name + :type input_file: str + :param output_file: output file name (=> 2D, depth-y) + :param output_file: str + :return: + """ + nco = Utils.nco + if os.path.exists(output_file): + os.remove(output_file) + + cdftools.run('cdfmoc', input=input_file, output=output_file) + nco.ncwa(input=output_file, output=output_file, options='-O -a x') + nco.ncks(input=output_file, output=output_file, options='-O -x -v nav_lon,nav_lat') + + nco.ncrename(input=output_file, options='-v .time_counter,time -d .time_counter,time') + nco.ncrename(input=output_file, options='-d .gsize,y') + + temp = Utils.get_temp_file() + shutil.copy(input_file, temp) + nco.ncrename(input=output_file, options='-v .time_counter,time -d .time_counter,time') + + nco.ncks(input=input_file, output=output_file, options='-A -v nav_lon,nav_lat') + +def main(): + try: + moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out.nc") + Utils.clean() + except NCOException as ex: + Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py new file mode 100644 index 0000000..308c8e4 --- /dev/null +++ b/earthdiagnostics/ocean/heat.py @@ -0,0 +1,96 @@ +from earthdiagnostics import Utils +from log import Log +import os +import shutil +import traceback +from nco import NCOException + + +class Heat: + + @staticmethod + def layer(input_file, output_file, upper, lower): + cdo = Utils.cdo + nco = Utils.nco + + temp = Utils.get_temp_file() + temp2 = Utils.get_temp_file() + heatc_sl_out = Utils.get_temp_file() + heatc_sl_top = Utils.get_temp_file() + heatc_sl_bottom = Utils.get_temp_file() + heatc_sl_invert = Utils.get_temp_file() + e3tfile = Utils.get_temp_file() + + # Use this names for debugging + # temp = 'temp.nc' + # temp2 = 'temp2.nc' + # heatc_sl_out = 'heatc_sl_out.nc' + # heatc_sl_top = 'heatc_sl_top.nc' + # heatc_sl_bottom = 'heatc_sl_bottom.nc' + # heatc_sl_invert = 'heatc_sl_invert.nc' + # e3tfile = 'e3t_file.nc' + + nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*e3t"'), + nco.ncrename(input=e3tfile, output=e3tfile, options='-d t,time -d z,deptht') + + cdo.seltimestep('1', input=input_file, output=temp) + + nco.ncks(input=temp, output=temp, options='-O -v votemper') + nco.ncrename(input=temp, output=temp, options='-v votemper,heatc_sl') + cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) + os.remove(e3tfile) + nco.ncks(input=heatc_sl_out, output=temp, options='-O -d deptht,{0}.0,{1}.0'.format(upper, lower)) + + # perform the integration of ohc down to that level (main contribution) + nco.ncap2(input=temp, output=heatc_sl_top, options='-O -s "heatc_sl=heatc_sl.total($deptht)"') + + # now extract a few levels below, to compute the residual ohc + # obtain the weight for the extra level containing the 300 m + # deptht in the gridT files is positive + # weight = (300.0 - depth_top)/(depth_bottom - depth_top) + # and add the thickness down to 300 m in the next layer + nco.ncpdq(input=heatc_sl_out, output=heatc_sl_invert, options='-a "-deptht"') + nco.ncks(input=heatc_sl_invert, output=heatc_sl_invert, options='-O -d deptht,0,0,1') + nco.ncrename(input=heatc_sl_invert, output=heatc_sl_invert, options='-v deptht,layerthcknss') + + nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, + options='-O -d deptht,{0}.0,{1}.0'.format(lower, lower + 200)) + nco.ncks(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-O -d deptht,0,0,1') + nco.ncrename(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-v deptht,layerthcknss') + + os.remove(heatc_sl_out) + + # Here, add the residual contribution, before adding it to the main contribution + nco.ncbo(input=' '.join([heatc_sl_bottom, heatc_sl_invert]), output=temp, + options='-A --op_typ=sub -v layerthcknss') + + nco.ncrename(input=temp, output=temp, options='-v layerthcknss,heatc_sl') + nco.ncap2(input=heatc_sl_invert, output=temp2, options='-s "heatc_sl=($3 - layerthcknss)"') + os.remove(heatc_sl_invert) + nco.ncbo(input=' '.join([temp, temp2]), output=temp, options='--op_typ=/ -v heatc_sl') + os.remove(temp2) + nco.ncrename(input=temp, output=temp, options='-v heatc_sl,factor') + nco.ncks(input=temp, output=heatc_sl_bottom, options='-A -v factor') + nco.ncap2(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-O -s "heatc_sl=(factor * heatc_sl)"') + nco.ncwa(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-O -a deptht') + nco.ncbo(input=' '.join([heatc_sl_top, heatc_sl_bottom]), output=temp, options='--op_typ=+ -v heatc_sl') + os.remove(heatc_sl_top) + os.remove(heatc_sl_bottom) + nco.ncap2(input=temp, output=temp, options='-s "heatc_sl=1020.0*4000*heatc_sl"') + + Utils.setminmax(temp, ['heatc_sl']) + + shutil.move(temp, output_file) + os.remove(temp) + + +def main(): + try: + Heat.layer("ORCA1_MM_19601101_19610228_grid_T.nc", "out.nc", 300, 2000) + except NCOException as ex: + Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) + Log.error(traceback.format_exc()) + + +if __name__ == "__main__": + main() diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py new file mode 100644 index 0000000..e70fc06 --- /dev/null +++ b/earthdiagnostics/ocean/salinity.py @@ -0,0 +1,103 @@ +from earthdiagnostics import Utils, cdftools +from log import Log +import os +import shutil + + +class Salinity: + @staticmethod + def vertical_mean(input_file, output_file, upper, lower): + """ + Vertically averaged salt content + Created in February 2012 Author : vguemas@ic3.cat + + :param input_file: input grid_T file name + :param upper: upper depth of the layer (in meters) + :type upper: int + :param lower: lower depth of the layer (in meters) + :type lower: int + :param output_file: output file name (=> 2D) + """ + cdo = Utils.cdo + nco = Utils.nco + + temp = Utils.get_temp_file() + nco.ncrename(input=input_file, output=temp, + options='-O -d time,time_counter -v time,time_counter') + + Log.info('Calculating vertical mean') + # test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values + # out of that range to be replaced by NaN + + if cdo.version() > u'1.5.6': + nco.ncatted(input=temp, output=temp, options='-O -a valid_max,deptht,d,,') + nco.ncatted(input=temp, output=temp, options='-O -a valid_min,deptht,d,,') + + cdftools.run('cdfvertmean', input=temp, output=output_file, options=['vosaline', 'T', str(upper), str(lower), + '-full']) + nco.ncrename(input=output_file, output=output_file, + options='-O -v vosaline_vert_mean,vertmeansal -d time_counter,time -v time_counter,time') + Utils.setminmax(output_file, ['vertmeansal']) + Log.result('Finished!') + + @staticmethod + def heat_sal_mxl(input_file, output_file): + """ + Compute mixed layer heat and salt content + + Created in February 2012 Author : vguemas@ic3.cat + + :param input_file: input grid_T file name + :param output_file: output file name (=> 2D x-y ) + :return: + """ + + cdo = Utils.cdo + nco = Utils.nco + + temp = Utils.get_temp_file() + temp2 = Utils.get_temp_file() + + handler = cdo.openCdf(input_file) + + if 'time' in handler.variables: + nco.ncrename(input=input_file, output=temp, options='-O -d time,time_counter -v time,time_counter') + else: + shutil.copy(input_file, temp) + + if 'somxl010' not in handler.variables: + Log.info('Computing mixed layer') + cdftools.run('cdfmxl', input=temp, output=temp2) + nco.ncrename(input=temp2, output=temp2, options='-d time_counter,time') + nco.ncks(input=temp2, output=temp, options='-A') + os.remove(temp2) + + Log.info('Computing heat content') + cdftools.run('cdfmxlheatc', input=temp, options=['-full']) + + if 'vosaline' in handler.variables: + Log.info('Computing salt content') + cdftools.run('cdfmxlsaltc', input=temp, options=['-full']) + nco.ncks(input='mxlsaltc.nc', output='mxlheatc.nc', options='-A') + os.remove('mxlsaltc.nc') + shutil.move('mxlheatc.nc', temp) + + nco.ncrename(input=temp, output=temp, options='-v .time_counter,time -d .time_counter,time') + + handler = cdo.openCdf(temp) + variables = ['somxlheatc'] + if 'somxlsaltc' in handler.variables: + variables.append('somxlsaltc') + + Utils.setminmax(temp, variables) + shutil.move(temp, output_file) + Log.result('Finished!') + + +def main(): + Salinity.vertical_mean("ORCA1_MM_19601101_19610228_grid_T.nc", "out.nc", 300, 5400) + Salinity.heat_sal_mxl("ORCA1_MM_19601101_19610228_grid_T.nc", "out.nc") + + +if __name__ == "__main__": + main() diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py new file mode 100644 index 0000000..2651ccd --- /dev/null +++ b/earthdiagnostics/utils.py @@ -0,0 +1,41 @@ +import numpy as np +from log import Log +from cdo import Cdo +from nco import Nco +import tempfile +import os + + +class Utils(object): + scratch_folder = '/scratch/Earth/jvegas' + + nco = Nco() + cdo = Cdo() + files = list() + + @staticmethod + def setminmax(filename, variable_list): + Log.info('Getting max and min values for {0}', ' '.join(variable_list)) + dataset = Utils.nco.readCdf(filename) + for variable in variable_list: + var = dataset.variables[variable] + values = [np.max(var), np.min(var)] + Utils.nco.ncatted(input=filename, output=filename, + options='-h -a valid_max,{0},m,f,{1}'.format(variable, values[0])) + Utils.nco.ncatted(input=filename, output=filename, + options='-h -a valid_min,{0},m,f,{1}'.format(variable, values[1])) + + @staticmethod + def get_temp_file(): + temp_file = tempfile.mkstemp(dir=Utils.scratch_folder, prefix='diag', suffix='.nc')[1] + Utils.files.append(temp_file) + return temp_file + + @staticmethod + def get_scratch_file(filename): + return os.path.join(Utils.scratch_folder, filename) + + @staticmethod + def clean(): + for temp_file in Utils.files: + os.remove(temp_file) diff --git a/log.py b/log.py new file mode 100644 index 0000000..6b11b74 --- /dev/null +++ b/log.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python + +# Copyright 2015 Earth Sciences Department, BSC-CNS + +# This file is part of Autosubmit. + +# Autosubmit is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# Autosubmit is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with Autosubmit. If not, see . + +import logging +import os +import sys +from datetime import datetime + + +class LogFormatter: + """ + Class to format log output. + + :param to_file: If True, creates a LogFormatter for files; if False, for console + :type to_file: bool + """ + RESULT = '\033[32m' + WARNING = '\033[33m' + ERROR = '\033[31m' + CRITICAL = '\033[1m \033[31m' + DEFAULT = '\033[0m\033[39m' + + def __init__(self, to_file=False): + """ + Initializer for LogFormatter + + + """ + self._file = to_file + if self._file: + self._formatter = logging.Formatter('%(asctime)s %(message)s') + else: + self._formatter = logging.Formatter('%(message)s') + + def format(self, record): + """ + Format log output, adding labels if needed for log level. If logging to console, also manages font color. + If logging to file adds timestamp + + :param record: log record to format + :type record: LogRecord + :return: formatted record + :rtype: str + """ + header = '' + if record.levelno == Log.RESULT: + if not self._file: + header = LogFormatter.RESULT + elif record.levelno == Log.USER_WARNING: + if not self._file: + header = LogFormatter.WARNING + elif record.levelno == Log.WARNING: + if not self._file: + header = LogFormatter.WARNING + header += "[WARNING] " + elif record.levelno == Log.ERROR: + if not self._file: + header = LogFormatter.ERROR + header += "[ERROR] " + elif record.levelno == Log.CRITICAL: + if not self._file: + header = LogFormatter.ERROR + header += "[CRITICAL] " + + msg = self._formatter.format(record) + if header != '' and not self._file: + msg += LogFormatter.DEFAULT + return header + msg + + +class Log: + """ + Static class to manage the log for the application. Messages will be sent to console and to file if it is + configured. Levels can be set for each output independently. These levels are (from lower to higher priority): + + - EVERYTHING : this level is just defined to show every output + - DEBUG + - INFO + - RESULT + - USER_WARNING + - WARNING + - ERROR + - CRITICAL + - NO_LOG : this level is just defined to remove every output + + """ + EVERYTHING = 0 + DEBUG = logging.DEBUG + INFO = logging.INFO + RESULT = 25 + USER_WARNING = 29 + WARNING = logging.WARNING + ERROR = logging.ERROR + CRITICAL = logging.CRITICAL + NO_LOG = CRITICAL + 1 + + logging.basicConfig() + + log = logging.Logger('Autosubmit', EVERYTHING) + + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setLevel(INFO) + console_handler.setFormatter(LogFormatter(False)) + log.addHandler(console_handler) + + file_handler = None + file_level = INFO + + @staticmethod + def set_file(file_path): + """ + Configure the file to store the log. If another file was specified earlier, new messages will only go to the + new file. + + :param file_path: file to store the log + :type file_path: str + """ + (directory, filename) = os.path.split(file_path) + if not os.path.exists(directory): + os.mkdir(directory) + files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f)) and + f.endswith(filename)] + if len(files) >= 5: + files.sort() + os.remove(os.path.join(directory, files[0])) + file_path = os.path.join(directory, '{0:%Y%m%d_%H%M%S}_'.format(datetime.now()) + filename) + if Log.file_handler is not None: + Log.log.removeHandler(Log.file_handler) + Log.file_handler = logging.FileHandler(file_path, 'w') + Log.file_handler.setLevel(Log.file_level) + Log.file_handler.setFormatter(LogFormatter(True)) + Log.log.addHandler(Log.file_handler) + os.chmod(file_path, 0o775) + + @staticmethod + def set_console_level(level): + """ + Sets log level for logging to console. Every output of level equal or higher to parameter level will be + printed on console + + :param level: new level for console + :return: None + """ + if type(level) is str: + level = getattr(Log, level) + Log.console_handler.level = level + + @staticmethod + def set_file_level(level): + """ + Sets log level for logging to file. Every output of level equal or higher to parameter level will be + added to log file + + :param level: new level for log file + """ + if type(level) is str: + level = getattr(Log, level) + Log.file_level = level + if Log.file_handler is not None: + Log.file_handler.level = level + + @staticmethod + def debug(msg, *args): + """ + Sends debug information to the log + + :param msg: message to show + :param args: arguments for message formating (it will be done using format() method on str) + """ + Log.log.debug(msg.format(*args)) + + @staticmethod + def info(msg, *args): + """ + Sends information to the log + + :param msg: message to show + :param args: arguments for message formating (it will be done using format() method on str) + """ + Log.log.info(msg.format(*args)) + + @staticmethod + def result(msg, *args): + """ + Sends results information to the log. It will be shown in green in the console. + + :param msg: message to show + :param args: arguments for message formating (it will be done using format() method on str) + """ + Log.log.log(Log.RESULT, msg.format(*args)) + + @staticmethod + def user_warning(msg, *args): + """ + Sends warnings for the user to the log. It will be shown in yellow in the console. + + :param msg: message to show + :param args: arguments for message formating (it will be done using format() method on str) + """ + Log.log.log(Log.USER_WARNING, msg.format(*args)) + + @staticmethod + def warning(msg, *args): + """ + Sends program warnings to the log. It will be shown in yellow in the console. + + :param msg: message to show + :param args: arguments for message formating (it will be done using format() method on str) + """ + Log.log.warning(msg.format(*args)) + + @staticmethod + def error(msg, *args): + """ + Sends errors to the log. It will be shown in red in the console. + + :param msg: message to show + :param args: arguments for message formating (it will be done using format() method on str) + """ + Log.log.error(msg.format(*args)) + + @staticmethod + def critical(msg, *args): + """ + Sends critical errors to the log. It will be shown in red in the console. + + :param msg: message to show + :param args: arguments for message formating (it will be done using format() method on str) + """ + Log.log.critical(msg.format(*args)) -- GitLab From e871e703da8ce9ccadd42a1b8ea858631f6740e7 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 5 Apr 2016 17:56:09 +0200 Subject: [PATCH 025/268] Added MOC --- earthdiagnostics/models.py | 13 ++++ earthdiagnostics/ocean/__init__.py | 3 + earthdiagnostics/ocean/circulation.py | 62 +++++++++-------- earthdiagnostics/ocean/convection.py | 96 +++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 29 deletions(-) create mode 100644 earthdiagnostics/models.py create mode 100644 earthdiagnostics/ocean/convection.py diff --git a/earthdiagnostics/models.py b/earthdiagnostics/models.py new file mode 100644 index 0000000..93fd31d --- /dev/null +++ b/earthdiagnostics/models.py @@ -0,0 +1,13 @@ + +class Grid(object): + + ECEARTH_2_3_O1L42 = 'Ec2.3_O1L42' + ECEARTH_3_0_O1L46 = 'Ec3.0_O1L46' + ECEARTH_3_0_O25L46 = 'Ec3.0_O25L46' + ECEARTH_3_0_O25L75 = 'Ec3.0_O25L75' + + NEMO_3_2_O1L42 = 'N3.2_O1L42' + NEMO_3_3_O1L46 = 'N3.3_O1L46' + + NEMOVAR_O1L42 = 'nemovar_O1L42' + GLORYS2_V1_O25L75 = 'glorys2v1_O25L75' diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 61065a0..6724e3d 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1 +1,4 @@ from salinity import Salinity +from heat import Heat +from convection import Convection +from circulation import Circulation diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index f12f73c..992504f 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -5,38 +5,42 @@ import os import shutil -def moc(input_file, output_file): - """ - Compute the MOC for oceanic basins - Created in March 2012 - Author : vguemas@ic3.cat - - :param input_file: input grid_V file name - :type input_file: str - :param output_file: output file name (=> 2D, depth-y) - :param output_file: str - :return: - """ - nco = Utils.nco - if os.path.exists(output_file): - os.remove(output_file) - - cdftools.run('cdfmoc', input=input_file, output=output_file) - nco.ncwa(input=output_file, output=output_file, options='-O -a x') - nco.ncks(input=output_file, output=output_file, options='-O -x -v nav_lon,nav_lat') - - nco.ncrename(input=output_file, options='-v .time_counter,time -d .time_counter,time') - nco.ncrename(input=output_file, options='-d .gsize,y') - - temp = Utils.get_temp_file() - shutil.copy(input_file, temp) - nco.ncrename(input=output_file, options='-v .time_counter,time -d .time_counter,time') - - nco.ncks(input=input_file, output=output_file, options='-A -v nav_lon,nav_lat') +class Circulation(object): + + @staticmethod + def moc(input_file, output_file): + """ + Compute the MOC for oceanic basins + Created in March 2012 + Author : vguemas@ic3.cat + + :param input_file: input grid_V file name + :type input_file: str + :param output_file: output file name (=> 2D, depth-y) + :param output_file: str + :return: + """ + nco = Utils.nco + if os.path.exists(output_file): + os.remove(output_file) + + cdftools.run('cdfmoc', input=input_file, output=output_file) + nco.ncwa(input=output_file, output=output_file, options='-O -a x') + nco.ncks(input=output_file, output=output_file, options='-O -x -v nav_lon,nav_lat') + + nco.ncrename(input=output_file, output=output_file, options='-v .time_counter,time -d .time_counter,time') + nco.ncrename(input=output_file, output=output_file, options='-d .gsize,y') + + temp = Utils.get_temp_file() + shutil.copy(input_file, temp) + nco.ncrename(input=output_file, output=output_file, options='-v .time_counter,time -d .time_counter,time') + + nco.ncks(input=input_file, output=output_file, options='-A -v nav_lon,nav_lat') + def main(): try: - moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out.nc") + Circulation.moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out.nc") Utils.clean() except NCOException as ex: Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) diff --git a/earthdiagnostics/ocean/convection.py b/earthdiagnostics/ocean/convection.py new file mode 100644 index 0000000..7a4e230 --- /dev/null +++ b/earthdiagnostics/ocean/convection.py @@ -0,0 +1,96 @@ +from earthdiagnostics.models import Grid +from earthdiagnostics import Utils +from nco import NCOException +from log import Log + +############################################################################### +# # +# Compute the intensity of convection in the four main convection sites # +# # +# $1 : input oce file name containing somxl010 # +# $2 : input grid # +# $3 : output file name (=> index) # +# # +# Created in October 2013 Author : vguemas@ic3.cat # +############################################################################### + +class Convection(object): + @staticmethod + def main_sites(input_file, input_grid, output_file): + """ + Compute the intensity of convection in the four main convection sites + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_file: input oce file name containing somxl010 + :param input_grid: input grid + :param output_file: output file name (=> index) + :return: + """ + if input_grid in [Grid.ECEARTH_2_3_O1L42, Grid.ECEARTH_3_0_O1L46, + Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, + Grid.NEMOVAR_O1L42]: + labrador = [255, 245, 215, 255] + irminger = [245, 290, 215, 245] + gin = [260, 310, 245, 291] + wedell = [225, 280, 1, 50] + + elif input_grid in [Grid.ECEARTH_3_0_O25L46, Grid.ECEARTH_3_0_O25L75, + Grid.GLORYS2_V1_O25L75]: + raise Exception("Option convection not available yet for {0}".format(input_grid)) + else: + raise Exception("Input grid {0} not recognized".format(input_grid)) + + labrador_file = Utils.get_temp_file() + Convection.site(input_file, labrador, labrador_file) + + irminger_file = Utils.get_temp_file() + Convection.site(input_file, irminger, irminger_file) + + gin_file = Utils.get_temp_file() + Convection.site(input_file, gin, gin_file) + + wedell_file = Utils.get_temp_file() + Convection.site(input_file, wedell, wedell_file) + + nco = Utils.nco + + nco.ncrename(input=labrador_file, output=labrador_file, options='-v somxl010,Labrador') + nco.ncrename(input=irminger_file, output=irminger_file, options='-v somxl010,Irminger') + nco.ncrename(input=gin_file, output=gin_file, options='-v somxl010,GIN') + nco.ncrename(input=wedell_file, output=wedell_file, options='-v somxl010,Wedell') + + nco.ncks(input=labrador_file, output=output_file, options='-O -v Labrador') + nco.ncks(input=irminger_file, output=output_file, options='-A -v Irminger') + nco.ncks(input=gin_file, output=output_file, options='-A -v GIN') + nco.ncks(input=wedell_file, output=output_file, options='-A -v Wedell') + + @staticmethod + def site(input_file, site, output_file): + """ + Compute the intensity of convection at one site + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_file: input oce file name containing somxl010 + :param site: site to calculate convection on + :param output_file: output file name (=> index) + :return: + """ + + Utils.cdo.fldmax(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), + output=output_file) + + + + +def main(): + try: + Convection.main_sites("/scratch/Earth/jvegas/compsstest/ORCA1_MM_19601101_19610228_grid_T.nc", + Grid.ECEARTH_2_3_O1L42, "outconvection.nc") + Utils.clean() + except NCOException as ex: + Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) + +if __name__ == "__main__": + main() \ No newline at end of file -- GitLab From abc25bf9a6b8a6ff12771163e40ba960538f2783 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 6 Apr 2016 10:07:02 +0200 Subject: [PATCH 026/268] Added psi --- earthdiagnostics/cdftools.py | 6 ++++- earthdiagnostics/ocean/circulation.py | 33 +++++++++++++++++++++++---- earthdiagnostics/ocean/convection.py | 21 ++++------------- earthdiagnostics/utils.py | 15 +++++++++++- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 527a155..7b31876 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -11,7 +11,11 @@ class CDFTools: def run(self, command, input, output=None, options=None): line = [os.path.join(self.path, command)] if input: - line.append(input) + if isinstance(input, basestring): + line.append(input) + else: + for element in input: + line.append(element) if options: for option in options: line.append(option) diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 992504f..a0aea28 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -28,22 +28,45 @@ class Circulation(object): nco.ncwa(input=output_file, output=output_file, options='-O -a x') nco.ncks(input=output_file, output=output_file, options='-O -x -v nav_lon,nav_lat') - nco.ncrename(input=output_file, output=output_file, options='-v .time_counter,time -d .time_counter,time') - nco.ncrename(input=output_file, output=output_file, options='-d .gsize,y') + Utils.rename_variable(output_file, 'time_counter', 'time', False, True) + Utils.rename_variable(output_file, 'gsize', 'y', False) temp = Utils.get_temp_file() shutil.copy(input_file, temp) - nco.ncrename(input=output_file, output=output_file, options='-v .time_counter,time -d .time_counter,time') + Utils.rename_variable(output_file, 'time_counter', 'time', False, True) nco.ncks(input=input_file, output=output_file, options='-A -v nav_lon,nav_lat') + @staticmethod + def psi(input_file_u, input_file_v, output_file): + """ + Compute the barotropic stream function + + Created in March 2012 Author : vguemas@ic3.cat + :param input_file_u: input grid_U file name + :rtype input_file_U: str + :param input_file_v: input grid_V file name + :rtype input_file_V: str + :param output_file: output file name without nc extension (=> 2D x-y) + :rtype output_file: str + """ + integrated_u = Utils.get_temp_file() + integrated_v = Utils.get_temp_file() + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_u, ) + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_v, options='V') + + Utils.nco.ncea(input=[integrated_u, integrated_v], output=output_file) + Utils.rename_variable(output_file, 'time_counter', 'time', False, True) + def main(): try: - Circulation.moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out.nc") - Utils.clean() + Circulation.psi("ORCA1_MM_19601101_19610228_grid_U.nc", "ORCA1_MM_19601101_19610228_grid_V.nc", "out_psi.nc") + Circulation.moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out_moc.nc") except NCOException as ex: Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) + Utils.clean() + if __name__ == "__main__": main() \ No newline at end of file diff --git a/earthdiagnostics/ocean/convection.py b/earthdiagnostics/ocean/convection.py index 7a4e230..3b9ce9a 100644 --- a/earthdiagnostics/ocean/convection.py +++ b/earthdiagnostics/ocean/convection.py @@ -3,16 +3,6 @@ from earthdiagnostics import Utils from nco import NCOException from log import Log -############################################################################### -# # -# Compute the intensity of convection in the four main convection sites # -# # -# $1 : input oce file name containing somxl010 # -# $2 : input grid # -# $3 : output file name (=> index) # -# # -# Created in October 2013 Author : vguemas@ic3.cat # -############################################################################### class Convection(object): @staticmethod @@ -54,11 +44,10 @@ class Convection(object): Convection.site(input_file, wedell, wedell_file) nco = Utils.nco - - nco.ncrename(input=labrador_file, output=labrador_file, options='-v somxl010,Labrador') - nco.ncrename(input=irminger_file, output=irminger_file, options='-v somxl010,Irminger') - nco.ncrename(input=gin_file, output=gin_file, options='-v somxl010,GIN') - nco.ncrename(input=wedell_file, output=wedell_file, options='-v somxl010,Wedell') + Utils.rename_variable(labrador_file, 'somxl010', 'Labrador') + Utils.rename_variable(irminger_file, 'somxl010', 'Irminger') + Utils.rename_variable(gin_file, 'somxl010', 'GIN') + Utils.rename_variable(wedell_file, 'somxl010', 'Wedell') nco.ncks(input=labrador_file, output=output_file, options='-O -v Labrador') nco.ncks(input=irminger_file, output=output_file, options='-A -v Irminger') @@ -79,7 +68,7 @@ class Convection(object): """ Utils.cdo.fldmax(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), - output=output_file) + output=output_file) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 2651ccd..73b72de 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -38,4 +38,17 @@ class Utils(object): @staticmethod def clean(): for temp_file in Utils.files: - os.remove(temp_file) + if os.path.exists(temp_file): + os.remove(temp_file) + + @staticmethod + def rename_variable(filename, old_name, new_name, must_exist=True, rename_dimension=False): + if must_exist: + dot = '' + else: + dot = '.' + options = '-v {0}{1},{2}'.format(dot, old_name, new_name) + if rename_dimension: + options += ' -d {0}{1},{2}'.format(dot, old_name, new_name) + Utils.nco.ncrename(input=filename, output=filename, options=options) + return os.path.join(Utils.scratch_folder, filename) -- GitLab From 68a1109be34d1d9cddf0e3bc89408ac0dfd581e8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 6 Apr 2016 10:55:51 +0200 Subject: [PATCH 027/268] Added gyres --- earthdiagnostics/ocean/circulation.py | 98 +++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index a0aea28..c71aa7e 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -1,4 +1,5 @@ from earthdiagnostics import Utils, cdftools +from earthdiagnostics.models import Grid from log import Log from nco import NCOException import os @@ -58,10 +59,107 @@ class Circulation(object): Utils.nco.ncea(input=[integrated_u, integrated_v], output=output_file) Utils.rename_variable(output_file, 'time_counter', 'time', False, True) +############################################################################### +# # +# Compute the intensity of the subtropical and subpolar gyres # +# # +# $1 : input psi file name # +# $2 : input grid # +# $3 : output file name ( => index ) # +# # +# Created in October 2013 Author : vguemas@ic3.cat # +############################################################################### + @staticmethod + def gyres(input_psi, input_grid, output_file): + """ + Compute the intensity of the subtropical and subpolar gyres + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_psi: input psi file name + :param input_grid: input grid + :param output_file: output file name ( => index ) + :return: + """ + + if input_grid in [Grid.ECEARTH_2_3_O1L42, Grid.ECEARTH_3_0_O1L46, + Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, + Grid.NEMOVAR_O1L42]: + subpolNAtl = [230, 275, 215, 245] + subpolNPac = [70, 145, 195, 235] + subtropNPac = [45, 175, 165, 220] + subtropSPac = [195, 275, 175, 225] + subtropNAtl = [230, 275, 215, 245] + subtropSAtl = [70, 145, 195, 235] + subtropInd = [45, 175, 165, 220] + ACC = [195, 275, 175, 225] + + elif input_grid in [Grid.ECEARTH_3_0_O25L46, Grid.ECEARTH_3_0_O25L75, + Grid.GLORYS2_V1_O25L75]: + raise Exception("Option gyres not available yet for {0}".format(input_grid)) + else: + raise Exception("Input grid {0} not recognized".format(input_grid)) + + temp = Utils.get_temp_file() + Circulation.gyre(input_psi, subpolNAtl, output_file, invert=True) + Utils.rename_variable(output_file, 'sobarstf', 'subpolNAtl') + + Circulation.gyre(input_psi, subpolNPac, temp, invert=True) + Utils.rename_variable(temp, 'sobarstf', 'subpolNPac') + Utils.nco.ncks(input=temp, output=output_file, options='-A') + + Circulation.gyre(input_psi, subtropNPac, temp) + Utils.rename_variable(temp, 'sobarstf', 'subtropNPac') + Utils.nco.ncks(input=temp, output=output_file, options='-A') + + Circulation.gyre(input_psi, subtropSPac, temp) + Utils.rename_variable(temp, 'sobarstf', 'subtropSPac') + Utils.nco.ncks(input=temp, output=output_file, options='-A') + + Circulation.gyre(input_psi, subtropNAtl, temp) + Utils.rename_variable(temp, 'sobarstf', 'subtropNAtl') + Utils.nco.ncks(input=temp, output=output_file, options='-A') + + Circulation.gyre(input_psi, subtropSAtl, temp) + Utils.rename_variable(temp, 'sobarstf', 'subtropSAtl') + Utils.nco.ncks(input=temp, output=output_file, options='-A') + + Circulation.gyre(input_psi, subtropInd, temp) + Utils.rename_variable(temp, 'sobarstf', 'subtropInd') + Utils.nco.ncks(input=temp, output=output_file, options='-A') + + Circulation.gyre(input_psi, ACC, temp) + Utils.rename_variable(temp, 'sobarstf', 'ACC') + Utils.nco.ncks(input=temp, output=output_file, options='-A') + + @staticmethod + def gyre(input_file, site, output_file, invert=False): + """ + Compute the intensity of a given gyre + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_file: input oce file name containing sobarstf + :param site: site to calculate convection on + :param output_file: output file name (=> index) + :param invert: if True, multiplies result by -1 + :return: + """ + temp = Utils.get_temp_file() + Utils.cdo.fldmin(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), + output=temp) + if invert: + Utils.cdo.mulc(-1, input=temp, output=output_file) + os.remove(temp) + else: + shutil.move(temp, output_file) + def main(): try: Circulation.psi("ORCA1_MM_19601101_19610228_grid_U.nc", "ORCA1_MM_19601101_19610228_grid_V.nc", "out_psi.nc") + Circulation.gyres("/scratch/Earth/jvegas/compsstest/out_psi.nc", + Grid.ECEARTH_2_3_O1L42, "out_gyres.nc") Circulation.moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out_moc.nc") except NCOException as ex: Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) -- GitLab From 186a1c7827cfcc1d840774f3b260f950075a9c4b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 6 Apr 2016 15:30:25 +0200 Subject: [PATCH 028/268] Added area_moc --- earthdiagnostics/cdftools.py | 1 + earthdiagnostics/ocean/circulation.py | 77 ++++++++++++++++++++++----- earthdiagnostics/ocean/convection.py | 8 ++- 3 files changed, 68 insertions(+), 18 deletions(-) diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 7b31876..91b84fd 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -8,6 +8,7 @@ class CDFTools: def __init__(self, path=''): self.path = path + # noinspection PyShadowingBuiltins def run(self, command, input, output=None, options=None): line = [os.path.join(self.path, command)] if input: diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index c71aa7e..1599116 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -38,6 +38,65 @@ class Circulation(object): nco.ncks(input=input_file, output=output_file, options='-A -v nav_lon,nav_lat') + ############################################################################### +# # +# Compute an Atlantic MOC index by averaging the meridional overturning # +# in a latitude band between 1km and 2km # +# or any other index averaging the meridional overturning in # +# a given basin and a given domain # +# # +# $1 : input moc file name # +# $2 : latitude min # +# $3 : latitude max # +# $4 : output file name ( => index ) # +# $5 : depth min (default : 1km) # +# $6 : depth max (default : 2km) # +# $7 : basin (default : zomsfatl) # +# # +# Created in March 2012 Author : vguemas@ic3.cat # +############################################################################### + @staticmethod + def area_moc(input_file, lat_min, lat_max, output_file, depth_min=1000, depth_max=2000, basin='zomsfatl'): + """ + Compute an Atlantic MOC index by averaging the meridional overturning + in a latitude band between 1km and 2km + or any other index averaging the meridional overturning in + a given basin and a given domain + + Created in March 2012 Author : vguemas@ic3.cat + + :param input_file: input moc file name + :param lat_min: latitude min + :param lat_max: latitude max + :param output_file: output file name ( => index ) + :param depth_min: depth min (default : 1km) + :param depth_max: depth max (default : 2km) + :param basin: basin (default : zomsfatl) + :return: + """ + nco = Utils.nco + cdo = Utils.cdo + temp = Utils.get_temp_file() + temp2 = Utils.get_temp_file() + + handler = Utils.cdo.openCdf(input_file) + + if 'x' in handler.dimensions: + nco.ncwa(input=input_file, output=temp, options='-O -a x') + else: + shutil.copy(input_file, temp) + + nco.ncrename(input=temp, output=temp2, options='-v nav_lat,lat -d y,lat') + + nco.ncks(input=temp2, output=temp, options='-O -v {0},time,depthw,lat'.format(basin)) + nco.ncks(input=temp, output=temp, options='-O -d lat,{0:.1f},{1:.1f} -d depthw,' + '-{2:.1f},-{3:.1f}'.format(lat_min, lat_max, depth_max, depth_min)) + + cdo.vertmean(input=temp, output=temp2) + nco.ncap2(input=temp2, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') + nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') + nco.ncks(input=temp, output=output_file, options='-O -v {0},time'.format(basin)) + @staticmethod def psi(input_file_u, input_file_v, output_file): """ @@ -59,16 +118,7 @@ class Circulation(object): Utils.nco.ncea(input=[integrated_u, integrated_v], output=output_file) Utils.rename_variable(output_file, 'time_counter', 'time', False, True) -############################################################################### -# # -# Compute the intensity of the subtropical and subpolar gyres # -# # -# $1 : input psi file name # -# $2 : input grid # -# $3 : output file name ( => index ) # -# # -# Created in October 2013 Author : vguemas@ic3.cat # -############################################################################### + # noinspection PyPep8Naming @staticmethod def gyres(input_psi, input_grid, output_file): """ @@ -83,8 +133,8 @@ class Circulation(object): """ if input_grid in [Grid.ECEARTH_2_3_O1L42, Grid.ECEARTH_3_0_O1L46, - Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, - Grid.NEMOVAR_O1L42]: + Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, + Grid.NEMOVAR_O1L42]: subpolNAtl = [230, 275, 215, 245] subpolNPac = [70, 145, 195, 235] subtropNPac = [45, 175, 165, 220] @@ -161,10 +211,11 @@ def main(): Circulation.gyres("/scratch/Earth/jvegas/compsstest/out_psi.nc", Grid.ECEARTH_2_3_O1L42, "out_gyres.nc") Circulation.moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out_moc.nc") + Circulation.area_moc("out_moc.nc", 40, 80, 'out_area_moc.nc', 0, 41) except NCOException as ex: Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) Utils.clean() if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/earthdiagnostics/ocean/convection.py b/earthdiagnostics/ocean/convection.py index 3b9ce9a..108a2c8 100644 --- a/earthdiagnostics/ocean/convection.py +++ b/earthdiagnostics/ocean/convection.py @@ -18,8 +18,8 @@ class Convection(object): :return: """ if input_grid in [Grid.ECEARTH_2_3_O1L42, Grid.ECEARTH_3_0_O1L46, - Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, - Grid.NEMOVAR_O1L42]: + Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, + Grid.NEMOVAR_O1L42]: labrador = [255, 245, 215, 255] irminger = [245, 290, 215, 245] gin = [260, 310, 245, 291] @@ -71,8 +71,6 @@ class Convection(object): output=output_file) - - def main(): try: Convection.main_sites("/scratch/Earth/jvegas/compsstest/ORCA1_MM_19601101_19610228_grid_T.nc", @@ -82,4 +80,4 @@ def main(): Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) if __name__ == "__main__": - main() \ No newline at end of file + main() -- GitLab From c8372cd312e4bb54f92770485e56ced3b5cd863e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 11 Apr 2016 16:05:03 +0200 Subject: [PATCH 029/268] First version of diagnostics executer --- earthdiagnostics/cdftools.py | 13 +- earthdiagnostics/diags.conf | 17 ++ earthdiagnostics/diags.py | 132 ++++++++++++++ earthdiagnostics/ocean/circulation.py | 66 ++++--- earthdiagnostics/ocean/convection.py | 2 +- earthdiagnostics/ocean/heat.py | 2 +- earthdiagnostics/ocean/salinity.py | 31 ++-- earthdiagnostics/parser.py | 207 ++++++++++++++++++++++ earthdiagnostics/utils.py | 17 +- log.py | 246 -------------------------- 10 files changed, 446 insertions(+), 287 deletions(-) create mode 100644 earthdiagnostics/diags.conf create mode 100644 earthdiagnostics/diags.py create mode 100644 earthdiagnostics/parser.py delete mode 100644 log.py diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 91b84fd..04d0155 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -1,6 +1,6 @@ import subprocess import os -from log import Log +from autosubmit.config.log import Log class CDFTools: @@ -9,7 +9,7 @@ class CDFTools: self.path = path # noinspection PyShadowingBuiltins - def run(self, command, input, output=None, options=None): + def run(self, command, input, output=None, options=None, log_level=Log.DEBUG): line = [os.path.join(self.path, command)] if input: if isinstance(input, basestring): @@ -21,9 +21,14 @@ class CDFTools: for option in options: line.append(option) if output: + if input == output: + raise Exception('Input and output file can not be the same on CDFTools') line.append('-o') line.append(output) - + Log.debug('Executing {0}', ' '.join(line)) process = subprocess.Popen(line, stdout=subprocess.PIPE) - Log.log.log(Log.INFO, process.communicate()) + for line in process.communicate(): + if not line: + continue + Log.log.log(log_level, line) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf new file mode 100644 index 0000000..c9d1fcc --- /dev/null +++ b/earthdiagnostics/diags.conf @@ -0,0 +1,17 @@ +[DIAGNOSTICS] +SCRATCH_DIR = /scratch/Earth/jvegas +DATA_DIR = /esnas/exp/ecearth/cmorfiles +CON_FILES = /esnas/autosubmit/con_files/ +DIAGS =vert_mean_sal +FREQUENCY = mon +CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin + +[EXPERIMENT] +INSTITUTE = IC3 +EXPID = a030 +STARTDATES = 19900101 +CHUNK_SIZE = 3 +CHUNKS = 2 +MEMBERS = 0 +MODEL = EC-EARTH3 +NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py new file mode 100644 index 0000000..8d0bf2d --- /dev/null +++ b/earthdiagnostics/diags.py @@ -0,0 +1,132 @@ +from parser import Parser +from autosubmit.config.log import Log +from earthdiagnostics.ocean import Salinity +from utils import Utils +from earthdiagnostics import cdftools +from autosubmit.date.chunk_date_lib import * +import shutil +import os + + +class Diags: + def __init__(self, config_file): + self._read_config(config_file) + Utils.scratch_folder = os.path.join(self.scratch_dir) + cdftools.path = self.cdftools_path + + def run(self): + if not os.path.exists(self.scratch_dir): + os.makedirs(self.scratch_dir) + os.chdir(self.scratch_dir) + + # Copy mesh files + Log.info('Copying mesh files') + shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc') + shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_zgr.nc') + shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mask.nc') + shutil.copy(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc') + + # dic_variables = dict() + # dic_variables['x'] = 'i' + # dic_variables['y'] = 'j' + # dic_variables['z'] = 'lev' + # dic_variables['nav_lon'] = 'lon' + # dic_variables['nav_lat'] = 'lat' + # dic_variables['nav_lev'] = 'lev' + # dic_variables['time_counter'] = 'time' + # dic_variables['t'] = 'time' + # + # Utils.rename_variables('mesh_hgr.nc', dic_variables, False, True) + # Utils.rename_variables('mesh_zgr.nc', dic_variables, False, True) + # Utils.rename_variables('mask.nc', dic_variables, False, True) + + if os.path.exists(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version))): + shutil.copy(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), + 'mask_regions.nc') + + # Check if cmorized and convert if not + + # Run diagnostics + Log.info('Running diagnostics') + for diag in self.diags.split(): + if diag == 'vert_mean_sal': + Log.info("Running vert_mean_sal") + min_depth = 0 + max_depth = 300 + for [input_file, output_file] in self._get_file_names('ocean', 'so', + 'vertmeansal'.format(min_depth, max_depth)): + Salinity.vertical_mean(str(input_file), str(output_file), min_depth, max_depth) + Log.result('Finished vert_mean_sal') + + Utils.clean() + + def _read_config(self, config_file): + self.parser = Parser() + self.parser.optionxform = str + self.parser.read(config_file) + + # Read diags config + self.scratch_dir = self.parser.get_option('DIAGNOSTICS', 'SCRATCH_DIR') + self.data_dir = self.parser.get_option('DIAGNOSTICS', 'DATA_DIR') + self.con_files = self.parser.get_option('DIAGNOSTICS', 'CON_FILES') + self.diags = self.parser.get_option('DIAGNOSTICS', 'DIAGS') + self.frequency = self.parser.get_option('DIAGNOSTICS', 'FREQUENCY') + self.cdftools_path = self.parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') + + # Read experiment config + self.institute = self.parser.get_option('EXPERIMENT', 'INSTITUTE') + self.expid = self.parser.get_option('EXPERIMENT', 'EXPID') + self.members = self.parser.get_option('EXPERIMENT', 'MEMBERS') + self.startdates = self.parser.get_option('EXPERIMENT', 'STARTDATES') + self.chunk_size = self.parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') + self.chunks = self.parser.get_int_option('EXPERIMENT', 'CHUNKS') + self.model = self.parser.get_option('EXPERIMENT', 'MODEL') + self.nemo_version = self.parser.get_option('EXPERIMENT', 'NEMO_VERSION') + + self.scratch_dir = os.path.join(self.scratch_dir, 'diags', self.expid) + + def _get_file_names(self, domain, input_var, output_var): + file_names = list() + + for startdate in self.startdates.split(): + start = parse_date(startdate) + for member in self.members: + member_plus = str(int(member)+1) + member_path = os.path.join(self.data_dir,self.expid, startdate, 'fc'+member, 'outputs', 'output', + self.institute, self.model, self.model, 'S'+startdate, self.frequency, + domain) + for chunk in range(1, self.chunks + 1): + chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + + input_file = os.path.join(member_path, input_var, 'r{0}i1p1'.format(member_plus), + '{0}_{1[0]}{2}_{3}_output_r{4}i1p1_' + '{5}-{6}.nc'.format(input_var, domain.upper(), + self.frequency, self.model, member_plus, + "{0:04}{1:02}".format(chunk_start.year, + chunk_start.month), + "{0:04}{1:02}".format(chunk_end.year, + chunk_end.month))) + output_file = os.path.join(member_path, input_var, 'r{0}i1p1'.format(member_plus), + '{0}_{1[0]}{2}_{3}_output_r{4}i1p1_' + '{5}-{6}.nc'.format(output_var, domain.upper(), + self.frequency, self.model, member_plus, + "{0:04}{1:02}".format(chunk_start.year, + chunk_start.month), + "{0:04}{1:02}".format(chunk_end.year, + chunk_end.month))) + file_names.append([input_file, output_file]) + + return file_names + + +def main(): + Log.set_console_level(Log.DEBUG) + diags = Diags('/home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/diags.conf') + diags.run() + # Utils.clean() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 1599116..7ecd403 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -1,6 +1,6 @@ from earthdiagnostics import Utils, cdftools from earthdiagnostics.models import Grid -from log import Log +from autosubmit.config.log import Log from nco import NCOException import os import shutil @@ -38,23 +38,6 @@ class Circulation(object): nco.ncks(input=input_file, output=output_file, options='-A -v nav_lon,nav_lat') - ############################################################################### -# # -# Compute an Atlantic MOC index by averaging the meridional overturning # -# in a latitude band between 1km and 2km # -# or any other index averaging the meridional overturning in # -# a given basin and a given domain # -# # -# $1 : input moc file name # -# $2 : latitude min # -# $3 : latitude max # -# $4 : output file name ( => index ) # -# $5 : depth min (default : 1km) # -# $6 : depth max (default : 2km) # -# $7 : basin (default : zomsfatl) # -# # -# Created in March 2012 Author : vguemas@ic3.cat # -############################################################################### @staticmethod def area_moc(input_file, lat_min, lat_max, output_file, depth_min=1000, depth_max=2000, basin='zomsfatl'): """ @@ -80,11 +63,11 @@ class Circulation(object): temp2 = Utils.get_temp_file() handler = Utils.cdo.openCdf(input_file) - if 'x' in handler.dimensions: nco.ncwa(input=input_file, output=temp, options='-O -a x') else: shutil.copy(input_file, temp) + handler.close() nco.ncrename(input=temp, output=temp2, options='-v nav_lat,lat -d y,lat') @@ -97,12 +80,54 @@ class Circulation(object): nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') nco.ncks(input=temp, output=output_file, options='-O -v {0},time'.format(basin)) + @staticmethod + def max_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max): + """ + Compute an Atlantic MOC index by finding the maximum of the annual + mean meridional overturning in a latitude / depth region + + Created in March 2012 Author : vguemas@ic3.cat + + :param input_file: input moc file name + :param lat_min: latitude min + :param lat_max: latitude max + :param output_file: output file name + :param depth_min: depth mean + :param depth_max: depth max + :return: + """ + + nco = Utils.nco + cdo = Utils.cdo + temp = Utils.get_temp_file() + temp2 = Utils.get_temp_file() + + handler = Utils.cdo.openCdf(input_file) + if 'x' in handler.dimensions: + nco.ncwa(input=input_file, output=temp, options='-O -a x') + else: + shutil.copy(input_file, temp) + handler.close() + + Utils.rename_variable(temp, 'record', 'x') + nco.ncdpq(input=temp, output=temp, options='-O -h -a time,x') + nco.ncdpq(input=temp, output=temp, options='-O -h -a depthw,x') + nco.ncdpq(input=temp, output=temp, options='-O -h -a y,x') + + cdo.yearmean(input=temp, output=temp2) + + cdftools.run('cdfmaxmoc', temp2, output=output_file, options='{0:.1f} {1:.1f} ' + '{2:.1f} {3:.1f}'.format(lat_min, lat_max, + depth_min, depth_max)) + Utils.rename_variable(output_file, 'time_counter', 'time', False, True) + @staticmethod def psi(input_file_u, input_file_v, output_file): """ Compute the barotropic stream function Created in March 2012 Author : vguemas@ic3.cat + z :param input_file_u: input grid_U file name :rtype input_file_U: str :param input_file_v: input grid_V file name @@ -211,7 +236,8 @@ def main(): Circulation.gyres("/scratch/Earth/jvegas/compsstest/out_psi.nc", Grid.ECEARTH_2_3_O1L42, "out_gyres.nc") Circulation.moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out_moc.nc") - Circulation.area_moc("out_moc.nc", 40, 80, 'out_area_moc.nc', 0, 41) + Circulation.max_moc("out_moc.nc", 40, 80, 'out_max<_moc.nc', 1000, 2000) + Circulation.area_moc("out_moc.nc", 40, 80, 'out_area_moc.nc', 1000, 2000) except NCOException as ex: Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) Utils.clean() diff --git a/earthdiagnostics/ocean/convection.py b/earthdiagnostics/ocean/convection.py index 108a2c8..2e2c59e 100644 --- a/earthdiagnostics/ocean/convection.py +++ b/earthdiagnostics/ocean/convection.py @@ -1,7 +1,7 @@ from earthdiagnostics.models import Grid from earthdiagnostics import Utils from nco import NCOException -from log import Log +from autosubmit.config.log import Log class Convection(object): diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 308c8e4..3b90dc3 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -1,5 +1,5 @@ from earthdiagnostics import Utils -from log import Log +from autosubmit.config.log import Log import os import shutil import traceback diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index e70fc06..38c44af 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -1,5 +1,5 @@ from earthdiagnostics import Utils, cdftools -from log import Log +from autosubmit.config.log import Log import os import shutil @@ -22,22 +22,25 @@ class Salinity: nco = Utils.nco temp = Utils.get_temp_file() - nco.ncrename(input=input_file, output=temp, - options='-O -d time,time_counter -v time,time_counter') - - Log.info('Calculating vertical mean') + temp2 = Utils.get_temp_file() + Log.info('Calculating vertical mean between {0} and {1}', upper, lower) + Log.debug('Input file: {0}', input_file) + Log.debug('Output file: {0}', output_file) # test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values # out of that range to be replaced by NaN - + # if cdo.version() > u'1.5.6': - nco.ncatted(input=temp, output=temp, options='-O -a valid_max,deptht,d,,') - nco.ncatted(input=temp, output=temp, options='-O -a valid_min,deptht,d,,') - - cdftools.run('cdfvertmean', input=temp, output=output_file, options=['vosaline', 'T', str(upper), str(lower), - '-full']) - nco.ncrename(input=output_file, output=output_file, - options='-O -v vosaline_vert_mean,vertmeansal -d time_counter,time -v time_counter,time') - Utils.setminmax(output_file, ['vertmeansal']) + nco.ncatted(input=input_file, output=temp, options='-O -a valid_max,lev,d,,') + nco.ncatted(input=temp, output=temp, options='-O -a valid_min,lev,d,,') + else: + shutil.copy(input_file, temp) + + cdftools.run('cdfvertmean', input=temp, output=temp2, options=['so', 'T', str(upper), str(lower), + '-full', '-debug']) + os.remove(temp) + Utils.rename_variable(temp2, 'so_vert_mean', 'vertmeansal') + Utils.setminmax(temp2, ['vertmeansal']) + shutil.move(temp2, output_file) Log.result('Finished!') @staticmethod diff --git a/earthdiagnostics/parser.py b/earthdiagnostics/parser.py new file mode 100644 index 0000000..59f1633 --- /dev/null +++ b/earthdiagnostics/parser.py @@ -0,0 +1,207 @@ +from ConfigParser import SafeConfigParser +from autosubmit.config.log import Log +import re + + +class Parser(SafeConfigParser): + + def get_option(self, section, option, default=''): + """ + Gets an option + + :param section: section that contains the option + :type section: str + :param option: option to get + :type option: str + :param default: value to be returned if option is not present + :type default: object + :return: option value + :rtype: str + """ + if self.has_option(section, option): + return self.get(section, option) + else: + return default + + def get_list_option(self, section, option, default=list(), separator=' '): + """ + Gets a list option + + :param section: section that contains the option + :type section: str + :param option: option to get + :type option: str + :param default: value to be returned if option is not present + :type default: object + :param separator: separator used to split the list + :type separator: str + :return: option value + :rtype: list + """ + if self.has_option(section, option): + return self.get(section, option).split(separator) + else: + return default + + def get_bool_option(self, section, option, default=True): + """ + Gets a boolean option + + :param section: section that contains the option + :type section: str + :param option: option to get + :type option: str + :param default: value to be returned if option is not present + :type default: bool + :return: option value + :rtype: bool + """ + if self.has_option(section, option): + return self.get(section, option).lower().strip() == 'true' + else: + return default + + def get_int_option(self, section, option, default=0): + """ + Gets an integer option + + :param section: section that contains the option + :type section: str + :param option: option to get + :type option: str + :param default: value to be returned if option is not present + :type default: int + :return: option value + :rtype: int + """ + if self.has_option(section, option): + return int(self.get(section, option)) + else: + return default + + def get_float_option(self, section, option, default=0.0): + """ + Gets a float option + + :param section: section that contains the option + :type section: str + :param option: option to get + :type option: str + :param default: value to be returned if option is not present + :type default: float + :return: option value + :rtype: float + """ + if self.has_option(section, option): + return float(self.get(section, option)) + else: + return default + + def check_exists(self, section, option): + """ + Checks if an option exists + + :param section: section that contains the option + :type section: str + :param option: option to check + :type option: str + :return: True if option exists, False otherwise + :rtype: bool + """ + if self.has_option(section, option): + return True + else: + Log.error('Option {0} in section {1} not found'.format(option, section)) + return False + + def check_is_boolean(self, section, option, must_exist): + """ + Checks if an option is a boolean value + + :param section: section that contains the option + :type section: str + :param option: option to check + :type option: str + :param must_exist: if True, option must exist + :type must_exist: bool + :return: True if option value is boolean, False otherwise + :rtype: bool + """ + if must_exist and not self.check_exists( section, option): + Log.error('Option {0} in section {1} must exist'.format(option, section)) + return False + if self.get_option( section, option, 'false').lower() not in ['false', 'true']: + Log.error('Option {0} in section {1} must be true or false'.format(option, section)) + return False + return True + + def check_is_choice(self, section, option, must_exist, choices): + """ + Checks if an option is a valid choice in given self + + :param section: section that contains the option + :type section: str + :param option: option to check + :type option: str + :param must_exist: if True, option must exist + :type must_exist: bool + :param choices: valid choices + :type choices: list + :return: True if option value is a valid choice, False otherwise + :rtype: bool + """ + if must_exist and not self.check_exists( section, option): + return False + value = self.get_option( section, option, choices[0]) + if value not in choices: + Log.error('Value {2} in option {0} in section {1} is not a valid choice'.format(option, section, value)) + return False + return True + + def check_is_int(self, section, option, must_exist): + """ + Checks if an option is an integer value + + :param section: section that contains the option + :type section: str + :param option: option to check + :type option: str + :param must_exist: if True, option must exist + :type must_exist: bool + :return: True if option value is integer, False otherwise + :rtype: bool + """ + if must_exist and not self.check_exists( section, option): + return False + value = self.get_option( section, option, '1') + try: + int(value) + except ValueError: + Log.error('Option {0} in section {1} is not valid an integer'.format(option, section)) + return False + return True + + def check_regex(self, section, option, must_exist, regex): + """ + Checks if an option complies with a regular expression + + :param section: section that contains the option + :type section: str + :param option: option to check + :type option: str + :param must_exist: if True, option must exist + :type must_exist: bool + :param regex: regular expression to check + :type regex: str + :return: True if option complies with regex, False otherwise + :rtype: bool + """ + if must_exist and not self.check_exists(section, option): + return False + prog = re.compile(regex) + value = self.get_option(section, option, '1') + if not prog.match(value): + Log.error('Option {0} in section {1} is not valid: {2}'.format(option, section, value)) + return False + return True + diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 73b72de..f846c97 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -1,5 +1,5 @@ import numpy as np -from log import Log +from autosubmit.config.log import Log from cdo import Cdo from nco import Nco import tempfile @@ -40,6 +40,7 @@ class Utils(object): for temp_file in Utils.files: if os.path.exists(temp_file): os.remove(temp_file) + Utils.files = list() @staticmethod def rename_variable(filename, old_name, new_name, must_exist=True, rename_dimension=False): @@ -52,3 +53,17 @@ class Utils(object): options += ' -d {0}{1},{2}'.format(dot, old_name, new_name) Utils.nco.ncrename(input=filename, output=filename, options=options) return os.path.join(Utils.scratch_folder, filename) + + @staticmethod + def rename_variables(filename, dic_names, must_exist=True, rename_dimension=False): + if must_exist: + dot = '' + else: + dot = '.' + options = '' + for old_name, new_name in dic_names.items(): + options += '-v {0}{1},{2} '.format(dot, old_name, new_name) + if rename_dimension: + options += ' -d {0}{1},{2} '.format(dot, old_name, new_name) + Utils.nco.ncrename(input=filename, output=filename, options=options) + return os.path.join(Utils.scratch_folder, filename) diff --git a/log.py b/log.py deleted file mode 100644 index 6b11b74..0000000 --- a/log.py +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2015 Earth Sciences Department, BSC-CNS - -# This file is part of Autosubmit. - -# Autosubmit is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# Autosubmit is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with Autosubmit. If not, see . - -import logging -import os -import sys -from datetime import datetime - - -class LogFormatter: - """ - Class to format log output. - - :param to_file: If True, creates a LogFormatter for files; if False, for console - :type to_file: bool - """ - RESULT = '\033[32m' - WARNING = '\033[33m' - ERROR = '\033[31m' - CRITICAL = '\033[1m \033[31m' - DEFAULT = '\033[0m\033[39m' - - def __init__(self, to_file=False): - """ - Initializer for LogFormatter - - - """ - self._file = to_file - if self._file: - self._formatter = logging.Formatter('%(asctime)s %(message)s') - else: - self._formatter = logging.Formatter('%(message)s') - - def format(self, record): - """ - Format log output, adding labels if needed for log level. If logging to console, also manages font color. - If logging to file adds timestamp - - :param record: log record to format - :type record: LogRecord - :return: formatted record - :rtype: str - """ - header = '' - if record.levelno == Log.RESULT: - if not self._file: - header = LogFormatter.RESULT - elif record.levelno == Log.USER_WARNING: - if not self._file: - header = LogFormatter.WARNING - elif record.levelno == Log.WARNING: - if not self._file: - header = LogFormatter.WARNING - header += "[WARNING] " - elif record.levelno == Log.ERROR: - if not self._file: - header = LogFormatter.ERROR - header += "[ERROR] " - elif record.levelno == Log.CRITICAL: - if not self._file: - header = LogFormatter.ERROR - header += "[CRITICAL] " - - msg = self._formatter.format(record) - if header != '' and not self._file: - msg += LogFormatter.DEFAULT - return header + msg - - -class Log: - """ - Static class to manage the log for the application. Messages will be sent to console and to file if it is - configured. Levels can be set for each output independently. These levels are (from lower to higher priority): - - - EVERYTHING : this level is just defined to show every output - - DEBUG - - INFO - - RESULT - - USER_WARNING - - WARNING - - ERROR - - CRITICAL - - NO_LOG : this level is just defined to remove every output - - """ - EVERYTHING = 0 - DEBUG = logging.DEBUG - INFO = logging.INFO - RESULT = 25 - USER_WARNING = 29 - WARNING = logging.WARNING - ERROR = logging.ERROR - CRITICAL = logging.CRITICAL - NO_LOG = CRITICAL + 1 - - logging.basicConfig() - - log = logging.Logger('Autosubmit', EVERYTHING) - - console_handler = logging.StreamHandler(sys.stdout) - console_handler.setLevel(INFO) - console_handler.setFormatter(LogFormatter(False)) - log.addHandler(console_handler) - - file_handler = None - file_level = INFO - - @staticmethod - def set_file(file_path): - """ - Configure the file to store the log. If another file was specified earlier, new messages will only go to the - new file. - - :param file_path: file to store the log - :type file_path: str - """ - (directory, filename) = os.path.split(file_path) - if not os.path.exists(directory): - os.mkdir(directory) - files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f)) and - f.endswith(filename)] - if len(files) >= 5: - files.sort() - os.remove(os.path.join(directory, files[0])) - file_path = os.path.join(directory, '{0:%Y%m%d_%H%M%S}_'.format(datetime.now()) + filename) - if Log.file_handler is not None: - Log.log.removeHandler(Log.file_handler) - Log.file_handler = logging.FileHandler(file_path, 'w') - Log.file_handler.setLevel(Log.file_level) - Log.file_handler.setFormatter(LogFormatter(True)) - Log.log.addHandler(Log.file_handler) - os.chmod(file_path, 0o775) - - @staticmethod - def set_console_level(level): - """ - Sets log level for logging to console. Every output of level equal or higher to parameter level will be - printed on console - - :param level: new level for console - :return: None - """ - if type(level) is str: - level = getattr(Log, level) - Log.console_handler.level = level - - @staticmethod - def set_file_level(level): - """ - Sets log level for logging to file. Every output of level equal or higher to parameter level will be - added to log file - - :param level: new level for log file - """ - if type(level) is str: - level = getattr(Log, level) - Log.file_level = level - if Log.file_handler is not None: - Log.file_handler.level = level - - @staticmethod - def debug(msg, *args): - """ - Sends debug information to the log - - :param msg: message to show - :param args: arguments for message formating (it will be done using format() method on str) - """ - Log.log.debug(msg.format(*args)) - - @staticmethod - def info(msg, *args): - """ - Sends information to the log - - :param msg: message to show - :param args: arguments for message formating (it will be done using format() method on str) - """ - Log.log.info(msg.format(*args)) - - @staticmethod - def result(msg, *args): - """ - Sends results information to the log. It will be shown in green in the console. - - :param msg: message to show - :param args: arguments for message formating (it will be done using format() method on str) - """ - Log.log.log(Log.RESULT, msg.format(*args)) - - @staticmethod - def user_warning(msg, *args): - """ - Sends warnings for the user to the log. It will be shown in yellow in the console. - - :param msg: message to show - :param args: arguments for message formating (it will be done using format() method on str) - """ - Log.log.log(Log.USER_WARNING, msg.format(*args)) - - @staticmethod - def warning(msg, *args): - """ - Sends program warnings to the log. It will be shown in yellow in the console. - - :param msg: message to show - :param args: arguments for message formating (it will be done using format() method on str) - """ - Log.log.warning(msg.format(*args)) - - @staticmethod - def error(msg, *args): - """ - Sends errors to the log. It will be shown in red in the console. - - :param msg: message to show - :param args: arguments for message formating (it will be done using format() method on str) - """ - Log.log.error(msg.format(*args)) - - @staticmethod - def critical(msg, *args): - """ - Sends critical errors to the log. It will be shown in red in the console. - - :param msg: message to show - :param args: arguments for message formating (it will be done using format() method on str) - """ - Log.log.critical(msg.format(*args)) -- GitLab From d231366791a3c3dc9228290e1b6338582065521f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 13 Apr 2016 17:18:55 +0200 Subject: [PATCH 030/268] Added som diagnostics to the launcher --- config_file-ocean_pp.bash | 14 ++--- earthdiagnostics/cdftools.py | 24 +++++++-- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 77 +++++++++++++++++---------- earthdiagnostics/ocean/circulation.py | 33 ++++++------ earthdiagnostics/ocean/convection.py | 10 ++-- earthdiagnostics/ocean/heat.py | 41 +++++++------- earthdiagnostics/ocean/salinity.py | 6 +-- ocean_pp.bash | 2 +- 9 files changed, 128 insertions(+), 81 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index ff51d3b..77936b1 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,20 +1,20 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('temp_lev' 'sal_lev') +listpost=('moc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 level2=14 #If temp_lev or sal_lev is chosen on listpost, the lev1 and lev2 correspond to the levels between which the vertical mean has to be calculated. Lev1 and lev2 should be between 1,42 or 1,46, depending on the numbers of vertical levels on the original files. raw_vars_ocean=( '' ) # If listpost contains "ext_raw_oce" option, this is the list ocean variables you want to extract. If nothing is specified, all variables present in input file will be treated. If raw_vars_ocean='default', sosstsst, sosaline, somixhgt and somxl010 will be extracted. raw_vars_ice=( '' ) # If listpost contains "ext_raw_ice" option, this is the list of seaice variables you want to extract. If nothing is specified, all variables will be treated. If raw_vars_ice='default', isnowthi, iicethic, ileadfra, iicetemp, and ice_pres will be extracted. -expid=m02j # expid or nemovar_s4 / nemovar_combine / glorys2v1 +expid=i00k # expid or nemovar_s4 / nemovar_combine / glorys2v1 mod='ecearth' # nemo / ecearth typeoutput='MMO' # diags / MMO #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -listmemb=( 0 1 2 3 4 5 6 7 8 9 ) # list of members -syeari=1993 # first start date, format "yyyy" -syearf=2009 # last start date, format "yyyy" +listmemb=( 0 ) # list of members +syeari=1960 # first start date, format "yyyy" +syearf=1960 # last start date, format "yyyy" moni=11 # first month of the hindcast, format "mm", e.g. 05 for May intsdate=1 # interval between start dates chunklen=4 # length of the chunks (in months) @@ -38,7 +38,7 @@ NEMOVERSION=Ec3.0_O1L46 # NEMO version # glorys2v1_O25L75 for Nemo GLORYS2v1 ORCA025L75 # ucl_O2L31 for Nemo UCL ORCA2L31 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -PATHCOMMONOCEANDIAG='/home/Earth/'${USER}'/ocean_diagnostics' +PATHCOMMONOCEANDIAG='/home/Earth/'${USER}'/pyCharm/ocean_diagnostics' CON_FILES='/esnas/autosubmit/con_files' -rootout='/esnas/exp/'${mod}'/'${expid}'/monthly_mean' +rootout='/scratch/Earth/jvegas/old_diags/'${mod}'/'${expid} #rootout='/esnas/exp/'${mod}'/'${expid}'/daily_mean' diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 04d0155..be9c136 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -3,13 +3,22 @@ import os from autosubmit.config.log import Log -class CDFTools: +class CDFTools(object): def __init__(self, path=''): self.path = path # noinspection PyShadowingBuiltins - def run(self, command, input, output=None, options=None, log_level=Log.DEBUG): + def run(self, command, input, output=None, options=None, log_level=Log.INFO): + """ + Runs one of the CDFTools + + :param command: executable to run + :param input: input file + :param output: output file. Not all tools support this parameter + :param options: options for the tool. + :param log_level: log level at which the output of the cdftool command will be added + """ line = [os.path.join(self.path, command)] if input: if isinstance(input, basestring): @@ -18,6 +27,8 @@ class CDFTools: for element in input: line.append(element) if options: + if isinstance(options, basestring): + options = options.split() for option in options: line.append(option) if output: @@ -25,10 +36,17 @@ class CDFTools: raise Exception('Input and output file can not be the same on CDFTools') line.append('-o') line.append(output) - Log.debug('Executing {0}', ' '.join(line)) + Log.info('Executing {0}', ' '.join(line)) process = subprocess.Popen(line, stdout=subprocess.PIPE) for line in process.communicate(): if not line: continue Log.log.log(log_level, line) + if process.returncode != 0: + raise Exception('Error executing {0}\n Return code: {1}', ' '.join(line), process.returncode) + + if output: + if not os.path.exists(output): + raise Exception('Error executing {0}\n Output file not created', ' '.join(line), process.returncode) + diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index c9d1fcc..98ab549 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS =vert_mean_sal +DIAGS = psi FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 8d0bf2d..ed3060a 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,6 +1,6 @@ from parser import Parser from autosubmit.config.log import Log -from earthdiagnostics.ocean import Salinity +from earthdiagnostics.ocean import Salinity, Convection, Circulation, Heat from utils import Utils from earthdiagnostics import cdftools from autosubmit.date.chunk_date_lib import * @@ -19,47 +19,70 @@ class Diags: os.makedirs(self.scratch_dir) os.chdir(self.scratch_dir) - # Copy mesh files - Log.info('Copying mesh files') - shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc') - shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_zgr.nc') - shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mask.nc') - shutil.copy(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc') - - # dic_variables = dict() - # dic_variables['x'] = 'i' - # dic_variables['y'] = 'j' - # dic_variables['z'] = 'lev' - # dic_variables['nav_lon'] = 'lon' - # dic_variables['nav_lat'] = 'lat' - # dic_variables['nav_lev'] = 'lev' - # dic_variables['time_counter'] = 'time' - # dic_variables['t'] = 'time' - # - # Utils.rename_variables('mesh_hgr.nc', dic_variables, False, True) - # Utils.rename_variables('mesh_zgr.nc', dic_variables, False, True) - # Utils.rename_variables('mask.nc', dic_variables, False, True) - - if os.path.exists(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version))): - shutil.copy(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), - 'mask_regions.nc') + self._prepare_mesh_files() # Check if cmorized and convert if not # Run diagnostics Log.info('Running diagnostics') for diag in self.diags.split(): + Log.info("Running {0}", diag) if diag == 'vert_mean_sal': - Log.info("Running vert_mean_sal") min_depth = 0 max_depth = 300 for [input_file, output_file] in self._get_file_names('ocean', 'so', 'vertmeansal'.format(min_depth, max_depth)): Salinity.vertical_mean(str(input_file), str(output_file), min_depth, max_depth) - Log.result('Finished vert_mean_sal') + elif diag == 'convection': + for [input_file, output_file] in self._get_file_names('ocean', 'mlotst', + 'mlotst_sites'): + Convection.main_sites(str(input_file), self.nemo_version, str(output_file)) + elif diag == 'psi': + for [input_file, output_file] in self._get_file_names('ocean', 'sobarstf', + 'psi'): + Circulation.psi(str(input_file), self.nemo_version, str(output_file)) + elif diag == 'gyres': + for [input_file, output_file] in self._get_file_names('ocean', 'psi', + 'msftbarot'): + Circulation.gyres(str(input_file), self.nemo_version, str(output_file)) + elif diag == 'ohc_specified_layer': + for [input_file, output_file] in self._get_file_names('ocean', 'ohc', + 'ohc_2d_avg_0-300m'): + Heat.layer(input_file, output_file, 0, 300) + Heat.layer(input_file, output_file.replace('ohc_2d_avg_0-300m', 'ohc_2d_avg_300-800m'), 300, 800) + Log.result('Finished {0}', diag) Utils.clean() + def _prepare_mesh_files(self): + + dic_variables = dict() + dic_variables['x'] = 'i' + dic_variables['y'] = 'j' + dic_variables['z'] = 'lev' + dic_variables['nav_lon'] = 'lon' + dic_variables['nav_lat'] = 'lat' + dic_variables['nav_lev'] = 'lev' + dic_variables['time_counter'] = 'time' + dic_variables['t'] = 'time' + + Log.info('Copying mesh files') + if not os.path.exists('mesh_hgr.nc'): + shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc') + Utils.rename_variables('mesh_hgr.nc', dic_variables, False, True) + if not os.path.exists('mesh_zgr.nc'): + os.link('mesh_hgr.nc', 'mesh_zgr.nc') + if not os.path.exists('mask.nc'): + os.link('mesh_hgr.nc', 'mask.nc') + if not os.path.exists('new_maskglo.nc'): + shutil.copy(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc') + + if os.path.exists(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version))) and \ + os.path.exists('mask_regions.nc'): + shutil.copy(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), + 'mask_regions.nc') + Utils.rename_variables('mask_regions.nc', dic_variables, False, True) + def _read_config(self, config_file): self.parser = Parser() self.parser.optionxform = str diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 7ecd403..4df9679 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -4,6 +4,7 @@ from autosubmit.config.log import Log from nco import NCOException import os import shutil +import traceback class Circulation(object): @@ -109,16 +110,15 @@ class Circulation(object): shutil.copy(input_file, temp) handler.close() - Utils.rename_variable(temp, 'record', 'x') - nco.ncdpq(input=temp, output=temp, options='-O -h -a time,x') - nco.ncdpq(input=temp, output=temp, options='-O -h -a depthw,x') - nco.ncdpq(input=temp, output=temp, options='-O -h -a y,x') + # Utils.rename_variable(temp, 'record', 'x') + nco.ncpdq(input=temp, output=temp, options='-O -h -a time,x') + nco.ncpdq(input=temp, output=temp, options='-O -h -a depthw,x') + nco.ncpdq(input=temp, output=temp, options='-O -h -a y,x') cdo.yearmean(input=temp, output=temp2) - cdftools.run('cdfmaxmoc', temp2, output=output_file, options='{0:.1f} {1:.1f} ' - '{2:.1f} {3:.1f}'.format(lat_min, lat_max, - depth_min, depth_max)) + cdftools.run('cdfmaxmoc', temp2, options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max, + depth_min, depth_max)) Utils.rename_variable(output_file, 'time_counter', 'time', False, True) @staticmethod @@ -137,8 +137,8 @@ class Circulation(object): """ integrated_u = Utils.get_temp_file() integrated_v = Utils.get_temp_file() - cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_u, ) - cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_v, options='V') + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_u, options='-full') + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_v, options='-full V') Utils.nco.ncea(input=[integrated_u, integrated_v], output=output_file) Utils.rename_variable(output_file, 'time_counter', 'time', False, True) @@ -232,15 +232,18 @@ class Circulation(object): def main(): try: - Circulation.psi("ORCA1_MM_19601101_19610228_grid_U.nc", "ORCA1_MM_19601101_19610228_grid_V.nc", "out_psi.nc") - Circulation.gyres("/scratch/Earth/jvegas/compsstest/out_psi.nc", - Grid.ECEARTH_2_3_O1L42, "out_gyres.nc") + cdftools.path = '/home/Earth/jvegas/CDFTOOLS_3.0/bin' + # Circulation.psi("ORCA1_MM_19601101_19610228_grid_U.nc", "ORCA1_MM_19601101_19610228_grid_V.nc", "out_psi.nc") + # Circulation.gyres("/scratch/Earth/jvegas/compsstest/out_psi.nc", + # Grid.ECEARTH_2_3_O1L42, "out_gyres.nc") Circulation.moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out_moc.nc") - Circulation.max_moc("out_moc.nc", 40, 80, 'out_max<_moc.nc', 1000, 2000) - Circulation.area_moc("out_moc.nc", 40, 80, 'out_area_moc.nc', 1000, 2000) + Circulation.max_moc("out_moc.nc", 38, 50, 'out_max_moc.nc', 500, 2000) + Circulation.max_moc("out_moc.nc", 40, 40, 'out_max_moc.nc', 0, 10000) + # Circulation.area_moc("out_moc.nc", 40, 80, 'out_area_moc.nc', 1000, 2000) except NCOException as ex: Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) - Utils.clean() + Log.error(traceback.format_exc()) + # Utils.clean() if __name__ == "__main__": diff --git a/earthdiagnostics/ocean/convection.py b/earthdiagnostics/ocean/convection.py index 2e2c59e..e82016a 100644 --- a/earthdiagnostics/ocean/convection.py +++ b/earthdiagnostics/ocean/convection.py @@ -44,12 +44,12 @@ class Convection(object): Convection.site(input_file, wedell, wedell_file) nco = Utils.nco - Utils.rename_variable(labrador_file, 'somxl010', 'Labrador') - Utils.rename_variable(irminger_file, 'somxl010', 'Irminger') - Utils.rename_variable(gin_file, 'somxl010', 'GIN') - Utils.rename_variable(wedell_file, 'somxl010', 'Wedell') + Utils.rename_variable(labrador_file, 'mlotst', 'Labrador') + Utils.rename_variable(irminger_file, 'mlotst', 'Irminger') + Utils.rename_variable(gin_file, 'mlotst', 'GIN') + Utils.rename_variable(wedell_file, 'mlotst', 'Wedell') - nco.ncks(input=labrador_file, output=output_file, options='-O -v Labrador') + nco.ncks(input=labrador_file, output=output_file, options='-A -v Labrador') nco.ncks(input=irminger_file, output=output_file, options='-A -v Irminger') nco.ncks(input=gin_file, output=output_file, options='-A -v GIN') nco.ncks(input=wedell_file, output=output_file, options='-A -v Wedell') diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 3b90dc3..8318b36 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -6,10 +6,23 @@ import traceback from nco import NCOException -class Heat: +class Heat(object): @staticmethod def layer(input_file, output_file, upper, lower): + """ + Pointwise Ocean Heat Content in a specified ocean thickness (J/m-2) + + Created in June 2012 Author : isabel.andreu-burillo@ic3.cat + May 2014 - Virginie Guemas - Way around the bc that does not work on moore + + :param input_file: input grid_T file nam + :param output_file: output file name (=> 2D x-y ) + :param upper: upper depth of the layer (in meters) + :param lower: lower depth of the layer (in meters) + :return: + """ + cdo = Utils.cdo nco = Utils.nco @@ -21,21 +34,10 @@ class Heat: heatc_sl_invert = Utils.get_temp_file() e3tfile = Utils.get_temp_file() - # Use this names for debugging - # temp = 'temp.nc' - # temp2 = 'temp2.nc' - # heatc_sl_out = 'heatc_sl_out.nc' - # heatc_sl_top = 'heatc_sl_top.nc' - # heatc_sl_bottom = 'heatc_sl_bottom.nc' - # heatc_sl_invert = 'heatc_sl_invert.nc' - # e3tfile = 'e3t_file.nc' - nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*e3t"'), nco.ncrename(input=e3tfile, output=e3tfile, options='-d t,time -d z,deptht') - cdo.seltimestep('1', input=input_file, output=temp) - - nco.ncks(input=temp, output=temp, options='-O -v votemper') + nco.ncks(input=input_file, output=temp, options='-O -v votemper') nco.ncrename(input=temp, output=temp, options='-v votemper,heatc_sl') cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) os.remove(e3tfile) @@ -50,13 +52,14 @@ class Heat: # weight = (300.0 - depth_top)/(depth_bottom - depth_top) # and add the thickness down to 300 m in the next layer nco.ncpdq(input=heatc_sl_out, output=heatc_sl_invert, options='-a "-deptht"') - nco.ncks(input=heatc_sl_invert, output=heatc_sl_invert, options='-O -d deptht,0,0,1') - nco.ncrename(input=heatc_sl_invert, output=heatc_sl_invert, options='-v deptht,layerthcknss') + nco.ncks(input=heatc_sl_invert, output=temp2, options='-O -d deptht,0,0') + Utils.rename_variable(temp2, 'deptht', 'layerthcknss') + shutil.move(temp2, heatc_sl_invert) nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, options='-O -d deptht,{0}.0,{1}.0'.format(lower, lower + 200)) - nco.ncks(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-O -d deptht,0,0,1') - nco.ncrename(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-v deptht,layerthcknss') + nco.ncks(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-O -d deptht,0,0') + Utils.rename_variable(heatc_sl_bottom, 'deptht', 'layerthcknss') os.remove(heatc_sl_out) @@ -64,8 +67,8 @@ class Heat: nco.ncbo(input=' '.join([heatc_sl_bottom, heatc_sl_invert]), output=temp, options='-A --op_typ=sub -v layerthcknss') - nco.ncrename(input=temp, output=temp, options='-v layerthcknss,heatc_sl') - nco.ncap2(input=heatc_sl_invert, output=temp2, options='-s "heatc_sl=($3 - layerthcknss)"') + Utils.rename_variable(temp, 'layerthcknss', 'heatc_sl') + nco.ncap2(input=heatc_sl_invert, output=temp2, options='-s "heatc_sl=({0:.1f} - layerthcknss)"'.format(lower)) os.remove(heatc_sl_invert) nco.ncbo(input=' '.join([temp, temp2]), output=temp, options='--op_typ=/ -v heatc_sl') os.remove(temp2) diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index 38c44af..f460ed0 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -4,7 +4,7 @@ import os import shutil -class Salinity: +class Salinity(object): @staticmethod def vertical_mean(input_file, output_file, upper, lower): """ @@ -23,7 +23,7 @@ class Salinity: temp = Utils.get_temp_file() temp2 = Utils.get_temp_file() - Log.info('Calculating vertical mean between {0} and {1}', upper, lower) + Log.debug('Calculating vertical mean between {0} and {1}', upper, lower) Log.debug('Input file: {0}', input_file) Log.debug('Output file: {0}', output_file) # test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values @@ -41,7 +41,7 @@ class Salinity: Utils.rename_variable(temp2, 'so_vert_mean', 'vertmeansal') Utils.setminmax(temp2, ['vertmeansal']) shutil.move(temp2, output_file) - Log.result('Finished!') + Log.debug('Finished!') @staticmethod def heat_sal_mxl(input_file, output_file): diff --git a/ocean_pp.bash b/ocean_pp.bash index ddabc08..cf7f2b9 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash set -evx -#module load CDFTOOLS/2.1-foss-2015a CDO NCO +module load CDFTOOLS/2.1-foss-2015a CDO NCO function delete { at now +7 days << EOF -- GitLab From 9586846bbff88b83ff9111925673d0109cd499fd Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 2 May 2016 17:16:27 +0200 Subject: [PATCH 031/268] MOC finished --- config_file-ocean_pp.bash | 12 +-- earthdiagnostics/__init__.py | 2 +- earthdiagnostics/basins.py | 9 +++ earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 19 +++-- earthdiagnostics/ocean/circulation.py | 38 ++++------ earthdiagnostics/ocean/convection.py | 12 +-- earthdiagnostics/ocean/heat.py | 104 +++++++++++++++++++++++--- earthdiagnostics/ocean/salinity.py | 12 ++- earthdiagnostics/parser.py | 12 +-- earthdiagnostics/utils.py | 59 +++++++++------ 11 files changed, 195 insertions(+), 86 deletions(-) create mode 100644 earthdiagnostics/basins.py diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 77936b1..8aef95c 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -8,19 +8,19 @@ level1=1 level2=14 #If temp_lev or sal_lev is chosen on listpost, the lev1 and lev2 correspond to the levels between which the vertical mean has to be calculated. Lev1 and lev2 should be between 1,42 or 1,46, depending on the numbers of vertical levels on the original files. raw_vars_ocean=( '' ) # If listpost contains "ext_raw_oce" option, this is the list ocean variables you want to extract. If nothing is specified, all variables present in input file will be treated. If raw_vars_ocean='default', sosstsst, sosaline, somixhgt and somxl010 will be extracted. raw_vars_ice=( '' ) # If listpost contains "ext_raw_ice" option, this is the list of seaice variables you want to extract. If nothing is specified, all variables will be treated. If raw_vars_ice='default', isnowthi, iicethic, ileadfra, iicetemp, and ice_pres will be extracted. -expid=i00k # expid or nemovar_s4 / nemovar_combine / glorys2v1 +expid=a030 # expid or nemovar_s4 / nemovar_combine / glorys2v1 mod='ecearth' # nemo / ecearth typeoutput='MMO' # diags / MMO #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ listmemb=( 0 ) # list of members -syeari=1960 # first start date, format "yyyy" -syearf=1960 # last start date, format "yyyy" -moni=11 # first month of the hindcast, format "mm", e.g. 05 for May +syeari=1990 # first start date, format "yyyy" +syearf=1990 # last start date, format "yyyy" +moni=01 # first month of the hindcast, format "mm", e.g. 05 for May intsdate=1 # interval between start dates -chunklen=4 # length of the chunks (in months) +chunklen=3 # length of the chunks (in months) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ltime0=1 # first leadtime to post-process -ltimef=4 # last leadtime to postprocess +ltimef=3 # last leadtime to postprocess # Fill up either ltime0/ltimef or year0/yearf year0= # first year to post-process in the fist start date yearf= # last year to post-process in the fist start date diff --git a/earthdiagnostics/__init__.py b/earthdiagnostics/__init__.py index bab3e60..7081a60 100644 --- a/earthdiagnostics/__init__.py +++ b/earthdiagnostics/__init__.py @@ -1,6 +1,6 @@ from cdo import Cdo from nco import Nco -from earthdiagnostics.utils import Utils +from earthdiagnostics.utils import Utils, TempFile from earthdiagnostics.cdftools import CDFTools import os diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py new file mode 100644 index 0000000..90abab1 --- /dev/null +++ b/earthdiagnostics/basins.py @@ -0,0 +1,9 @@ +class Basin: + Global = 'glob' + NorthAtlantic = 'NAtl' + NorthPacific = 'NPac' + TropicalAtlantic = 'TAtl' + TropicalPacific = 'TPac' + TropicalIndic = 'TInd' + Antarctic = 'Anta' + Arctic = 'Arct' diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 98ab549..5fff8f2 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = psi +DIAGS = moc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index ed3060a..026ea5e 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -2,7 +2,7 @@ from parser import Parser from autosubmit.config.log import Log from earthdiagnostics.ocean import Salinity, Convection, Circulation, Heat from utils import Utils -from earthdiagnostics import cdftools +from earthdiagnostics import cdftools, TempFile from autosubmit.date.chunk_date_lib import * import shutil import os @@ -50,9 +50,17 @@ class Diags: 'ohc_2d_avg_0-300m'): Heat.layer(input_file, output_file, 0, 300) Heat.layer(input_file, output_file.replace('ohc_2d_avg_0-300m', 'ohc_2d_avg_300-800m'), 300, 800) + elif diag == 'moc': + for [input_file, output_file] in self._get_file_names('ocean', 'vo', + 'moc'): + Circulation.moc(input_file, output_file) + else: + Log.warning('Diagnostic {0} not available', diag) + continue + Log.result('Finished {0}', diag) - Utils.clean() + TempFile.clean() def _prepare_mesh_files(self): @@ -115,7 +123,7 @@ class Diags: start = parse_date(startdate) for member in self.members: member_plus = str(int(member)+1) - member_path = os.path.join(self.data_dir,self.expid, startdate, 'fc'+member, 'outputs', 'output', + member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc'+member, 'outputs', 'output', self.institute, self.model, self.model, 'S'+startdate, self.frequency, domain) for chunk in range(1, self.chunks + 1): @@ -131,7 +139,7 @@ class Diags: chunk_start.month), "{0:04}{1:02}".format(chunk_end.year, chunk_end.month))) - output_file = os.path.join(member_path, input_var, 'r{0}i1p1'.format(member_plus), + output_file = os.path.join(member_path, output_var, 'r{0}i1p1'.format(member_plus), '{0}_{1[0]}{2}_{3}_output_r{4}i1p1_' '{5}-{6}.nc'.format(output_var, domain.upper(), self.frequency, self.model, member_plus, @@ -145,6 +153,7 @@ class Diags: def main(): + TempFile.scratch_folder = '/scratch/Earth/jvegas' Log.set_console_level(Log.DEBUG) diags = Diags('/home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/diags.conf') diags.run() @@ -152,4 +161,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 4df9679..3285958 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -1,4 +1,4 @@ -from earthdiagnostics import Utils, cdftools +from earthdiagnostics import Utils, cdftools, TempFile from earthdiagnostics.models import Grid from autosubmit.config.log import Log from nco import NCOException @@ -16,28 +16,22 @@ class Circulation(object): Created in March 2012 Author : vguemas@ic3.cat - :param input_file: input grid_V file name + :param input_file: input grid_V file namez :type input_file: str :param output_file: output file name (=> 2D, depth-y) :param output_file: str :return: """ - nco = Utils.nco if os.path.exists(output_file): os.remove(output_file) - cdftools.run('cdfmoc', input=input_file, output=output_file) - nco.ncwa(input=output_file, output=output_file, options='-O -a x') - nco.ncks(input=output_file, output=output_file, options='-O -x -v nav_lon,nav_lat') - - Utils.rename_variable(output_file, 'time_counter', 'time', False, True) - Utils.rename_variable(output_file, 'gsize', 'y', False) + # temp = TempFile.get() - temp = Utils.get_temp_file() - shutil.copy(input_file, temp) - Utils.rename_variable(output_file, 'time_counter', 'time', False, True) + cdftools.run('cdfmoc', input=input_file, output=output_file) - nco.ncks(input=input_file, output=output_file, options='-A -v nav_lon,nav_lat') + # if not os.path.exists(os.path.dirname(output_file)): + # os.makedirs(os.path.dirname(output_file)) + # shutil.move(temp, output_file) @staticmethod def area_moc(input_file, lat_min, lat_max, output_file, depth_min=1000, depth_max=2000, basin='zomsfatl'): @@ -60,8 +54,8 @@ class Circulation(object): """ nco = Utils.nco cdo = Utils.cdo - temp = Utils.get_temp_file() - temp2 = Utils.get_temp_file() + temp = TempFile.get() + temp2 = TempFile.get() handler = Utils.cdo.openCdf(input_file) if 'x' in handler.dimensions: @@ -100,8 +94,8 @@ class Circulation(object): nco = Utils.nco cdo = Utils.cdo - temp = Utils.get_temp_file() - temp2 = Utils.get_temp_file() + temp = TempFile.get() + temp2 = TempFile.get() handler = Utils.cdo.openCdf(input_file) if 'x' in handler.dimensions: @@ -118,7 +112,7 @@ class Circulation(object): cdo.yearmean(input=temp, output=temp2) cdftools.run('cdfmaxmoc', temp2, options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max, - depth_min, depth_max)) + depth_min, depth_max)) Utils.rename_variable(output_file, 'time_counter', 'time', False, True) @staticmethod @@ -135,8 +129,8 @@ class Circulation(object): :param output_file: output file name without nc extension (=> 2D x-y) :rtype output_file: str """ - integrated_u = Utils.get_temp_file() - integrated_v = Utils.get_temp_file() + integrated_u = TempFile.get() + integrated_v = TempFile.get() cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_u, options='-full') cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_v, options='-full V') @@ -175,7 +169,7 @@ class Circulation(object): else: raise Exception("Input grid {0} not recognized".format(input_grid)) - temp = Utils.get_temp_file() + temp = TempFile.get() Circulation.gyre(input_psi, subpolNAtl, output_file, invert=True) Utils.rename_variable(output_file, 'sobarstf', 'subpolNAtl') @@ -220,7 +214,7 @@ class Circulation(object): :param invert: if True, multiplies result by -1 :return: """ - temp = Utils.get_temp_file() + temp = TempFile.get() Utils.cdo.fldmin(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), output=temp) if invert: diff --git a/earthdiagnostics/ocean/convection.py b/earthdiagnostics/ocean/convection.py index e82016a..0d0bab2 100644 --- a/earthdiagnostics/ocean/convection.py +++ b/earthdiagnostics/ocean/convection.py @@ -1,5 +1,5 @@ from earthdiagnostics.models import Grid -from earthdiagnostics import Utils +from earthdiagnostics import Utils, TempFile from nco import NCOException from autosubmit.config.log import Log @@ -31,16 +31,16 @@ class Convection(object): else: raise Exception("Input grid {0} not recognized".format(input_grid)) - labrador_file = Utils.get_temp_file() + labrador_file = TempFile.get() Convection.site(input_file, labrador, labrador_file) - irminger_file = Utils.get_temp_file() + irminger_file = TempFile.get() Convection.site(input_file, irminger, irminger_file) - gin_file = Utils.get_temp_file() + gin_file = TempFile.get() Convection.site(input_file, gin, gin_file) - wedell_file = Utils.get_temp_file() + wedell_file = TempFile.get() Convection.site(input_file, wedell, wedell_file) nco = Utils.nco @@ -75,7 +75,7 @@ def main(): try: Convection.main_sites("/scratch/Earth/jvegas/compsstest/ORCA1_MM_19601101_19610228_grid_T.nc", Grid.ECEARTH_2_3_O1L42, "outconvection.nc") - Utils.clean() + TempFile.clean() except NCOException as ex: Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 8318b36..f194ce0 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -1,4 +1,5 @@ -from earthdiagnostics import Utils +from earthdiagnostics import Utils, cdftools, cdo, TempFile +from earthdiagnostics.basins import Basin from autosubmit.config.log import Log import os import shutil @@ -23,16 +24,15 @@ class Heat(object): :return: """ - cdo = Utils.cdo nco = Utils.nco - temp = Utils.get_temp_file() - temp2 = Utils.get_temp_file() - heatc_sl_out = Utils.get_temp_file() - heatc_sl_top = Utils.get_temp_file() - heatc_sl_bottom = Utils.get_temp_file() - heatc_sl_invert = Utils.get_temp_file() - e3tfile = Utils.get_temp_file() + temp = TempFile.get() + temp2 = TempFile.get() + heatc_sl_out = TempFile.get() + heatc_sl_top = TempFile.get() + heatc_sl_bottom = TempFile.get() + heatc_sl_invert = TempFile.get() + e3tfile = TempFile.get() nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*e3t"'), nco.ncrename(input=e3tfile, output=e3tfile, options='-d t,time -d z,deptht') @@ -86,6 +86,92 @@ class Heat(object): shutil.move(temp, output_file) os.remove(temp) + @staticmethod + def total(input_file, output_file, basin=Basin.Global, mixed_layer=0, upper=None, lower=None): + """ + Compute the total ocean heat extent + + Created in May 2012 Author : vguemas@ic3.cat + + :param input_file: input temperature file name + :param output_file: output file name ( => 2D x-y + :param basin: basin name (default: global) + :param mixed_layer: mixed layer (1=only, 0=included, -1=without) + :param upper: upper level of the layer (optional) Default : top + :param lower: lower level of the layer (optional) Default : bottom + """ + + # + # cp ${CON_FILES}/heatc_template.nc template_heatc.nc + # ncdump template_heatc.nc > template_heatc.cdl + # # + # # Define some parameters + # # + # typeset var para + # typeset var output + # typeset var nlev=`cat depth.txt | wc -l` + # if [[ ! -z "$depmin" && ! -z "$depmax" ]] ; then + # if [[ $depmin != 0 || ${down} != ${nlev} && ${down} != 0 ]] ; then + # output=${depmin}-${depmax}'_' + # fi + # fi + temp = TempFile.get() + temp2 = TempFile.get() + + shutil.copy(input_file, temp) + + if basin == Basin.NorthAtlantic: + para = "atl $mxl 0 0 10 65" + output_file = 'NAtl_10N65N_' + output_file + elif basin == Basin.TropicalAtlantic: + para = "atl $mxl 0 0 -30 30" + output_file = 'TAtl_30S30N_' + output_file + elif basin == Basin.NorthPacific: + para = "pac $mxl 0 0 10 70" + output_file = 'NPac_10N70N_' + output_file + elif basin == Basin.TropicalPacific: + para = "pac $mxl 0 0 -30 30" + output_file = 'TPac_30S30N_' + output_file + elif basin == Basin.Arctic: + para = "atl $mxl 0 0 65 90" + output_file = 'Arc_65N90N_' + output_file + elif basin == Basin.Antarctic: + para = "all $mxl 0 0 -90 -60" + output_file = 'Ant_90S60S_' + output_file + elif basin == Basin.TropicalIndic: + para = "ind $mxl 0 0 -30 30" + output_file = 'TInd_30S30N_' + output_file + elif basin == Basin.Global: + para = "all $mxl 0 0 0 0" + else: + raise Exception('Basin {0} not recognized in Heat.total'.format(basin)) + + if mixed_layer == 1: + output_file = 'mxl_' + output_file + elif mixed_layer == -1: + output_file = 'nonmxl_' + output_file + + # + # Compute ohc + # + handler = cdo.openCdf(input_file) + + if 'somxl010' in handler.variables: + cdftools.run('cdfmxl', input=temp, output=temp2) + para = para.split() + para.append(upper) + para.append(lower) + cdftools.run('cdfheatc', options=para, input=temp2, output=temp) + # thc=`cat tmp.log | grep "Total Heat content :" | awk '{print $5}'`; + # uhc=`cat tmp.log | grep "Total Heat content/volume" | awk '{print $5}'`; + # sed -e "s/thc =.*/thc = $thc ;/" template_heatc.cdl > template_heatc2.cdl + # sed -e "s/uhc =.*/uhc = $uhc ;/" template_heatc2.cdl > template_heatc.cdl + # ncgen -o heatc_${jt}.nc template_heatc.cdl + # rm -f template_heatc2.cdl tmpohc.nc mxl.nc tmp.log + # list=$list" "heatc_${jt}.nc + # + # setminmax ${output}$2 thc uhc + def main(): try: diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index f460ed0..c0ebab7 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -1,4 +1,4 @@ -from earthdiagnostics import Utils, cdftools +from earthdiagnostics import Utils, cdftools, TempFile from autosubmit.config.log import Log import os import shutil @@ -21,8 +21,8 @@ class Salinity(object): cdo = Utils.cdo nco = Utils.nco - temp = Utils.get_temp_file() - temp2 = Utils.get_temp_file() + temp = TempFile() + temp2 = TempFile() Log.debug('Calculating vertical mean between {0} and {1}', upper, lower) Log.debug('Input file: {0}', input_file) Log.debug('Output file: {0}', output_file) @@ -58,8 +58,8 @@ class Salinity(object): cdo = Utils.cdo nco = Utils.nco - temp = Utils.get_temp_file() - temp2 = Utils.get_temp_file() + temp = TempFile.get() + temp2 = TempFile.get() handler = cdo.openCdf(input_file) @@ -73,7 +73,6 @@ class Salinity(object): cdftools.run('cdfmxl', input=temp, output=temp2) nco.ncrename(input=temp2, output=temp2, options='-d time_counter,time') nco.ncks(input=temp2, output=temp, options='-A') - os.remove(temp2) Log.info('Computing heat content') cdftools.run('cdfmxlheatc', input=temp, options=['-full']) @@ -94,7 +93,6 @@ class Salinity(object): Utils.setminmax(temp, variables) shutil.move(temp, output_file) - Log.result('Finished!') def main(): diff --git a/earthdiagnostics/parser.py b/earthdiagnostics/parser.py index 59f1633..790308d 100644 --- a/earthdiagnostics/parser.py +++ b/earthdiagnostics/parser.py @@ -127,10 +127,10 @@ class Parser(SafeConfigParser): :return: True if option value is boolean, False otherwise :rtype: bool """ - if must_exist and not self.check_exists( section, option): + if must_exist and not self.check_exists(section, option): Log.error('Option {0} in section {1} must exist'.format(option, section)) return False - if self.get_option( section, option, 'false').lower() not in ['false', 'true']: + if self.get_option(section, option, 'false').lower() not in ['false', 'true']: Log.error('Option {0} in section {1} must be true or false'.format(option, section)) return False return True @@ -150,9 +150,9 @@ class Parser(SafeConfigParser): :return: True if option value is a valid choice, False otherwise :rtype: bool """ - if must_exist and not self.check_exists( section, option): + if must_exist and not self.check_exists(section, option): return False - value = self.get_option( section, option, choices[0]) + value = self.get_option(section, option, choices[0]) if value not in choices: Log.error('Value {2} in option {0} in section {1} is not a valid choice'.format(option, section, value)) return False @@ -171,9 +171,9 @@ class Parser(SafeConfigParser): :return: True if option value is integer, False otherwise :rtype: bool """ - if must_exist and not self.check_exists( section, option): + if must_exist and not self.check_exists(section, option): return False - value = self.get_option( section, option, '1') + value = self.get_option(section, option, '1') try: int(value) except ValueError: diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index f846c97..3d12e82 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -4,14 +4,14 @@ from cdo import Cdo from nco import Nco import tempfile import os +import pwd +import shutil class Utils(object): - scratch_folder = '/scratch/Earth/jvegas' nco = Nco() cdo = Cdo() - files = list() @staticmethod def setminmax(filename, variable_list): @@ -25,23 +25,6 @@ class Utils(object): Utils.nco.ncatted(input=filename, output=filename, options='-h -a valid_min,{0},m,f,{1}'.format(variable, values[1])) - @staticmethod - def get_temp_file(): - temp_file = tempfile.mkstemp(dir=Utils.scratch_folder, prefix='diag', suffix='.nc')[1] - Utils.files.append(temp_file) - return temp_file - - @staticmethod - def get_scratch_file(filename): - return os.path.join(Utils.scratch_folder, filename) - - @staticmethod - def clean(): - for temp_file in Utils.files: - if os.path.exists(temp_file): - os.remove(temp_file) - Utils.files = list() - @staticmethod def rename_variable(filename, old_name, new_name, must_exist=True, rename_dimension=False): if must_exist: @@ -52,10 +35,9 @@ class Utils(object): if rename_dimension: options += ' -d {0}{1},{2}'.format(dot, old_name, new_name) Utils.nco.ncrename(input=filename, output=filename, options=options) - return os.path.join(Utils.scratch_folder, filename) @staticmethod - def rename_variables(filename, dic_names, must_exist=True, rename_dimension=False): + def rename_variables(filepath, dic_names, must_exist=True, rename_dimension=False): if must_exist: dot = '' else: @@ -65,5 +47,36 @@ class Utils(object): options += '-v {0}{1},{2} '.format(dot, old_name, new_name) if rename_dimension: options += ' -d {0}{1},{2} '.format(dot, old_name, new_name) - Utils.nco.ncrename(input=filename, output=filename, options=options) - return os.path.join(Utils.scratch_folder, filename) + Utils.nco.ncrename(input=filepath, output=filepath, options=options) + + def move_file(self, source, destiny): + if not os.path.exists(os.path.dirname(destiny)): + os.makedirs(os.path.dirname(destiny)) + shutil.move(source, destiny) + + +class TempFile(object): + + autoclean = True + files = list() + scratch_folder = os.path.join('/scratch', pwd.getpwuid(os.getuid())[0]) + prefix = 'temp' + + @staticmethod + def get(filename=None, clean=True): + if filename: + path = os.path.join(TempFile.scratch_folder, filename) + else: + path = tempfile.mkstemp(dir=TempFile.scratch_folder, prefix=TempFile.prefix, suffix='.nc')[1] + + if clean: + TempFile.files.append(path) + + return path + + @staticmethod + def clean(): + for temp_file in TempFile.files: + if os.path.exists(temp_file): + os.remove(temp_file) + TempFile.files = list() -- GitLab From 0fc9a660b8a52d57c748c2e3cb7821d15cca1077 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 4 May 2016 13:42:33 +0200 Subject: [PATCH 032/268] Changes in configuration --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/basins.py | 33 ++++++-- earthdiagnostics/cdftools.py | 6 +- earthdiagnostics/diags.conf | 11 ++- earthdiagnostics/diags.py | 114 +++++++++++++++++++++----- earthdiagnostics/ocean/circulation.py | 29 +++---- earthdiagnostics/ocean/heat.py | 43 +++++++--- earthdiagnostics/ocean/salinity.py | 55 +++++-------- earthdiagnostics/utils.py | 8 +- 9 files changed, 207 insertions(+), 94 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 8aef95c..d4426f5 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('moc') +listpost=('max_moc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index 90abab1..ceb6ad0 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -1,9 +1,24 @@ -class Basin: - Global = 'glob' - NorthAtlantic = 'NAtl' - NorthPacific = 'NPac' - TropicalAtlantic = 'TAtl' - TropicalPacific = 'TPac' - TropicalIndic = 'TInd' - Antarctic = 'Anta' - Arctic = 'Arct' +class Basin(object): + + def __init__(self, shortname, fullname): + self._shortname = shortname + self._fullname = fullname + + @property + def shortname(self): + return self._shortname + + @property + def fullname(self): + return self._fullname + + +class Basins(object): + Global = Basin('glob', 'global_ocean') + NorthAtlantic = Basin('NAtl', 'north_atlantic_ocean') + NorthPacific = Basin('NPac', 'north_pacific_ocean') + TropicalAtlantic = Basin('TAtl', 'tropical_atlantic_ocean') + TropicalPacific = Basin('TPac', 'tropical_pacific_ocean') + TropicalIndic = Basin('TInd', 'indian_ocean') + Antarctic = Basin('Anta', 'antarctic_ocean') + Arctic = Basin('Arct', 'arctic_ocean') diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index be9c136..2c95fd3 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -23,9 +23,13 @@ class CDFTools(object): if input: if isinstance(input, basestring): line.append(input) + if not os.path.exists(input): + raise Exception('Error executing {0}\n Input file {1} file does not exist', command, input) else: for element in input: line.append(element) + if not os.path.exists(element): + raise Exception('Error executing {0}\n Input file {1} file does not exist', command, element) if options: if isinstance(options, basestring): options = options.split() @@ -48,5 +52,5 @@ class CDFTools(object): if output: if not os.path.exists(output): - raise Exception('Error executing {0}\n Output file not created', ' '.join(line), process.returncode) + raise Exception('Error executing {0}\n Output file not created', ' '.join(line)) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 5fff8f2..7d5375b 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = moc +DIAGS = max_moc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -15,3 +15,12 @@ CHUNKS = 2 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 + +[ALIAS] +MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 +AREA_MOC = mocarea,40,55,1000,2000,zomsfatl mocarea,30,40,1000,2000,zomsfatl +STC = mocarea,0,25,0,200,zomsfpac mocarea,-25,0,0,200,zomsfpac mocarea,0,25,0,200,zomsfatl mocarea,-25,0,0,200,zomsfatl +HEAT_SAL_MXL = mlotstsc mlotstohc + + + diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 026ea5e..1166b12 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -10,9 +10,11 @@ import os class Diags: def __init__(self, config_file): + Log.debug('Initialising Diags') self._read_config(config_file) Utils.scratch_folder = os.path.join(self.scratch_dir) cdftools.path = self.cdftools_path + Log.debug('Diags ready') def run(self): if not os.path.exists(self.scratch_dir): @@ -25,8 +27,11 @@ class Diags: # Run diagnostics Log.info('Running diagnostics') - for diag in self.diags.split(): + for fulldiag in self._get_commands(): + diag_options = fulldiag.split(',') + diag = diag_options[0] Log.info("Running {0}", diag) + Log.debug('Full command: {0}', fulldiag) if diag == 'vert_mean_sal': min_depth = 0 max_depth = 300 @@ -35,7 +40,7 @@ class Diags: Salinity.vertical_mean(str(input_file), str(output_file), min_depth, max_depth) elif diag == 'convection': for [input_file, output_file] in self._get_file_names('ocean', 'mlotst', - 'mlotst_sites'): + 'mlotst'): Convection.main_sites(str(input_file), self.nemo_version, str(output_file)) elif diag == 'psi': for [input_file, output_file] in self._get_file_names('ocean', 'sobarstf', @@ -54,6 +59,49 @@ class Diags: for [input_file, output_file] in self._get_file_names('ocean', 'vo', 'moc'): Circulation.moc(input_file, output_file) + elif diag == 'mocmax': + if len(diag_options) != 5: + Log.warning('Max_moc requires 4 arguments. Skipping!') + continue + + lat_min = int(diag_options[1]) + lat_max = int(diag_options[2]) + lat = '{0}-{1}'.format(lat_min, lat_max) + + depth_min = int(diag_options[3]) + depth_max = int(diag_options[4]) + depth = '{0}-{1}'.format(depth_min, depth_max) + + for [input_file, output_file] in self._get_file_names('ocean', 'moc', + 'mocmax'): + + Circulation.max_moc(input_file, lat_min, lat_max, + output_file.replace('mocmax', 'mocmax{0}-{1}'.format(lat, depth)), + depth_min, depth_max) + elif diag == 'mocarea': + if len(diag_options) != 6: + Log.warning('area_moc requires between 5 arguments. Skipping!') + continue + + lat_min = int(diag_options[1]) + lat_max = int(diag_options[2]) + lat = '{0}-{1}'.format(lat_min, lat_max) + + depth_min = int(diag_options[3]) + depth_max = int(diag_options[4]) + depth = '{0}-{1}'.format(depth_min, depth_max) + + basin = diag_options[5] + + for [input_file, output_file] in self._get_file_names('ocean', 'moc', + 'moc{0}-{1}-{2}'.format(lat, depth, basin)): + Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) + elif diag == 'mlotstohc': + for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'ohc', 'mlotst', 'mlotstohc'): + Heat.mixed_layer_content(input_file, mlotst_file, output_file) + elif diag == 'mlotstsc': + for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'so', 'mlotst', 'mlotstsc'): + Salinity.mixed_layer_content(input_file, mlotst_file, output_file) else: Log.warning('Diagnostic {0} not available', diag) continue @@ -62,6 +110,19 @@ class Diags: TempFile.clean() + def _get_commands(self): + Log.debug('Preparing command list') + commands = self.diags.split() + + for alias, added_commands in self._aliases.items(): + if alias in commands: + Log.debug('Changing alias {0} for {1}', alias, ' '.join(added_commands)) + commands.remove(alias) + for add_command in added_commands: + commands.append(add_command) + Log.debug('Command list ready ') + return commands + def _prepare_mesh_files(self): dic_variables = dict() @@ -76,20 +137,29 @@ class Diags: Log.info('Copying mesh files') if not os.path.exists('mesh_hgr.nc'): + Log.info('Copying mesh_hgr.nc') shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc') Utils.rename_variables('mesh_hgr.nc', dic_variables, False, True) + if not os.path.exists('mesh_zgr.nc'): + Log.info('Linking mesh_zgr.nc') os.link('mesh_hgr.nc', 'mesh_zgr.nc') + if not os.path.exists('mask.nc'): + Log.info('Linking mask.nc') os.link('mesh_hgr.nc', 'mask.nc') + if not os.path.exists('new_maskglo.nc'): + Log.info('Copying new_maskglo.nc') shutil.copy(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc') if os.path.exists(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version))) and \ - os.path.exists('mask_regions.nc'): + not os.path.exists('mask_regions.nc'): + Log.info('Copying mask_regions.nc') shutil.copy(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), 'mask_regions.nc') Utils.rename_variables('mask_regions.nc', dic_variables, False, True) + Log.result('Mesh files ready!') def _read_config(self, config_file): self.parser = Parser() @@ -100,7 +170,7 @@ class Diags: self.scratch_dir = self.parser.get_option('DIAGNOSTICS', 'SCRATCH_DIR') self.data_dir = self.parser.get_option('DIAGNOSTICS', 'DATA_DIR') self.con_files = self.parser.get_option('DIAGNOSTICS', 'CON_FILES') - self.diags = self.parser.get_option('DIAGNOSTICS', 'DIAGS') + self.diags = self.parser.get_option('DIAGNOSTICS', 'DIAGS').lower() self.frequency = self.parser.get_option('DIAGNOSTICS', 'FREQUENCY') self.cdftools_path = self.parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') @@ -114,9 +184,15 @@ class Diags: self.model = self.parser.get_option('EXPERIMENT', 'MODEL') self.nemo_version = self.parser.get_option('EXPERIMENT', 'NEMO_VERSION') + # Read aliases + self._aliases = dict() + if self.parser.has_section('ALIAS'): + for option in self.parser.options('ALIAS'): + self._aliases[option.lower()] = self.parser.get_option('ALIAS', option).lower().split() + self.scratch_dir = os.path.join(self.scratch_dir, 'diags', self.expid) - def _get_file_names(self, domain, input_var, output_var): + def _get_file_names(self, domain, *variables): file_names = list() for startdate in self.startdates.split(): @@ -131,23 +207,17 @@ class Diags: chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') - input_file = os.path.join(member_path, input_var, 'r{0}i1p1'.format(member_plus), - '{0}_{1[0]}{2}_{3}_output_r{4}i1p1_' - '{5}-{6}.nc'.format(input_var, domain.upper(), - self.frequency, self.model, member_plus, - "{0:04}{1:02}".format(chunk_start.year, - chunk_start.month), - "{0:04}{1:02}".format(chunk_end.year, - chunk_end.month))) - output_file = os.path.join(member_path, output_var, 'r{0}i1p1'.format(member_plus), - '{0}_{1[0]}{2}_{3}_output_r{4}i1p1_' - '{5}-{6}.nc'.format(output_var, domain.upper(), - self.frequency, self.model, member_plus, - "{0:04}{1:02}".format(chunk_start.year, - chunk_start.month), - "{0:04}{1:02}".format(chunk_end.year, - chunk_end.month))) - file_names.append([input_file, output_file]) + var_file = list() + for var in variables: + var_file.append(os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus), + '{0}_{1[0]}{2}_{3}_output_r{4}i1p1_' + '{5}-{6}.nc'.format(var, domain.upper(), + self.frequency, self.model, member_plus, + "{0:04}{1:02}".format(chunk_start.year, + chunk_start.month), + "{0:04}{1:02}".format(chunk_end.year, + chunk_end.month)))) + file_names.append(var_file) return file_names diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 3285958..1cd048f 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -22,16 +22,13 @@ class Circulation(object): :param output_file: str :return: """ + if os.path.exists(output_file): os.remove(output_file) - - # temp = TempFile.get() - - cdftools.run('cdfmoc', input=input_file, output=output_file) - - # if not os.path.exists(os.path.dirname(output_file)): - # os.makedirs(os.path.dirname(output_file)) - # shutil.move(temp, output_file) + temp = TempFile.get() + cdftools.run('cdfmoc', input=input_file, output=temp) + Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') + Utils.move_file(temp, output_file) @staticmethod def area_moc(input_file, lat_min, lat_max, output_file, depth_min=1000, depth_max=2000, basin='zomsfatl'): @@ -64,11 +61,9 @@ class Circulation(object): shutil.copy(input_file, temp) handler.close() - nco.ncrename(input=temp, output=temp2, options='-v nav_lat,lat -d y,lat') - - nco.ncks(input=temp2, output=temp, options='-O -v {0},time,depthw,lat'.format(basin)) - nco.ncks(input=temp, output=temp, options='-O -d lat,{0:.1f},{1:.1f} -d depthw,' - '-{2:.1f},-{3:.1f}'.format(lat_min, lat_max, depth_max, depth_min)) + nco.ncks(input=temp, output=temp, options='-O -v {0},time,lev,lat'.format(basin)) + nco.ncks(input=temp, output=temp, options='-O -d lev,{0:.1f},{1:.1f}'.format(depth_min, depth_max)) + nco.ncks(input=temp, output=temp, options='-O -d lat,{0:.1f},{1:.1f} '.format(lat_min, lat_max)) cdo.vertmean(input=temp, output=temp2) nco.ncap2(input=temp2, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') @@ -111,9 +106,11 @@ class Circulation(object): cdo.yearmean(input=temp, output=temp2) - cdftools.run('cdfmaxmoc', temp2, options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max, - depth_min, depth_max)) - Utils.rename_variable(output_file, 'time_counter', 'time', False, True) + cdftools.run('cdfmaxmoc', input=temp2, + options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max,depth_min, depth_max)) + Utils.move_file('maxmoc.nc', temp) + # Utils.rename_variable(temp, 'max_moc', 'mocmax'+'-'.join([lat_min, lat_max, depth_min, depth_max])) + Utils.move_file(temp, output_file) @staticmethod def psi(input_file_u, input_file_v, output_file): diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index f194ce0..1f2ce0d 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -1,5 +1,5 @@ from earthdiagnostics import Utils, cdftools, cdo, TempFile -from earthdiagnostics.basins import Basin +from earthdiagnostics.basins import Basins from autosubmit.config.log import Log import os import shutil @@ -9,6 +9,29 @@ from nco import NCOException class Heat(object): + @staticmethod + def mixed_layer_content(input_file, mltost_file, output_file): + """ + Compute mixed layer heat and salt content + + Created in February 2012 Author : vguemas@ic3.cat + + :param input_file: input grid_T file name + :param output_file: output file name (=> 2D x-y ) + :return: + """ + + temp = TempFile.get() + shutil.copy(input_file, temp) + Utils.nco.ncks(input=mltost_file, output=temp, options='-A -v mlotst') + + Log.info('Computing heat content') + cdftools.run('cdfmxlheatc', input=temp, options=['-full']) + Utils.rename_variable(temp, 'somxlheatc', 'mlotstsc') + Utils.move_file('mxlheatc.nc', temp) + Utils.setminmax(temp, 'mlotstohc') + shutil.move(temp, output_file) + @staticmethod def layer(input_file, output_file, upper, lower): """ @@ -87,7 +110,7 @@ class Heat(object): os.remove(temp) @staticmethod - def total(input_file, output_file, basin=Basin.Global, mixed_layer=0, upper=None, lower=None): + def total(input_file, output_file, basin=Basins.Global.shortname, mixed_layer=0, upper=None, lower=None): """ Compute the total ocean heat extent @@ -120,28 +143,28 @@ class Heat(object): shutil.copy(input_file, temp) - if basin == Basin.NorthAtlantic: + if basin == Basins.NorthAtlantic.shortname: para = "atl $mxl 0 0 10 65" output_file = 'NAtl_10N65N_' + output_file - elif basin == Basin.TropicalAtlantic: + elif basin == Basins.TropicalAtlantic.shortname: para = "atl $mxl 0 0 -30 30" output_file = 'TAtl_30S30N_' + output_file - elif basin == Basin.NorthPacific: + elif basin == Basins.NorthPacific.shortname: para = "pac $mxl 0 0 10 70" output_file = 'NPac_10N70N_' + output_file - elif basin == Basin.TropicalPacific: + elif basin == Basins.TropicalPacific.shortname: para = "pac $mxl 0 0 -30 30" output_file = 'TPac_30S30N_' + output_file - elif basin == Basin.Arctic: + elif basin == Basins.Arctic.shortname: para = "atl $mxl 0 0 65 90" output_file = 'Arc_65N90N_' + output_file - elif basin == Basin.Antarctic: + elif basin == Basins.Antarctic.shortname: para = "all $mxl 0 0 -90 -60" output_file = 'Ant_90S60S_' + output_file - elif basin == Basin.TropicalIndic: + elif basin == Basins.TropicalIndic.shortname: para = "ind $mxl 0 0 -30 30" output_file = 'TInd_30S30N_' + output_file - elif basin == Basin.Global: + elif basin == Basins.Global.shortname: para = "all $mxl 0 0 0 0" else: raise Exception('Basin {0} not recognized in Heat.total'.format(basin)) diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index c0ebab7..a28d7da 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -44,7 +44,7 @@ class Salinity(object): Log.debug('Finished!') @staticmethod - def heat_sal_mxl(input_file, output_file): + def mixed_layer_content(input_file, mlotst_file, output_file): """ Compute mixed layer heat and salt content @@ -54,50 +54,39 @@ class Salinity(object): :param output_file: output file name (=> 2D x-y ) :return: """ - - cdo = Utils.cdo nco = Utils.nco + cdo = Utils.cdo + input_scratch = TempFile.get() + shutil.copy(input_file, input_scratch) + Utils.nco.ncks(input=mlotst_file, output=input_scratch, options='-A -v mlotst') - temp = TempFile.get() - temp2 = TempFile.get() - - handler = cdo.openCdf(input_file) - - if 'time' in handler.variables: - nco.ncrename(input=input_file, output=temp, options='-O -d time,time_counter -v time,time_counter') - else: - shutil.copy(input_file, temp) - - if 'somxl010' not in handler.variables: - Log.info('Computing mixed layer') - cdftools.run('cdfmxl', input=temp, output=temp2) - nco.ncrename(input=temp2, output=temp2, options='-d time_counter,time') - nco.ncks(input=temp2, output=temp, options='-A') - - Log.info('Computing heat content') - cdftools.run('cdfmxlheatc', input=temp, options=['-full']) + ntime = int(cdo.ntime(input=input_scratch)[0]) + files = list() - if 'vosaline' in handler.variables: + for time in range(ntime): + Log.info('Running time {0}', time) + temp = TempFile.get() + nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) Log.info('Computing salt content') cdftools.run('cdfmxlsaltc', input=temp, options=['-full']) - nco.ncks(input='mxlsaltc.nc', output='mxlheatc.nc', options='-A') - os.remove('mxlsaltc.nc') - shutil.move('mxlheatc.nc', temp) + Utils.move_file('mxlsaltc.nc', temp) + files.append(temp) - nco.ncrename(input=temp, output=temp, options='-v .time_counter,time -d .time_counter,time') + temp = TempFile.get() + cdo.cat(input=' '.join(files), output=temp,) + nco.ncks(input=input_file, output=temp, options='-A -v time') - handler = cdo.openCdf(temp) - variables = ['somxlheatc'] - if 'somxlsaltc' in handler.variables: - variables.append('somxlsaltc') + for temp_file in files: + os.remove(temp_file) + os.remove(input_scratch) - Utils.setminmax(temp, variables) - shutil.move(temp, output_file) + Utils.rename_variable(temp, 'somxlsaltc', 'mlotstsc') + Utils.setminmax(temp, 'mlotstsc') + Utils.move_file(temp, output_file) def main(): Salinity.vertical_mean("ORCA1_MM_19601101_19610228_grid_T.nc", "out.nc", 300, 5400) - Salinity.heat_sal_mxl("ORCA1_MM_19601101_19610228_grid_T.nc", "out.nc") if __name__ == "__main__": diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 3d12e82..5f5db32 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -15,7 +15,12 @@ class Utils(object): @staticmethod def setminmax(filename, variable_list): + + if isinstance(variable_list, basestring): + variable_list = variable_list.split() + Log.info('Getting max and min values for {0}', ' '.join(variable_list)) + dataset = Utils.nco.readCdf(filename) for variable in variable_list: var = dataset.variables[variable] @@ -49,7 +54,8 @@ class Utils(object): options += ' -d {0}{1},{2} '.format(dot, old_name, new_name) Utils.nco.ncrename(input=filepath, output=filepath, options=options) - def move_file(self, source, destiny): + @staticmethod + def move_file(source, destiny): if not os.path.exists(os.path.dirname(destiny)): os.makedirs(os.path.dirname(destiny)) shutil.move(source, destiny) -- GitLab From aa0ca53c4afc55bcf85658aa0c56712683b0883f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 4 May 2016 18:43:03 +0200 Subject: [PATCH 033/268] Update MOC to treat basins as an extra dimension to comply with CMOR --- earthdiagnostics/basins.py | 12 +++++++-- earthdiagnostics/cdftools.py | 13 +++------- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/ocean/circulation.py | 36 ++++++++++++++++++++++++++- earthdiagnostics/utils.py | 15 +++++++++++ 5 files changed, 65 insertions(+), 13 deletions(-) diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index ceb6ad0..3099409 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -15,10 +15,18 @@ class Basin(object): class Basins(object): Global = Basin('glob', 'global_ocean') + + Atlantic = Basin('Atl', 'atlantic_ocean') NorthAtlantic = Basin('NAtl', 'north_atlantic_ocean') - NorthPacific = Basin('NPac', 'north_pacific_ocean') TropicalAtlantic = Basin('TAtl', 'tropical_atlantic_ocean') + + Pacific = Basin('Pac', 'pacific_ocean') + NorthPacific = Basin('NPac', 'north_pacific_ocean') TropicalPacific = Basin('TPac', 'tropical_pacific_ocean') - TropicalIndic = Basin('TInd', 'indian_ocean') + IndoPacific = Basin('IndPac', 'indo_pacific_ocean') + + Indian = Basin('Ind', 'indian_ocean') + TropicalIndian = Basin('TInd', 'tropical_indian_ocean') + Antarctic = Basin('Anta', 'antarctic_ocean') Arctic = Basin('Arct', 'arctic_ocean') diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 2c95fd3..8f834dc 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -1,4 +1,4 @@ -import subprocess +from earthdiagnostics import Utils import os from autosubmit.config.log import Log @@ -41,16 +41,11 @@ class CDFTools(object): line.append('-o') line.append(output) Log.info('Executing {0}', ' '.join(line)) - process = subprocess.Popen(line, stdout=subprocess.PIPE) - for line in process.communicate(): - if not line: - continue - Log.log.log(log_level, line) - - if process.returncode != 0: - raise Exception('Error executing {0}\n Return code: {1}', ' '.join(line), process.returncode) + line = Utils.execute_shell_command(line, log_level) if output: if not os.path.exists(output): raise Exception('Error executing {0}\n Output file not created', ' '.join(line)) + + diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 7d5375b..ba7525c 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = max_moc +DIAGS = moc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 1cd048f..f2eb34d 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -1,7 +1,13 @@ +import subprocess + +import numpy as np + from earthdiagnostics import Utils, cdftools, TempFile +from earthdiagnostics.basins import Basins from earthdiagnostics.models import Grid from autosubmit.config.log import Log from nco import NCOException +from netCDF4 import stringtochar import os import shutil import traceback @@ -26,8 +32,36 @@ class Circulation(object): if os.path.exists(output_file): os.remove(output_file) temp = TempFile.get() - cdftools.run('cdfmoc', input=input_file, output=temp) + temp2 = TempFile.get() + cdftools.run('cdfmoc', input=input_file, output=temp2) + Utils.execute_shell_command('nccopy -k netCDF-4 {0} {1}'.format(temp2, temp)) + os.remove(temp2) Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') + handler = Utils.cdo.openCdf(temp) + + handler.createDimension('basin', 5) + handler.createDimension('str_len', 20) + handler.createVariable('basin', 'S20', 'basin') + handler.variables['basin'] = stringtochar(np.array([Basins.Global.fullname, Basins.Atlantic.fullname, + Basins.Pacific.fullname, Basins.IndoPacific.fullname, + Basins.Indian.fullname])) + example = handler.variables['zomsfglo'] + moc = handler.createVariable('moc', handler.variables['zomsfglo'].datatype, ('time', 'lev', 'i', 'j', 'basin')) + + moc.units = example.units + + handler.variables['moc'][:, :, :, :, 0] = handler.variables['zomsfglo'][:] + handler.variables['moc'][:, :, :, :, 1] = handler.variables['zomsfatl'][:] + handler.variables['moc'][:, :, :, :, 2] = handler.variables['zomsfpac'][:] + handler.variables['moc'][:, :, :, :, 3] = handler.variables['zomsfinp'][:] + handler.variables['moc'][:, :, :, :, 4] = handler.variables['zomsfind'][:] + + handler.close() + + Utils.nco.ncks(input=temp, output=temp, + options='-O -x -v zomsfglo,zomsfatl,zomsfpac,zomsfinp,zomsfind,zomsfinp0') + Utils.setminmax(temp, 'moc') + Utils.move_file(temp, output_file) @staticmethod diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 5f5db32..d2d6226 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -1,3 +1,5 @@ +import subprocess + import numpy as np from autosubmit.config.log import Log from cdo import Cdo @@ -60,6 +62,19 @@ class Utils(object): os.makedirs(os.path.dirname(destiny)) shutil.move(source, destiny) + @staticmethod + def execute_shell_command(line, log_level=Log.DEBUG): + if isinstance(line, basestring): + line = line.split() + process = subprocess.Popen(line, stdout=subprocess.PIPE) + for line in process.communicate(): + if not line: + continue + Log.log.log(log_level, line) + if process.returncode != 0: + raise Exception('Error executing {0}\n Return code: {1}', ' '.join(line), process.returncode) + return line + class TempFile(object): -- GitLab From 68109217138e3fcda800922bb3d24838c8e7fb5d Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 5 May 2016 11:41:15 +0200 Subject: [PATCH 034/268] Added usalc y lmsalc --- earthdiagnostics/diags.conf | 4 +++- earthdiagnostics/diags.py | 33 ++++++++++++++------------- earthdiagnostics/ocean/circulation.py | 22 +++++++++++++----- earthdiagnostics/ocean/salinity.py | 12 +++++----- 4 files changed, 42 insertions(+), 29 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index ba7525c..87ef9c5 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = moc +DIAGS = usalc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -21,6 +21,8 @@ MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 AREA_MOC = mocarea,40,55,1000,2000,zomsfatl mocarea,30,40,1000,2000,zomsfatl STC = mocarea,0,25,0,200,zomsfpac mocarea,-25,0,0,200,zomsfpac mocarea,0,25,0,200,zomsfatl mocarea,-25,0,0,200,zomsfatl HEAT_SAL_MXL = mlotstsc mlotstohc +LMSALC = vertmeansal,300,5400 +USALC = vertmeansal,0,300 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 1166b12..b061a3e 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -32,16 +32,17 @@ class Diags: diag = diag_options[0] Log.info("Running {0}", diag) Log.debug('Full command: {0}', fulldiag) - if diag == 'vert_mean_sal': - min_depth = 0 - max_depth = 300 + if diag == 'vertmeansal': + depth_min = int(diag_options[1]) + depth_max = int(diag_options[2]) + depth = '{0}-{1}'.format(depth_min, depth_max) for [input_file, output_file] in self._get_file_names('ocean', 'so', - 'vertmeansal'.format(min_depth, max_depth)): - Salinity.vertical_mean(str(input_file), str(output_file), min_depth, max_depth) + 'somean{0}'.format(depth)): + Salinity.vertical_mean(input_file, output_file, depth_min, depth_max) elif diag == 'convection': for [input_file, output_file] in self._get_file_names('ocean', 'mlotst', 'mlotst'): - Convection.main_sites(str(input_file), self.nemo_version, str(output_file)) + Convection.main_sites(input_file, self.nemo_version, output_file) elif diag == 'psi': for [input_file, output_file] in self._get_file_names('ocean', 'sobarstf', 'psi'): @@ -55,13 +56,13 @@ class Diags: 'ohc_2d_avg_0-300m'): Heat.layer(input_file, output_file, 0, 300) Heat.layer(input_file, output_file.replace('ohc_2d_avg_0-300m', 'ohc_2d_avg_300-800m'), 300, 800) - elif diag == 'moc': + elif diag in ['moc', 'msftmyz']: for [input_file, output_file] in self._get_file_names('ocean', 'vo', - 'moc'): + 'msftmyz'): Circulation.moc(input_file, output_file) - elif diag == 'mocmax': + elif diag in ['mocmax', 'msftmyzmax']: if len(diag_options) != 5: - Log.warning('Max_moc requires 4 arguments. Skipping!') + Log.warning('Moc max requires 4 arguments. Skipping!') continue lat_min = int(diag_options[1]) @@ -72,13 +73,13 @@ class Diags: depth_max = int(diag_options[4]) depth = '{0}-{1}'.format(depth_min, depth_max) - for [input_file, output_file] in self._get_file_names('ocean', 'moc', - 'mocmax'): + for [input_file, output_file] in self._get_file_names('ocean', 'msftmyz', + 'msftmyzmax'): Circulation.max_moc(input_file, lat_min, lat_max, - output_file.replace('mocmax', 'mocmax{0}-{1}'.format(lat, depth)), + output_file.replace('msftmyzmax', 'msftmyzmax{0}-{1}'.format(lat, depth)), depth_min, depth_max) - elif diag == 'mocarea': + elif diag in ['mocarea', 'msftmyzarea']: if len(diag_options) != 6: Log.warning('area_moc requires between 5 arguments. Skipping!') continue @@ -93,8 +94,8 @@ class Diags: basin = diag_options[5] - for [input_file, output_file] in self._get_file_names('ocean', 'moc', - 'moc{0}-{1}-{2}'.format(lat, depth, basin)): + for [input_file, output_file] in self._get_file_names('ocean', 'msftmyz', + 'msftmyz{0}-{1}-{2}'.format(lat, depth, basin)): Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) elif diag == 'mlotstohc': for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'ohc', 'mlotst', 'mlotstohc'): diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index f2eb34d..61a9a72 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -7,7 +7,7 @@ from earthdiagnostics.basins import Basins from earthdiagnostics.models import Grid from autosubmit.config.log import Log from nco import NCOException -from netCDF4 import stringtochar +from netCDF4 import stringtochar, chartostring import os import shutil import traceback @@ -42,9 +42,9 @@ class Circulation(object): handler.createDimension('basin', 5) handler.createDimension('str_len', 20) handler.createVariable('basin', 'S20', 'basin') - handler.variables['basin'] = stringtochar(np.array([Basins.Global.fullname, Basins.Atlantic.fullname, - Basins.Pacific.fullname, Basins.IndoPacific.fullname, - Basins.Indian.fullname])) + handler.variables['basin'] = np.array([Basins.Global.fullname, Basins.Atlantic.fullname, + Basins.Pacific.fullname, Basins.IndoPacific.fullname, + Basins.Indian.fullname]) example = handler.variables['zomsfglo'] moc = handler.createVariable('moc', handler.variables['zomsfglo'].datatype, ('time', 'lev', 'i', 'j', 'basin')) @@ -95,7 +95,8 @@ class Circulation(object): shutil.copy(input_file, temp) handler.close() - nco.ncks(input=temp, output=temp, options='-O -v {0},time,lev,lat'.format(basin)) + nco.ncks(input=temp, output=temp, options='-O -v moc,time,lev,lat') + nco.ncks(input=temp, output=temp, options='-O -d basin,{0:.1f}'.format(basin)) nco.ncks(input=temp, output=temp, options='-O -d lev,{0:.1f},{1:.1f}'.format(depth_min, depth_max)) nco.ncks(input=temp, output=temp, options='-O -d lat,{0:.1f},{1:.1f} '.format(lat_min, lat_max)) @@ -138,12 +139,21 @@ class Circulation(object): nco.ncpdq(input=temp, output=temp, options='-O -h -a depthw,x') nco.ncpdq(input=temp, output=temp, options='-O -h -a y,x') + handler = cdo.openCdf(temp) + basins = handler.variables['basin'][:] + index = np.where(basins == Basins.Global.fullname)[0] + if len(index) == 0: + raise Exception("Global basin is not defined in {0}", input_file) + index = index[0] + + zomsfglo = handler.createVariable('zomsfglo', handler.variables['moc'].datatype, ('time', 'lev', 'i', 'j')) + zomsfglo[:] = handler.variables['moc'][:, :, :, :, index] cdo.yearmean(input=temp, output=temp2) cdftools.run('cdfmaxmoc', input=temp2, options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max,depth_min, depth_max)) Utils.move_file('maxmoc.nc', temp) - # Utils.rename_variable(temp, 'max_moc', 'mocmax'+'-'.join([lat_min, lat_max, depth_min, depth_max])) + Utils.rename_variable(temp, 'max_moc', 'mocmax'+'-'.join([lat_min, lat_max, depth_min, depth_max])) Utils.move_file(temp, output_file) @staticmethod diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index a28d7da..f1a1d08 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -21,8 +21,8 @@ class Salinity(object): cdo = Utils.cdo nco = Utils.nco - temp = TempFile() - temp2 = TempFile() + temp = TempFile.get() + temp2 = TempFile.get() Log.debug('Calculating vertical mean between {0} and {1}', upper, lower) Log.debug('Input file: {0}', input_file) Log.debug('Output file: {0}', output_file) @@ -38,9 +38,9 @@ class Salinity(object): cdftools.run('cdfvertmean', input=temp, output=temp2, options=['so', 'T', str(upper), str(lower), '-full', '-debug']) os.remove(temp) - Utils.rename_variable(temp2, 'so_vert_mean', 'vertmeansal') - Utils.setminmax(temp2, ['vertmeansal']) - shutil.move(temp2, output_file) + Utils.setminmax(temp2, 'so_vert_mean') + Utils.rename_variable(temp2, 'so_vert_mean', 'somean{0}-{1}'.format(upper, lower)) + Utils.move_file(temp2, output_file) Log.debug('Finished!') @staticmethod @@ -80,7 +80,7 @@ class Salinity(object): os.remove(temp_file) os.remove(input_scratch) - Utils.rename_variable(temp, 'somxlsaltc', 'mlotstsc') + Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'mlotstsc'}, False, True) Utils.setminmax(temp, 'mlotstsc') Utils.move_file(temp, output_file) -- GitLab From cf79b574c0fad767f22c37c0d5a79da2ac1253fc Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 5 May 2016 12:06:57 +0200 Subject: [PATCH 035/268] Added vertical mean --- earthdiagnostics/cdftools.py | 2 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 10 +++++++++- earthdiagnostics/ocean/__init__.py | 1 + earthdiagnostics/ocean/general.py | 19 +++++++++++++++++++ earthdiagnostics/ocean/salinity.py | 10 +--------- 6 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 earthdiagnostics/ocean/general.py diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 8f834dc..72a634e 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -34,7 +34,7 @@ class CDFTools(object): if isinstance(options, basestring): options = options.split() for option in options: - line.append(option) + line.append(str(option)) if output: if input == output: raise Exception('Input and output file can not be the same on CDFTools') diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 87ef9c5..702b562 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = usalc +DIAGS = vertmean,so,0,301 FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index b061a3e..73e8fe7 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,6 +1,6 @@ from parser import Parser from autosubmit.config.log import Log -from earthdiagnostics.ocean import Salinity, Convection, Circulation, Heat +from earthdiagnostics.ocean import Salinity, Convection, Circulation, Heat, General from utils import Utils from earthdiagnostics import cdftools, TempFile from autosubmit.date.chunk_date_lib import * @@ -103,6 +103,14 @@ class Diags: elif diag == 'mlotstsc': for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'so', 'mlotst', 'mlotstsc'): Salinity.mixed_layer_content(input_file, mlotst_file, output_file) + elif diag == 'vertmean': + variable = diag_options[1] + lev_min = int(diag_options[2]) + lev_max = int(diag_options[3]) + lev = '{0}-{1}'.format(lev_min, lev_max) + for [input_file, output_file] in self._get_file_names('ocean', variable, + '{0}mean{1}'.format(variable, lev)): + General.vertical_mean(input_file, output_file, variable, lev_min, lev_max) else: Log.warning('Diagnostic {0} not available', diag) continue diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 6724e3d..c43d2ed 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -2,3 +2,4 @@ from salinity import Salinity from heat import Heat from convection import Convection from circulation import Circulation +from general import General diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py new file mode 100644 index 0000000..0317ea8 --- /dev/null +++ b/earthdiagnostics/ocean/general.py @@ -0,0 +1,19 @@ +from earthdiagnostics import Utils, TempFile, cdftools +import shutil +import os + +class General(object): + + @staticmethod + def vertical_mean(input_file, output_file, variable, lev_min, lev_max): + temp = TempFile.get() + temp2 = TempFile.get() + + shutil.copy(input_file, temp) + + cdftools.run('cdfvertmean', input=temp, output=temp2, options=[variable, 'T', lev_min, lev_max, + '-full', '-debug']) + os.remove(temp) + Utils.setminmax(temp2, '{0}_vert_mean'.format(variable)) + Utils.rename_variable(temp2, '{0}_vert_mean'.format(variable), '{0}mean{1}-{2}'.format(variable, lev_min, lev_max)) + Utils.move_file(temp2, output_file) \ No newline at end of file diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index f1a1d08..fac11dd 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -82,12 +82,4 @@ class Salinity(object): Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'mlotstsc'}, False, True) Utils.setminmax(temp, 'mlotstsc') - Utils.move_file(temp, output_file) - - -def main(): - Salinity.vertical_mean("ORCA1_MM_19601101_19610228_grid_T.nc", "out.nc", 300, 5400) - - -if __name__ == "__main__": - main() + Utils.move_file(temp, output_file) \ No newline at end of file -- GitLab From a799e829e40a22871a410cad3f169e48ddfa3b7a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 5 May 2016 12:23:36 +0200 Subject: [PATCH 036/268] Added doc for vertical mean --- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/ocean/general.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 702b562..312e1dc 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = vertmean,so,0,301 +DIAGS = vertmean,so,0,10 FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 0317ea8..1d0cbc6 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -6,11 +6,31 @@ class General(object): @staticmethod def vertical_mean(input_file, output_file, variable, lev_min, lev_max): + """ + Choose vertical level in ocean, or vertically average between + 2 or more ocean levels + + Created in February 2012 Author : vguemas@ic3.cat + Modified (more generic, i.e. for any input var) in December 2014 + Author : eleftheria.exarchou@ic3.cat + + :param input_file: input file name + :param output_file: output file name (=> 2D field ) + :param variable: variable name + :param lev_min: upper depth of the layer (in level number) + :param lev_max: lower depth of the layer (in level number. If same as the upper layer, then the script just + selects this layer. If its different, a vertical integral (weighted) between upper and lower level is computed + """ + temp = TempFile.get() temp2 = TempFile.get() shutil.copy(input_file, temp) + handler = Utils.nco.openCdf(temp) + lev_min = handler.variables['lev'][lev_min] + lev_max = handler.variables['lev'][lev_max] + cdftools.run('cdfvertmean', input=temp, output=temp2, options=[variable, 'T', lev_min, lev_max, '-full', '-debug']) os.remove(temp) -- GitLab From 869a582ff13e9722c168681eced55203e7df61b8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 5 May 2016 15:42:50 +0200 Subject: [PATCH 037/268] First version of interpolate3d (not working) --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 4 ++- earthdiagnostics/diags.py | 28 +++++++++++---- earthdiagnostics/ocean/general.py | 59 ++++++++++++++++++++++++++++++- earthdiagnostics/ocean/heat.py | 36 ++++++------------- 5 files changed, 95 insertions(+), 34 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index d4426f5..e068b25 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('max_moc') +listpost=('3dtemp') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 312e1dc..4368298 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = vertmean,so,0,10 +DIAGS = 3dtemp FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -23,6 +23,8 @@ STC = mocarea,0,25,0,200,zomsfpac mocarea,-25,0,0,200,zomsfpac mocarea,0,25,0,20 HEAT_SAL_MXL = mlotstsc mlotstohc LMSALC = vertmeansal,300,5400 USALC = vertmeansal,0,300 +OHC = ohc,glob,0,0,10 +3DTEMP = interp3d,thetao diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 73e8fe7..ed97112 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -51,11 +51,22 @@ class Diags: for [input_file, output_file] in self._get_file_names('ocean', 'psi', 'msftbarot'): Circulation.gyres(str(input_file), self.nemo_version, str(output_file)) - elif diag == 'ohc_specified_layer': - for [input_file, output_file] in self._get_file_names('ocean', 'ohc', - 'ohc_2d_avg_0-300m'): - Heat.layer(input_file, output_file, 0, 300) - Heat.layer(input_file, output_file.replace('ohc_2d_avg_0-300m', 'ohc_2d_avg_300-800m'), 300, 800) + elif diag == 'ohc': + basin = diag_options[1] + mixed_layer = int(diag_options[2]) + if mixed_layer == 1: + mxl = '-mlotst' + elif mixed_layer == 0: + mxl = '' + else: + mxl = '-nomlotst' + + depth_min = int(diag_options[3]) + depth_max = int(diag_options[4]) + depth = '{0}-{1}'.format(depth_min, depth_max) + for [input_file, output_file] in self._get_file_names('ocean', 'thetao', + 'ohc{0}{1}'.format(depth, mxl)): + Heat.total(input_file, output_file, basin, mixed_layer, depth_min, depth_max) elif diag in ['moc', 'msftmyz']: for [input_file, output_file] in self._get_file_names('ocean', 'vo', 'msftmyz'): @@ -95,7 +106,7 @@ class Diags: basin = diag_options[5] for [input_file, output_file] in self._get_file_names('ocean', 'msftmyz', - 'msftmyz{0}-{1}-{2}'.format(lat, depth, basin)): + 'msftmyz{0}-{1}'.format(lat, depth)): Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) elif diag == 'mlotstohc': for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'ohc', 'mlotst', 'mlotstohc'): @@ -111,6 +122,11 @@ class Diags: for [input_file, output_file] in self._get_file_names('ocean', variable, '{0}mean{1}'.format(variable, lev)): General.vertical_mean(input_file, output_file, variable, lev_min, lev_max) + elif diag == 'interp3d': + variable = diag_options[1] + for [input_file, output_file] in self._get_file_names('ocean', variable, + '{0}interp'.format(variable)): + General.interpolate3d(input_file, output_file, variable, self.nemo_version) else: Log.warning('Diagnostic {0} not available', diag) continue diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 1d0cbc6..deb73a8 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -2,6 +2,7 @@ from earthdiagnostics import Utils, TempFile, cdftools import shutil import os + class General(object): @staticmethod @@ -35,5 +36,61 @@ class General(object): '-full', '-debug']) os.remove(temp) Utils.setminmax(temp2, '{0}_vert_mean'.format(variable)) - Utils.rename_variable(temp2, '{0}_vert_mean'.format(variable), '{0}mean{1}-{2}'.format(variable, lev_min, lev_max)) + Utils.rename_variable(temp2, '{0}_vert_mean'.format(variable), + '{0}mean{1}-{2}'.format(variable, lev_min, lev_max)) + Utils.move_file(temp2, output_file) + + @staticmethod + def interpolate3d(input_file, output_file, variable, nemo_version): + """ + 3-dimensional conservative interpolation to the regular atmospheric grid + + Created in November 2012 Author : vguemas@ic3.cat + + :param input_file: + :param output_file: + :param variable: + :return: + """ + temp = TempFile.get() + shutil.copy(input_file, temp) + if not os.path.exists('scrip_use'): + os.link('/shared/earth/software/scripts/interpolation/scrip_use', 'scrip_use') + + cdo = Utils.cdo + nco = Utils.nco + handler = cdo.openCdf(temp) + for lev in range(0, handler.dimensions['lev'].size): + temp2 = TempFile.get() + nco.ncks(input=temp, output=temp2, options='-O -d lev,{0} -v {1}'.format(lev, variable)) + nco.ncwa(input=temp2, output=temp2, options='-O -h -a lev') + # link = 'rmp_{0}_to_regular_lev{1}.nc'.format(nemo_version, lev) + # if not os.path.exists(link): + # os.link('/esnas/autosubmit/con_files/weigths/{0}/rmp_{0}_to_*_lev${1}.nc'.format(nemo_version, lev+1), + # link) + scrip_use_in = open('scrip_use_in', 'w') + scrip_use_in.writelines("&remap_inputs\n") + scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" + "weigths/{0}/rmp_{0}_to_*_lev{1}.nc'\n".format(nemo_version, lev+1)) + scrip_use_in.writelines(" infile = '{0}'\n".format(temp2)) + scrip_use_in.writelines(" invertlat = FALSE\n") + scrip_use_in.writelines(" var = '{0}'\n".format(variable)) + scrip_use_in.writelines(" fromregular = FALSE\n") + scrip_use_in.writelines(" outfile = '{0}'\n".format(temp)) + scrip_use_in.writelines("/\n") + scrip_use_in.close() + + Utils.execute_shell_command('/shared/earth/software/scripts/interpolation/scrip_use') + + nco.ncecat(input=temp2, output=temp2, options="-O -h") + nco.ncecat(input=temp2, output=temp2, options="-O -h") + shutil.move(temp2, 'tmp_{0:02d}.nc'.format(lev+1)) + + nco.ncrcat(input='tmp_01.nc', output=temp2, + options='-n {0},2,1 -v {1}'.format(len(handler.dimensions['lev'].size), variable)) + nco.ncpdq(input=temp2, output=temp2, options='-O -h -a time,lev') + nco.ncks(input=temp, output=temp2, options='-A -v lev') + cdo.setgrid(',t106grid', input=temp2, output=temp2) + if nemo_version[6:9] == '025': + cdo.invertlatdata(input=temp2, output=temp2) Utils.move_file(temp2, output_file) \ No newline at end of file diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 1f2ce0d..1c70746 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -144,44 +144,30 @@ class Heat(object): shutil.copy(input_file, temp) if basin == Basins.NorthAtlantic.shortname: - para = "atl $mxl 0 0 10 65" - output_file = 'NAtl_10N65N_' + output_file + para = "atl {0} 0 0 10 65" elif basin == Basins.TropicalAtlantic.shortname: - para = "atl $mxl 0 0 -30 30" - output_file = 'TAtl_30S30N_' + output_file + para = "atl {0} 0 0 -30 30" elif basin == Basins.NorthPacific.shortname: - para = "pac $mxl 0 0 10 70" - output_file = 'NPac_10N70N_' + output_file + para = "pac {0} 0 0 10 70" elif basin == Basins.TropicalPacific.shortname: - para = "pac $mxl 0 0 -30 30" - output_file = 'TPac_30S30N_' + output_file + para = "pac {0} 0 0 -30 30" elif basin == Basins.Arctic.shortname: - para = "atl $mxl 0 0 65 90" - output_file = 'Arc_65N90N_' + output_file + para = "atl {0} 0 0 65 90" elif basin == Basins.Antarctic.shortname: - para = "all $mxl 0 0 -90 -60" - output_file = 'Ant_90S60S_' + output_file - elif basin == Basins.TropicalIndic.shortname: - para = "ind $mxl 0 0 -30 30" - output_file = 'TInd_30S30N_' + output_file + para = "all {0} 0 0 -90 -60" + elif basin == Basins.TropicalIndian.shortname: + para = "ind {0} 0 0 -30 30" elif basin == Basins.Global.shortname: - para = "all $mxl 0 0 0 0" + para = "all {0} 0 0 0 0" else: raise Exception('Basin {0} not recognized in Heat.total'.format(basin)) - if mixed_layer == 1: - output_file = 'mxl_' + output_file - elif mixed_layer == -1: - output_file = 'nonmxl_' + output_file - # # Compute ohc # - handler = cdo.openCdf(input_file) - - if 'somxl010' in handler.variables: - cdftools.run('cdfmxl', input=temp, output=temp2) + para = para.format(mixed_layer) para = para.split() + para = para[2:] para.append(upper) para.append(lower) cdftools.run('cdfheatc', options=para, input=temp2, output=temp) -- GitLab From d861b7196c35cbf2fc42f98870e89b89068e10e6 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 5 May 2016 18:53:13 +0200 Subject: [PATCH 038/268] Advances in area_moc. Now it is failing when renaming dimension j to lat --- earthdiagnostics/basins.py | 12 +++ earthdiagnostics/diags.conf | 7 +- earthdiagnostics/diags.py | 2 +- earthdiagnostics/ocean/circulation.py | 109 ++++++++++++-------------- earthdiagnostics/ocean/general.py | 10 +-- earthdiagnostics/ocean/salinity.py | 2 +- earthdiagnostics/utils.py | 31 ++++---- 7 files changed, 90 insertions(+), 83 deletions(-) diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index 3099409..f59aeff 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -30,3 +30,15 @@ class Basins(object): Antarctic = Basin('Anta', 'antarctic_ocean') Arctic = Basin('Arct', 'arctic_ocean') + + @classmethod + def parse(cls, basin): + for name in cls.__dict__.keys(): + if name.startswith('_'): + continue + # noinspection PyCallByClass + value = cls.__getattribute__(cls, name) + if isinstance(value, Basin): + if basin.lower() in [value.shortname.lower(), value.fullname.lower()]: + return value + return None diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 4368298..7bbf83c 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = 3dtemp +DIAGS = area_moc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -18,13 +18,14 @@ NEMO_VERSION = Ec3.0_O1L46 [ALIAS] MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 -AREA_MOC = mocarea,40,55,1000,2000,zomsfatl mocarea,30,40,1000,2000,zomsfatl -STC = mocarea,0,25,0,200,zomsfpac mocarea,-25,0,0,200,zomsfpac mocarea,0,25,0,200,zomsfatl mocarea,-25,0,0,200,zomsfatl +AREA_MOC = mocarea,40,55,1000,2000,Atl mocarea,30,40,1000,2000,Atl +STC = mocarea,0,25,0,200,Pac mocarea,-25,0,0,200,Pac mocarea,0,25,0,200,Atl mocarea,-25,0,0,200,Atl HEAT_SAL_MXL = mlotstsc mlotstohc LMSALC = vertmeansal,300,5400 USALC = vertmeansal,0,300 OHC = ohc,glob,0,0,10 3DTEMP = interp3d,thetao +3DSAL = interp3d,so diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index ed97112..8465f02 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -37,7 +37,7 @@ class Diags: depth_max = int(diag_options[2]) depth = '{0}-{1}'.format(depth_min, depth_max) for [input_file, output_file] in self._get_file_names('ocean', 'so', - 'somean{0}'.format(depth)): + 'someanm{0}'.format(depth)): Salinity.vertical_mean(input_file, output_file, depth_min, depth_max) elif diag == 'convection': for [input_file, output_file] in self._get_file_names('ocean', 'mlotst', diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 61a9a72..085ec6a 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -1,16 +1,10 @@ -import subprocess - -import numpy as np - from earthdiagnostics import Utils, cdftools, TempFile from earthdiagnostics.basins import Basins from earthdiagnostics.models import Grid from autosubmit.config.log import Log -from nco import NCOException -from netCDF4 import stringtochar, chartostring +import numpy as np import os import shutil -import traceback class Circulation(object): @@ -33,39 +27,44 @@ class Circulation(object): os.remove(output_file) temp = TempFile.get() temp2 = TempFile.get() + Log.debug('Computing MOC') cdftools.run('cdfmoc', input=input_file, output=temp2) + Log.debug('Reformating to netCDF-4') Utils.execute_shell_command('nccopy -k netCDF-4 {0} {1}'.format(temp2, temp)) os.remove(temp2) Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') + Log.debug('Reformatting variables') handler = Utils.cdo.openCdf(temp) handler.createDimension('basin', 5) - handler.createDimension('str_len', 20) - handler.createVariable('basin', 'S20', 'basin') - handler.variables['basin'] = np.array([Basins.Global.fullname, Basins.Atlantic.fullname, - Basins.Pacific.fullname, Basins.IndoPacific.fullname, - Basins.Indian.fullname]) + handler.createVariable('basin', str, 'basin') + handler.variables['basin'][:] = np.array([Basins.Global.fullname, Basins.Atlantic.fullname, + Basins.Pacific.fullname, Basins.IndoPacific.fullname, + Basins.Indian.fullname], dtype=object) example = handler.variables['zomsfglo'] - moc = handler.createVariable('moc', handler.variables['zomsfglo'].datatype, ('time', 'lev', 'i', 'j', 'basin')) + moc = handler.createVariable('msftmyz', example.datatype, + ('time', 'lev', 'i', 'j', 'basin')) moc.units = example.units + moc.add_offset = example.add_offset + moc.scale_factor = example.scale_factor - handler.variables['moc'][:, :, :, :, 0] = handler.variables['zomsfglo'][:] - handler.variables['moc'][:, :, :, :, 1] = handler.variables['zomsfatl'][:] - handler.variables['moc'][:, :, :, :, 2] = handler.variables['zomsfpac'][:] - handler.variables['moc'][:, :, :, :, 3] = handler.variables['zomsfinp'][:] - handler.variables['moc'][:, :, :, :, 4] = handler.variables['zomsfind'][:] + moc[:, :, :, :, 0] = handler.variables['zomsfglo'][:] + moc[:, :, :, :, 1] = handler.variables['zomsfatl'][:] + moc[:, :, :, :, 2] = handler.variables['zomsfpac'][:] + moc[:, :, :, :, 3] = handler.variables['zomsfinp'][:] + moc[:, :, :, :, 4] = handler.variables['zomsfind'][:] handler.close() Utils.nco.ncks(input=temp, output=temp, options='-O -x -v zomsfglo,zomsfatl,zomsfpac,zomsfinp,zomsfind,zomsfinp0') - Utils.setminmax(temp, 'moc') + Utils.setminmax(temp, 'msftmyz') Utils.move_file(temp, output_file) @staticmethod - def area_moc(input_file, lat_min, lat_max, output_file, depth_min=1000, depth_max=2000, basin='zomsfatl'): + def area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin): """ Compute an Atlantic MOC index by averaging the meridional overturning in a latitude band between 1km and 2km @@ -78,9 +77,9 @@ class Circulation(object): :param lat_min: latitude min :param lat_max: latitude max :param output_file: output file name ( => index ) - :param depth_min: depth min (default : 1km) - :param depth_max: depth max (default : 2km) - :param basin: basin (default : zomsfatl) + :param depth_min: depth min + :param depth_max: depth max + :param basin: basin :return: """ nco = Utils.nco @@ -88,22 +87,40 @@ class Circulation(object): temp = TempFile.get() temp2 = TempFile.get() - handler = Utils.cdo.openCdf(input_file) - if 'x' in handler.dimensions: - nco.ncwa(input=input_file, output=temp, options='-O -a x') + shutil.copy(input_file, temp) + + handler = Utils.cdo.openCdf(temp) + if 'i' in handler.dimensions: + handler.close() + nco.ncwa(input=temp, output=temp, options='-O -a i') + nco.ncks(input=temp, output=temp, options='-x -v lon -d i') + handler = Utils.cdo.openCdf(temp) + + if isinstance(basin, basestring): + basin_instance = Basins.parse(basin) + if not basin_instance: + raise Exception("Basin {0} not recognized".format(basin)) else: - shutil.copy(input_file, temp) + basin_instance = basin + + basin_index = np.where(handler.variables['basin'][:] == basin_instance.fullname) handler.close() - nco.ncks(input=temp, output=temp, options='-O -v moc,time,lev,lat') - nco.ncks(input=temp, output=temp, options='-O -d basin,{0:.1f}'.format(basin)) - nco.ncks(input=temp, output=temp, options='-O -d lev,{0:.1f},{1:.1f}'.format(depth_min, depth_max)) - nco.ncks(input=temp, output=temp, options='-O -d lat,{0:.1f},{1:.1f} '.format(lat_min, lat_max)) + if len(basin_index) == 0: + raise Exception('Basin {0} not defined in file') + basin_index = basin_index[0][0] + + Utils.rename_variable(temp, 'j', 'lat', False, True) + nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time,lev,lat,basin') + nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) + nco.ncks(input=temp, output=temp, + options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(depth_min, depth_max, + lat_min, lat_max)) cdo.vertmean(input=temp, output=temp2) nco.ncap2(input=temp2, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') - nco.ncks(input=temp, output=output_file, options='-O -v {0},time'.format(basin)) + nco.ncks(input=temp, output=output_file, options='-O -v {0},time'.format(basin_index)) @staticmethod def max_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max): @@ -146,15 +163,13 @@ class Circulation(object): raise Exception("Global basin is not defined in {0}", input_file) index = index[0] - zomsfglo = handler.createVariable('zomsfglo', handler.variables['moc'].datatype, ('time', 'lev', 'i', 'j')) - zomsfglo[:] = handler.variables['moc'][:, :, :, :, index] + zomsfglo = handler.createVariable('zomsfglo', handler.variables['msftmyz'].datatype, ('time', 'lev', 'i', 'j')) + zomsfglo[:] = handler.variables['msftmyz'][:, :, :, :, index] cdo.yearmean(input=temp, output=temp2) cdftools.run('cdfmaxmoc', input=temp2, options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max,depth_min, depth_max)) - Utils.move_file('maxmoc.nc', temp) - Utils.rename_variable(temp, 'max_moc', 'mocmax'+'-'.join([lat_min, lat_max, depth_min, depth_max])) - Utils.move_file(temp, output_file) + Utils.move_file('maxmoc.nc', output_file) @staticmethod def psi(input_file_u, input_file_v, output_file): @@ -263,23 +278,3 @@ class Circulation(object): os.remove(temp) else: shutil.move(temp, output_file) - - -def main(): - try: - cdftools.path = '/home/Earth/jvegas/CDFTOOLS_3.0/bin' - # Circulation.psi("ORCA1_MM_19601101_19610228_grid_U.nc", "ORCA1_MM_19601101_19610228_grid_V.nc", "out_psi.nc") - # Circulation.gyres("/scratch/Earth/jvegas/compsstest/out_psi.nc", - # Grid.ECEARTH_2_3_O1L42, "out_gyres.nc") - Circulation.moc("ORCA1_MM_19601101_19610228_grid_V.nc", "out_moc.nc") - Circulation.max_moc("out_moc.nc", 38, 50, 'out_max_moc.nc', 500, 2000) - Circulation.max_moc("out_moc.nc", 40, 40, 'out_max_moc.nc', 0, 10000) - # Circulation.area_moc("out_moc.nc", 40, 80, 'out_area_moc.nc', 1000, 2000) - except NCOException as ex: - Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) - Log.error(traceback.format_exc()) - # Utils.clean() - - -if __name__ == "__main__": - main() diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index deb73a8..557a348 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -60,8 +60,9 @@ class General(object): cdo = Utils.cdo nco = Utils.nco handler = cdo.openCdf(temp) + temp2 = TempFile.get() + for lev in range(0, handler.dimensions['lev'].size): - temp2 = TempFile.get() nco.ncks(input=temp, output=temp2, options='-O -d lev,{0} -v {1}'.format(lev, variable)) nco.ncwa(input=temp2, output=temp2, options='-O -h -a lev') # link = 'rmp_{0}_to_regular_lev{1}.nc'.format(nemo_version, lev) @@ -83,14 +84,13 @@ class General(object): Utils.execute_shell_command('/shared/earth/software/scripts/interpolation/scrip_use') nco.ncecat(input=temp2, output=temp2, options="-O -h") - nco.ncecat(input=temp2, output=temp2, options="-O -h") + Utils.rename_variable(temp2, 'record', 'lev') shutil.move(temp2, 'tmp_{0:02d}.nc'.format(lev+1)) - nco.ncrcat(input='tmp_01.nc', output=temp2, - options='-n {0},2,1 -v {1}'.format(len(handler.dimensions['lev'].size), variable)) + options='-n {0},2,1 -v {1}'.format(handler.dimensions['lev'].size, variable)) nco.ncpdq(input=temp2, output=temp2, options='-O -h -a time,lev') nco.ncks(input=temp, output=temp2, options='-A -v lev') cdo.setgrid(',t106grid', input=temp2, output=temp2) if nemo_version[6:9] == '025': cdo.invertlatdata(input=temp2, output=temp2) - Utils.move_file(temp2, output_file) \ No newline at end of file + Utils.move_file(temp2, output_file) diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index fac11dd..026ef86 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -39,7 +39,7 @@ class Salinity(object): '-full', '-debug']) os.remove(temp) Utils.setminmax(temp2, 'so_vert_mean') - Utils.rename_variable(temp2, 'so_vert_mean', 'somean{0}-{1}'.format(upper, lower)) + Utils.rename_variable(temp2, 'so_vert_mean', 'someanm{0}-{1}'.format(upper, lower)) Utils.move_file(temp2, output_file) Log.debug('Finished!') diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index d2d6226..3c1134c 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -34,27 +34,26 @@ class Utils(object): @staticmethod def rename_variable(filename, old_name, new_name, must_exist=True, rename_dimension=False): - if must_exist: - dot = '' - else: - dot = '.' - options = '-v {0}{1},{2}'.format(dot, old_name, new_name) - if rename_dimension: - options += ' -d {0}{1},{2}'.format(dot, old_name, new_name) - Utils.nco.ncrename(input=filename, output=filename, options=options) + Utils.rename_variables(filename, {old_name: new_name}, must_exist, rename_dimension) @staticmethod def rename_variables(filepath, dic_names, must_exist=True, rename_dimension=False): - if must_exist: - dot = '' - else: - dot = '.' - options = '' + handler = Utils.nco.openCdf(filepath) + for old_name, new_name in dic_names.items(): - options += '-v {0}{1},{2} '.format(dot, old_name, new_name) + + if old_name in handler.variables: + handler.renameVariable(old_name, new_name) + elif must_exist: + raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) + if rename_dimension: - options += ' -d {0}{1},{2} '.format(dot, old_name, new_name) - Utils.nco.ncrename(input=filepath, output=filepath, options=options) + if old_name in handler.dimensions: + handler.renameDimension(old_name, new_name) + elif must_exist: + raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) + + handler.close() @staticmethod def move_file(source, destiny): -- GitLab From 02605f64b15136a39136b7e21e4aea20f83c32a4 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 6 May 2016 13:14:32 +0200 Subject: [PATCH 039/268] mocarea finished --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 7 ++-- earthdiagnostics/ocean/circulation.py | 58 ++++++++++++++++++--------- earthdiagnostics/ocean/general.py | 1 + earthdiagnostics/ocean/heat.py | 3 ++ earthdiagnostics/ocean/salinity.py | 3 +- earthdiagnostics/utils.py | 1 - 8 files changed, 51 insertions(+), 26 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index e068b25..39b865a 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('3dtemp') +listpost=('moc_area stc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 7bbf83c..854f1de 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = area_moc +DIAGS = max_moc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 8465f02..a99f466 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,9 +1,9 @@ -from parser import Parser -from autosubmit.config.log import Log from earthdiagnostics.ocean import Salinity, Convection, Circulation, Heat, General from utils import Utils from earthdiagnostics import cdftools, TempFile from autosubmit.date.chunk_date_lib import * +from parser import Parser +from autosubmit.config.log import Log import shutil import os @@ -109,7 +109,8 @@ class Diags: 'msftmyz{0}-{1}'.format(lat, depth)): Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) elif diag == 'mlotstohc': - for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'ohc', 'mlotst', 'mlotstohc'): + for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'ohc', + 'mlotst', 'mlotstohc'): Heat.mixed_layer_content(input_file, mlotst_file, output_file) elif diag == 'mlotstsc': for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'so', 'mlotst', 'mlotstsc'): diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 085ec6a..bd932a4 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -30,7 +30,7 @@ class Circulation(object): Log.debug('Computing MOC') cdftools.run('cdfmoc', input=input_file, output=temp2) Log.debug('Reformating to netCDF-4') - Utils.execute_shell_command('nccopy -k netCDF-4 {0} {1}'.format(temp2, temp)) + Utils.execute_shell_command(["nccopy", "-4", temp2, temp]) os.remove(temp2) Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') Log.debug('Reformatting variables') @@ -43,7 +43,8 @@ class Circulation(object): Basins.Indian.fullname], dtype=object) example = handler.variables['zomsfglo'] moc = handler.createVariable('msftmyz', example.datatype, - ('time', 'lev', 'i', 'j', 'basin')) + ('time', 'lev', 'i', 'j', 'basin'), + fill_value=example._FillValue) moc.units = example.units moc.add_offset = example.add_offset @@ -89,11 +90,10 @@ class Circulation(object): shutil.copy(input_file, temp) - handler = Utils.cdo.openCdf(temp) + handler = Utils.nco.openCdf(temp) if 'i' in handler.dimensions: handler.close() nco.ncwa(input=temp, output=temp, options='-O -a i') - nco.ncks(input=temp, output=temp, options='-x -v lon -d i') handler = Utils.cdo.openCdf(temp) if isinstance(basin, basestring): @@ -104,23 +104,39 @@ class Circulation(object): basin_instance = basin basin_index = np.where(handler.variables['basin'][:] == basin_instance.fullname) + lat_values = handler.variables['lat'][:] + lat_type = handler.variables['lat'].dtype + lat_units = handler.variables['lat'].units + lat_long_name = handler.variables['lat'].long_name + handler.close() if len(basin_index) == 0: raise Exception('Basin {0} not defined in file') basin_index = basin_index[0][0] - - Utils.rename_variable(temp, 'j', 'lat', False, True) - nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time,lev,lat,basin') nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) - nco.ncks(input=temp, output=temp, + # To remove basin dimension + nco.ncwa(input=temp, output=temp, options='-O -a basin') + nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time,lev') + + handler = Utils.nco.openCdf(temp) + handler.renameDimension('j', 'lat') + lat_variable = handler.createVariable('lat', lat_type, 'lat') + lat_variable[:] = lat_values[:] + lat_variable.units = lat_units + lat_variable.long_name = lat_long_name + + handler.close() + + nco.ncks(input=temp, output=temp2, options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(depth_min, depth_max, lat_min, lat_max)) - cdo.vertmean(input=temp, output=temp2) - nco.ncap2(input=temp2, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') + cdo.vertmean(input=temp2, output=temp) + nco.ncap2(input=temp, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') - nco.ncks(input=temp, output=output_file, options='-O -v {0},time'.format(basin_index)) + nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time') + Utils.move_file(temp, output_file) @staticmethod def max_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max): @@ -145,16 +161,16 @@ class Circulation(object): temp2 = TempFile.get() handler = Utils.cdo.openCdf(input_file) - if 'x' in handler.dimensions: - nco.ncwa(input=input_file, output=temp, options='-O -a x') + if 'i' in handler.dimensions: + nco.ncwa(input=input_file, output=temp, options='-O -a i') else: shutil.copy(input_file, temp) handler.close() # Utils.rename_variable(temp, 'record', 'x') - nco.ncpdq(input=temp, output=temp, options='-O -h -a time,x') - nco.ncpdq(input=temp, output=temp, options='-O -h -a depthw,x') - nco.ncpdq(input=temp, output=temp, options='-O -h -a y,x') + nco.ncpdq(input=temp, output=temp, options='-O -h -a time,i') + nco.ncpdq(input=temp, output=temp, options='-O -h -a lev,i') + nco.ncpdq(input=temp, output=temp, options='-O -h -a j,i') handler = cdo.openCdf(temp) basins = handler.variables['basin'][:] @@ -163,12 +179,16 @@ class Circulation(object): raise Exception("Global basin is not defined in {0}", input_file) index = index[0] - zomsfglo = handler.createVariable('zomsfglo', handler.variables['msftmyz'].datatype, ('time', 'lev', 'i', 'j')) - zomsfglo[:] = handler.variables['msftmyz'][:, :, :, :, index] + handler.close() + nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(index)) + # To remove basin dimension + nco.ncwa(input=temp, output=temp, options='-O -a basin') + Utils.rename_variable(temp, 'msftmyz', 'zomsfglo') cdo.yearmean(input=temp, output=temp2) + Utils.rename_variable(temp2, 'x', 'j', False, True) cdftools.run('cdfmaxmoc', input=temp2, - options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max,depth_min, depth_max)) + options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max, depth_min, depth_max)) Utils.move_file('maxmoc.nc', output_file) @staticmethod diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 557a348..d9c4e15 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -47,6 +47,7 @@ class General(object): Created in November 2012 Author : vguemas@ic3.cat + :param nemo_version: :param input_file: :param output_file: :param variable: diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 1c70746..50e8ccb 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -16,6 +16,7 @@ class Heat(object): Created in February 2012 Author : vguemas@ic3.cat + :param mltost_file: imput mltost file :param input_file: input grid_T file name :param output_file: output file name (=> 2D x-y ) :return: @@ -180,6 +181,8 @@ class Heat(object): # list=$list" "heatc_${jt}.nc # # setminmax ${output}$2 thc uhc + Utils.setminmax(temp, ['thc', 'uhc']) + Utils.move_file(temp, output_file) def main(): diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index 026ef86..17afc2c 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -50,6 +50,7 @@ class Salinity(object): Created in February 2012 Author : vguemas@ic3.cat + :param mlotst_file: :param input_file: input grid_T file name :param output_file: output file name (=> 2D x-y ) :return: @@ -82,4 +83,4 @@ class Salinity(object): Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'mlotstsc'}, False, True) Utils.setminmax(temp, 'mlotstsc') - Utils.move_file(temp, output_file) \ No newline at end of file + Utils.move_file(temp, output_file) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 3c1134c..08e7d66 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -41,7 +41,6 @@ class Utils(object): handler = Utils.nco.openCdf(filepath) for old_name, new_name in dic_names.items(): - if old_name in handler.variables: handler.renameVariable(old_name, new_name) elif must_exist: -- GitLab From 3ad7b195df9a055988aaf5a23d58e9607df4a0f7 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 6 May 2016 14:35:04 +0200 Subject: [PATCH 040/268] Convection finished --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 22 +++---- earthdiagnostics/ocean/__init__.py | 1 - earthdiagnostics/ocean/circulation.py | 67 +++++++++++++++++++++ earthdiagnostics/ocean/convection.py | 83 --------------------------- 6 files changed, 80 insertions(+), 97 deletions(-) delete mode 100644 earthdiagnostics/ocean/convection.py diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 39b865a..fad8eae 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('moc_area stc') +listpost=('convection') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 854f1de..8a936ae 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = max_moc +DIAGS = convection FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index a99f466..48f8443 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,4 +1,4 @@ -from earthdiagnostics.ocean import Salinity, Convection, Circulation, Heat, General +from earthdiagnostics.ocean import Salinity, Circulation, Heat, General from utils import Utils from earthdiagnostics import cdftools, TempFile from autosubmit.date.chunk_date_lib import * @@ -39,10 +39,18 @@ class Diags: for [input_file, output_file] in self._get_file_names('ocean', 'so', 'someanm{0}'.format(depth)): Salinity.vertical_mean(input_file, output_file, depth_min, depth_max) + elif diag == 'vertmean': + variable = diag_options[1] + lev_min = int(diag_options[2]) + lev_max = int(diag_options[3]) + lev = '{0}-{1}'.format(lev_min, lev_max) + for [input_file, output_file] in self._get_file_names('ocean', variable, + '{0}mean{1}'.format(variable, lev)): + General.vertical_mean(input_file, output_file, variable, lev_min, lev_max) elif diag == 'convection': for [input_file, output_file] in self._get_file_names('ocean', 'mlotst', - 'mlotst'): - Convection.main_sites(input_file, self.nemo_version, output_file) + 'mlotstsites'): + Circulation.convection_sites(input_file, self.nemo_version, output_file) elif diag == 'psi': for [input_file, output_file] in self._get_file_names('ocean', 'sobarstf', 'psi'): @@ -115,14 +123,6 @@ class Diags: elif diag == 'mlotstsc': for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'so', 'mlotst', 'mlotstsc'): Salinity.mixed_layer_content(input_file, mlotst_file, output_file) - elif diag == 'vertmean': - variable = diag_options[1] - lev_min = int(diag_options[2]) - lev_max = int(diag_options[3]) - lev = '{0}-{1}'.format(lev_min, lev_max) - for [input_file, output_file] in self._get_file_names('ocean', variable, - '{0}mean{1}'.format(variable, lev)): - General.vertical_mean(input_file, output_file, variable, lev_min, lev_max) elif diag == 'interp3d': variable = diag_options[1] for [input_file, output_file] in self._get_file_names('ocean', variable, diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index c43d2ed..5ac2fde 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,5 +1,4 @@ from salinity import Salinity from heat import Heat -from convection import Convection from circulation import Circulation from general import General diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index bd932a4..424f4f4 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -42,6 +42,7 @@ class Circulation(object): Basins.Pacific.fullname, Basins.IndoPacific.fullname, Basins.Indian.fullname], dtype=object) example = handler.variables['zomsfglo'] + # noinspection PyProtectedMember moc = handler.createVariable('msftmyz', example.datatype, ('time', 'lev', 'i', 'j', 'basin'), fill_value=example._FillValue) @@ -298,3 +299,69 @@ class Circulation(object): os.remove(temp) else: shutil.move(temp, output_file) + + @staticmethod + def convection_sites(input_file, input_grid, output_file): + """ + Compute the intensity of convection in the four main convection sites + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_file: input oce file name containing somxl010 + :param input_grid: input grid + :param output_file: output file name (=> index) + :return: + """ + if input_grid in [Grid.ECEARTH_2_3_O1L42, Grid.ECEARTH_3_0_O1L46, + Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, + Grid.NEMOVAR_O1L42]: + labrador = [255, 245, 215, 255] + irminger = [245, 290, 215, 245] + gin = [260, 310, 245, 291] + wedell = [225, 280, 1, 50] + + elif input_grid in [Grid.ECEARTH_3_0_O25L46, Grid.ECEARTH_3_0_O25L75, + Grid.GLORYS2_V1_O25L75]: + raise Exception("Option convection not available yet for {0}".format(input_grid)) + else: + raise Exception("Input grid {0} not recognized".format(input_grid)) + + labrador_file = TempFile.get() + Circulation.convection_site(input_file, labrador, labrador_file) + + irminger_file = TempFile.get() + Circulation.convection_site(input_file, irminger, irminger_file) + + gin_file = TempFile.get() + Circulation.convection_site(input_file, gin, gin_file) + + wedell_file = TempFile.get() + Circulation.convection_site(input_file, wedell, wedell_file) + + nco = Utils.nco + Utils.rename_variable(labrador_file, 'mlotst', 'mlotstLabrador') + Utils.rename_variable(irminger_file, 'mlotst', 'mlotstIrminger') + Utils.rename_variable(gin_file, 'mlotst', 'mlotstGIN') + Utils.rename_variable(wedell_file, 'mlotst', 'mlotstWedell') + + nco.ncks(input=irminger_file, output=labrador_file, options='-A -v mlotstIrminger') + nco.ncks(input=gin_file, output=labrador_file, options='-A -v mlotstGIN') + nco.ncks(input=wedell_file, output=labrador_file, options='-A -v mlotstWedell') + + Utils.move_file(labrador_file, output_file) + + @staticmethod + def convection_site(input_file, site, output_file): + """ + Compute the intensity of convection at one site + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_file: input oce file name containing somxl010 + :param site: site to calculate convection on + :param output_file: output file name (=> index) + :return: + """ + + Utils.cdo.fldmax(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), + output=output_file) diff --git a/earthdiagnostics/ocean/convection.py b/earthdiagnostics/ocean/convection.py deleted file mode 100644 index 0d0bab2..0000000 --- a/earthdiagnostics/ocean/convection.py +++ /dev/null @@ -1,83 +0,0 @@ -from earthdiagnostics.models import Grid -from earthdiagnostics import Utils, TempFile -from nco import NCOException -from autosubmit.config.log import Log - - -class Convection(object): - @staticmethod - def main_sites(input_file, input_grid, output_file): - """ - Compute the intensity of convection in the four main convection sites - - Created in October 2013 Author : vguemas@ic3.cat - - :param input_file: input oce file name containing somxl010 - :param input_grid: input grid - :param output_file: output file name (=> index) - :return: - """ - if input_grid in [Grid.ECEARTH_2_3_O1L42, Grid.ECEARTH_3_0_O1L46, - Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, - Grid.NEMOVAR_O1L42]: - labrador = [255, 245, 215, 255] - irminger = [245, 290, 215, 245] - gin = [260, 310, 245, 291] - wedell = [225, 280, 1, 50] - - elif input_grid in [Grid.ECEARTH_3_0_O25L46, Grid.ECEARTH_3_0_O25L75, - Grid.GLORYS2_V1_O25L75]: - raise Exception("Option convection not available yet for {0}".format(input_grid)) - else: - raise Exception("Input grid {0} not recognized".format(input_grid)) - - labrador_file = TempFile.get() - Convection.site(input_file, labrador, labrador_file) - - irminger_file = TempFile.get() - Convection.site(input_file, irminger, irminger_file) - - gin_file = TempFile.get() - Convection.site(input_file, gin, gin_file) - - wedell_file = TempFile.get() - Convection.site(input_file, wedell, wedell_file) - - nco = Utils.nco - Utils.rename_variable(labrador_file, 'mlotst', 'Labrador') - Utils.rename_variable(irminger_file, 'mlotst', 'Irminger') - Utils.rename_variable(gin_file, 'mlotst', 'GIN') - Utils.rename_variable(wedell_file, 'mlotst', 'Wedell') - - nco.ncks(input=labrador_file, output=output_file, options='-A -v Labrador') - nco.ncks(input=irminger_file, output=output_file, options='-A -v Irminger') - nco.ncks(input=gin_file, output=output_file, options='-A -v GIN') - nco.ncks(input=wedell_file, output=output_file, options='-A -v Wedell') - - @staticmethod - def site(input_file, site, output_file): - """ - Compute the intensity of convection at one site - - Created in October 2013 Author : vguemas@ic3.cat - - :param input_file: input oce file name containing somxl010 - :param site: site to calculate convection on - :param output_file: output file name (=> index) - :return: - """ - - Utils.cdo.fldmax(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), - output=output_file) - - -def main(): - try: - Convection.main_sites("/scratch/Earth/jvegas/compsstest/ORCA1_MM_19601101_19610228_grid_T.nc", - Grid.ECEARTH_2_3_O1L42, "outconvection.nc") - TempFile.clean() - except NCOException as ex: - Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) - -if __name__ == "__main__": - main() -- GitLab From 225d4c8fbfd3cfb920f969dbbaa79c16df43e77e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 6 May 2016 16:50:43 +0200 Subject: [PATCH 041/268] First version of OHC finished --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/cdftools.py | 4 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 4 +- earthdiagnostics/ocean/heat.py | 78 ++++++++++++++++++---------------- earthdiagnostics/utils.py | 7 ++- 6 files changed, 52 insertions(+), 45 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index fad8eae..48b348c 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('convection') +listpost=('ohc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 72a634e..3d72865 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -41,11 +41,11 @@ class CDFTools(object): line.append('-o') line.append(output) Log.info('Executing {0}', ' '.join(line)) - line = Utils.execute_shell_command(line, log_level) + shell_output = Utils.execute_shell_command(line, log_level) if output: if not os.path.exists(output): raise Exception('Error executing {0}\n Output file not created', ' '.join(line)) - + return shell_output diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 8a936ae..6bef890 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = convection +DIAGS = ohc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 48f8443..28c03ad 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -72,9 +72,9 @@ class Diags: depth_min = int(diag_options[3]) depth_max = int(diag_options[4]) depth = '{0}-{1}'.format(depth_min, depth_max) - for [input_file, output_file] in self._get_file_names('ocean', 'thetao', + for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'thetao', 'mlotst', 'ohc{0}{1}'.format(depth, mxl)): - Heat.total(input_file, output_file, basin, mixed_layer, depth_min, depth_max) + Heat.total(input_file, mlotst_file, output_file, basin, mixed_layer, depth_min, depth_max) elif diag in ['moc', 'msftmyz']: for [input_file, output_file] in self._get_file_names('ocean', 'vo', 'msftmyz'): diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 50e8ccb..3842f7f 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -5,6 +5,7 @@ import os import shutil import traceback from nco import NCOException +import numpy as np class Heat(object): @@ -111,7 +112,7 @@ class Heat(object): os.remove(temp) @staticmethod - def total(input_file, output_file, basin=Basins.Global.shortname, mixed_layer=0, upper=None, lower=None): + def total(input_file, mlotst_file, output_file, basin=Basins.Global.shortname, mixed_layer=0, upper=None, lower=None): """ Compute the total ocean heat extent @@ -125,64 +126,67 @@ class Heat(object): :param lower: lower level of the layer (optional) Default : bottom """ - # - # cp ${CON_FILES}/heatc_template.nc template_heatc.nc - # ncdump template_heatc.nc > template_heatc.cdl - # # - # # Define some parameters - # # - # typeset var para - # typeset var output - # typeset var nlev=`cat depth.txt | wc -l` - # if [[ ! -z "$depmin" && ! -z "$depmax" ]] ; then - # if [[ $depmin != 0 || ${down} != ${nlev} && ${down} != 0 ]] ; then - # output=${depmin}-${depmax}'_' - # fi - # fi + nco = Utils.nco temp = TempFile.get() temp2 = TempFile.get() shutil.copy(input_file, temp) + nco.ncks(input=mlotst_file, output=temp, options='-A -v mlotst') if basin == Basins.NorthAtlantic.shortname: - para = "atl {0} 0 0 10 65" + para = "{0} 0 0 10 65" elif basin == Basins.TropicalAtlantic.shortname: - para = "atl {0} 0 0 -30 30" + para = "{0} 0 0 -30 30" elif basin == Basins.NorthPacific.shortname: - para = "pac {0} 0 0 10 70" + para = "{0} 0 0 10 70" elif basin == Basins.TropicalPacific.shortname: - para = "pac {0} 0 0 -30 30" + para = "{0} 0 0 -30 30" elif basin == Basins.Arctic.shortname: - para = "atl {0} 0 0 65 90" + para = "{0} 0 0 65 90" elif basin == Basins.Antarctic.shortname: - para = "all {0} 0 0 -90 -60" + para = "{0} 0 0 -90 -60" elif basin == Basins.TropicalIndian.shortname: - para = "ind {0} 0 0 -30 30" + para = "{0} 0 0 -30 30" elif basin == Basins.Global.shortname: - para = "all {0} 0 0 0 0" + para = "{0} 0 0 0 0" else: raise Exception('Basin {0} not recognized in Heat.total'.format(basin)) # # Compute ohc # - para = para.format(mixed_layer) + para = "-full" + para.format(mixed_layer) para = para.split() - para = para[2:] + para = para[1:] para.append(upper) para.append(lower) - cdftools.run('cdfheatc', options=para, input=temp2, output=temp) - # thc=`cat tmp.log | grep "Total Heat content :" | awk '{print $5}'`; - # uhc=`cat tmp.log | grep "Total Heat content/volume" | awk '{print $5}'`; - # sed -e "s/thc =.*/thc = $thc ;/" template_heatc.cdl > template_heatc2.cdl - # sed -e "s/uhc =.*/uhc = $uhc ;/" template_heatc2.cdl > template_heatc.cdl - # ncgen -o heatc_${jt}.nc template_heatc.cdl - # rm -f template_heatc2.cdl tmpohc.nc mxl.nc tmp.log - # list=$list" "heatc_${jt}.nc - # - # setminmax ${output}$2 thc uhc - Utils.setminmax(temp, ['thc', 'uhc']) - Utils.move_file(temp, output_file) + para.append(str(mixed_layer)) + shell_output = cdftools.run('cdfheatc', options=para, input=temp) + + nco.ncks(input=temp, output=temp2, options='-O -v time') + output = nco.openCdf(temp2) + thc = output.createVariable('thc', float, 'time') + uhc = output.createVariable('uhc', float, 'time') + time = 0 + for lines in shell_output: + if not lines: + continue + + for line in lines.split('\n'): + line = line.lstrip() + if line.startswith("Total Heat content "): + Log.result(line) + thc[time] = line[line.index(':')+1: line.index('Joules')] + elif line.startswith("Total Heat content/volume"): + Log.user_warning(line) + uhc[time] = line[line.index(':')+1: line.index('Joules')] + time += 1 + elif line.startswith('TIME : '): + Log.info(line) + + output.close() + Utils.setminmax(temp2, ['thc', 'uhc']) + Utils.move_file(temp2, output_file) def main(): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 08e7d66..7364776 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -65,13 +65,16 @@ class Utils(object): if isinstance(line, basestring): line = line.split() process = subprocess.Popen(line, stdout=subprocess.PIPE) - for line in process.communicate(): + output = list() + comunicate = process.communicate() + for line in comunicate: if not line: continue Log.log.log(log_level, line) + output.append(line) if process.returncode != 0: raise Exception('Error executing {0}\n Return code: {1}', ' '.join(line), process.returncode) - return line + return output class TempFile(object): -- GitLab From 5a3b297ac843f7309a730856a9e13b82b807b90b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 6 May 2016 17:46:16 +0200 Subject: [PATCH 042/268] Finished Heat_Sal_Mxl --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 8 +++++-- earthdiagnostics/diags.py | 20 +++++++++-------- earthdiagnostics/ocean/heat.py | 36 ++++++++++++++++++++++-------- earthdiagnostics/ocean/salinity.py | 4 ++-- 5 files changed, 47 insertions(+), 23 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 48b348c..d76d20a 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('ohc') +listpost=('heat_sal_mxl') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 6bef890..14ec902 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = ohc +DIAGS = HEAT_SAL_MXL FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -20,10 +20,14 @@ NEMO_VERSION = Ec3.0_O1L46 MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 AREA_MOC = mocarea,40,55,1000,2000,Atl mocarea,30,40,1000,2000,Atl STC = mocarea,0,25,0,200,Pac mocarea,-25,0,0,200,Pac mocarea,0,25,0,200,Atl mocarea,-25,0,0,200,Atl -HEAT_SAL_MXL = mlotstsc mlotstohc +HEAT_SAL_MXL = mlotstsc mlotsthc LMSALC = vertmeansal,300,5400 USALC = vertmeansal,0,300 OHC = ohc,glob,0,0,10 +XOHC = ohc,glob,1,0,0 +LOHC = ohc,glob,0,23,46 +MOHC = ohc,glob,0,18,22 +UOHC = ohc,glob,0,0,17 3DTEMP = interp3d,thetao 3DSAL = interp3d,so diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 28c03ad..41e01ee 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -63,17 +63,19 @@ class Diags: basin = diag_options[1] mixed_layer = int(diag_options[2]) if mixed_layer == 1: - mxl = '-mlotst' + mxl = 'mlotst' + depth = '' elif mixed_layer == 0: mxl = '' + depth_min = int(diag_options[3]) + depth_max = int(diag_options[4]) + depth = '{0}-{1}'.format(depth_min, depth_max) else: - mxl = '-nomlotst' + mxl = 'nomlotst' + depth = '' - depth_min = int(diag_options[3]) - depth_max = int(diag_options[4]) - depth = '{0}-{1}'.format(depth_min, depth_max) for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'thetao', 'mlotst', - 'ohc{0}{1}'.format(depth, mxl)): + 'ohc{0}{1}'.format(mxl, depth)): Heat.total(input_file, mlotst_file, output_file, basin, mixed_layer, depth_min, depth_max) elif diag in ['moc', 'msftmyz']: for [input_file, output_file] in self._get_file_names('ocean', 'vo', @@ -116,9 +118,9 @@ class Diags: for [input_file, output_file] in self._get_file_names('ocean', 'msftmyz', 'msftmyz{0}-{1}'.format(lat, depth)): Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) - elif diag == 'mlotstohc': - for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'ohc', - 'mlotst', 'mlotstohc'): + elif diag == 'mlotsthc': + for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'thetao', + 'mlotst', 'mlotsthc'): Heat.mixed_layer_content(input_file, mlotst_file, output_file) elif diag == 'mlotstsc': for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'so', 'mlotst', 'mlotstsc'): diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 3842f7f..64e3c16 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -5,7 +5,6 @@ import os import shutil import traceback from nco import NCOException -import numpy as np class Heat(object): @@ -23,16 +22,35 @@ class Heat(object): :return: """ + nco = Utils.nco + + input_scratch = TempFile.get() + shutil.copy(input_file, input_scratch) + nco.ncks(input=mltost_file, output=input_scratch, options='-A -v mlotst') + + ntime = int(cdo.ntime(input=input_scratch)[0]) + files = list() + + for time in range(ntime): + Log.info('Running time {0}', time) + temp = TempFile.get() + nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) + Log.info('Computing salt content') + cdftools.run('cdfmxlheatc', input=temp, options=['-full']) + Utils.move_file('mxlheatc.nc', temp) + files.append(temp) + temp = TempFile.get() - shutil.copy(input_file, temp) - Utils.nco.ncks(input=mltost_file, output=temp, options='-A -v mlotst') + cdo.cat(input=' '.join(files), output=temp,) + nco.ncks(input=input_scratch, output=temp, options='-A -v time') - Log.info('Computing heat content') - cdftools.run('cdfmxlheatc', input=temp, options=['-full']) - Utils.rename_variable(temp, 'somxlheatc', 'mlotstsc') - Utils.move_file('mxlheatc.nc', temp) - Utils.setminmax(temp, 'mlotstohc') - shutil.move(temp, output_file) + for temp_file in files: + os.remove(temp_file) + os.remove(input_scratch) + + Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlheatc': 'mlotsthc'}, False, True) + Utils.setminmax(temp, 'mlotsthc') + Utils.move_file(temp, output_file) @staticmethod def layer(input_file, output_file, upper, lower): diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index 17afc2c..26f11a7 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -68,14 +68,14 @@ class Salinity(object): Log.info('Running time {0}', time) temp = TempFile.get() nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) - Log.info('Computing salt content') + Log.info('Computing heat content') cdftools.run('cdfmxlsaltc', input=temp, options=['-full']) Utils.move_file('mxlsaltc.nc', temp) files.append(temp) temp = TempFile.get() cdo.cat(input=' '.join(files), output=temp,) - nco.ncks(input=input_file, output=temp, options='-A -v time') + nco.ncks(input=input_scratch, output=temp, options='-A -v time') for temp_file in files: os.remove(temp_file) -- GitLab From 83da322703383118d4da3807598e28a2a010d719 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 9 May 2016 15:25:59 +0200 Subject: [PATCH 043/268] First version of ohc with basins --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/basins.py | 54 ++++++--- earthdiagnostics/diags.conf | 3 +- earthdiagnostics/diags.py | 25 ++++- earthdiagnostics/ocean/heat.py | 195 ++++++++++++++++++++------------- earthdiagnostics/utils.py | 10 +- 6 files changed, 186 insertions(+), 103 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index d76d20a..08e8b8c 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('heat_sal_mxl') +listpost=('uNAtlohc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index f59aeff..18730f6 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -1,8 +1,12 @@ class Basin(object): - def __init__(self, shortname, fullname): + def __init__(self, shortname, fullname, coordinates=None): self._shortname = shortname self._fullname = fullname + if coordinates: + self._coordinates = coordinates + else: + self._coordinates = [0, 0, 0, 0] @property def shortname(self): @@ -12,24 +16,48 @@ class Basin(object): def fullname(self): return self._fullname + @property + def min_lon(self): + return self._coordinates[0] + + @property + def max_lon(self): + return self._coordinates[1] + + @property + def min_lat(self): + return self._coordinates[2] + + @property + def max_lat(self): + return self._coordinates[3] + + @property + def lon(self): + return self._coordinates[0:2] + + @property + def lat(self): + return self._coordinates[2:] + class Basins(object): - Global = Basin('glob', 'global_ocean') + Global = Basin('glob', 'Global_Ocean') - Atlantic = Basin('Atl', 'atlantic_ocean') - NorthAtlantic = Basin('NAtl', 'north_atlantic_ocean') - TropicalAtlantic = Basin('TAtl', 'tropical_atlantic_ocean') + Atlantic = Basin('Atl', 'Atlantic_Ocean') + NorthAtlantic = Basin('NAtl', 'North_Atlantic_Ocean') + TropicalAtlantic = Basin('TAtl', 'Tropical_Atlantic_Ocean') - Pacific = Basin('Pac', 'pacific_ocean') - NorthPacific = Basin('NPac', 'north_pacific_ocean') - TropicalPacific = Basin('TPac', 'tropical_pacific_ocean') - IndoPacific = Basin('IndPac', 'indo_pacific_ocean') + Pacific = Basin('Pac', 'Pacific_Ocean') + NorthPacific = Basin('NPac', 'North_Pacific_Ocean') + TropicalPacific = Basin('TPac', 'Tropical_Pacific_Ocean') + IndoPacific = Basin('IndPac', 'Indo_Pacific_Ocean') - Indian = Basin('Ind', 'indian_ocean') - TropicalIndian = Basin('TInd', 'tropical_indian_ocean') + Indian = Basin('Ind', 'Indian_Ocean') + TropicalIndian = Basin('TInd', 'Tropical_Indian_Ocean') - Antarctic = Basin('Anta', 'antarctic_ocean') - Arctic = Basin('Arct', 'arctic_ocean') + Antarctic = Basin('Anta', 'Antarctic_Ocean') + Arctic = Basin('Arct', 'Arctic_Ocean') @classmethod def parse(cls, basin): diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 14ec902..53dc8c0 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = HEAT_SAL_MXL +DIAGS = ohc,NAtl,0,0,17 FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -28,6 +28,7 @@ XOHC = ohc,glob,1,0,0 LOHC = ohc,glob,0,23,46 MOHC = ohc,glob,0,18,22 UOHC = ohc,glob,0,0,17 +OHC_SPECIFIED_LAYER = ohclayer,0,300 ohclayer,300,800 3DTEMP = interp3d,thetao 3DSAL = interp3d,so diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 41e01ee..18f2667 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -12,7 +12,7 @@ class Diags: def __init__(self, config_file): Log.debug('Initialising Diags') self._read_config(config_file) - Utils.scratch_folder = os.path.join(self.scratch_dir) + TempFile.scratch_folder = self.scratch_dir cdftools.path = self.cdftools_path Log.debug('Diags ready') @@ -62,21 +62,31 @@ class Diags: elif diag == 'ohc': basin = diag_options[1] mixed_layer = int(diag_options[2]) + depth_min = int(diag_options[3]) + depth_max = int(diag_options[4]) + if mixed_layer == 1: mxl = 'mlotst' depth = '' elif mixed_layer == 0: mxl = '' - depth_min = int(diag_options[3]) - depth_max = int(diag_options[4]) depth = '{0}-{1}'.format(depth_min, depth_max) else: mxl = 'nomlotst' depth = '' for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'thetao', 'mlotst', - 'ohc{0}{1}'.format(mxl, depth)): + 'ohcsum{0}{1}'.format(mxl, depth)): Heat.total(input_file, mlotst_file, output_file, basin, mixed_layer, depth_min, depth_max) + elif diag == 'ohclayer': + depth_min = int(diag_options[1]) + depth_max = int(diag_options[2]) + + depth = '{0}-{1}'.format(depth_min, depth_max) + + for [input_file, output_file] in self._get_file_names('ocean', 'thetao', + 'ohc{0}'.format(depth)): + Heat.layer(input_file, output_file, depth_min, depth_max) elif diag in ['moc', 'msftmyz']: for [input_file, output_file] in self._get_file_names('ocean', 'vo', 'msftmyz'): @@ -187,6 +197,13 @@ class Diags: shutil.copy(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), 'mask_regions.nc') Utils.rename_variables('mask_regions.nc', dic_variables, False, True) + + if os.path.exists(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.nemo_version))) and \ + not os.path.exists('mask_regions.3d.nc'): + Log.info('Copying mask_regions.3d.nc') + shutil.copy(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.nemo_version)), + 'mask_regions.3d.nc') + Utils.rename_variables('mask_regions.3d.nc', dic_variables, False, True) Log.result('Mesh files ready!') def _read_config(self, config_file): diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 64e3c16..365774e 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -53,7 +53,7 @@ class Heat(object): Utils.move_file(temp, output_file) @staticmethod - def layer(input_file, output_file, upper, lower): + def layer(input_file, output_file, min_depth, max_depth): """ Pointwise Ocean Heat Content in a specified ocean thickness (J/m-2) @@ -62,68 +62,98 @@ class Heat(object): :param input_file: input grid_T file nam :param output_file: output file name (=> 2D x-y ) - :param upper: upper depth of the layer (in meters) - :param lower: lower depth of the layer (in meters) + :param min_depth: upper depth of the layer (in meters) + :param max_depth: lower depth of the layer (in meters) :return: """ nco = Utils.nco - temp = TempFile.get() + input_scratch = TempFile.get() temp2 = TempFile.get() heatc_sl_out = TempFile.get() heatc_sl_top = TempFile.get() + level_above = TempFile.get() + level_below = TempFile.get() heatc_sl_bottom = TempFile.get() - heatc_sl_invert = TempFile.get() + heatc_sl_top_invert = TempFile.get() + depth_diff_lay = TempFile.get() + depth_diff_sublay = TempFile.get() + total_heatc_sl = TempFile.get() e3tfile = TempFile.get() + factor = TempFile.get() nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*e3t"'), - nco.ncrename(input=e3tfile, output=e3tfile, options='-d t,time -d z,deptht') - - nco.ncks(input=input_file, output=temp, options='-O -v votemper') - nco.ncrename(input=temp, output=temp, options='-v votemper,heatc_sl') - cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) - os.remove(e3tfile) - nco.ncks(input=heatc_sl_out, output=temp, options='-O -d deptht,{0}.0,{1}.0'.format(upper, lower)) - - # perform the integration of ohc down to that level (main contribution) - nco.ncap2(input=temp, output=heatc_sl_top, options='-O -s "heatc_sl=heatc_sl.total($deptht)"') - - # now extract a few levels below, to compute the residual ohc - # obtain the weight for the extra level containing the 300 m - # deptht in the gridT files is positive - # weight = (300.0 - depth_top)/(depth_bottom - depth_top) - # and add the thickness down to 300 m in the next layer - nco.ncpdq(input=heatc_sl_out, output=heatc_sl_invert, options='-a "-deptht"') - nco.ncks(input=heatc_sl_invert, output=temp2, options='-O -d deptht,0,0') - Utils.rename_variable(temp2, 'deptht', 'layerthcknss') - shutil.move(temp2, heatc_sl_invert) - - nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, - options='-O -d deptht,{0}.0,{1}.0'.format(lower, lower + 200)) - nco.ncks(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-O -d deptht,0,0') - Utils.rename_variable(heatc_sl_bottom, 'deptht', 'layerthcknss') - - os.remove(heatc_sl_out) - - # Here, add the residual contribution, before adding it to the main contribution - nco.ncbo(input=' '.join([heatc_sl_bottom, heatc_sl_invert]), output=temp, - options='-A --op_typ=sub -v layerthcknss') - - Utils.rename_variable(temp, 'layerthcknss', 'heatc_sl') - nco.ncap2(input=heatc_sl_invert, output=temp2, options='-s "heatc_sl=({0:.1f} - layerthcknss)"'.format(lower)) - os.remove(heatc_sl_invert) - nco.ncbo(input=' '.join([temp, temp2]), output=temp, options='--op_typ=/ -v heatc_sl') - os.remove(temp2) - nco.ncrename(input=temp, output=temp, options='-v heatc_sl,factor') - nco.ncks(input=temp, output=heatc_sl_bottom, options='-A -v factor') - nco.ncap2(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-O -s "heatc_sl=(factor * heatc_sl)"') - nco.ncwa(input=heatc_sl_bottom, output=heatc_sl_bottom, options='-O -a deptht') - nco.ncbo(input=' '.join([heatc_sl_top, heatc_sl_bottom]), output=temp, options='--op_typ=+ -v heatc_sl') - os.remove(heatc_sl_top) - os.remove(heatc_sl_bottom) - nco.ncap2(input=temp, output=temp, options='-s "heatc_sl=1020.0*4000*heatc_sl"') + shutil.copy(input_file, input_scratch) + ntime = int(cdo.ntime(input=input_scratch)[0]) + files = list() + + for time in range(ntime): + try: + Log.info('Running time {0}', time) + temp = TempFile.get() + nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) + Utils.rename_variable(temp, 'thetao', 'heatc_sl') + nco.ncks(input=temp, output=temp, options='-O -v heatc_sl') + cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) + + # extract the data between the two given depths --> heatc_sl_top.nc + nco.ncks(input=heatc_sl_out, output=heatc_sl_top, + options='-O -d lev,{0}.0,{1}.0'.format(min_depth, max_depth)) + # perform the integration of ohc down to that level (main contribution) + nco.ncap2(options="-O -s 'heatc_sl=heatc_sl.total({0})'".format(max_depth), + input=heatc_sl_top, output=heatc_sl_top) + # now extract a few levels below, to compute the residual ohc + # addition with float returned: + nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, + options='-O -d lev,{0}.0,{1}.0'.format(max_depth, max_depth+200)) + + # obtain the weight for the extra level containing the 300 m + # deptht in the gridT files is positive + # weight = (300.0 - depth_top)/(depth_bottom - depth_top) + # and add the thickness down to 300 m in the next layer + nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) + nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') + nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') + + # Here, add the residual contribution, before adding it to the main contribution + Utils.rename_variable(level_below, 'lev', 'layerthcknss') + Utils.rename_variable(level_above, 'lev', 'layerthcknss') + Utils.execute_shell_command('ncbo -A --op_typ=sub -v layerthcknss {0} {1} {2}'.format(level_below, level_above, depth_diff_lay)) + # nco.ncbo(options='-A --op_typ=sub -v layerthcknss', + # input='{0} {1}'.format(level_below, level_above), output=depth_diff_lay) + Utils.rename_variable(depth_diff_lay, 'layerthcknss', 'lev') + + nco.ncap2(options='-s "heatc_sl=({0} - layerthcknss)"'.format(max_depth), + input=level_above, output=depth_diff_sublay) + nco.ncbo(options='--op_typ=/ -v heatc_sl', + input=' '.join([depth_diff_sublay, depth_diff_lay]), output=factor) + Utils.rename_variable(factor, 'heatc_sl', 'factor') + nco.ncks(input=factor, output=level_below, options='-A -v factor') + os.remove(depth_diff_lay) + os.remove(depth_diff_sublay) + + nco.ncap2(input=level_below, output=level_below, options='-O -s "heatc_sl=(factor * heatc_sl)"') + nco.ncwa(input=level_below, output=level_below, options='-O -a lev') + + # nco.ncbo(options=' --op_typ=+ -v heatc_sl', + # input=' '.join([heatc_sl_top, level_below]), output=total_heatc_sl) + Utils.execute_shell_command('ncbo --op_typ=+ -v heatc_sl ' + '{0} {1} {2}'.format(heatc_sl_top, level_above, total_heatc_sl)) + nco.ncap2(input=total_heatc_sl, output=temp, options='-s "heatc_sl=1020.0*4000*heatc_sl"') + files.append(temp) + except Exception as ex: + Log.error(ex.message) + raise ex + + temp = TempFile.get() + cdo.cat(input=' '.join(files), output=temp,) + nco.ncks(input=input_scratch, output=temp, options='-A -v time') + + for temp_file in files: + os.remove(temp_file) + os.remove(input_scratch) Utils.setminmax(temp, ['heatc_sl']) shutil.move(temp, output_file) @@ -151,40 +181,47 @@ class Heat(object): shutil.copy(input_file, temp) nco.ncks(input=mlotst_file, output=temp, options='-A -v mlotst') - if basin == Basins.NorthAtlantic.shortname: - para = "{0} 0 0 10 65" - elif basin == Basins.TropicalAtlantic.shortname: - para = "{0} 0 0 -30 30" - elif basin == Basins.NorthPacific.shortname: - para = "{0} 0 0 10 70" - elif basin == Basins.TropicalPacific.shortname: - para = "{0} 0 0 -30 30" - elif basin == Basins.Arctic.shortname: - para = "{0} 0 0 65 90" - elif basin == Basins.Antarctic.shortname: - para = "{0} 0 0 -90 -60" - elif basin == Basins.TropicalIndian.shortname: - para = "{0} 0 0 -30 30" - elif basin == Basins.Global.shortname: - para = "{0} 0 0 0 0" - else: - raise Exception('Basin {0} not recognized in Heat.total'.format(basin)) - - # - # Compute ohc - # - para = "-full" + para.format(mixed_layer) - para = para.split() - para = para[1:] - para.append(upper) - para.append(lower) - para.append(str(mixed_layer)) - shell_output = cdftools.run('cdfheatc', options=para, input=temp) + basin = Basins.parse(basin) + + handler = nco.openCdf('mask_regions.3d.nc') + if not basin.fullname in handler.variables: + raise Exception('Basin {0} is not defined on mask_regions.nc'.format(basin.fullname)) + + handler.close() + shutil.move('mask.nc', 'original_mask.nc') + shutil.move('mask_regions.3d.nc', 'mask.nc') + Utils.rename_variable('mask.nc', basin.fullname, 'tmask') + + try: + para = list() + para.append("-full") + para.append(str(basin.min_lon)) + para.append(str(basin.max_lon)) + para.append(str(basin.min_lat)) + para.append(str(basin.max_lat)) + para.append(upper) + para.append(lower) + para.append(str(mixed_layer)) + shell_output = cdftools.run('cdfheatc', options=para, input=temp) + except ex as Exception: + raise ex + finally: + Utils.rename_variable('mask.nc', 'tmask', basin.fullname) + shutil.move('mask.nc', 'mask_regions.3d.nc') + shutil.move('original_mask.nc', 'mask.nc') nco.ncks(input=temp, output=temp2, options='-O -v time') output = nco.openCdf(temp2) + thc = output.createVariable('thc', float, 'time') + thc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" + thc.long_name = "Total heat content" + thc.units = "Joules" + uhc = output.createVariable('uhc', float, 'time') + uhc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" + uhc.long_name = "Heat content per unit volume" + uhc.units = "Joules/m3" time = 0 for lines in shell_output: if not lines: diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 7364776..55cc536 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -61,10 +61,10 @@ class Utils(object): shutil.move(source, destiny) @staticmethod - def execute_shell_command(line, log_level=Log.DEBUG): - if isinstance(line, basestring): - line = line.split() - process = subprocess.Popen(line, stdout=subprocess.PIPE) + def execute_shell_command(command, log_level=Log.DEBUG): + if isinstance(command, basestring): + command = command.split() + process = subprocess.Popen(command, stdout=subprocess.PIPE) output = list() comunicate = process.communicate() for line in comunicate: @@ -73,7 +73,7 @@ class Utils(object): Log.log.log(log_level, line) output.append(line) if process.returncode != 0: - raise Exception('Error executing {0}\n Return code: {1}', ' '.join(line), process.returncode) + raise Exception('Error executing {0}\n Return code: {1}', ' '.join(command), process.returncode) return output -- GitLab From 10019d1c049ffc17dbb8e0814ad001fde70be1a2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 9 May 2016 17:51:43 +0200 Subject: [PATCH 044/268] Modifications to optimize global basin on ohc --- config_file-ocean_pp.bash | 4 ++-- earthdiagnostics/diags.conf | 4 ++-- earthdiagnostics/ocean/heat.py | 31 +++++++++++++++++++------------ 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 9de02c8..d2dd656 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,15 +1,15 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('uNAtlohc') +listpost=('xohc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 level2=14 #If temp_lev or sal_lev is chosen on listpost, the lev1 and lev2 correspond to the levels between which the vertical mean has to be calculated. Lev1 and lev2 should be between 1,42 or 1,46, depending on the numbers of vertical levels on the original files. raw_vars_ocean=( '' ) # If listpost contains "ext_raw_oce" option, this is the list ocean variables you want to extract. If nothing is specified, all variables present in input file will be treated. If raw_vars_ocean='default', sosstsst, sosaline, somixhgt and somxl010 will be extracted. raw_vars_ice=( '' ) # If listpost contains "ext_raw_ice" option, this is the list of seaice variables you want to extract. If nothing is specified, all variables will be treated. If raw_vars_ice='default', isnowthi, iicethic, ileadfra, iicetemp, and ice_pres will be extracted. +raw_regions_ice=( 'North_Atlantic_Ocean' ) # If listpost contains "ohc_Arcticreg1" or "siasiesivsit_Arcticreg1" option, this is the list of sea ice regions you want to compute expid=a030 # expid or nemovar_s4 / nemovar_combine / glorys2v1 -raw_regions_ice=( '' ) # If listpost contains "ohc_Arcticreg1" or "siasiesivsit_Arcticreg1" option, this is the list of sea ice regions you want to compute mod='ecearth' # nemo / ecearth typeoutput='MMO' # diags / MMO #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 53dc8c0..7e9f35d 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = ohc,NAtl,0,0,17 +DIAGS = xohc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -11,7 +11,7 @@ INSTITUTE = IC3 EXPID = a030 STARTDATES = 19900101 CHUNK_SIZE = 3 -CHUNKS = 2 +CHUNKS = 1 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 365774e..703f505 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -184,13 +184,15 @@ class Heat(object): basin = Basins.parse(basin) handler = nco.openCdf('mask_regions.3d.nc') - if not basin.fullname in handler.variables: + if basin.fullname not in handler.variables: raise Exception('Basin {0} is not defined on mask_regions.nc'.format(basin.fullname)) handler.close() - shutil.move('mask.nc', 'original_mask.nc') - shutil.move('mask_regions.3d.nc', 'mask.nc') - Utils.rename_variable('mask.nc', basin.fullname, 'tmask') + if basin != Basins.Global: + shutil.move('mask.nc', 'original_mask.nc') + shutil.move('mask_regions.3d.nc', 'mask.nc') + Utils.rename_variable('mask.nc', basin.fullname, 'tmask') + error = None try: para = list() @@ -203,12 +205,15 @@ class Heat(object): para.append(lower) para.append(str(mixed_layer)) shell_output = cdftools.run('cdfheatc', options=para, input=temp) - except ex as Exception: - raise ex + except Exception as ex: + error = ex.message finally: - Utils.rename_variable('mask.nc', 'tmask', basin.fullname) - shutil.move('mask.nc', 'mask_regions.3d.nc') - shutil.move('original_mask.nc', 'mask.nc') + if basin != Basins.Global: + Utils.rename_variable('mask.nc', 'tmask', basin.fullname) + shutil.move('mask.nc', 'mask_regions.3d.nc') + shutil.move('original_mask.nc', 'mask.nc') + if error: + raise Exception(error) nco.ncks(input=temp, output=temp2, options='-O -v time') output = nco.openCdf(temp2) @@ -229,13 +234,15 @@ class Heat(object): for line in lines.split('\n'): line = line.lstrip() - if line.startswith("Total Heat content "): - Log.result(line) - thc[time] = line[line.index(':')+1: line.index('Joules')] + if line.startswith("Heat Content at level"): + Log.info(line) elif line.startswith("Total Heat content/volume"): Log.user_warning(line) uhc[time] = line[line.index(':')+1: line.index('Joules')] time += 1 + if line.startswith("Total Heat content "): + Log.result(line) + thc[time] = line[line.index(':')+1: line.index('Joules')] elif line.startswith('TIME : '): Log.info(line) -- GitLab From 3867f81996b5bd25cddc83d809fdc1c1e55d98cd Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 10 May 2016 13:56:23 +0200 Subject: [PATCH 045/268] First version of siasiesiv (without basins and proper CMOR output) --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 3 +- earthdiagnostics/diags.py | 32 +++++++- earthdiagnostics/ocean/__init__.py | 1 + earthdiagnostics/ocean/general.py | 123 +++++++++++++++++++++++++++++ earthdiagnostics/ocean/heat.py | 108 ++++++++++++------------- earthdiagnostics/ocean/ice.py | 100 +++++++++++++++++++++++ ocean_pp.bash | 2 +- 8 files changed, 309 insertions(+), 62 deletions(-) create mode 100644 earthdiagnostics/ocean/ice.py diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index d2dd656..fd16ba4 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('xohc') +listpost=('siasiesiv') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 7e9f35d..715aa06 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = xohc +DIAGS = siasiesiv FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -31,6 +31,7 @@ UOHC = ohc,glob,0,0,17 OHC_SPECIFIED_LAYER = ohclayer,0,300 ohclayer,300,800 3DTEMP = interp3d,thetao 3DSAL = interp3d,so +VERT_SSECTIONS = cutsection,so,Z,0 cutsection,so,Z,0 cutsection,so,Z,-45 cutsection,so,M,-30 cutsection,so,M,180 cutsection,so,M,80 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 18f2667..0f8f528 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,4 +1,4 @@ -from earthdiagnostics.ocean import Salinity, Circulation, Heat, General +from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Ice from utils import Utils from earthdiagnostics import cdftools, TempFile from autosubmit.date.chunk_date_lib import * @@ -140,6 +140,17 @@ class Diags: for [input_file, output_file] in self._get_file_names('ocean', variable, '{0}interp'.format(variable)): General.interpolate3d(input_file, output_file, variable, self.nemo_version) + elif diag == 'cutsection': + variable = diag_options[1] + meridional = diag_options[2] == 'm' + value = int(diag_options[3]) + for [input_file, output_file] in self._get_file_names('ocean', variable, + '{0}interp'.format(variable)): + General.cut_section(input_file, output_file, variable, meridional, value) + elif diag == 'siasiesiv': + for [thickness_file, fraction_file, output_file] in self._get_file_names('seaIce', 'sit', 'sic', + 'siasiesiv'): + Ice.siasiesiv(thickness_file, fraction_file, output_file, 'global') else: Log.warning('Diagnostic {0} not available', diag) continue @@ -204,6 +215,17 @@ class Diags: shutil.copy(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.nemo_version)), 'mask_regions.3d.nc') Utils.rename_variables('mask_regions.3d.nc', dic_variables, False, True) + + if not os.path.exists('toto_N.nc'): + Log.info('Copying toto_N.nc') + shutil.copy(os.path.join(self.con_files, 'ice_template.nc'), 'toto_N.nc') + Utils.rename_variables('toto_N.nc', dic_variables, False, True) + + if not os.path.exists('toto_S.nc'): + Log.info('Linking toto_S.nc') + os.link('toto_N.nc', 'toto_S.nc') + Utils.rename_variables('toto_S.nc', dic_variables, False, True) + Log.result('Mesh files ready!') def _read_config(self, config_file): @@ -240,6 +262,10 @@ class Diags: def _get_file_names(self, domain, *variables): file_names = list() + if domain == 'seaIce': + domain_abreviattion = 'OI' + else: + domain_abreviattion = domain[0].upper() for startdate in self.startdates.split(): start = parse_date(startdate) for member in self.members: @@ -255,8 +281,8 @@ class Diags: var_file = list() for var in variables: var_file.append(os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus), - '{0}_{1[0]}{2}_{3}_output_r{4}i1p1_' - '{5}-{6}.nc'.format(var, domain.upper(), + '{0}_{1}{2}_{3}_output_r{4}i1p1_' + '{5}-{6}.nc'.format(var, domain_abreviattion, self.frequency, self.model, member_plus, "{0:04}{1:02}".format(chunk_start.year, chunk_start.month), diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 5ac2fde..e22abad 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -2,3 +2,4 @@ from salinity import Salinity from heat import Heat from circulation import Circulation from general import General +from ice import Ice diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index d9c4e15..a11ee18 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -1,6 +1,7 @@ from earthdiagnostics import Utils, TempFile, cdftools import shutil import os +import numpy as np class General(object): @@ -95,3 +96,125 @@ class General(object): if nemo_version[6:9] == '025': cdo.invertlatdata(input=temp2, output=temp2) Utils.move_file(temp2, output_file) + + +############################################################################### +# # +# Cut a meridional or zonal section # +# # +# # +# $1 : input file # +# $2 : input var # +# $3 : Z/M (zonal / meridional section) # +# $4 : lat/lon # +# $5 : output file ( => 2D ) # +# # +# Created in September 2012 Author : vguemas@ic3.cat # +# # +############################################################################### + @staticmethod + def cut_section(input_file, output_file, variable, meridional, value): + """ + Cut a meridional or zonal section + + Created in September 2012 Author : vguemas@ic3.cat + :param input_file: input file + :param output_file: output file ( => 2D ) + :param variable: input var + :param meridional: (zonal / meridional section) + :param value: lat/lon + :return: + """ + + nco = Utils.nco + + handler = nco.openCdf('mesh_hgr.nc') + dimi = handler.dimensions['i'].size + dimj = handler.dimensions['j'].size + dimlev = handler.dimensions['lev'].size + + lon = handler.variables['lon'][:] + lat = handler.variables['lat'][:] + lev = handler.variables['lev'][:] + handler.close() + + handler = nco.openCdf('mask.nc') + mask = handler.variables['tmask'][:] + handler.close() + + # Latitude / longitude of the zonal / meridional section + exactpos = value + if meridional: + while exactpos < min(lon): + exactpos += 360 + while exactpos > max(lon): + exactpos -= 360 + size = dimj + else: + size = dimi + + # Collect the indexes defining the section + + listi = np.empty(size, dtype=int) + listj = np.empty(size, dtype=int) + + for jpt in range(0, size): + if meridional: + vector = lon[jpt, :] + else: + vector = lat[:, jpt] + distance = abs(vector - exactpos) + if min(distance) < 2*360.0/dimi: + pos = np.where(distance == min(distance)) + if meridional: + listi[jpt] = pos[0][0] + listj[jpt] = jpt + else: + listi[jpt] = jpt + listj[jpt] = pos[0][0] + # listi=array(dim=switch('$3','Z'=$nx-2,'M'=$ny-1)) + # listj=array(dim=switch('$3','Z'=$nx-2,'M'=$ny-1)) + # for (jpt in 1:length(listi)) { + # vect=switch('$3','Z'=lat[jpt,],'M'=lon[,jpt+1]) + # if (min(abs(vect-exactpos))<(2*360./$nx)) { + # pos=sort(abs(vect-exactpos),index.return=T)\$ix[1] + # listi[jpt]=switch('$3','Z'=jpt+1,'M'=pos) + # listj[jpt]=switch('$3','Z'=pos,'M'=jpt) + # } + # } + # listi=listi[is.na(listi)==F] + # listj=listj[is.na(listj)==F] + # + # # Select variable at those indexes + temp = TempFile.get() + shutil.copy(input_file, temp) + handler = nco.openCdf(temp) + dimtime = handler.dimensions['time'].size + var = np.empty([dimtime, dimlev, size], dtype=handler.variables[variable].dtype) + for jpt in range(0, size): + var[:, :, jpt] = handler.variables[variable][:, :, listj[jpt], listi[jpt]] + handler.close() + var = np.multiply(var, mask) + # fnc1=open.ncdf('$1') + # varout=array(dim=c(length(listi),$nz,$ntime)) + # for (jt in 1:$ntime) { + # varin=get.var.ncdf(fnc1,'$2',start=c(1,1,1,jt),count=c($nx,$ny,$nz,1)) + # varin[which(mask<0.5)]=1e20 + # for (jpt in 1:length(listi)) { + # varout[jpt,,jt]=varin[listi[jpt],listj[jpt],] + # } + # } + # close.ncdf(fnc1) + # # Write the output + # wtime=dim.def.ncdf("time","",seq(1,$ntime),unlim=TRUE) + # dimout=array(dim=length(listi)) + # for (jpt in 1:length(listi)) { + # dimout[jpt]=switch('$3','Z'=lon[listi[jpt],listj[jpt]],'M'=lat[listi[jpt],listj[jpt]]) + # } + # wsec=switch('$3','Z'=dim.def.ncdf("lon","",dimout),'M'=dim.def.ncdf("lat","",dimout)) + # wdep=dim.def.ncdf("deptht","",depth) + # wvar=var.def.ncdf("$2","",list(wsec,wdep,wtime),1e20) + # fnc2=create.ncdf('$5',wvar) + # put.var.ncdf(fnc2,wvar,varout) + # close.ncdf(fnc2) + nco.ncks(input=input_file, output=output_file, options='-h -A -v time') diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 703f505..010735c 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -90,62 +90,58 @@ class Heat(object): files = list() for time in range(ntime): - try: - Log.info('Running time {0}', time) - temp = TempFile.get() - nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) - Utils.rename_variable(temp, 'thetao', 'heatc_sl') - nco.ncks(input=temp, output=temp, options='-O -v heatc_sl') - cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) - - # extract the data between the two given depths --> heatc_sl_top.nc - nco.ncks(input=heatc_sl_out, output=heatc_sl_top, - options='-O -d lev,{0}.0,{1}.0'.format(min_depth, max_depth)) - # perform the integration of ohc down to that level (main contribution) - nco.ncap2(options="-O -s 'heatc_sl=heatc_sl.total({0})'".format(max_depth), - input=heatc_sl_top, output=heatc_sl_top) - # now extract a few levels below, to compute the residual ohc - # addition with float returned: - nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, - options='-O -d lev,{0}.0,{1}.0'.format(max_depth, max_depth+200)) - - # obtain the weight for the extra level containing the 300 m - # deptht in the gridT files is positive - # weight = (300.0 - depth_top)/(depth_bottom - depth_top) - # and add the thickness down to 300 m in the next layer - nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) - nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') - nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') - - # Here, add the residual contribution, before adding it to the main contribution - Utils.rename_variable(level_below, 'lev', 'layerthcknss') - Utils.rename_variable(level_above, 'lev', 'layerthcknss') - Utils.execute_shell_command('ncbo -A --op_typ=sub -v layerthcknss {0} {1} {2}'.format(level_below, level_above, depth_diff_lay)) - # nco.ncbo(options='-A --op_typ=sub -v layerthcknss', - # input='{0} {1}'.format(level_below, level_above), output=depth_diff_lay) - Utils.rename_variable(depth_diff_lay, 'layerthcknss', 'lev') - - nco.ncap2(options='-s "heatc_sl=({0} - layerthcknss)"'.format(max_depth), - input=level_above, output=depth_diff_sublay) - nco.ncbo(options='--op_typ=/ -v heatc_sl', - input=' '.join([depth_diff_sublay, depth_diff_lay]), output=factor) - Utils.rename_variable(factor, 'heatc_sl', 'factor') - nco.ncks(input=factor, output=level_below, options='-A -v factor') - os.remove(depth_diff_lay) - os.remove(depth_diff_sublay) - - nco.ncap2(input=level_below, output=level_below, options='-O -s "heatc_sl=(factor * heatc_sl)"') - nco.ncwa(input=level_below, output=level_below, options='-O -a lev') - - # nco.ncbo(options=' --op_typ=+ -v heatc_sl', - # input=' '.join([heatc_sl_top, level_below]), output=total_heatc_sl) - Utils.execute_shell_command('ncbo --op_typ=+ -v heatc_sl ' - '{0} {1} {2}'.format(heatc_sl_top, level_above, total_heatc_sl)) - nco.ncap2(input=total_heatc_sl, output=temp, options='-s "heatc_sl=1020.0*4000*heatc_sl"') - files.append(temp) - except Exception as ex: - Log.error(ex.message) - raise ex + Log.info('Running time {0}', time) + temp = TempFile.get() + nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) + Utils.rename_variable(temp, 'thetao', 'heatc_sl') + nco.ncks(input=temp, output=temp, options='-O -v heatc_sl') + cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) + + # extract the data between the two given depths --> heatc_sl_top.nc + nco.ncks(input=heatc_sl_out, output=heatc_sl_top, + options='-O -d lev,{0}.0,{1}.0'.format(min_depth, max_depth)) + # perform the integration of ohc down to that level (main contribution) + nco.ncap2(options="-O -s 'heatc_sl=heatc_sl.total({0})'".format(max_depth), + input=heatc_sl_top, output=heatc_sl_top) + # now extract a few levels below, to compute the residual ohc + # addition with float returned: + nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, + options='-O -d lev,{0}.0,{1}.0'.format(max_depth, max_depth+200)) + + # obtain the weight for the extra level containing the 300 m + # deptht in the gridT files is positive + # weight = (300.0 - depth_top)/(depth_bottom - depth_top) + # and add the thickness down to 300 m in the next layer + nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) + nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') + nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') + + # Here, add the residual contribution, before adding it to the main contribution + Utils.rename_variable(level_below, 'lev', 'layerthcknss') + Utils.rename_variable(level_above, 'lev', 'layerthcknss') + # Utils.execute_shell_command('ncbo --op_typ=sub -v layerthcknss {0} {1} {2}'.format(level_below, level_above, depth_diff_lay)) + nco.ncbo(options='--op_typ=sub -v layerthcknss', + input='{0} {1}'.format(level_below, level_above), output=depth_diff_lay) + # Utils.rename_variable(depth_diff_lay, 'layerthcknss', 'lev') + + nco.ncap2(options='-s "heatc_sl=({0} - layerthcknss)"'.format(max_depth), + input=level_above, output=depth_diff_sublay) + nco.ncbo(options='--op_typ=/ -v heatc_sl', + input=' '.join([depth_diff_sublay, depth_diff_lay]), output=factor) + Utils.rename_variable(factor, 'heatc_sl', 'factor') + nco.ncks(input=factor, output=level_below, options='-A -v factor') + os.remove(depth_diff_lay) + os.remove(depth_diff_sublay) + + nco.ncap2(input=level_below, output=level_below, options='-O -s "heatc_sl=(factor * heatc_sl)"') + nco.ncwa(input=level_below, output=level_below, options='-O -a lev') + + nco.ncbo(options=' --op_typ=+ -v heatc_sl', + input=' '.join([heatc_sl_top, level_below]), output=total_heatc_sl) + Utils.execute_shell_command('ncbo --op_typ=+ -v heatc_sl ' + '{0} {1} {2}'.format(heatc_sl_top, level_above, total_heatc_sl)) + nco.ncap2(input=total_heatc_sl, output=temp, options='-s "heatc_sl=1020.0*4000*heatc_sl"') + files.append(temp) temp = TempFile.get() cdo.cat(input=' '.join(files), output=temp,) diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py new file mode 100644 index 0000000..7e07f58 --- /dev/null +++ b/earthdiagnostics/ocean/ice.py @@ -0,0 +1,100 @@ +from earthdiagnostics import Utils, cdftools, cdo, TempFile +from earthdiagnostics.basins import Basins +from autosubmit.config.log import Log +import shutil + + +class Ice(object): + + @staticmethod + def siasiesiv(thickness_file, fraction_file, output_file, basin): + """ + Compute the sea ice extent (1000km2), area (1000km2), volume (km3) + and mean thickness (m) in both hemispheres or a specified region. + + Created in April 2012 Author : vguemas@ic3.cat + Modified in June 2014 Author : neven.fuckar@ic3.cat + + Computation of the properties in various selected regions according to + mask.regions.${NEMOVERSION}.nc (mask_regions.nc) is based on modification + of mask.regions.ORCA1.noverticalinfo.Matt.nc from Matthieu Chevallier. + :param input_file: input ice file name + :param output_file: output file name + :param basin: region of interest + :return: + """ + nco = Utils.nco + input_scratch = TempFile.get() + shutil.copy(thickness_file, input_scratch) + nco.ncks(input=fraction_file, output=input_scratch, options='-A -v sic') + ntime = int(cdo.ntime(input=input_scratch)[0]) + files = list() + + for time in range(ntime): + Log.info('Running time {0}', time) + temp = TempFile.get() + nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) + Log.info('Computing salt content') + cdftools.run('cdficediags', input=temp) + Utils.move_file('icediags.nc', temp) + files.append(temp) + + temp = TempFile.get() + cdo.cat(input=' '.join(files), output=temp,) + nco.ncks(input=input_scratch, output=temp, options='-A -v time') + Utils.move_file(temp, output_file) + +# +# for jt in $(seq 1 $ntime) ; do +# cdo seltimestep,$jt $1 tmpice.nc +# cdficediags tmpice.nc>ice.txt +# for d in N S;do +# ncdump toto_${d}.nc > ice_template.cdl +# sia=`grep ${d}Area ice.txt |awk '{print $4}'` +# sie=`grep ${d}Exnsidc ice.txt|awk '{print $4}'` +# siv=`grep ${d}Volume ice.txt|awk '{print $4}'` +# sed -e "s/sia =.*/sia = $sia ;/" ice_template.cdl > ice_template2.cdl +# sed -e "s/sie =.*/sie = $sie ;/" ice_template2.cdl > ice_template3.cdl +# sed -e "s/siv =.*/siv = $siv ;/" ice_template3.cdl > ice_template.cdl +# ncgen -o ice_${d}_${jt}.nc ice_template.cdl +# rm -f ice_template.cdl ice_template2.cdl ice_template3.cdl +# done +# list1=$list1" "ice_N_${jt}.nc +# list2=$list2" "ice_S_${jt}.nc +# rm -f ice.txt tmpice.nc icediags.nc +# done +# cdo cat $list1 ice_N_${2} +# cdo cat $list2 ice_S_${2} +# ncks -A -v time $1 ice_N_${2} +# ncks -A -v time $1 ice_S_${2} +# rm -f $list1 $list2 toto_N.nc toto_S.nc +# +# for d in N S;do +# ncatted -O -a units,sia,m,c,1000km2 ice_${d}_${2} +# ncatted -O -a units,sie,m,c,1000km2 ice_${d}_${2} +# +# ncks -O -v siv ice_${d}_${2} siv_${d}_${2}1 +# ncks -O -v sia ice_${d}_${2} sia_${d}_${2}1 +# ncrename -h -v sia,siv sia_${d}_${2}1 +# ncbo -O --op_typ=dvd siv_${d}_${2}1 sia_${d}_${2}1 sit_${d}_${2} +# ncatted -O -a standard_name,siv,m,c,Mean_sea_ice_thickness sit_${d}_${2} +# ncatted -O -a long_name,siv,m,c,"Mean sea ice thickness" sit_${d}_${2} +# ncatted -O -a units,siv,m,c,m sit_${d}_${2} +# cdo ltc,100 sit_${d}_${2} sit_${d}_${2}1 +# cdo ifthenelse sit_${d}_${2}1 sit_${d}_${2} sit_${d}_${2}1 sit_${d}_${2}2 +# ncrename -h -v siv,sit sit_${d}_${2}2 +# ncks -A sit_${d}_${2}2 ice_${d}_${2} +# +# rm siv_${d}_${2}1 sia_${d}_${2}1 sit_${d}_${2} sit_${d}_${2}1 sit_${d}_${2}2 +# done +# +# setminmax ice_N_${2} sia sie siv sit +# setminmax ice_S_${2} sia sie siv sit +# +# if [ ! -z "$3" ] ; then +# ncrename -h -v tmask,$3 mask.nc +# mv mask.nc mask_regions.nc +# mv mask_tmp.nc mask.nc +# fi +# +# } \ No newline at end of file diff --git a/ocean_pp.bash b/ocean_pp.bash index 25cce0d..27e7eab 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -468,7 +468,7 @@ for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do for sea in $lstseas ; do - ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $sea 0 1 24 + ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $sea 0 1 46 done -- GitLab From e20a1fb33339c73811a967af07e90ee8cc601f72 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 10 May 2016 15:21:46 +0200 Subject: [PATCH 046/268] Finished siasiesiv and better launcher --- earthdiagnostics/cdftools.py | 2 +- earthdiagnostics/diags.conf | 3 +- earthdiagnostics/diags.py | 51 ++++++++++++++------- earthdiagnostics/ocean/ice.py | 85 ++++++++++------------------------- 4 files changed, 61 insertions(+), 80 deletions(-) diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 3d72865..d0a3fc8 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -40,7 +40,7 @@ class CDFTools(object): raise Exception('Input and output file can not be the same on CDFTools') line.append('-o') line.append(output) - Log.info('Executing {0}', ' '.join(line)) + Log.debug('Executing {0}', ' '.join(line)) shell_output = Utils.execute_shell_command(line, log_level) if output: diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 715aa06..9e17c23 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = siasiesiv +DIAGS = siasiesiv,natl siasiesiv,glob siasiesiv,arct FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -32,6 +32,7 @@ OHC_SPECIFIED_LAYER = ohclayer,0,300 ohclayer,300,800 3DTEMP = interp3d,thetao 3DSAL = interp3d,so VERT_SSECTIONS = cutsection,so,Z,0 cutsection,so,Z,0 cutsection,so,Z,-45 cutsection,so,M,-30 cutsection,so,M,180 cutsection,so,M,80 +SIASIESIV = siasesiv,glob diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 0f8f528..d5b6e5b 100644 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,3 +1,5 @@ +import argparse + from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Ice from utils import Utils from earthdiagnostics import cdftools, TempFile @@ -30,8 +32,7 @@ class Diags: for fulldiag in self._get_commands(): diag_options = fulldiag.split(',') diag = diag_options[0] - Log.info("Running {0}", diag) - Log.debug('Full command: {0}', fulldiag) + Log.info("Running {0}", fulldiag) if diag == 'vertmeansal': depth_min = int(diag_options[1]) depth_max = int(diag_options[2]) @@ -148,9 +149,10 @@ class Diags: '{0}interp'.format(variable)): General.cut_section(input_file, output_file, variable, meridional, value) elif diag == 'siasiesiv': + basin = diag_options[1] for [thickness_file, fraction_file, output_file] in self._get_file_names('seaIce', 'sit', 'sic', 'siasiesiv'): - Ice.siasiesiv(thickness_file, fraction_file, output_file, 'global') + Ice.siasiesiv(thickness_file, fraction_file, output_file, basin) else: Log.warning('Diagnostic {0} not available', diag) continue @@ -216,15 +218,15 @@ class Diags: 'mask_regions.3d.nc') Utils.rename_variables('mask_regions.3d.nc', dic_variables, False, True) - if not os.path.exists('toto_N.nc'): - Log.info('Copying toto_N.nc') - shutil.copy(os.path.join(self.con_files, 'ice_template.nc'), 'toto_N.nc') - Utils.rename_variables('toto_N.nc', dic_variables, False, True) - - if not os.path.exists('toto_S.nc'): - Log.info('Linking toto_S.nc') - os.link('toto_N.nc', 'toto_S.nc') - Utils.rename_variables('toto_S.nc', dic_variables, False, True) + # if not os.path.exists('toto_N.nc'): + # Log.info('Copying toto_N.nc') + # shutil.copy(os.path.join(self.con_files, 'ice_template.nc'), 'toto_N.nc') + # Utils.rename_variables('toto_N.nc', dic_variables, False, True) + # + # if not os.path.exists('toto_S.nc'): + # Log.info('Linking toto_S.nc') + # os.link('toto_N.nc', 'toto_S.nc') + # Utils.rename_variables('toto_S.nc', dic_variables, False, True) Log.result('Mesh files ready!') @@ -258,6 +260,7 @@ class Diags: self._aliases[option.lower()] = self.parser.get_option('ALIAS', option).lower().split() self.scratch_dir = os.path.join(self.scratch_dir, 'diags', self.expid) + os.chdir(self.scratch_dir) def _get_file_names(self, domain, *variables): file_names = list() @@ -294,11 +297,27 @@ class Diags: def main(): - TempFile.scratch_folder = '/scratch/Earth/jvegas' - Log.set_console_level(Log.DEBUG) - diags = Diags('/home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/diags.conf') + parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') + parser.add_argument('-v', '--version', action='version', version='0.1', + help="returns Earth Diagnostics's version number and exit") + parser.add_argument('-lf', '--logfile', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', + 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), + default='DEBUG', type=str, + help="sets file's log level.") + parser.add_argument('-lc', '--logconsole', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', + 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), + default='INFO', type=str, + help="sets console's log level") + + parser.add_argument('-f', '--configfile', default='diags.conf', type=str) + + args = parser.parse_args() + Log.set_console_level(args.logconsole) + Log.set_file_level(args.logfile) + + diags = Diags(args.configfile) diags.run() - # Utils.clean() + TempFile.clean() if __name__ == "__main__": diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index 7e07f58..2703324 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -30,71 +30,32 @@ class Ice(object): ntime = int(cdo.ntime(input=input_scratch)[0]) files = list() - for time in range(ntime): - Log.info('Running time {0}', time) - temp = TempFile.get() - nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) - Log.info('Computing salt content') - cdftools.run('cdficediags', input=temp) - Utils.move_file('icediags.nc', temp) - files.append(temp) + basin = Basins.parse(basin) + if basin != Basins.Global: + shutil.move('mask.nc', 'original_mask.nc') + shutil.move('mask_regions.nc', 'mask.nc') + Utils.rename_variable('mask.nc', basin.fullname, 'tmask') + error = None + try: + for time in range(ntime): + Log.info('Running time {0}', time) + temp = TempFile.get() + nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) + cdftools.run('cdficediags', input=temp) + Utils.move_file('icediags.nc', temp) + files.append(temp) + except Exception as ex: + error = ex.message + finally: + if basin != Basins.Global: + Utils.rename_variable('mask.nc', 'tmask', basin.fullname) + shutil.move('mask.nc', 'mask_regions.nc') + shutil.move('original_mask.nc', 'mask.nc') + if error: + raise Exception(error) temp = TempFile.get() cdo.cat(input=' '.join(files), output=temp,) nco.ncks(input=input_scratch, output=temp, options='-A -v time') Utils.move_file(temp, output_file) -# -# for jt in $(seq 1 $ntime) ; do -# cdo seltimestep,$jt $1 tmpice.nc -# cdficediags tmpice.nc>ice.txt -# for d in N S;do -# ncdump toto_${d}.nc > ice_template.cdl -# sia=`grep ${d}Area ice.txt |awk '{print $4}'` -# sie=`grep ${d}Exnsidc ice.txt|awk '{print $4}'` -# siv=`grep ${d}Volume ice.txt|awk '{print $4}'` -# sed -e "s/sia =.*/sia = $sia ;/" ice_template.cdl > ice_template2.cdl -# sed -e "s/sie =.*/sie = $sie ;/" ice_template2.cdl > ice_template3.cdl -# sed -e "s/siv =.*/siv = $siv ;/" ice_template3.cdl > ice_template.cdl -# ncgen -o ice_${d}_${jt}.nc ice_template.cdl -# rm -f ice_template.cdl ice_template2.cdl ice_template3.cdl -# done -# list1=$list1" "ice_N_${jt}.nc -# list2=$list2" "ice_S_${jt}.nc -# rm -f ice.txt tmpice.nc icediags.nc -# done -# cdo cat $list1 ice_N_${2} -# cdo cat $list2 ice_S_${2} -# ncks -A -v time $1 ice_N_${2} -# ncks -A -v time $1 ice_S_${2} -# rm -f $list1 $list2 toto_N.nc toto_S.nc -# -# for d in N S;do -# ncatted -O -a units,sia,m,c,1000km2 ice_${d}_${2} -# ncatted -O -a units,sie,m,c,1000km2 ice_${d}_${2} -# -# ncks -O -v siv ice_${d}_${2} siv_${d}_${2}1 -# ncks -O -v sia ice_${d}_${2} sia_${d}_${2}1 -# ncrename -h -v sia,siv sia_${d}_${2}1 -# ncbo -O --op_typ=dvd siv_${d}_${2}1 sia_${d}_${2}1 sit_${d}_${2} -# ncatted -O -a standard_name,siv,m,c,Mean_sea_ice_thickness sit_${d}_${2} -# ncatted -O -a long_name,siv,m,c,"Mean sea ice thickness" sit_${d}_${2} -# ncatted -O -a units,siv,m,c,m sit_${d}_${2} -# cdo ltc,100 sit_${d}_${2} sit_${d}_${2}1 -# cdo ifthenelse sit_${d}_${2}1 sit_${d}_${2} sit_${d}_${2}1 sit_${d}_${2}2 -# ncrename -h -v siv,sit sit_${d}_${2}2 -# ncks -A sit_${d}_${2}2 ice_${d}_${2} -# -# rm siv_${d}_${2}1 sia_${d}_${2}1 sit_${d}_${2} sit_${d}_${2}1 sit_${d}_${2}2 -# done -# -# setminmax ice_N_${2} sia sie siv sit -# setminmax ice_S_${2} sia sie siv sit -# -# if [ ! -z "$3" ] ; then -# ncrename -h -v tmask,$3 mask.nc -# mv mask.nc mask_regions.nc -# mv mask_tmp.nc mask.nc -# fi -# -# } \ No newline at end of file -- GitLab From 30dcbc2e05033bdc6409596bfa7ed8e95c4bc613 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 11 May 2016 10:39:36 +0200 Subject: [PATCH 047/268] Finished cutsection function and added control to detect if data is not cmorized --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 5 +- earthdiagnostics/diags.py | 22 ++++++- earthdiagnostics/ocean/general.py | 105 ++++++++++++++---------------- ocean_pp.bash | 2 +- 5 files changed, 74 insertions(+), 62 deletions(-) mode change 100644 => 100755 earthdiagnostics/diags.py diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index fd16ba4..5cc91e3 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('siasiesiv') +listpost=('vert_Tsections') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 9e17c23..ac17294 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = siasiesiv,natl siasiesiv,glob siasiesiv,arct +DIAGS = VERT_TSECTIONS FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -31,7 +31,8 @@ UOHC = ohc,glob,0,0,17 OHC_SPECIFIED_LAYER = ohclayer,0,300 ohclayer,300,800 3DTEMP = interp3d,thetao 3DSAL = interp3d,so -VERT_SSECTIONS = cutsection,so,Z,0 cutsection,so,Z,0 cutsection,so,Z,-45 cutsection,so,M,-30 cutsection,so,M,180 cutsection,so,M,80 +VERT_SSECTIONS = cutsection,so,Z,0 cutsection,so,Z,45 cutsection,so,Z,-45 cutsection,so,M,-30 cutsection,so,M,180 cutsection,so,M,80 +VERT_TSECTIONS = cutsection,thetao,Z,0 cutsection,thetao,Z,45 cutsection,thetao,Z,-45 cutsection,thetao,M,-30 cutsection,thetao,M,180 cutsection,thetao,M,80 SIASIESIV = siasesiv,glob diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py old mode 100644 new mode 100755 index d5b6e5b..81b4cf8 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python + import argparse from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Ice @@ -26,6 +28,9 @@ class Diags: self._prepare_mesh_files() # Check if cmorized and convert if not + if not os.path.exists(os.path.join(self.data_dir, self.expid)): + Log.error('Your experiment is not CMORized. Please, CMORize it and launch again.') + exit(1) # Run diagnostics Log.info('Running diagnostics') @@ -143,11 +148,22 @@ class Diags: General.interpolate3d(input_file, output_file, variable, self.nemo_version) elif diag == 'cutsection': variable = diag_options[1] - meridional = diag_options[2] == 'm' + zonal = diag_options[2] == 'z' value = int(diag_options[3]) + if zonal: + if value < 0: + direction = 'S' + else: + direction = 'N' + else: + if value < 0: + direction = 'W' + else: + direction = 'E' for [input_file, output_file] in self._get_file_names('ocean', variable, - '{0}interp'.format(variable)): - General.cut_section(input_file, output_file, variable, meridional, value) + '{0}{1}{2}'.format(variable, abs(value), + direction)): + General.cut_section(input_file, output_file, variable, zonal, value) elif diag == 'siasiesiv': basin = diag_options[1] for [thickness_file, fraction_file, output_file] in self._get_file_names('seaIce', 'sit', 'sic', diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index a11ee18..da072fa 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -1,3 +1,5 @@ +from autosubmit.config.log import Log + from earthdiagnostics import Utils, TempFile, cdftools import shutil import os @@ -113,7 +115,7 @@ class General(object): # # ############################################################################### @staticmethod - def cut_section(input_file, output_file, variable, meridional, value): + def cut_section(input_file, output_file, variable, zonal, value): """ Cut a meridional or zonal section @@ -121,7 +123,7 @@ class General(object): :param input_file: input file :param output_file: output file ( => 2D ) :param variable: input var - :param meridional: (zonal / meridional section) + :param zonal: (zonal / meridional section) :param value: lat/lon :return: """ @@ -135,19 +137,20 @@ class General(object): lon = handler.variables['lon'][:] lat = handler.variables['lat'][:] - lev = handler.variables['lev'][:] handler.close() handler = nco.openCdf('mask.nc') - mask = handler.variables['tmask'][:] + mask_lev = handler.variables['tmask'][:] + mask_lev = mask_lev.astype(float) + np.place(mask_lev, mask_lev == 0, [1e20]) handler.close() # Latitude / longitude of the zonal / meridional section exactpos = value - if meridional: - while exactpos < min(lon): + if not zonal: + while exactpos < np.min(lon): exactpos += 360 - while exactpos > max(lon): + while exactpos > np.max(lon): exactpos -= 360 size = dimj else: @@ -159,62 +162,54 @@ class General(object): listj = np.empty(size, dtype=int) for jpt in range(0, size): - if meridional: + if not zonal: vector = lon[jpt, :] else: vector = lat[:, jpt] distance = abs(vector - exactpos) - if min(distance) < 2*360.0/dimi: - pos = np.where(distance == min(distance)) - if meridional: - listi[jpt] = pos[0][0] - listj[jpt] = jpt - else: - listi[jpt] = jpt - listj[jpt] = pos[0][0] - # listi=array(dim=switch('$3','Z'=$nx-2,'M'=$ny-1)) - # listj=array(dim=switch('$3','Z'=$nx-2,'M'=$ny-1)) - # for (jpt in 1:length(listi)) { - # vect=switch('$3','Z'=lat[jpt,],'M'=lon[,jpt+1]) - # if (min(abs(vect-exactpos))<(2*360./$nx)) { - # pos=sort(abs(vect-exactpos),index.return=T)\$ix[1] - # listi[jpt]=switch('$3','Z'=jpt+1,'M'=pos) - # listj[jpt]=switch('$3','Z'=pos,'M'=jpt) - # } - # } - # listi=listi[is.na(listi)==F] - # listj=listj[is.na(listj)==F] - # - # # Select variable at those indexes + pos = np.where(distance == min(distance)) + if not zonal: + listi[jpt] = pos[0][0] + listj[jpt] = jpt + else: + listi[jpt] = jpt + listj[jpt] = pos[0][0] + temp = TempFile.get() shutil.copy(input_file, temp) + handler = nco.openCdf(temp) dimtime = handler.dimensions['time'].size + var_array = handler.variables[variable][:] + handler.close() + var = np.empty([dimtime, dimlev, size], dtype=handler.variables[variable].dtype) + new_coord = np.empty(size, dtype=float) + if zonal: + old_coord = lon + else: + old_coord = lat + for jpt in range(0, size): - var[:, :, jpt] = handler.variables[variable][:, :, listj[jpt], listi[jpt]] + Log.info(str(jpt)) + var[:, :, jpt] = np.maximum(var_array[:, :, listj[jpt], listi[jpt]], + mask_lev[:, :, listj[jpt], listi[jpt]]) + new_coord[jpt] = old_coord[listj[jpt], listi[jpt]] + + nco.ncks(input=temp, output=temp, options='-O -v lev,time') + + handler = nco.openCdf(temp) + if not zonal: + handler.createDimension('lat', size) + coord_var = handler.createVariable('lat', float, 'lat') + file_var = handler.createVariable(variable, float, ('time', 'lev', 'lat')) + else: + handler.createDimension('lon', size) + coord_var = handler.createVariable('lon', float, 'lon') + file_var = handler.createVariable(variable, float, ('time', 'lev', 'lon')) + coord_var[:] = new_coord[:] + file_var[:] = var[:] + file_var.missing_value = 1e20 handler.close() - var = np.multiply(var, mask) - # fnc1=open.ncdf('$1') - # varout=array(dim=c(length(listi),$nz,$ntime)) - # for (jt in 1:$ntime) { - # varin=get.var.ncdf(fnc1,'$2',start=c(1,1,1,jt),count=c($nx,$ny,$nz,1)) - # varin[which(mask<0.5)]=1e20 - # for (jpt in 1:length(listi)) { - # varout[jpt,,jt]=varin[listi[jpt],listj[jpt],] - # } - # } - # close.ncdf(fnc1) - # # Write the output - # wtime=dim.def.ncdf("time","",seq(1,$ntime),unlim=TRUE) - # dimout=array(dim=length(listi)) - # for (jpt in 1:length(listi)) { - # dimout[jpt]=switch('$3','Z'=lon[listi[jpt],listj[jpt]],'M'=lat[listi[jpt],listj[jpt]]) - # } - # wsec=switch('$3','Z'=dim.def.ncdf("lon","",dimout),'M'=dim.def.ncdf("lat","",dimout)) - # wdep=dim.def.ncdf("deptht","",depth) - # wvar=var.def.ncdf("$2","",list(wsec,wdep,wtime),1e20) - # fnc2=create.ncdf('$5',wvar) - # put.var.ncdf(fnc2,wvar,varout) - # close.ncdf(fnc2) - nco.ncks(input=input_file, output=output_file, options='-h -A -v time') + Utils.move_file(temp, output_file) + diff --git a/ocean_pp.bash b/ocean_pp.bash index 27e7eab..f92f9b9 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash set -evx -module load CDFTOOLS/2.1-foss-2015a CDO NCO +module load CDFTOOLS/2.1-foss-2015a CDO NCO R function delete { at now +7 days << EOF -- GitLab From 6d5a634986da3007af3f321158a7389011823a01 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 11 May 2016 10:42:14 +0200 Subject: [PATCH 048/268] Some code cleaning --- earthdiagnostics/diags.py | 2 +- earthdiagnostics/ocean/general.py | 1 + earthdiagnostics/ocean/heat.py | 7 ++++--- earthdiagnostics/ocean/ice.py | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 81b4cf8..bcef8dd 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -82,7 +82,7 @@ class Diags: depth = '' for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'thetao', 'mlotst', - 'ohcsum{0}{1}'.format(mxl, depth)): + 'ohcsum{0}{1}'.format(mxl, depth)): Heat.total(input_file, mlotst_file, output_file, basin, mixed_layer, depth_min, depth_max) elif diag == 'ohclayer': depth_min = int(diag_options[1]) diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index da072fa..58fa96d 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -142,6 +142,7 @@ class General(object): handler = nco.openCdf('mask.nc') mask_lev = handler.variables['tmask'][:] mask_lev = mask_lev.astype(float) + # noinspection PyTypeChecker np.place(mask_lev, mask_lev == 0, [1e20]) handler.close() diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 010735c..7e6687a 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -70,7 +70,6 @@ class Heat(object): nco = Utils.nco input_scratch = TempFile.get() - temp2 = TempFile.get() heatc_sl_out = TempFile.get() heatc_sl_top = TempFile.get() level_above = TempFile.get() @@ -119,7 +118,6 @@ class Heat(object): # Here, add the residual contribution, before adding it to the main contribution Utils.rename_variable(level_below, 'lev', 'layerthcknss') Utils.rename_variable(level_above, 'lev', 'layerthcknss') - # Utils.execute_shell_command('ncbo --op_typ=sub -v layerthcknss {0} {1} {2}'.format(level_below, level_above, depth_diff_lay)) nco.ncbo(options='--op_typ=sub -v layerthcknss', input='{0} {1}'.format(level_below, level_above), output=depth_diff_lay) # Utils.rename_variable(depth_diff_lay, 'layerthcknss', 'lev') @@ -156,12 +154,14 @@ class Heat(object): os.remove(temp) @staticmethod - def total(input_file, mlotst_file, output_file, basin=Basins.Global.shortname, mixed_layer=0, upper=None, lower=None): + def total(input_file, mlotst_file, output_file, basin=Basins.Global.shortname, mixed_layer=0, + upper=None, lower=None): """ Compute the total ocean heat extent Created in May 2012 Author : vguemas@ic3.cat + :param mlotst_file: :param input_file: input temperature file name :param output_file: output file name ( => 2D x-y :param basin: basin name (default: global) @@ -224,6 +224,7 @@ class Heat(object): uhc.long_name = "Heat content per unit volume" uhc.units = "Joules/m3" time = 0 + # noinspection PyUnboundLocalVariable for lines in shell_output: if not lines: continue diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index 2703324..68f6886 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -18,7 +18,8 @@ class Ice(object): Computation of the properties in various selected regions according to mask.regions.${NEMOVERSION}.nc (mask_regions.nc) is based on modification of mask.regions.ORCA1.noverticalinfo.Matt.nc from Matthieu Chevallier. - :param input_file: input ice file name + :param fraction_file: + :param thickness_file: :param output_file: output file name :param basin: region of interest :return: -- GitLab From 7a37f51a3291368a8e2d251d3807dda5062fd2da Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 11 May 2016 18:15:51 +0200 Subject: [PATCH 049/268] Fixed bug in moc and areamoc --- common_ocean_post.txt | 9 +++---- config_file-ocean_pp.bash | 2 +- earthdiagnostics/basins.py | 2 ++ earthdiagnostics/diags.conf | 6 +++-- earthdiagnostics/diags.py | 34 ++++++++++++++++----------- earthdiagnostics/ocean/circulation.py | 13 +++++----- earthdiagnostics/ocean/general.py | 9 +++++-- earthdiagnostics/utils.py | 14 +++++++++++ setup_development.bash | 18 +++++++------- 9 files changed, 69 insertions(+), 38 deletions(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index e3adbe9..2058dbf 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -772,10 +772,11 @@ cdo vertmean area_moc.nc area_ave_moc.nc ncap -O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)" area_ave_moc.nc area_ave_moc2.nc ncwa -w coslat -a lat area_ave_moc2.nc area_ave_moc3.nc ncks -O -v $basin,time area_ave_moc3.nc $4 -rm -f tmpmoc.nc area_moc.nc area_ave_moc2.nc area_ave_moc3.nc -if [[ $4 != area_ave_moc.nc ]] ; then - rm -f area_ave_moc.nc -fi +# rm -f tmpmoc.nc area_moc.nc area_ave_moc2.nc area_ave_moc3.nc +#if [[ $4 != area_ave_moc.nc ]] ; then +# rm -f area_ave_moc.nc +#fi +exit } ############################################################################### # # diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 5cc91e3..2534b53 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('vert_Tsections') +listpost=('moc area_moc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index 18730f6..b3abaaf 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -61,6 +61,8 @@ class Basins(object): @classmethod def parse(cls, basin): + if isinstance(basin, Basin): + return basin for name in cls.__dict__.keys(): if name.startswith('_'): continue diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index ac17294..ffdbb14 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = VERT_TSECTIONS +DIAGS = MAX_MOC FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -18,7 +18,7 @@ NEMO_VERSION = Ec3.0_O1L46 [ALIAS] MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 -AREA_MOC = mocarea,40,55,1000,2000,Atl mocarea,30,40,1000,2000,Atl +AREA_MOC = mocarea,40,55,1000,2000,atl mocarea,30,40,1000,2000,atl STC = mocarea,0,25,0,200,Pac mocarea,-25,0,0,200,Pac mocarea,0,25,0,200,Atl mocarea,-25,0,0,200,Atl HEAT_SAL_MXL = mlotstsc mlotsthc LMSALC = vertmeansal,300,5400 @@ -31,6 +31,8 @@ UOHC = ohc,glob,0,0,17 OHC_SPECIFIED_LAYER = ohclayer,0,300 ohclayer,300,800 3DTEMP = interp3d,thetao 3DSAL = interp3d,so +TSEC_AVE190-220E =avgsection,thetaointerp,190,220,-90,90 +SSEC_AVE190-220E =avgsection,sointerp,190,220,-90,90 VERT_SSECTIONS = cutsection,so,Z,0 cutsection,so,Z,45 cutsection,so,Z,-45 cutsection,so,M,-30 cutsection,so,M,180 cutsection,so,M,80 VERT_TSECTIONS = cutsection,thetao,Z,0 cutsection,thetao,Z,45 cutsection,thetao,Z,-45 cutsection,thetao,M,-30 cutsection,thetao,M,180 cutsection,thetao,M,80 SIASIESIV = siasesiv,glob diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index bcef8dd..5f94748 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -123,7 +123,8 @@ class Diags: lat_min = int(diag_options[1]) lat_max = int(diag_options[2]) - lat = '{0}-{1}'.format(lat_min, lat_max) + lat = '{0}{1}'.format(Utils.get_cardinal_coordinate(lat_min, True), + Utils.get_cardinal_coordinate(lat_max, True)) depth_min = int(diag_options[3]) depth_max = int(diag_options[4]) @@ -132,7 +133,7 @@ class Diags: basin = diag_options[5] for [input_file, output_file] in self._get_file_names('ocean', 'msftmyz', - 'msftmyz{0}-{1}'.format(lat, depth)): + 'msftmyz{0}{1}{2}'.format(lat, depth, basin)): Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) elif diag == 'mlotsthc': for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'thetao', @@ -150,20 +151,25 @@ class Diags: variable = diag_options[1] zonal = diag_options[2] == 'z' value = int(diag_options[3]) - if zonal: - if value < 0: - direction = 'S' - else: - direction = 'N' - else: - if value < 0: - direction = 'W' - else: - direction = 'E' + coordinate = Utils.get_cardinal_coordinate(value, zonal) for [input_file, output_file] in self._get_file_names('ocean', variable, - '{0}{1}{2}'.format(variable, abs(value), - direction)): + '{0}{1}{2}'.format(variable, coordinate)): General.cut_section(input_file, output_file, variable, zonal, value) + elif diag == 'avgsection': + variable = diag_options[1] + lon_min = int(diag_options[2]) + lon_max = int(diag_options[3]) + lat_min = int(diag_options[4]) + lat_max = int(diag_options[5]) + + output_name = '{0}{1}{2}{3}{4}'.format(variable, Utils.get_cardinal_coordinate(lon_min, False), + Utils.get_cardinal_coordinate(lon_max, False), + Utils.get_cardinal_coordinate(lat_min, True), + Utils.get_cardinal_coordinate(lat_max, True)) + + for [input_file, output_file] in self._get_file_names('ocean', variable, output_name): + General.avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max) + elif diag == 'siasiesiv': basin = diag_options[1] for [thickness_file, fraction_file, output_file] in self._get_file_names('seaIce', 'sit', 'sic', diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 424f4f4..f55d99e 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -29,10 +29,11 @@ class Circulation(object): temp2 = TempFile.get() Log.debug('Computing MOC') cdftools.run('cdfmoc', input=input_file, output=temp2) + Utils.nco.ncks(input=input_file, output=temp2, options='-A -v lev') Log.debug('Reformating to netCDF-4') Utils.execute_shell_command(["nccopy", "-4", temp2, temp]) os.remove(temp2) - Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') + Log.debug('Reformatting variables') handler = Utils.cdo.openCdf(temp) @@ -97,12 +98,9 @@ class Circulation(object): nco.ncwa(input=temp, output=temp, options='-O -a i') handler = Utils.cdo.openCdf(temp) - if isinstance(basin, basestring): - basin_instance = Basins.parse(basin) - if not basin_instance: - raise Exception("Basin {0} not recognized".format(basin)) - else: - basin_instance = basin + basin_instance = Basins.parse(basin) + if not basin_instance: + raise Exception("Basin {0} not recognized".format(basin)) basin_index = np.where(handler.variables['basin'][:] == basin_instance.fullname) lat_values = handler.variables['lat'][:] @@ -118,6 +116,7 @@ class Circulation(object): nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) # To remove basin dimension nco.ncwa(input=temp, output=temp, options='-O -a basin') + nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time,lev') handler = Utils.nco.openCdf(temp) diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 58fa96d..f6073d8 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -58,8 +58,6 @@ class General(object): """ temp = TempFile.get() shutil.copy(input_file, temp) - if not os.path.exists('scrip_use'): - os.link('/shared/earth/software/scripts/interpolation/scrip_use', 'scrip_use') cdo = Utils.cdo nco = Utils.nco @@ -85,6 +83,7 @@ class General(object): scrip_use_in.writelines("/\n") scrip_use_in.close() + # Utils.execute_shell_command('/shared/earth/software/scripts/interpolation/scrip_use') Utils.execute_shell_command('/shared/earth/software/scripts/interpolation/scrip_use') nco.ncecat(input=temp2, output=temp2, options="-O -h") @@ -214,3 +213,9 @@ class General(object): handler.close() Utils.move_file(temp, output_file) + @staticmethod + def avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max): + Utils.cdo.zonmean(input=input_file, output=output_file, + options='-sellonlatbox,{0},{1},{1},{2}'.format(lon_min, lon_max, lat_min, lat_max)) + + diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 55cc536..3f5f74b 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -76,6 +76,20 @@ class Utils(object): raise Exception('Error executing {0}\n Return code: {1}', ' '.join(command), process.returncode) return output + @staticmethod + def get_cardinal_coordinate(value, latitude): + if latitude: + if value < 0: + direction = 'S' + else: + direction = 'N' + else: + if value < 0: + direction = 'W' + else: + direction = 'E' + return str(abs(value)) + direction + class TempFile(object): diff --git a/setup_development.bash b/setup_development.bash index 9591a89..cb08c82 100755 --- a/setup_development.bash +++ b/setup_development.bash @@ -14,26 +14,28 @@ CON_FILES='/esnas/autosubmit/con_files' NEMOVERSION=Ec2.3_O1L42 # This lines needs to be replaced by the path were you stored your modifed # version of common_ocean_post.txt : -source /home/Earth/rcruzgar/ocean_diagnostics/common_ocean_post.txt +source /home/Earth/jvegas/pyCharm/ocean_diagnostics/common_ocean_post.txt # Here we only fetch one random chunk of outputs from i00k : -cp /esnas/exp/ecearth/i00k/19601101/fc0/outputs/MMO_i00k_19601101_fc0_19601101-19610228.tar . +# cp /esnas/exp/ecearth/a030/19900101/fc0/outputs/MMO_a030_19900101_fc0_19900101-19900331.tar . # Here we untar and gunzip these files : -tar -xvf MMO_i00k_19601101_fc0_19601101-19610228.tar -gunzip *.gz +#tar -xvf MMO_a030_19900101_fc0_19900101-19900331.tar +#gunzip *.gz # The lines below might need to be changed depending on which function you need # to test. In the case below, the grid_T files are needed because they contain # the 3d temperature = input to ohc function. If you test siasiesiv for exemple, # you would need to replace grid_T by icemod. -filein=`ls *grid_T*` -cdo cat *grid_T* tmp.nc +#filein=`ls *grid_T*`*grid* +#cdo cat *grid_T* tmp.nc + # The lines below are essential because the files have a time dimension named # time in all the functions from common_ocean_post.txt (this is handled in # ocean_pp.bash and in the templates) timevar=`ncdump -h tmp.nc | grep UNLIMITED | awk '{print $1}'` if [[ $timevar == 'time_counter' ]] ; then ncrename -v time_counter,time -d time_counter,time tmp.nc ; fi # Some cleaning -rm -f *grid* *icemod* +# rm -f *grid* *icemod* # This is the final testing line. You need to replace that line by the function # you want to test (here it is ohc) followed by all its arguments (here we have # only the input file tmp.nc and the output file tmpout.nc) -ohc tmp.nc tmppout.nc 'Glob' +moc a030_1m_19900101_19900331_grid_T.nc mocfile.nc +area_moc mocfile.nc 40.0 55.0 area_mocfile.nc -- GitLab From c126c9d79ec4a0b42859a340ebb67ce64ed2b311 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 12 May 2016 14:54:14 +0200 Subject: [PATCH 050/268] Max moc implemented on python --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/ocean/circulation.py | 126 +++++++++++++++++++++----- 2 files changed, 103 insertions(+), 25 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 2534b53..14676e8 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('moc area_moc') +listpost=('max_moc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index f55d99e..778d6d2 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -5,6 +5,7 @@ from autosubmit.config.log import Log import numpy as np import os import shutil +import netCDF4 class Circulation(object): @@ -139,7 +140,7 @@ class Circulation(object): Utils.move_file(temp, output_file) @staticmethod - def max_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max): + def max_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin=None): """ Compute an Atlantic MOC index by finding the maximum of the annual mean meridional overturning in a latitude / depth region @@ -154,42 +155,119 @@ class Circulation(object): :param depth_max: depth max :return: """ - nco = Utils.nco - cdo = Utils.cdo temp = TempFile.get() temp2 = TempFile.get() + if not basin: + basin = Basins.Global + basin = Basins.parse(basin) - handler = Utils.cdo.openCdf(input_file) + shutil.copy(input_file, temp) + handler = Utils.cdo.openCdf(temp) if 'i' in handler.dimensions: - nco.ncwa(input=input_file, output=temp, options='-O -a i') + nco.ncwa(input=temp, output=temp, options='-O -a i') else: - shutil.copy(input_file, temp) + shutil.copy(temp, temp) + basin_index = np.where(handler.variables['basin'][:] == basin.fullname) + if len(basin_index) == 0: + raise Exception("Basin {1} is not defined in {0}", input_file, basin.fullname) + if len(basin_index) == 0: + raise Exception('Basin {0} not defined in file') + basin_index = basin_index[0][0] handler.close() # Utils.rename_variable(temp, 'record', 'x') - nco.ncpdq(input=temp, output=temp, options='-O -h -a time,i') - nco.ncpdq(input=temp, output=temp, options='-O -h -a lev,i') - nco.ncpdq(input=temp, output=temp, options='-O -h -a j,i') - - handler = cdo.openCdf(temp) - basins = handler.variables['basin'][:] - index = np.where(basins == Basins.Global.fullname)[0] - if len(index) == 0: - raise Exception("Global basin is not defined in {0}", input_file) - index = index[0] - + handler = Utils.nco.openCdf(temp) + lat_values = handler.variables['lat'][:] + lat_type = handler.variables['lat'].dtype + lat_units = handler.variables['lat'].units + lat_long_name = handler.variables['lat'].long_name handler.close() - nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(index)) + nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) # To remove basin dimension nco.ncwa(input=temp, output=temp, options='-O -a basin') - Utils.rename_variable(temp, 'msftmyz', 'zomsfglo') - cdo.yearmean(input=temp, output=temp2) - Utils.rename_variable(temp2, 'x', 'j', False, True) - cdftools.run('cdfmaxmoc', input=temp2, - options='glo {0:.1f} {1:.1f} {2:.1f} {3:.1f}'.format(lat_min, lat_max, depth_min, depth_max)) - Utils.move_file('maxmoc.nc', output_file) + nco.ncks(input=temp, output=temp2, options='-O -v msftmyz,time,lev,lev_bnds') + + handler = Utils.nco.openCdf(temp2) + handler.renameDimension('j', 'lat') + lat_variable = handler.createVariable('lat', lat_type, 'lat') + lat_variable[:] = lat_values[:] + lat_variable.units = lat_units + lat_variable.long_name = lat_long_name + handler.close() + + nco.ncks(input=temp2, output=temp, + options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(depth_min, depth_max, + lat_min, lat_max)) + + handler = nco.openCdf(temp) + + moc = handler.variables['msftmyz'][:] + + maximum = np.amax(moc) + max_index = np.unravel_index(np.argmax(moc), moc.shape) + max_lev = handler.variables['lev'][max_index[1]] + max_lat = handler.variables['lat'][max_index[2]] + + minimum = np.amin(moc) + minimum_index = np.unravel_index(np.argmin(moc), moc.shape) + min_lev = handler.variables['lev'][minimum_index[1]] + min_lat = handler.variables['lat'][minimum_index[2]] + + handler.close() + + Log.info('Maximum {0} Sv, latitude {1} depth {2} m', maximum, max_lat, max_lev) + Log.info('Minimum {0} Sv, latitude {1} depth {2} m', minimum, min_lat, min_lev) + + os.remove(temp) + + handler = netCDF4.Dataset(temp, 'w') + + var = handler.createVariable('msftmyzmax', float) + var.long_name = 'Maximum_Overturing' + var.units = 'Sverdrup' + var.valid_min = -1000. + var.valid_max = 1000. + var[:] = maximum + + var = handler.createVariable('msftmyzmaxlat', float) + var.long_name = 'Latitude_of_Maximum_Overturing' + var.units = 'Degrees' + var.valid_min = -90. + var.valid_max = 90. + var[:] = lat_max + + var = handler.createVariable('msftmyzmaxlev', float) + var.long_name = 'Depth_of_Maximum_Overturing' + var.units = 'Meters' + var.valid_min = 0. + var.valid_max = 10000. + var[:] = max_lev + + var = handler.createVariable('msftmyzmin', float) + var.long_name = 'Minimum_Overtuning' + var.units = 'Sverdrup' + var.valid_min = -1000. + var.valid_max = 1000. + var[:] = maximum + + var = handler.createVariable('msftmyzminlat', float) + var.long_name = 'Latitude_of_Minimum_Overtuning' + var.units = 'Degrees' + var.valid_min = -90. + var.valid_max = 90. + var[:] = lat_max + + var = handler.createVariable('msftmyzminlev', float) + var.long_name = 'Depth_of_Minimum_Overtuning' + var.units = 'Meters' + var.valid_min = 0. + var.valid_max = 10000. + var[:] = max_lev + + handler.close() + Utils.move_file(temp, output_file) @staticmethod def psi(input_file_u, input_file_v, output_file): -- GitLab From 8d943f07d90f7799a7e05a90d6f90a3885207991 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 12 May 2016 15:25:57 +0200 Subject: [PATCH 051/268] Solved bug in max_moc --- earthdiagnostics/ocean/circulation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 778d6d2..5511d12 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -187,9 +187,9 @@ class Circulation(object): # To remove basin dimension nco.ncwa(input=temp, output=temp, options='-O -a basin') - nco.ncks(input=temp, output=temp2, options='-O -v msftmyz,time,lev,lev_bnds') + nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time,lev,lev_bnds') - handler = Utils.nco.openCdf(temp2) + handler = Utils.nco.openCdf(temp) handler.renameDimension('j', 'lat') lat_variable = handler.createVariable('lat', lat_type, 'lat') lat_variable[:] = lat_values[:] @@ -197,10 +197,10 @@ class Circulation(object): lat_variable.long_name = lat_long_name handler.close() - nco.ncks(input=temp2, output=temp, + nco.ncks(input=temp, output=temp2, options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(depth_min, depth_max, lat_min, lat_max)) - + Utils.cdo.yearmean(input=temp2, output=temp) handler = nco.openCdf(temp) moc = handler.variables['msftmyz'][:] -- GitLab From cf1a2525900526e78b7fe0252497b90cbbfd94e0 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 12 May 2016 18:02:46 +0200 Subject: [PATCH 052/268] PSI finished --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 4 +- earthdiagnostics/diags.py | 110 +++++++++++++------------- earthdiagnostics/ocean/circulation.py | 10 ++- ocean_pp.bash | 2 +- 5 files changed, 65 insertions(+), 63 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 14676e8..8eb9477 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('max_moc') +listpost=('gyres') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index ffdbb14..a5bf451 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = MAX_MOC +DIAGS = gyres FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -35,7 +35,7 @@ TSEC_AVE190-220E =avgsection,thetaointerp,190,220,-90,90 SSEC_AVE190-220E =avgsection,sointerp,190,220,-90,90 VERT_SSECTIONS = cutsection,so,Z,0 cutsection,so,Z,45 cutsection,so,Z,-45 cutsection,so,M,-30 cutsection,so,M,180 cutsection,so,M,80 VERT_TSECTIONS = cutsection,thetao,Z,0 cutsection,thetao,Z,45 cutsection,thetao,Z,-45 cutsection,thetao,M,-30 cutsection,thetao,M,180 cutsection,thetao,M,80 -SIASIESIV = siasesiv,glob +SIASIESIV = siasiesiv,glob diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 5f94748..6e78df7 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -18,8 +18,20 @@ class Diags: self._read_config(config_file) TempFile.scratch_folder = self.scratch_dir cdftools.path = self.cdftools_path + self._create_dic_variables() Log.debug('Diags ready') + def _create_dic_variables(self): + self.dic_variables = dict() + self.dic_variables['x'] = 'i' + self.dic_variables['y'] = 'j' + self.dic_variables['z'] = 'lev' + self.dic_variables['nav_lon'] = 'lon' + self.dic_variables['nav_lat'] = 'lat' + self.dic_variables['nav_lev'] = 'lev' + self.dic_variables['time_counter'] = 'time' + self.dic_variables['t'] = 'time' + def run(self): if not os.path.exists(self.scratch_dir): os.makedirs(self.scratch_dir) @@ -58,12 +70,12 @@ class Diags: 'mlotstsites'): Circulation.convection_sites(input_file, self.nemo_version, output_file) elif diag == 'psi': - for [input_file, output_file] in self._get_file_names('ocean', 'sobarstf', - 'psi'): - Circulation.psi(str(input_file), self.nemo_version, str(output_file)) + for [u_file, v_file, output_file] in self._get_file_names('ocean', 'uo', 'vo', + 'msftbarot'): + Circulation.psi(u_file, v_file, output_file) elif diag == 'gyres': - for [input_file, output_file] in self._get_file_names('ocean', 'psi', - 'msftbarot'): + for [input_file, output_file] in self._get_file_names('ocean', 'msftbarot', + 'msftbarotgyres'): Circulation.gyres(str(input_file), self.nemo_version, str(output_file)) elif diag == 'ohc': basin = diag_options[1] @@ -153,7 +165,7 @@ class Diags: value = int(diag_options[3]) coordinate = Utils.get_cardinal_coordinate(value, zonal) for [input_file, output_file] in self._get_file_names('ocean', variable, - '{0}{1}{2}'.format(variable, coordinate)): + '{0}{1}'.format(variable, coordinate)): General.cut_section(input_file, output_file, variable, zonal, value) elif diag == 'avgsection': variable = diag_options[1] @@ -197,61 +209,47 @@ class Diags: return commands def _prepare_mesh_files(self): - - dic_variables = dict() - dic_variables['x'] = 'i' - dic_variables['y'] = 'j' - dic_variables['z'] = 'lev' - dic_variables['nav_lon'] = 'lon' - dic_variables['nav_lat'] = 'lat' - dic_variables['nav_lev'] = 'lev' - dic_variables['time_counter'] = 'time' - dic_variables['t'] = 'time' - Log.info('Copying mesh files') - if not os.path.exists('mesh_hgr.nc'): - Log.info('Copying mesh_hgr.nc') - shutil.copy(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc') - Utils.rename_variables('mesh_hgr.nc', dic_variables, False, True) - - if not os.path.exists('mesh_zgr.nc'): - Log.info('Linking mesh_zgr.nc') - os.link('mesh_hgr.nc', 'mesh_zgr.nc') - - if not os.path.exists('mask.nc'): - Log.info('Linking mask.nc') - os.link('mesh_hgr.nc', 'mask.nc') - - if not os.path.exists('new_maskglo.nc'): - Log.info('Copying new_maskglo.nc') - shutil.copy(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc') - - if os.path.exists(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version))) and \ - not os.path.exists('mask_regions.nc'): - Log.info('Copying mask_regions.nc') - shutil.copy(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), - 'mask_regions.nc') - Utils.rename_variables('mask_regions.nc', dic_variables, False, True) + self._copy_file(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc') + self._link_file('mesh_hgr.nc', 'mesh_zgr.nc') + self._link_file('mesh_hgr.nc', 'mask.nc') - if os.path.exists(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.nemo_version))) and \ - not os.path.exists('mask_regions.3d.nc'): - Log.info('Copying mask_regions.3d.nc') - shutil.copy(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.nemo_version)), + self._copy_file(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc') + self._copy_file(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), + 'mask_regions.nc') + self._copy_file(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.nemo_version)), 'mask_regions.3d.nc') - Utils.rename_variables('mask_regions.3d.nc', dic_variables, False, True) - - # if not os.path.exists('toto_N.nc'): - # Log.info('Copying toto_N.nc') - # shutil.copy(os.path.join(self.con_files, 'ice_template.nc'), 'toto_N.nc') - # Utils.rename_variables('toto_N.nc', dic_variables, False, True) - # - # if not os.path.exists('toto_S.nc'): - # Log.info('Linking toto_S.nc') - # os.link('toto_N.nc', 'toto_S.nc') - # Utils.rename_variables('toto_S.nc', dic_variables, False, True) Log.result('Mesh files ready!') + def _copy_file(self, source, destiny): + if not os.path.exists(source): + Log.user_warning('File {0} is not available for {1}', destiny, self.nemo_version) + + if os.path.exists(destiny): + if os.stat(source).st_size == os.stat(destiny).st_size: + Log.info('File {0} already exists', destiny) + return + + Log.info('Creating file {0}', destiny) + shutil.copy(source, destiny) + Log.info('File {0} ready', destiny) + Utils.rename_variables('mesh_hgr.nc', self.dic_variables, False, True) + + def _link_file(self, source, destiny): + if not os.path.exists(source): + Log.user_warning('File {0} is not available for {1}', destiny, self.nemo_version) + + if os.path.exists(destiny): + if os.stat(source).st_size == os.stat(destiny).st_size: + Log.info('File {0} already exists', destiny) + return + else: + os.remove(destiny) + + os.symlink(source, destiny) + Log.info('File {0} ready', destiny) + def _read_config(self, config_file): self.parser = Parser() self.parser.optionxform = str @@ -282,6 +280,8 @@ class Diags: self._aliases[option.lower()] = self.parser.get_option('ALIAS', option).lower().split() self.scratch_dir = os.path.join(self.scratch_dir, 'diags', self.expid) + if not os.path.exists(self.scratch_dir): + os.makedirs(self.scratch_dir) os.chdir(self.scratch_dir) def _get_file_names(self, domain, *variables): diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 5511d12..54a9bdb 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -285,11 +285,13 @@ class Circulation(object): """ integrated_u = TempFile.get() integrated_v = TempFile.get() - cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_u, options='-full') - cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_v, options='-full V') + temp = TempFile.get() + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_u, options='-full -mask') + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_v, options='-full -mask V') - Utils.nco.ncea(input=[integrated_u, integrated_v], output=output_file) - Utils.rename_variable(output_file, 'time_counter', 'time', False, True) + Utils.nco.ncea(input=[integrated_u, integrated_v], output=temp) + Utils.setminmax(temp, 'msftbarot') + Utils.move_file(temp, output_file) # noinspection PyPep8Naming @staticmethod diff --git a/ocean_pp.bash b/ocean_pp.bash index f92f9b9..48e5d09 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -39,7 +39,7 @@ if [[ ${listpost[@]} =~ "psi" ]] ; then list_files=$(echo ${list_files} grid_U) fi -if [[ ${listpost[@]} =~ "moc" ]] ; then +if [[ ${listpost[@]} =~ "moc" ]] || [[ ${listpost[@]} =~ "psi" ]]; then echo "The list of diags require grid_V" list_files=$(echo ${list_files} grid_V) fi -- GitLab From e9fa1733bbfd03938b712a177f495049a5f04fa0 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 13 May 2016 12:13:19 +0200 Subject: [PATCH 053/268] PSI corrections --- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/ocean/circulation.py | 64 +++++++++++++-------------- ocean_pp.bash | 4 +- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index a5bf451..dd3f43f 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = gyres +DIAGS = psi gyres FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 54a9bdb..1cd11c1 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -283,13 +283,9 @@ class Circulation(object): :param output_file: output file name without nc extension (=> 2D x-y) :rtype output_file: str """ - integrated_u = TempFile.get() - integrated_v = TempFile.get() temp = TempFile.get() - cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_u, options='-full -mask') - cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=integrated_v, options='-full -mask V') - - Utils.nco.ncea(input=[integrated_u, integrated_v], output=temp) + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-full -mask -mean') + Utils.rename_variable(temp, 'sobarstf', 'msftbarot') Utils.setminmax(temp, 'msftbarot') Utils.move_file(temp, output_file) @@ -314,10 +310,10 @@ class Circulation(object): subpolNPac = [70, 145, 195, 235] subtropNPac = [45, 175, 165, 220] subtropSPac = [195, 275, 175, 225] - subtropNAtl = [230, 275, 215, 245] - subtropSAtl = [70, 145, 195, 235] - subtropInd = [45, 175, 165, 220] - ACC = [195, 275, 175, 225] + subtropNAtl = [70, 205, 120, 145] + subtropSAtl = [235, 300, 120, 145] + subtropInd = [320, 30, 110, 180] + ACC = [1, 361, 1, 65] elif input_grid in [Grid.ECEARTH_3_0_O25L46, Grid.ECEARTH_3_0_O25L75, Grid.GLORYS2_V1_O25L75]: @@ -326,36 +322,39 @@ class Circulation(object): raise Exception("Input grid {0} not recognized".format(input_grid)) temp = TempFile.get() - Circulation.gyre(input_psi, subpolNAtl, output_file, invert=True) - Utils.rename_variable(output_file, 'sobarstf', 'subpolNAtl') + temp2 = TempFile.get() + Circulation.gyre(input_psi, subpolNAtl, temp2, invert=True) + Utils.rename_variable(temp2, 'msftbarot', 'subpolNAtl') Circulation.gyre(input_psi, subpolNPac, temp, invert=True) - Utils.rename_variable(temp, 'sobarstf', 'subpolNPac') - Utils.nco.ncks(input=temp, output=output_file, options='-A') + Utils.rename_variable(temp, 'msftbarot', 'subpolNPac') + Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropNPac, temp) - Utils.rename_variable(temp, 'sobarstf', 'subtropNPac') - Utils.nco.ncks(input=temp, output=output_file, options='-A') + Utils.rename_variable(temp, 'msftbarot', 'subtropNPac') + Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropSPac, temp) - Utils.rename_variable(temp, 'sobarstf', 'subtropSPac') - Utils.nco.ncks(input=temp, output=output_file, options='-A') + Utils.rename_variable(temp, 'msftbarot', 'subtropSPac') + Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropNAtl, temp) - Utils.rename_variable(temp, 'sobarstf', 'subtropNAtl') - Utils.nco.ncks(input=temp, output=output_file, options='-A') + Utils.rename_variable(temp, 'msftbarot', 'subtropNAtl') + Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropSAtl, temp) - Utils.rename_variable(temp, 'sobarstf', 'subtropSAtl') - Utils.nco.ncks(input=temp, output=output_file, options='-A') + Utils.rename_variable(temp, 'msftbarot', 'subtropSAtl') + Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropInd, temp) - Utils.rename_variable(temp, 'sobarstf', 'subtropInd') - Utils.nco.ncks(input=temp, output=output_file, options='-A') + Utils.rename_variable(temp, 'msftbarot', 'subtropInd') + Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, ACC, temp) - Utils.rename_variable(temp, 'sobarstf', 'ACC') - Utils.nco.ncks(input=temp, output=output_file, options='-A') + Utils.rename_variable(temp, 'msftbarot', 'ACC') + Utils.nco.ncks(input=temp, output=temp2, options='-A') + + Utils.move_file(temp2, output_file) @staticmethod def gyre(input_file, site, output_file, invert=False): @@ -364,20 +363,21 @@ class Circulation(object): Created in October 2013 Author : vguemas@ic3.cat - :param input_file: input oce file name containing sobarstf + :param input_file: input oce file name containing msftbarot :param site: site to calculate convection on :param output_file: output file name (=> index) :param invert: if True, multiplies result by -1 :return: """ temp = TempFile.get() - Utils.cdo.fldmin(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), - output=temp) if invert: + Utils.cdo.fldmin(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), + output=temp) Utils.cdo.mulc(-1, input=temp, output=output_file) - os.remove(temp) else: - shutil.move(temp, output_file) + + Utils.cdo.fldmax(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), + output=output_file) @staticmethod def convection_sites(input_file, input_grid, output_file): @@ -386,7 +386,7 @@ class Circulation(object): Created in October 2013 Author : vguemas@ic3.cat - :param input_file: input oce file name containing somxl010 + :param input_file: input oce file name containing mlotst :param input_grid: input grid :param output_file: output file name (=> index) :return: diff --git a/ocean_pp.bash b/ocean_pp.bash index 48e5d09..d8e4a14 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -34,12 +34,12 @@ config_file=$1 . ${config_file} list_files='grid_T' -if [[ ${listpost[@]} =~ "psi" ]] ; then +if [[ ${listpost[@]} =~ "psi" ]] || [[ ${listpost[@]} =~ "gyres" ]]; then echo "The list of diags require grid_U" list_files=$(echo ${list_files} grid_U) fi -if [[ ${listpost[@]} =~ "moc" ]] || [[ ${listpost[@]} =~ "psi" ]]; then +if [[ ${listpost[@]} =~ "moc" ]] || [[ ${listpost[@]} =~ "psi" ]] || [[ ${listpost[@]} =~ "gyres" ]]; then echo "The list of diags require grid_V" list_files=$(echo ${list_files} grid_V) fi -- GitLab From 2524f6cdc4b975b4b73d86707b76f1d7c63befb8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 13 May 2016 12:52:44 +0200 Subject: [PATCH 054/268] First version of doc --- CHANGES | 4 ++++ VERSION | 1 + doc/source/codedoc/main.rst | 15 +++++++++++++++ doc/source/codedoc/ocean.rst | 27 +++++++++++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 CHANGES create mode 100644 VERSION create mode 100644 doc/source/codedoc/main.rst create mode 100644 doc/source/codedoc/ocean.rst diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..c7cdfd4 --- /dev/null +++ b/CHANGES @@ -0,0 +1,4 @@ +3.0.0 + Migration to Python + Move from CDFTools 2.1 to CDFTools 3.0 + Adoption of CMOR standard diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..4a36342 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +3.0.0 diff --git a/doc/source/codedoc/main.rst b/doc/source/codedoc/main.rst new file mode 100644 index 0000000..9ce57d9 --- /dev/null +++ b/doc/source/codedoc/main.rst @@ -0,0 +1,15 @@ +******************** +Module documentation +******************** + +.. toctree:: + :titlesonly: + + autosubmit + config + database + date + git + job + monitor + platforms \ No newline at end of file diff --git a/doc/source/codedoc/ocean.rst b/doc/source/codedoc/ocean.rst new file mode 100644 index 0000000..391ed75 --- /dev/null +++ b/doc/source/codedoc/ocean.rst @@ -0,0 +1,27 @@ +earthdiagnsotics.ocean +================= + +.. automodule:: earthdiagnsotics.ocean.general.General + :show-inheritance: + :inherited-members: + :members: + +.. automodule:: earthdiagnsotics.ocean.circulation.Circulation + :show-inheritance: + :inherited-members: + :members: + +.. automodule:: earthdiagnsotics.ocean.heat.Heat + :show-inheritance: + :inherited-members: + :members: + +.. automodule:: earthdiagnsotics.ocean.salinity.Salinity + :show-inheritance: + :inherited-members: + :members: + +.. automodule:: earthdiagnsotics.ocean.ice.Ice + :show-inheritance: + :inherited-members: + :members: \ No newline at end of file -- GitLab From f406a94690daccba9c21558204c7e88fc237e6ef Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 17 May 2016 16:31:27 +0200 Subject: [PATCH 055/268] Documentation updated --- doc/Makefile | 177 +++++++++++++ doc/source/codedoc/basin.rst | 7 + doc/source/codedoc/cdftools.rst | 7 + doc/source/codedoc/main.rst | 12 +- doc/source/codedoc/ocean.rst | 16 +- doc/source/codedoc/utils.rst | 7 + doc/source/conf.py | 343 ++++++++++++++++++++++++++ doc/source/index.rst | 24 ++ earthdiagnostics/basins.py | 71 ++++++ earthdiagnostics/cdftools.py | 8 + earthdiagnostics/ocean/circulation.py | 3 + earthdiagnostics/ocean/general.py | 17 +- earthdiagnostics/ocean/heat.py | 3 + earthdiagnostics/ocean/ice.py | 3 + earthdiagnostics/ocean/salinity.py | 4 + earthdiagnostics/utils.py | 101 +++++++- 16 files changed, 769 insertions(+), 34 deletions(-) create mode 100644 doc/Makefile create mode 100644 doc/source/codedoc/basin.rst create mode 100644 doc/source/codedoc/cdftools.rst create mode 100644 doc/source/codedoc/utils.rst create mode 100644 doc/source/conf.py create mode 100644 doc/source/index.rst diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..bb91b47 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/EarthDiagnostics.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/EarthDiagnostics.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/EarthDiagnostics" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/EarthDiagnostics" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/source/codedoc/basin.rst b/doc/source/codedoc/basin.rst new file mode 100644 index 0000000..f0d2fac --- /dev/null +++ b/doc/source/codedoc/basin.rst @@ -0,0 +1,7 @@ +earthdiagnsotics.basins +======================= + +.. automodule:: earthdiagnostics.basins + :show-inheritance: + :inherited-members: + :members: \ No newline at end of file diff --git a/doc/source/codedoc/cdftools.rst b/doc/source/codedoc/cdftools.rst new file mode 100644 index 0000000..cdc6305 --- /dev/null +++ b/doc/source/codedoc/cdftools.rst @@ -0,0 +1,7 @@ +earthdiagnsotics.cdftools +========================= + +.. automodule:: earthdiagnostics.cdftools + :show-inheritance: + :inherited-members: + :members: \ No newline at end of file diff --git a/doc/source/codedoc/main.rst b/doc/source/codedoc/main.rst index 9ce57d9..716ce07 100644 --- a/doc/source/codedoc/main.rst +++ b/doc/source/codedoc/main.rst @@ -5,11 +5,7 @@ Module documentation .. toctree:: :titlesonly: - autosubmit - config - database - date - git - job - monitor - platforms \ No newline at end of file + utils + basin + cdftools + ocean \ No newline at end of file diff --git a/doc/source/codedoc/ocean.rst b/doc/source/codedoc/ocean.rst index 391ed75..b5bffb6 100644 --- a/doc/source/codedoc/ocean.rst +++ b/doc/source/codedoc/ocean.rst @@ -1,27 +1,27 @@ -earthdiagnsotics.ocean -================= +earthdiagnsotics.Ocean +======================= -.. automodule:: earthdiagnsotics.ocean.general.General +.. automodule:: earthdiagnostics.ocean.general :show-inheritance: :inherited-members: :members: -.. automodule:: earthdiagnsotics.ocean.circulation.Circulation +.. automodule:: earthdiagnostics.ocean.circulation :show-inheritance: :inherited-members: :members: -.. automodule:: earthdiagnsotics.ocean.heat.Heat +.. automodule:: earthdiagnostics.ocean.heat :show-inheritance: :inherited-members: :members: -.. automodule:: earthdiagnsotics.ocean.salinity.Salinity +.. automodule:: earthdiagnostics.ocean.salinity :show-inheritance: :inherited-members: :members: -.. automodule:: earthdiagnsotics.ocean.ice.Ice +.. automodule:: earthdiagnostics.ocean.ice :show-inheritance: :inherited-members: - :members: \ No newline at end of file + :members: diff --git a/doc/source/codedoc/utils.rst b/doc/source/codedoc/utils.rst new file mode 100644 index 0000000..c0878f9 --- /dev/null +++ b/doc/source/codedoc/utils.rst @@ -0,0 +1,7 @@ +earthdiagnsotics.utils +======================= + +.. automodule:: earthdiagnostics.utils + :show-inheritance: + :inherited-members: + :members: \ No newline at end of file diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 0000000..a3963dd --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,343 @@ +# -*- coding: utf-8 -*- +# +# Earth Diagnostics documentation build configuration file, created by +# sphinx-quickstart on Fri May 13 12:40:01 2016. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('../..')) +print os.path.abspath('../..') + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.pngmath', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Earth Diagnostics' +copyright = u'2016, BSC-CNS Earth Sciences Department' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '3.0' +# The full version, including alpha/beta/rc tags. +release = '3.0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'EarthDiagnosticsdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'EarthDiagnostics.tex', u'Earth Diagnostics Documentation', + u'BSC-CNS Earth Sciences Department', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'earthdiagnostics', u'Earth Diagnostics Documentation', + [u'BSC-CNS Earth Sciences Department'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'EarthDiagnostics', u'Earth Diagnostics Documentation', + u'BSC-CNS Earth Sciences Department', 'EarthDiagnostics', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = u'Earth Diagnostics' +epub_author = u'BSC-CNS Earth Sciences Department' +epub_publisher = u'BSC-CNS Earth Sciences Department' +epub_copyright = u'2016, BSC-CNS Earth Sciences Department' + +# The basename for the epub file. It defaults to the project name. +#epub_basename = u'Earth Diagnostics' + +# The HTML theme for the epub output. Since the default themes are not optimized +# for small screen space, using the same theme for HTML and epub output is +# usually not wise. This defaults to 'epub', a theme designed to save visual +# space. +#epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or en if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +#epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files shat should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +#epub_tocscope = 'default' + +# Fix unsupported image types using the PIL. +#epub_fix_images = False + +# Scale large images. +#epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#epub_show_urls = 'inline' + +# If false, no index is generated. +#epub_use_index = True + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 0000000..f2cadb2 --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,24 @@ +.. Earth Diagnostics documentation master file, created by + sphinx-quickstart on Fri May 13 12:40:01 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Earth Diagnostics's documentation! +============================================= + +Contents: + +.. toctree:: + :maxdepth: 2 + + codedoc/main + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index b3abaaf..176cf80 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -1,6 +1,20 @@ class Basin(object): + """ + Class representing a given basin + """ def __init__(self, shortname, fullname, coordinates=None): + """ + Constructor for Basin + + :param shortname: sfull basin's name + :type shortname: str + :param fullname: full basin's name + :type fullname: str + :param coordinates: list of coordinates for the basin in the order: min longitude, max longitude, min latitude, + max latitude + :type coordinates: tuple + """ self._shortname = shortname self._fullname = fullname if coordinates: @@ -10,57 +24,114 @@ class Basin(object): @property def shortname(self): + """ + Basin's short name + :rtype: str + """ return self._shortname @property def fullname(self): + """ + Basin's full name + :rtype: str + """ return self._fullname @property def min_lon(self): + """ + Minimum longitude + :rtype: int + """ return self._coordinates[0] @property def max_lon(self): + """ + Maximum longitude + :rtype: int + """ return self._coordinates[1] @property def min_lat(self): + """ + Minimum latitude + :rtype: int + """ return self._coordinates[2] @property def max_lat(self): + """ + Maximum latitude + :rtype: int + """ return self._coordinates[3] @property def lon(self): + """ + Longitude limits of the basin + :rtype: tuple + """ return self._coordinates[0:2] @property def lat(self): + """ + Latitude limits of the basin + :rtype: tuple + """ return self._coordinates[2:] class Basins(object): + """ + Predefined basins + """ Global = Basin('glob', 'Global_Ocean') + """ Global ocean """ Atlantic = Basin('Atl', 'Atlantic_Ocean') + """ Atlantic ocean """ NorthAtlantic = Basin('NAtl', 'North_Atlantic_Ocean') + """ North Atlantic Ocean """ TropicalAtlantic = Basin('TAtl', 'Tropical_Atlantic_Ocean') + """ Tropical Atlantic Ocean """ Pacific = Basin('Pac', 'Pacific_Ocean') + """ Pacific Ocean """ NorthPacific = Basin('NPac', 'North_Pacific_Ocean') + """ North Pacific Ocean """ TropicalPacific = Basin('TPac', 'Tropical_Pacific_Ocean') + """ Tropical Pacific Ocean """ IndoPacific = Basin('IndPac', 'Indo_Pacific_Ocean') + """ Indo Pacific Ocean """ Indian = Basin('Ind', 'Indian_Ocean') + """ Indian Ocean """ TropicalIndian = Basin('TInd', 'Tropical_Indian_Ocean') + """ Tropical Indian Ocean """ Antarctic = Basin('Anta', 'Antarctic_Ocean') + """ Antarctic Ocean """ Arctic = Basin('Arct', 'Arctic_Ocean') + """ Arctic Ocean """ @classmethod def parse(cls, basin): + """ + Return the basin matching the given name. If the parameter basin is a Basin instance, directly returns the same + instance. This bahaviour is intended to facilitate the development of methods that can either accept a name + or an instance to charcterize the basin. + + :param basin: basin name or basin instance + :type basin: str | Basin + :return: basin instance corresponding to the basin name + :rtype: Basin + """ if isinstance(basin, Basin): return basin for name in cls.__dict__.keys(): diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index d0a3fc8..111763e 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -4,6 +4,9 @@ from autosubmit.config.log import Log class CDFTools(object): + """ + Class to run CDFTools executables + """ def __init__(self, path=''): self.path = path @@ -14,10 +17,15 @@ class CDFTools(object): Runs one of the CDFTools :param command: executable to run + :type command: str :param input: input file + :type input: str :param output: output file. Not all tools support this parameter + :type options: str :param options: options for the tool. + :type options: str | list :param log_level: log level at which the output of the cdftool command will be added + :type log_level: int """ line = [os.path.join(self.path, command)] if input: diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 1cd11c1..9f50318 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -9,6 +9,9 @@ import netCDF4 class Circulation(object): + """ + Class containing all the diagnostics related to circulation + """ @staticmethod def moc(input_file, output_file): diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index f6073d8..d4966a6 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -7,6 +7,9 @@ import numpy as np class General(object): + """ + General diagnostics that can be used with different variables + """ @staticmethod def vertical_mean(input_file, output_file, variable, lev_min, lev_max): @@ -99,20 +102,6 @@ class General(object): Utils.move_file(temp2, output_file) -############################################################################### -# # -# Cut a meridional or zonal section # -# # -# # -# $1 : input file # -# $2 : input var # -# $3 : Z/M (zonal / meridional section) # -# $4 : lat/lon # -# $5 : output file ( => 2D ) # -# # -# Created in September 2012 Author : vguemas@ic3.cat # -# # -############################################################################### @staticmethod def cut_section(input_file, output_file, variable, zonal, value): """ diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 7e6687a..9f98e87 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -8,6 +8,9 @@ from nco import NCOException class Heat(object): + """ + Diagnsotics for the ocean heat content + """ @staticmethod def mixed_layer_content(input_file, mltost_file, output_file): diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index 68f6886..17b9872 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -5,6 +5,9 @@ import shutil class Ice(object): + """ + Class containing all the diagnostics related to ice + """ @staticmethod def siasiesiv(thickness_file, fraction_file, output_file, basin): diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index 26f11a7..cc505bd 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -5,6 +5,10 @@ import shutil class Salinity(object): + """ + Class containing all the diagnostics related to salinity + """ + @staticmethod def vertical_mean(input_file, output_file, upper, lower): """ diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 3f5f74b..90aedba 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -11,13 +11,24 @@ import shutil class Utils(object): + """ + Container class for miscellaneous utility methods + """ nco = Nco() + """An instance of Nco class ready to be used""" cdo = Cdo() + """An instance of Cdo class ready to be used""" @staticmethod def setminmax(filename, variable_list): - + """ + Sets the valid_max and valid_min values to the current max and min values on the file + :param filename: path to file + :type filename: str + :param variable_list: list of variables in which valid_min and valid_max will be set + :type variable_list: str | list + """ if isinstance(variable_list, basestring): variable_list = variable_list.split() @@ -33,11 +44,35 @@ class Utils(object): options='-h -a valid_min,{0},m,f,{1}'.format(variable, values[1])) @staticmethod - def rename_variable(filename, old_name, new_name, must_exist=True, rename_dimension=False): - Utils.rename_variables(filename, {old_name: new_name}, must_exist, rename_dimension) + def rename_variable(filepath, old_name, new_name, must_exist=True, rename_dimension=False): + """ + Rename multiple variables from a NetCDF file + :param filepath: path to file + :type filepath: str + :param old_name: variable's name to change + :type old_name: str + :param new_name: new name + :type new_name: str + :param must_exist: if True, the function will raise an exception if the variable name does not exist + :type must_exist: bool + :param rename_dimension: if True, also rename dimensions with the same name + :type rename_dimension: bool + """ + Utils.rename_variables(filepath, {old_name: new_name}, must_exist, rename_dimension) @staticmethod def rename_variables(filepath, dic_names, must_exist=True, rename_dimension=False): + """ + Rename multiple variables from a NetCDF file + :param filepath: path to file + :type filepath: str + :param dic_names: dictionary containing old names as keys and new names as values + :type dic_names: dict + :param must_exist: if True, the function will raise an exception if the variable name does not exist + :type must_exist: bool + :param rename_dimension: if True, also rename dimensions with the same name + :type rename_dimension: bool + """ handler = Utils.nco.openCdf(filepath) for old_name, new_name in dic_names.items(): @@ -56,12 +91,29 @@ class Utils(object): @staticmethod def move_file(source, destiny): + """ + Moves a file from source to destiny, creating dirs if necessary + + :param source: path to source + :type source: str + :param destiny: path to destiny + :type destiny: str + """ if not os.path.exists(os.path.dirname(destiny)): os.makedirs(os.path.dirname(destiny)) shutil.move(source, destiny) @staticmethod def execute_shell_command(command, log_level=Log.DEBUG): + """ + Executes a sheel command + :param command: command to execute + :type command: str|list + :param log_level: log level to use for command output + :type log_level: int + :return: command output + :rtype: list + """ if isinstance(command, basestring): command = command.split() process = subprocess.Popen(command, stdout=subprocess.PIPE) @@ -78,6 +130,16 @@ class Utils(object): @staticmethod def get_cardinal_coordinate(value, latitude): + """ + Translates a degree value into degrees NSEO + + :param value: value in degress + :type value: float + :param latitude: if True, value is latitude, Otherwise value is longitude + :type latitude: bool + :return: transformed value + :rtype: str + """ if latitude: if value < 0: direction = 'S' @@ -92,14 +154,42 @@ class Utils(object): class TempFile(object): + """ + Class to manage temporal files + """ autoclean = True + """ + If True, new temporary files are added to the list for future cleaning + """ files = list() + """ + List of files to clean automatically + """ scratch_folder = os.path.join('/scratch', pwd.getpwuid(os.getuid())[0]) + """ + Scratch folder to create temporary files on it + """ prefix = 'temp' + """ + Prefix for temporary filenames + """ @staticmethod - def get(filename=None, clean=True): + def get(filename=None, clean=None): + """ + Gets a new temporal filename, storing it for automated cleaning + + :param filename: if it is not none, the function will use this filename instead of a random one + :type filename: str + :param clean: if true, stores filename for cleaning + :type clean: bool + :return: path to the temporal file + :rtype: str + """ + if clean is None: + clean = TempFile.autoclean + if filename: path = os.path.join(TempFile.scratch_folder, filename) else: @@ -112,6 +202,9 @@ class TempFile(object): @staticmethod def clean(): + """ + Removes all temporary files created with Tempfile until now + """ for temp_file in TempFile.files: if os.path.exists(temp_file): os.remove(temp_file) -- GitLab From 38fa579479bc81558e8cf1b2301de7d999915857 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 17 May 2016 16:53:54 +0200 Subject: [PATCH 056/268] Documentation updated --- doc/source/codedoc/diags.rst | 7 +++++++ doc/source/codedoc/main.rst | 2 ++ doc/source/codedoc/models.rst | 7 +++++++ doc/source/index.rst | 12 ------------ earthdiagnostics/diags.py | 11 +++++++++++ earthdiagnostics/models.py | 13 ++++++++++++- earthdiagnostics/ocean/circulation.py | 22 +++++++++++----------- 7 files changed, 50 insertions(+), 24 deletions(-) create mode 100644 doc/source/codedoc/diags.rst create mode 100644 doc/source/codedoc/models.rst diff --git a/doc/source/codedoc/diags.rst b/doc/source/codedoc/diags.rst new file mode 100644 index 0000000..d64bb81 --- /dev/null +++ b/doc/source/codedoc/diags.rst @@ -0,0 +1,7 @@ +earthdiagnsotics.diags +====================== + +.. automodule:: earthdiagnostics.diags + :show-inheritance: + :inherited-members: + :members: \ No newline at end of file diff --git a/doc/source/codedoc/main.rst b/doc/source/codedoc/main.rst index 716ce07..4f323a2 100644 --- a/doc/source/codedoc/main.rst +++ b/doc/source/codedoc/main.rst @@ -5,6 +5,8 @@ Module documentation .. toctree:: :titlesonly: + diags + models utils basin cdftools diff --git a/doc/source/codedoc/models.rst b/doc/source/codedoc/models.rst new file mode 100644 index 0000000..c52eb16 --- /dev/null +++ b/doc/source/codedoc/models.rst @@ -0,0 +1,7 @@ +earthdiagnsotics.models +======================= + +.. automodule:: earthdiagnostics.models + :show-inheritance: + :inherited-members: + :members: \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst index f2cadb2..23e5ce1 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -6,19 +6,7 @@ Welcome to Earth Diagnostics's documentation! ============================================= -Contents: - .. toctree:: :maxdepth: 2 codedoc/main - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 6e78df7..ea9758d 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -13,7 +13,15 @@ import os class Diags: + """ + Launcher class for the diagnostics + """ def __init__(self, config_file): + """ + Constructor for the diags class + :param config_file: path to the configuration file + :type config_file: str + """ Log.debug('Initialising Diags') self._read_config(config_file) TempFile.scratch_folder = self.scratch_dir @@ -33,6 +41,9 @@ class Diags: self.dic_variables['t'] = 'time' def run(self): + """ + Run the diagnostics + """ if not os.path.exists(self.scratch_dir): os.makedirs(self.scratch_dir) os.chdir(self.scratch_dir) diff --git a/earthdiagnostics/models.py b/earthdiagnostics/models.py index 93fd31d..0723b1a 100644 --- a/earthdiagnostics/models.py +++ b/earthdiagnostics/models.py @@ -1,13 +1,24 @@ -class Grid(object): +class Models(object): + """ + Predefined models + """ ECEARTH_2_3_O1L42 = 'Ec2.3_O1L42' + """ EC-Earth 2.3 ORCA1 L42""" ECEARTH_3_0_O1L46 = 'Ec3.0_O1L46' + """ EC-Earth 3 ORCA1 L46 """ ECEARTH_3_0_O25L46 = 'Ec3.0_O25L46' + """ EC-Earth 3 ORCA0.25 L46 """ ECEARTH_3_0_O25L75 = 'Ec3.0_O25L75' + """ EC-Earth 3 ORCA0.25 L75 """ NEMO_3_2_O1L42 = 'N3.2_O1L42' + """ NEMO 3.2 ORCA1 L42 """ NEMO_3_3_O1L46 = 'N3.3_O1L46' + """ NEMO 3.3 ORCA1 L46 """ NEMOVAR_O1L42 = 'nemovar_O1L42' + """ NEMOVAR ORCA1 L42 """ GLORYS2_V1_O25L75 = 'glorys2v1_O25L75' + """ GLORYS2v1 ORCA0.25 L75 """ diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 9f50318..b37fb20 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -1,6 +1,6 @@ from earthdiagnostics import Utils, cdftools, TempFile from earthdiagnostics.basins import Basins -from earthdiagnostics.models import Grid +from earthdiagnostics.models import Models from autosubmit.config.log import Log import numpy as np import os @@ -306,9 +306,9 @@ class Circulation(object): :return: """ - if input_grid in [Grid.ECEARTH_2_3_O1L42, Grid.ECEARTH_3_0_O1L46, - Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, - Grid.NEMOVAR_O1L42]: + if input_grid in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, + Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, + Models.NEMOVAR_O1L42]: subpolNAtl = [230, 275, 215, 245] subpolNPac = [70, 145, 195, 235] subtropNPac = [45, 175, 165, 220] @@ -318,8 +318,8 @@ class Circulation(object): subtropInd = [320, 30, 110, 180] ACC = [1, 361, 1, 65] - elif input_grid in [Grid.ECEARTH_3_0_O25L46, Grid.ECEARTH_3_0_O25L75, - Grid.GLORYS2_V1_O25L75]: + elif input_grid in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, + Models.GLORYS2_V1_O25L75]: raise Exception("Option gyres not available yet for {0}".format(input_grid)) else: raise Exception("Input grid {0} not recognized".format(input_grid)) @@ -394,16 +394,16 @@ class Circulation(object): :param output_file: output file name (=> index) :return: """ - if input_grid in [Grid.ECEARTH_2_3_O1L42, Grid.ECEARTH_3_0_O1L46, - Grid.NEMO_3_2_O1L42, Grid.NEMO_3_3_O1L46, - Grid.NEMOVAR_O1L42]: + if input_grid in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, + Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, + Models.NEMOVAR_O1L42]: labrador = [255, 245, 215, 255] irminger = [245, 290, 215, 245] gin = [260, 310, 245, 291] wedell = [225, 280, 1, 50] - elif input_grid in [Grid.ECEARTH_3_0_O25L46, Grid.ECEARTH_3_0_O25L75, - Grid.GLORYS2_V1_O25L75]: + elif input_grid in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, + Models.GLORYS2_V1_O25L75]: raise Exception("Option convection not available yet for {0}".format(input_grid)) else: raise Exception("Input grid {0} not recognized".format(input_grid)) -- GitLab From 1afe294f89661b66c44cad68f9066fc03edeecbb Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 17 May 2016 17:15:42 +0200 Subject: [PATCH 057/268] Corrected errors on doc --- earthdiagnostics/basins.py | 21 +++++++++------------ earthdiagnostics/diags.py | 8 +++----- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index 176cf80..e6e60bd 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -1,20 +1,17 @@ class Basin(object): """ Class representing a given basin + + :param shortname: sfull basin's name + :type shortname: str + :param fullname: full basin's name + :type fullname: str + :param coordinates: list of coordinates for the basin in the order: min longitude, max longitude, min latitude, + max latitude + :type coordinates: tuple """ def __init__(self, shortname, fullname, coordinates=None): - """ - Constructor for Basin - - :param shortname: sfull basin's name - :type shortname: str - :param fullname: full basin's name - :type fullname: str - :param coordinates: list of coordinates for the basin in the order: min longitude, max longitude, min latitude, - max latitude - :type coordinates: tuple - """ self._shortname = shortname self._fullname = fullname if coordinates: @@ -125,7 +122,7 @@ class Basins(object): """ Return the basin matching the given name. If the parameter basin is a Basin instance, directly returns the same instance. This bahaviour is intended to facilitate the development of methods that can either accept a name - or an instance to charcterize the basin. + or a Basin instance to characterize the basin. :param basin: basin name or basin instance :type basin: str | Basin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index ea9758d..be8c033 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -15,13 +15,11 @@ import os class Diags: """ Launcher class for the diagnostics + + :param config_file: path to the configuration file + :type config_file: str """ def __init__(self, config_file): - """ - Constructor for the diags class - :param config_file: path to the configuration file - :type config_file: str - """ Log.debug('Initialising Diags') self._read_config(config_file) TempFile.scratch_folder = self.scratch_dir -- GitLab From a5ad146065331f85d3549a4f762fb23465b6087a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 18 May 2016 10:44:41 +0200 Subject: [PATCH 058/268] ohc specified layer finished --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/ocean/heat.py | 77 ++++++++++++++++------------------ 3 files changed, 37 insertions(+), 44 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 8eb9477..34837e6 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('gyres') +listpost=('ohc_specified_layer') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index dd3f43f..77d8db4 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = psi gyres +DIAGS = OHC_SPECIFIED_LAYER FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 9f98e87..db1d36b 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -4,6 +4,7 @@ from autosubmit.config.log import Log import os import shutil import traceback +import numpy as np from nco import NCOException @@ -79,32 +80,28 @@ class Heat(object): level_below = TempFile.get() heatc_sl_bottom = TempFile.get() heatc_sl_top_invert = TempFile.get() - depth_diff_lay = TempFile.get() - depth_diff_sublay = TempFile.get() - total_heatc_sl = TempFile.get() e3tfile = TempFile.get() - factor = TempFile.get() + results = TempFile.get() nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*e3t"'), shutil.copy(input_file, input_scratch) + ntime = int(cdo.ntime(input=input_scratch)[0]) - files = list() for time in range(ntime): Log.info('Running time {0}', time) temp = TempFile.get() nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) Utils.rename_variable(temp, 'thetao', 'heatc_sl') + nco.ncks(input=temp, output=temp, options='-O -v heatc_sl') cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) # extract the data between the two given depths --> heatc_sl_top.nc nco.ncks(input=heatc_sl_out, output=heatc_sl_top, options='-O -d lev,{0}.0,{1}.0'.format(min_depth, max_depth)) - # perform the integration of ohc down to that level (main contribution) - nco.ncap2(options="-O -s 'heatc_sl=heatc_sl.total({0})'".format(max_depth), - input=heatc_sl_top, output=heatc_sl_top) + # now extract a few levels below, to compute the residual ohc # addition with float returned: nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, @@ -118,43 +115,39 @@ class Heat(object): nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') - # Here, add the residual contribution, before adding it to the main contribution - Utils.rename_variable(level_below, 'lev', 'layerthcknss') - Utils.rename_variable(level_above, 'lev', 'layerthcknss') - nco.ncbo(options='--op_typ=sub -v layerthcknss', - input='{0} {1}'.format(level_below, level_above), output=depth_diff_lay) - # Utils.rename_variable(depth_diff_lay, 'layerthcknss', 'lev') - - nco.ncap2(options='-s "heatc_sl=({0} - layerthcknss)"'.format(max_depth), - input=level_above, output=depth_diff_sublay) - nco.ncbo(options='--op_typ=/ -v heatc_sl', - input=' '.join([depth_diff_sublay, depth_diff_lay]), output=factor) - Utils.rename_variable(factor, 'heatc_sl', 'factor') - nco.ncks(input=factor, output=level_below, options='-A -v factor') - os.remove(depth_diff_lay) - os.remove(depth_diff_sublay) - - nco.ncap2(input=level_below, output=level_below, options='-O -s "heatc_sl=(factor * heatc_sl)"') - nco.ncwa(input=level_below, output=level_below, options='-O -a lev') - - nco.ncbo(options=' --op_typ=+ -v heatc_sl', - input=' '.join([heatc_sl_top, level_below]), output=total_heatc_sl) - Utils.execute_shell_command('ncbo --op_typ=+ -v heatc_sl ' - '{0} {1} {2}'.format(heatc_sl_top, level_above, total_heatc_sl)) - nco.ncap2(input=total_heatc_sl, output=temp, options='-s "heatc_sl=1020.0*4000*heatc_sl"') - files.append(temp) + handler = nco.openCdf(level_above) + lev_above = handler.variables['lev'][:] + handler.close() - temp = TempFile.get() - cdo.cat(input=' '.join(files), output=temp,) - nco.ncks(input=input_scratch, output=temp, options='-A -v time') + handler = nco.openCdf(level_below) + layerthcknss = handler.variables['lev'][:] - lev_above + heatc_sl_below = handler.variables['heatc_sl'][:] + handler.close() - for temp_file in files: - os.remove(temp_file) - os.remove(input_scratch) - Utils.setminmax(temp, ['heatc_sl']) + factor = (max_depth - lev_above) / layerthcknss + + heatc_sl_below = heatc_sl_below * factor + handler = nco.openCdf(heatc_sl_top) + heatc_sl = handler.variables['heatc_sl'][:] + handler.close() + + heatc_sl = np.sum(heatc_sl, 1) + heatc_sl = heatc_sl[:] + heatc_sl_below[:] + heatc_sl = heatc_sl[0, 0, :] * 1020 * 4000 + + if time == 0: + nco.ncks(input=heatc_sl_top_invert, output=results, options='-O -v lon,lat') + nco.ncks(input=input_scratch, output=results, options='-A -v time') + handler_results = nco.openCdf(results) + handler_results.createVariable('heatc', float, ('time', 'y', 'x')) + handler_results.close() + + handler_results = nco.openCdf(results) + handler_results.variables['heatc'][time, :] = heatc_sl + handler_results.close() - shutil.move(temp, output_file) - os.remove(temp) + Utils.setminmax(results, 'heatc') + Utils.move_file(results, output_file) @staticmethod def total(input_file, mlotst_file, output_file, basin=Basins.Global.shortname, mixed_layer=0, -- GitLab From cb34b941f36dbfd1e42ff0fe9f9b8bf18de55e1a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 18 May 2016 18:08:30 +0200 Subject: [PATCH 059/268] Interpolation ready --- common_ocean_post.txt | 2 +- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/ocean/general.py | 20 ++++++++++---------- earthdiagnostics/ocean/heat.py | 8 +++++--- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 2058dbf..622e774 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -1154,7 +1154,7 @@ EOF ./scrip_use ncecat -O -h tmp_$(printf "%02d" $lev).nc tmp_$(printf "%02d" $lev).nc ncrename -h -O -d record,deptht tmp_$(printf "%02d" $lev).nc tmp_$(printf "%02d" $lev).nc - done + donex ncrcat -n $nz,2,1 -v $2 tmp_01.nc tmpout.nc ncpdq -O -h -a time,deptht tmpout.nc tmp2out.nc ncks -A -v deptht $1 tmp2out.nc diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 34837e6..839f827 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('ohc_specified_layer') +listpost=('3dtemp') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 77d8db4..a2cd26b 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = OHC_SPECIFIED_LAYER +DIAGS = 3DTEMP FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index d4966a6..7872da5 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -68,6 +68,7 @@ class General(object): temp2 = TempFile.get() for lev in range(0, handler.dimensions['lev'].size): + Log.debug('Interpolating level {0}'.format(lev)) nco.ncks(input=temp, output=temp2, options='-O -d lev,{0} -v {1}'.format(lev, variable)) nco.ncwa(input=temp2, output=temp2, options='-O -h -a lev') # link = 'rmp_{0}_to_regular_lev{1}.nc'.format(nemo_version, lev) @@ -77,30 +78,29 @@ class General(object): scrip_use_in = open('scrip_use_in', 'w') scrip_use_in.writelines("&remap_inputs\n") scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" - "weigths/{0}/rmp_{0}_to_*_lev{1}.nc'\n".format(nemo_version, lev+1)) + "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(nemo_version, lev+1)) scrip_use_in.writelines(" infile = '{0}'\n".format(temp2)) scrip_use_in.writelines(" invertlat = FALSE\n") scrip_use_in.writelines(" var = '{0}'\n".format(variable)) scrip_use_in.writelines(" fromregular = FALSE\n") - scrip_use_in.writelines(" outfile = '{0}'\n".format(temp)) + scrip_use_in.writelines(" outfile = '{0}'\n".format(temp2)) scrip_use_in.writelines("/\n") scrip_use_in.close() - # Utils.execute_shell_command('/shared/earth/software/scripts/interpolation/scrip_use') - Utils.execute_shell_command('/shared/earth/software/scripts/interpolation/scrip_use') - + Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use', Log.NO_LOG) nco.ncecat(input=temp2, output=temp2, options="-O -h") - Utils.rename_variable(temp2, 'record', 'lev') shutil.move(temp2, 'tmp_{0:02d}.nc'.format(lev+1)) nco.ncrcat(input='tmp_01.nc', output=temp2, options='-n {0},2,1 -v {1}'.format(handler.dimensions['lev'].size, variable)) + handler = nco.openCdf(temp2) + handler.renameDimension('record', 'lev') + handler.close() nco.ncpdq(input=temp2, output=temp2, options='-O -h -a time,lev') nco.ncks(input=temp, output=temp2, options='-A -v lev') - cdo.setgrid(',t106grid', input=temp2, output=temp2) + cdo.setgrid('t106grid', input=temp2, output=temp) if nemo_version[6:9] == '025': - cdo.invertlatdata(input=temp2, output=temp2) - Utils.move_file(temp2, output_file) - + cdo.invertlatdata(input=temp, output=temp) + Utils.move_file(temp, output_file) @staticmethod def cut_section(input_file, output_file, variable, zonal, value): diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index db1d36b..0399b9a 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -139,14 +139,16 @@ class Heat(object): nco.ncks(input=heatc_sl_top_invert, output=results, options='-O -v lon,lat') nco.ncks(input=input_scratch, output=results, options='-A -v time') handler_results = nco.openCdf(results) - handler_results.createVariable('heatc', float, ('time', 'y', 'x')) + # handler_results.renameDimension('x', 'i') + # handler_results.renameDimension('y', 'j') + handler_results.createVariable('ohc', float, ('time', 'y', 'x')) handler_results.close() handler_results = nco.openCdf(results) - handler_results.variables['heatc'][time, :] = heatc_sl + handler_results.variables['ohc'][time, :] = heatc_sl handler_results.close() - Utils.setminmax(results, 'heatc') + Utils.setminmax(results, 'ohc') Utils.move_file(results, output_file) @staticmethod -- GitLab From 2d9ba67d4f8d8356fe5c78dab22b2cf0c52d149f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 19 May 2016 17:10:41 +0200 Subject: [PATCH 060/268] Refactored data management --- common_ocean_post.txt | 2 +- config_file-ocean_pp.bash | 2 +- earthdiagnostics/datamanager.py | 61 ++++++ earthdiagnostics/diags.conf | 12 +- earthdiagnostics/diags.py | 338 ++++++++++++++---------------- earthdiagnostics/ocean/general.py | 69 +++--- earthdiagnostics/utils.py | 14 +- 7 files changed, 285 insertions(+), 213 deletions(-) create mode 100644 earthdiagnostics/datamanager.py diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 622e774..2058dbf 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -1154,7 +1154,7 @@ EOF ./scrip_use ncecat -O -h tmp_$(printf "%02d" $lev).nc tmp_$(printf "%02d" $lev).nc ncrename -h -O -d record,deptht tmp_$(printf "%02d" $lev).nc tmp_$(printf "%02d" $lev).nc - donex + done ncrcat -n $nz,2,1 -v $2 tmp_01.nc tmpout.nc ncpdq -O -h -a time,deptht tmpout.nc tmp2out.nc ncks -A -v deptht $1 tmp2out.nc diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 839f827..a57ebce 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('3dtemp') +listpost=('TSec_ave190-220E SSec_ave190-220E') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py new file mode 100644 index 0000000..e6c3745 --- /dev/null +++ b/earthdiagnostics/datamanager.py @@ -0,0 +1,61 @@ +import os +from autosubmit.config.log import Log +from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day + +from earthdiagnostics import Utils + + +class DataManager(object): + + def __init__(self, institution, model, expid, datafolder, frequency, chunk_size): + self.institution = institution + self.model = model + self.expid = expid + self.data_dir = datafolder + self.frequency = frequency + self.chunk_size = chunk_size + + def prepare_CMOR_files(self, startdates, members): + # Check if cmorized and convert if not + if not os.path.exists(os.path.join(self.data_dir, self.expid)): + raise Exception('The experiment {0} is not CMORized. Please, CMORize it and launch again.'.format(self.expid)) + + for startdate in startdates: + for member in members: + member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') + if not os.path.exists(os.path.join(member_path, 'output')): + Utils.execute_shell_command('gunzip {0}'.format(os.path.join(member_path, '*.gz'))) + Utils.execute_shell_command('tar -xvf {0}'.format(os.path.join(member_path, '*.tar'))) + + def get_files(self, startdate, member, chunk, domain, variables): + + file_names = list() + + if domain == 'seaIce': + domain_abreviattion = 'OI' + else: + domain_abreviattion = domain[0].upper() + + start = parse_date(startdate) + member_plus = str(member + 1) + member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', + self.institution, self.model, self.model, 'S' + startdate, self.frequency, + domain) + + chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + + var_file = list() + for var in variables: + var_file.append(os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus), + '{0}_{1}{2}_{3}_output_r{4}i1p1_' + '{5}-{6}.nc'.format(var, domain_abreviattion, + self.frequency, self.model, member_plus, + "{0:04}{1:02}".format(chunk_start.year, + chunk_start.month), + "{0:04}{1:02}".format(chunk_end.year, + chunk_end.month)))) + file_names.append(var_file) + + return file_names diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index a2cd26b..3a14262 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,10 +2,20 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = 3DTEMP +DIAGS = 3DTEMP 3DSAL FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin +# [EXPERIMENT] +# INSTITUTE = IC3 +# EXPID = m02 +# STARTDATES = 19900101 +# CHUNK_SIZE = 3 +# CHUNKS = 1 +# MEMBERS = 0 +# MODEL = EC-EARTH3 +# NEMO_VERSION = Ec3.0_O1L46 + [EXPERIMENT] INSTITUTE = IC3 EXPID = a030 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index be8c033..4bb4b17 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -2,6 +2,7 @@ import argparse +from datamanager import DataManager from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Ice from utils import Utils from earthdiagnostics import cdftools, TempFile @@ -22,6 +23,8 @@ class Diags: def __init__(self, config_file): Log.debug('Initialising Diags') self._read_config(config_file) + self.datamanager = DataManager(self.institute, self.model, self.expid, self.data_dir, + self.frequency, self.chunk_size) TempFile.scratch_folder = self.scratch_dir cdftools.path = self.cdftools_path self._create_dic_variables() @@ -42,167 +45,172 @@ class Diags: """ Run the diagnostics """ + time = datetime.datetime.now() + Log.info("Starting diagnostics at {0}", time) if not os.path.exists(self.scratch_dir): os.makedirs(self.scratch_dir) os.chdir(self.scratch_dir) self._prepare_mesh_files() - # Check if cmorized and convert if not - if not os.path.exists(os.path.join(self.data_dir, self.expid)): - Log.error('Your experiment is not CMORized. Please, CMORize it and launch again.') - exit(1) + self.datamanager.prepare_CMOR_files(self.startdates, self.members) # Run diagnostics Log.info('Running diagnostics') for fulldiag in self._get_commands(): - diag_options = fulldiag.split(',') - diag = diag_options[0] Log.info("Running {0}", fulldiag) - if diag == 'vertmeansal': - depth_min = int(diag_options[1]) - depth_max = int(diag_options[2]) - depth = '{0}-{1}'.format(depth_min, depth_max) - for [input_file, output_file] in self._get_file_names('ocean', 'so', - 'someanm{0}'.format(depth)): - Salinity.vertical_mean(input_file, output_file, depth_min, depth_max) - elif diag == 'vertmean': - variable = diag_options[1] - lev_min = int(diag_options[2]) - lev_max = int(diag_options[3]) - lev = '{0}-{1}'.format(lev_min, lev_max) - for [input_file, output_file] in self._get_file_names('ocean', variable, - '{0}mean{1}'.format(variable, lev)): - General.vertical_mean(input_file, output_file, variable, lev_min, lev_max) - elif diag == 'convection': - for [input_file, output_file] in self._get_file_names('ocean', 'mlotst', - 'mlotstsites'): - Circulation.convection_sites(input_file, self.nemo_version, output_file) - elif diag == 'psi': - for [u_file, v_file, output_file] in self._get_file_names('ocean', 'uo', 'vo', - 'msftbarot'): - Circulation.psi(u_file, v_file, output_file) - elif diag == 'gyres': - for [input_file, output_file] in self._get_file_names('ocean', 'msftbarot', - 'msftbarotgyres'): - Circulation.gyres(str(input_file), self.nemo_version, str(output_file)) - elif diag == 'ohc': - basin = diag_options[1] - mixed_layer = int(diag_options[2]) - depth_min = int(diag_options[3]) - depth_max = int(diag_options[4]) - - if mixed_layer == 1: - mxl = 'mlotst' - depth = '' - elif mixed_layer == 0: - mxl = '' - depth = '{0}-{1}'.format(depth_min, depth_max) - else: - mxl = 'nomlotst' - depth = '' - - for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'thetao', 'mlotst', - 'ohcsum{0}{1}'.format(mxl, depth)): - Heat.total(input_file, mlotst_file, output_file, basin, mixed_layer, depth_min, depth_max) - elif diag == 'ohclayer': - depth_min = int(diag_options[1]) - depth_max = int(diag_options[2]) - - depth = '{0}-{1}'.format(depth_min, depth_max) - - for [input_file, output_file] in self._get_file_names('ocean', 'thetao', - 'ohc{0}'.format(depth)): - Heat.layer(input_file, output_file, depth_min, depth_max) - elif diag in ['moc', 'msftmyz']: - for [input_file, output_file] in self._get_file_names('ocean', 'vo', - 'msftmyz'): - Circulation.moc(input_file, output_file) - elif diag in ['mocmax', 'msftmyzmax']: - if len(diag_options) != 5: - Log.warning('Moc max requires 4 arguments. Skipping!') - continue - - lat_min = int(diag_options[1]) - lat_max = int(diag_options[2]) - lat = '{0}-{1}'.format(lat_min, lat_max) - - depth_min = int(diag_options[3]) - depth_max = int(diag_options[4]) - depth = '{0}-{1}'.format(depth_min, depth_max) + for startdate in self.startdates: + for member in self.members: + for chunk in range(1, self.chunks+1): + self._execute_diagnostic(fulldiag.split(','), startdate, member, chunk) - for [input_file, output_file] in self._get_file_names('ocean', 'msftmyz', - 'msftmyzmax'): + Log.result('Finished {0}', fulldiag) - Circulation.max_moc(input_file, lat_min, lat_max, - output_file.replace('msftmyzmax', 'msftmyzmax{0}-{1}'.format(lat, depth)), - depth_min, depth_max) - elif diag in ['mocarea', 'msftmyzarea']: - if len(diag_options) != 6: - Log.warning('area_moc requires between 5 arguments. Skipping!') - continue - - lat_min = int(diag_options[1]) - lat_max = int(diag_options[2]) - lat = '{0}{1}'.format(Utils.get_cardinal_coordinate(lat_min, True), - Utils.get_cardinal_coordinate(lat_max, True)) - - depth_min = int(diag_options[3]) - depth_max = int(diag_options[4]) + TempFile.clean() + finsih_time = datetime.datetime.now() + Log.result("Diagnostics finished at {0}", finsih_time) + Log.result("Time ellapsed: {0}", finsih_time - time) + + def _execute_diagnostic(self, diag_options, startdate, member, chunk): + diag = diag_options[0] + if diag == 'vertmeansal': + depth_min = int(diag_options[1]) + depth_max = int(diag_options[2]) + depth = '{0}-{1}'.format(depth_min, depth_max) + variables = ('so', 'someanm{0}'.format(depth)) + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + Salinity.vertical_mean(input_file, output_file, depth_min, depth_max) + elif diag == 'vertmean': + variable = diag_options[1] + lev_min = int(diag_options[2]) + lev_max = int(diag_options[3]) + lev = '{0}-{1}'.format(lev_min, lev_max) + variables = (variable, '{0}mean{1}'.format(variable, lev)) + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + General.vertical_mean(input_file, output_file, variable, lev_min, lev_max) + elif diag == 'convection': + variables = ('mlotst','mlotstsites') + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + Circulation.convection_sites(input_file, self.nemo_version, output_file) + elif diag == 'psi': + variables = ('uo', 'vo', 'msftbarot') + for [u_file, v_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + Circulation.psi(u_file, v_file, output_file) + elif diag == 'gyres': + variables = ('msftbarot', 'msftbarotgyres') + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + Circulation.gyres(str(input_file), self.nemo_version, str(output_file)) + elif diag == 'ohc': + basin = diag_options[1] + mixed_layer = int(diag_options[2]) + depth_min = int(diag_options[3]) + depth_max = int(diag_options[4]) + + if mixed_layer == 1: + mxl = 'mlotst' + depth = '' + elif mixed_layer == 0: + mxl = '' depth = '{0}-{1}'.format(depth_min, depth_max) - - basin = diag_options[5] - - for [input_file, output_file] in self._get_file_names('ocean', 'msftmyz', - 'msftmyz{0}{1}{2}'.format(lat, depth, basin)): - Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) - elif diag == 'mlotsthc': - for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'thetao', - 'mlotst', 'mlotsthc'): - Heat.mixed_layer_content(input_file, mlotst_file, output_file) - elif diag == 'mlotstsc': - for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'so', 'mlotst', 'mlotstsc'): - Salinity.mixed_layer_content(input_file, mlotst_file, output_file) - elif diag == 'interp3d': - variable = diag_options[1] - for [input_file, output_file] in self._get_file_names('ocean', variable, - '{0}interp'.format(variable)): - General.interpolate3d(input_file, output_file, variable, self.nemo_version) - elif diag == 'cutsection': - variable = diag_options[1] - zonal = diag_options[2] == 'z' - value = int(diag_options[3]) - coordinate = Utils.get_cardinal_coordinate(value, zonal) - for [input_file, output_file] in self._get_file_names('ocean', variable, - '{0}{1}'.format(variable, coordinate)): - General.cut_section(input_file, output_file, variable, zonal, value) - elif diag == 'avgsection': - variable = diag_options[1] - lon_min = int(diag_options[2]) - lon_max = int(diag_options[3]) - lat_min = int(diag_options[4]) - lat_max = int(diag_options[5]) - - output_name = '{0}{1}{2}{3}{4}'.format(variable, Utils.get_cardinal_coordinate(lon_min, False), - Utils.get_cardinal_coordinate(lon_max, False), - Utils.get_cardinal_coordinate(lat_min, True), - Utils.get_cardinal_coordinate(lat_max, True)) - - for [input_file, output_file] in self._get_file_names('ocean', variable, output_name): - General.avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max) - - elif diag == 'siasiesiv': - basin = diag_options[1] - for [thickness_file, fraction_file, output_file] in self._get_file_names('seaIce', 'sit', 'sic', - 'siasiesiv'): - Ice.siasiesiv(thickness_file, fraction_file, output_file, basin) else: - Log.warning('Diagnostic {0} not available', diag) - continue + mxl = 'nomlotst' + depth = '' + variables = ('thetao', 'mlotst', 'ohcsum{0}{1}'.format(mxl, depth)) + for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', + variables): + Heat.total(input_file, mlotst_file, output_file, basin, mixed_layer, depth_min, depth_max) + elif diag == 'ohclayer': + depth_min = int(diag_options[1]) + depth_max = int(diag_options[2]) + + depth = '{0}-{1}'.format(depth_min, depth_max) + variables = ('thetao', 'ohc{0}'.format(depth)) + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + Heat.layer(input_file, output_file, depth_min, depth_max) + elif diag in ['moc', 'msftmyz']: + variables = ('vo', 'msftmyz') + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + Circulation.moc(input_file, output_file) + elif diag in ['mocmax', 'msftmyzmax']: + if len(diag_options) != 5: + Log.warning('Moc max requires 4 arguments. Skipping!') + return - Log.result('Finished {0}', diag) + lat_min = int(diag_options[1]) + lat_max = int(diag_options[2]) + lat = '{0}-{1}'.format(lat_min, lat_max) + + depth_min = int(diag_options[3]) + depth_max = int(diag_options[4]) + depth = '{0}-{1}'.format(depth_min, depth_max) + variables = ('msftmyz', 'msftmyzmax') + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + Circulation.max_moc(input_file, lat_min, lat_max, + output_file.replace('msftmyzmax', 'msftmyzmax{0}-{1}'.format(lat, depth)), + depth_min, depth_max) + elif diag in ['mocarea', 'msftmyzarea']: + if len(diag_options) != 6: + Log.warning('area_moc requires between 5 arguments. Skipping!') + return - TempFile.clean() + lat_min = int(diag_options[1]) + lat_max = int(diag_options[2]) + lat = '{0}{1}'.format(Utils.get_cardinal_coordinate(lat_min, True), + Utils.get_cardinal_coordinate(lat_max, True)) + + depth_min = int(diag_options[3]) + depth_max = int(diag_options[4]) + depth = '{0}-{1}'.format(depth_min, depth_max) + + basin = diag_options[5] + variables = ('msftmyz', 'msftmyz{0}{1}{2}'.format(lat, depth, basin)) + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) + elif diag == 'mlotsthc': + variables = ('thetao', 'mlotst', 'mlotsthc') + for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', + variables): + Heat.mixed_layer_content(input_file, mlotst_file, output_file) + elif diag == 'mlotstsc': + for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'so', 'mlotst', 'mlotstsc'): + Salinity.mixed_layer_content(input_file, mlotst_file, output_file) + elif diag == 'interp3d': + variable = diag_options[1] + variables = (variable, '{0}interp'.format(variable)) + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + General.interpolate3d(input_file, output_file, variable, self.nemo_version) + elif diag == 'cutsection': + variable = diag_options[1] + zonal = diag_options[2] == 'z' + value = int(diag_options[3]) + coordinate = Utils.get_cardinal_coordinate(value, zonal) + variables = (variable, '{0}{1}'.format(variable, coordinate)) + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + General.cut_section(input_file, output_file, variable, zonal, value) + elif diag == 'avgsection': + variable = diag_options[1] + lon_min = int(diag_options[2]) + lon_max = int(diag_options[3]) + lat_min = int(diag_options[4]) + lat_max = int(diag_options[5]) + + output_name = '{0}{1}{2}{3}{4}'.format(variable, Utils.get_cardinal_coordinate(lon_min, False), + Utils.get_cardinal_coordinate(lon_max, False), + Utils.get_cardinal_coordinate(lat_min, True), + Utils.get_cardinal_coordinate(lat_max, True)) + variables = (variable, output_name) + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + General.avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max) + + elif diag == 'siasiesiv': + basin = diag_options[1] + variables = ('sit', 'sic', 'siasiesiv') + for [thickness_file, fraction_file, output_file] in self.datamanager.get_files(startdate, member, chunk, + 'seaIce', variables): + Ice.siasiesiv(thickness_file, fraction_file, output_file, basin) + else: + Log.warning('Diagnostic {0} not available', diag) + return def _get_commands(self): Log.debug('Preparing command list') @@ -234,6 +242,7 @@ class Diags: def _copy_file(self, source, destiny): if not os.path.exists(source): Log.user_warning('File {0} is not available for {1}', destiny, self.nemo_version) + return if os.path.exists(destiny): if os.stat(source).st_size == os.stat(destiny).st_size: @@ -275,8 +284,12 @@ class Diags: # Read experiment config self.institute = self.parser.get_option('EXPERIMENT', 'INSTITUTE') self.expid = self.parser.get_option('EXPERIMENT', 'EXPID') - self.members = self.parser.get_option('EXPERIMENT', 'MEMBERS') - self.startdates = self.parser.get_option('EXPERIMENT', 'STARTDATES') + + self.members = list() + for member in self.parser.get_option('EXPERIMENT', 'MEMBERS').split(): + self.members.append(int(member)) + + self.startdates = self.parser.get_option('EXPERIMENT', 'STARTDATES').split() self.chunk_size = self.parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') self.chunks = self.parser.get_int_option('EXPERIMENT', 'CHUNKS') self.model = self.parser.get_option('EXPERIMENT', 'MODEL') @@ -293,39 +306,6 @@ class Diags: os.makedirs(self.scratch_dir) os.chdir(self.scratch_dir) - def _get_file_names(self, domain, *variables): - file_names = list() - - if domain == 'seaIce': - domain_abreviattion = 'OI' - else: - domain_abreviattion = domain[0].upper() - for startdate in self.startdates.split(): - start = parse_date(startdate) - for member in self.members: - member_plus = str(int(member)+1) - member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc'+member, 'outputs', 'output', - self.institute, self.model, self.model, 'S'+startdate, self.frequency, - domain) - for chunk in range(1, self.chunks + 1): - chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') - - var_file = list() - for var in variables: - var_file.append(os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus), - '{0}_{1}{2}_{3}_output_r{4}i1p1_' - '{5}-{6}.nc'.format(var, domain_abreviattion, - self.frequency, self.model, member_plus, - "{0:04}{1:02}".format(chunk_start.year, - chunk_start.month), - "{0:04}{1:02}".format(chunk_end.year, - chunk_end.month)))) - file_names.append(var_file) - - return file_names - def main(): parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 7872da5..624e587 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -4,6 +4,7 @@ from earthdiagnostics import Utils, TempFile, cdftools import shutil import os import numpy as np +import threading class General(object): @@ -60,48 +61,63 @@ class General(object): :return: """ temp = TempFile.get() + temp2 = TempFile.get() shutil.copy(input_file, temp) cdo = Utils.cdo nco = Utils.nco handler = cdo.openCdf(temp) - temp2 = TempFile.get() + threads = list() + lock = threading.Lock() for lev in range(0, handler.dimensions['lev'].size): - Log.debug('Interpolating level {0}'.format(lev)) - nco.ncks(input=temp, output=temp2, options='-O -d lev,{0} -v {1}'.format(lev, variable)) - nco.ncwa(input=temp2, output=temp2, options='-O -h -a lev') - # link = 'rmp_{0}_to_regular_lev{1}.nc'.format(nemo_version, lev) - # if not os.path.exists(link): - # os.link('/esnas/autosubmit/con_files/weigths/{0}/rmp_{0}_to_*_lev${1}.nc'.format(nemo_version, lev+1), - # link) - scrip_use_in = open('scrip_use_in', 'w') - scrip_use_in.writelines("&remap_inputs\n") - scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" - "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(nemo_version, lev+1)) - scrip_use_in.writelines(" infile = '{0}'\n".format(temp2)) - scrip_use_in.writelines(" invertlat = FALSE\n") - scrip_use_in.writelines(" var = '{0}'\n".format(variable)) - scrip_use_in.writelines(" fromregular = FALSE\n") - scrip_use_in.writelines(" outfile = '{0}'\n".format(temp2)) - scrip_use_in.writelines("/\n") - scrip_use_in.close() - - Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use', Log.NO_LOG) - nco.ncecat(input=temp2, output=temp2, options="-O -h") - shutil.move(temp2, 'tmp_{0:02d}.nc'.format(lev+1)) + t = threading.Thread(target=General._interpolate_level, args=(lev, temp, variable, nemo_version, lock)) + threads.append(t) + t.start() + + for t in threads: + t.join() + nco.ncrcat(input='tmp_01.nc', output=temp2, options='-n {0},2,1 -v {1}'.format(handler.dimensions['lev'].size, variable)) + + for lev in range(0, handler.dimensions['lev'].size): + os.remove('tmp_{0:02d}.nc'.format(lev+1)) handler = nco.openCdf(temp2) handler.renameDimension('record', 'lev') handler.close() nco.ncpdq(input=temp2, output=temp2, options='-O -h -a time,lev') nco.ncks(input=temp, output=temp2, options='-A -v lev') + cdo.setgrid('t106grid', input=temp2, output=temp) if nemo_version[6:9] == '025': cdo.invertlatdata(input=temp, output=temp) Utils.move_file(temp, output_file) + @staticmethod + def _interpolate_level(lev, input_file, variable, nemo_version, lock): + nco = Utils.nco + temp2 = TempFile.get() + nco.ncks(input=input_file, output=temp2, options='-O -d lev,{0} -v {1}'.format(lev, variable)) + nco.ncwa(input=temp2, output=temp2, options='-O -h -a lev') + namelist_file = 'scrip_use_in{0}'.format(lev) + scrip_use_in = open(namelist_file, 'w') + scrip_use_in.writelines("&remap_inputs\n") + scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" + "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(nemo_version, lev+1)) + scrip_use_in.writelines(" infile = '{0}'\n".format(temp2)) + scrip_use_in.writelines(" invertlat = FALSE\n") + scrip_use_in.writelines(" var = '{0}'\n".format(variable)) + scrip_use_in.writelines(" fromregular = FALSE\n") + scrip_use_in.writelines(" outfile = '{0}'\n".format(temp2)) + scrip_use_in.writelines("/\n") + scrip_use_in.close() + Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use {0}'.format(namelist_file), Log.NO_LOG) + os.remove(namelist_file) + nco.ncecat(input=temp2, output=temp2, options="-O -h") + shutil.move(temp2, 'tmp_{0:02d}.nc'.format(lev+1)) + Log.debug("Level {0} ready", lev) + @staticmethod def cut_section(input_file, output_file, variable, zonal, value): """ @@ -204,7 +220,10 @@ class General(object): @staticmethod def avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max): - Utils.cdo.zonmean(input=input_file, output=output_file, - options='-sellonlatbox,{0},{1},{1},{2}'.format(lon_min, lon_max, lat_min, lat_max)) + temp = TempFile.get() + Utils.cdo.zonmean(input='-sellonlatbox,{0},{1},{2},{3} {4}'.format(lon_min, lon_max, lat_min, lat_max, + input_file), + output=temp) + Utils.move_file(temp, output_file) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 90aedba..ba4aff5 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -77,7 +77,8 @@ class Utils(object): for old_name, new_name in dic_names.items(): if old_name in handler.variables: - handler.renameVariable(old_name, new_name) + if new_name not in handler.variables: + handler.renameVariable(old_name, new_name) elif must_exist: raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) @@ -119,11 +120,12 @@ class Utils(object): process = subprocess.Popen(command, stdout=subprocess.PIPE) output = list() comunicate = process.communicate() - for line in comunicate: - if not line: - continue - Log.log.log(log_level, line) - output.append(line) + if log_level != Log.NO_LOG: + for line in comunicate: + if not line: + continue + Log.log.log(log_level, line) + output.append(line) if process.returncode != 0: raise Exception('Error executing {0}\n Return code: {1}', ' '.join(command), process.returncode) return output -- GitLab From dca746027844157a4d6c749637939c318e165b84 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 20 May 2016 17:41:56 +0200 Subject: [PATCH 061/268] Updated ohc_layer to avoid time splitting --- earthdiagnostics/datamanager.py | 121 ++++++++++++++++++++++++-- earthdiagnostics/diags.conf | 28 +++--- earthdiagnostics/diags.py | 17 +++- earthdiagnostics/ocean/circulation.py | 1 + earthdiagnostics/ocean/general.py | 54 ++++++------ earthdiagnostics/ocean/heat.py | 112 +++++++++++------------- testing_diags_moore.job | 17 ++++ 7 files changed, 241 insertions(+), 109 deletions(-) create mode 100755 testing_diags_moore.job diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index e6c3745..a946a3e 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,3 +1,4 @@ +import glob import os from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day @@ -7,25 +8,36 @@ from earthdiagnostics import Utils class DataManager(object): - def __init__(self, institution, model, expid, datafolder, frequency, chunk_size): + def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name): self.institution = institution self.model = model self.expid = expid self.data_dir = datafolder self.frequency = frequency self.chunk_size = chunk_size + self.experiment_name = experiment_name + self.add_startdate = True + self.add_name = True + + + + # noinspection PyPep8Naming def prepare_CMOR_files(self, startdates, members): # Check if cmorized and convert if not if not os.path.exists(os.path.join(self.data_dir, self.expid)): - raise Exception('The experiment {0} is not CMORized. Please, CMORize it and launch again.'.format(self.expid)) + raise Exception('The experiment {0} is not CMORized. ' + 'Please, CMORize it and launch again.'.format(self.expid)) for startdate in startdates: for member in members: member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') if not os.path.exists(os.path.join(member_path, 'output')): - Utils.execute_shell_command('gunzip {0}'.format(os.path.join(member_path, '*.gz'))) - Utils.execute_shell_command('tar -xvf {0}'.format(os.path.join(member_path, '*.tar'))) + Log.info('Unpacking CMOR files for startdate {0} and member {1}'.format(startdate, member)) + for filepath in glob.glob(os.path.join(member_path, '*.gz')): + Utils.execute_shell_command('gunzip {0}'.format(filepath)) + for filepath in glob.glob(os.path.join(member_path, '*.tar')): + Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) def get_files(self, startdate, member, chunk, domain, variables): @@ -39,19 +51,30 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', - self.institution, self.model, self.model, 'S' + startdate, self.frequency, + self.institution, self.model, self.experiment_name, 'S' + startdate, self.frequency, domain) chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') + if self.add_startdate: + str_date = 'S' + startdate + '_' + else: + str_date = '' + + if self.add_name: + str_name = self.experiment_name + '_' + else: + str_name = 'output_' + var_file = list() for var in variables: var_file.append(os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus), - '{0}_{1}{2}_{3}_output_r{4}i1p1_' - '{5}-{6}.nc'.format(var, domain_abreviattion, - self.frequency, self.model, member_plus, + '{0}_{1}{2}_{3}_{4}{5}r{6}i1p1_' + '{7}-{8}.nc'.format(var, domain_abreviattion, + self.frequency, self.model, str_name, str_date, + member_plus, "{0:04}{1:02}".format(chunk_start.year, chunk_start.month), "{0:04}{1:02}".format(chunk_end.year, @@ -59,3 +82,85 @@ class DataManager(object): file_names.append(var_file) return file_names + + +# +# set -vx +# +# exp=a034 +# dir=/group_workspaces/jasmin2/primavera1/WP2/CPL/EC-EARTH3.1/HIST_T511ORCA025 +# res=$( echo $dir | cut -f3 -d"_" ) +# model=$(echo $dir | cut -f7 -d"/" ) +# +# cd /esnas/exp/ecearth/$exp/ +# +# for sd in [1-2]* +# do +# cd /esnas/exp/ecearth/$exp/$sd +# for fc in * +# do +# cd /esnas/exp/ecearth/$exp/$sd/$fc/outputs +# realization=$(( $(echo $fc | cut -c 3-) + 1 )) +# outdir=/esnas/exp/ecearth/$exp/$sd/$fc/outputs/primavera +# mkdir -p $outdir +# for tarfile in MMO*tar +# do +# lt=$(echo $tarfile | cut -f 5-6 -d"_" | cut -f1 -d"." ) +# tar kxvf $tarfile -C $outdir +# cd $outdir +# for file in ${exp}_1m_*grid*gz ${exp}_*icemod*gz +# do +# echo $file +# gunzip $file +# for var in $( cdo showvar ${file%???} ) +# do +# varnew="" +# case $var in +# votemper) varnew=thetao; realm=Omon ; modeling_realm="ocean" ; units="C";; +# vosaline) varnew=so; realm=Omon ; modeling_realm="ocean" ;; +# sosstsst) varnew=tos; realm=Omon ; modeling_realm="ocean" ; units="C";; +# sosaline) varnew=sos; realm=Omon ; modeling_realm="ocean" ;; +# sossheig) varnew=zos; realm=Omon ; modeling_realm="ocean" ;; +# vozocrtx) varnew=uo; realm=Omon ; modeling_realm="ocean" ;; +# vomecrty) varnew=vo; realm=Omon ; modeling_realm="ocean" ;; +# iiceconc) varnew=sic; realm=OImon ; modeling_realm="seaIce" ;; +# iicethic) varnew=sit; realm=OImon ; modeling_realm="seaIce" ;; +# isnowthi) varnew=snd; realm=OImon ; modeling_realm="seaIce" ;; +# iicesurt) varnew=tsice; realm=OImon ; modeling_realm="seaIce" ; units="C";; +# esac +# outfile=$(echo ${varnew}_${realm}_${model}_${res}_BSC_${realization}_${lt}.nc ) +# if [[ ! -z $varnew ]] && [[ ! -f ${outdir}/${outfile} ]]; then #check if var belongs to list +# cdo selvar,$var ${file%???} ${outdir}/$outfile +# ncrename -v .time_counter,time -d time_counter,time -v nav_lon,longitude -v nav_lat,latitude -v .${var},${varnew} ${outdir}/${outfile} +# for att in institution institute_id experiment_id model_id contact experiment frequency creation_date project_id modeling_realm realization +# do +# case $att in +# institution) att_val="Barcelona Supercomputing Center - Centro Nacional de Supercomputacion" ;; +# institute_id) att_val="BSC-CNS" ;; +# experiment_id) att_val=$(echo $dir | cut -f7 -d"/") ;; +# model_id) att_val="$model" ;; +# contact) att_val="pierre-antoine.bretonniere@bsc.es" ;; +# experiment) att_val=$(echo $dir | cut -f7 -d"/") ;; +# frequency) att_val="mon" ;; +# creation_date) att_val="$(echo $(date --rfc-3339=seconds | cut -f1 -d"+" | sed -e 's/ /T/')Z)" ;; +# project_id) att_val="PRIMAVERA" ;; +# modeling_realm) att_val="$modeling_realm" ;; +# realization) att_val="$realization" ;; +# esac +# ncatted -O -h -a ${att},global,c,c,"${att_val}" ${outdir}/$outfile +# if [[ "$units" == "C" ]]; then +# cdo addc,273.25 ${outdir}/$outfile ${outdir}/${outfile}.tmp +# mv ${outdir}/${outfile}.tmp ${outdir}/${outfile} +# ncatted -O -h -a units,${varnew},m,c,"K" ${outdir}/$outfile +# fi #temp from C to K +# done #attributes +# fi +# done #var +# rm ${file%???} +# done #file +# cd /esnas/exp/ecearth/$exp/$sd/$fc/outputs +# done #tarfile +# scp -i ~/.ssh/id_rsa_jasmin ${outdir}/*Omon*nc pabretonniere@jasmin-xfer1.ceda.ac.uk:$dir/. +# scp -i ~/.ssh/id_rsa_jasmin ${outdir}/*OImon*nc pabretonniere@jasmin-xfer1.ceda.ac.uk:$dir/. +# done #fc +# done #sd diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 3a14262..bb7d6f0 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,23 +2,14 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = 3DTEMP 3DSAL +DIAGS = OHC_SPECIFIED_LAYER FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin -# [EXPERIMENT] -# INSTITUTE = IC3 -# EXPID = m02 -# STARTDATES = 19900101 -# CHUNK_SIZE = 3 -# CHUNKS = 1 -# MEMBERS = 0 -# MODEL = EC-EARTH3 -# NEMO_VERSION = Ec3.0_O1L46 - [EXPERIMENT] INSTITUTE = IC3 EXPID = a030 +NAME = EC-EARTH3 STARTDATES = 19900101 CHUNK_SIZE = 3 CHUNKS = 1 @@ -26,6 +17,21 @@ MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 +[CMOR] +ADD_STARTDATE = False +ADD_NAME = False + +# [EXPERIMENT] +# INSTITUTE = IC3 +# EXPID = m04s +# NAME = horizlResImpact_series2 +# STARTDATES = 19930501 +# CHUNK_SIZE = 4 +# CHUNKS = 1 +# MEMBERS = 0 1 2 3 4 +# MODEL = EC-EARTH3 +# NEMO_VERSION = Ec3.0_O25L75 + [ALIAS] MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 AREA_MOC = mocarea,40,55,1000,2000,atl mocarea,30,40,1000,2000,atl diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 4bb4b17..0ecb74f 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -24,7 +24,9 @@ class Diags: Log.debug('Initialising Diags') self._read_config(config_file) self.datamanager = DataManager(self.institute, self.model, self.expid, self.data_dir, - self.frequency, self.chunk_size) + self.frequency, self.chunk_size, self.experiment_name) + self.datamanager.add_startdate = self.add_startdate + self.datamanager.add_name = self.add_name TempFile.scratch_folder = self.scratch_dir cdftools.path = self.cdftools_path self._create_dic_variables() @@ -89,12 +91,13 @@ class Diags: for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): General.vertical_mean(input_file, output_file, variable, lev_min, lev_max) elif diag == 'convection': - variables = ('mlotst','mlotstsites') + variables = ('mlotst', 'mlotstsites') for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.convection_sites(input_file, self.nemo_version, output_file) elif diag == 'psi': variables = ('uo', 'vo', 'msftbarot') - for [u_file, v_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [u_file, v_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', + variables): Circulation.psi(u_file, v_file, output_file) elif diag == 'gyres': variables = ('msftbarot', 'msftbarotgyres') @@ -172,7 +175,9 @@ class Diags: variables): Heat.mixed_layer_content(input_file, mlotst_file, output_file) elif diag == 'mlotstsc': - for [input_file, mlotst_file, output_file] in self._get_file_names('ocean', 'so', 'mlotst', 'mlotstsc'): + variables = ('so', 'mlotst', 'mlotstsc') + for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', + variables): Salinity.mixed_layer_content(input_file, mlotst_file, output_file) elif diag == 'interp3d': variable = diag_options[1] @@ -284,6 +289,7 @@ class Diags: # Read experiment config self.institute = self.parser.get_option('EXPERIMENT', 'INSTITUTE') self.expid = self.parser.get_option('EXPERIMENT', 'EXPID') + self.experiment_name = self.parser.get_option('EXPERIMENT', 'NAME') self.members = list() for member in self.parser.get_option('EXPERIMENT', 'MEMBERS').split(): @@ -295,6 +301,9 @@ class Diags: self.model = self.parser.get_option('EXPERIMENT', 'MODEL') self.nemo_version = self.parser.get_option('EXPERIMENT', 'NEMO_VERSION') + self.add_name = self.parser.get_bool_option('CMOR', 'ADD_NAME') + self.add_startdate = self.parser.get_bool_option('CMOR', 'ADD_STARTDATE') + # Read aliases self._aliases = dict() if self.parser.has_section('ALIAS'): diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index b37fb20..5582069 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -150,6 +150,7 @@ class Circulation(object): Created in March 2012 Author : vguemas@ic3.cat + :param basin: basin :param input_file: input moc file name :param lat_min: latitude min :param lat_max: latitude max diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 624e587..5cbedbf 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -69,9 +69,11 @@ class General(object): handler = cdo.openCdf(temp) threads = list() - lock = threading.Lock() - for lev in range(0, handler.dimensions['lev'].size): - t = threading.Thread(target=General._interpolate_level, args=(lev, temp, variable, nemo_version, lock)) + numthreads = 8 + for numthread in range(0, numthreads): + t = threading.Thread(target=General._interpolate_level, + args=(range(numthread, handler.dimensions['lev'].size, numthreads), temp, variable, + nemo_version)) threads.append(t) t.start() @@ -95,28 +97,30 @@ class General(object): Utils.move_file(temp, output_file) @staticmethod - def _interpolate_level(lev, input_file, variable, nemo_version, lock): - nco = Utils.nco - temp2 = TempFile.get() - nco.ncks(input=input_file, output=temp2, options='-O -d lev,{0} -v {1}'.format(lev, variable)) - nco.ncwa(input=temp2, output=temp2, options='-O -h -a lev') - namelist_file = 'scrip_use_in{0}'.format(lev) - scrip_use_in = open(namelist_file, 'w') - scrip_use_in.writelines("&remap_inputs\n") - scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" - "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(nemo_version, lev+1)) - scrip_use_in.writelines(" infile = '{0}'\n".format(temp2)) - scrip_use_in.writelines(" invertlat = FALSE\n") - scrip_use_in.writelines(" var = '{0}'\n".format(variable)) - scrip_use_in.writelines(" fromregular = FALSE\n") - scrip_use_in.writelines(" outfile = '{0}'\n".format(temp2)) - scrip_use_in.writelines("/\n") - scrip_use_in.close() - Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use {0}'.format(namelist_file), Log.NO_LOG) - os.remove(namelist_file) - nco.ncecat(input=temp2, output=temp2, options="-O -h") - shutil.move(temp2, 'tmp_{0:02d}.nc'.format(lev+1)) - Log.debug("Level {0} ready", lev) + def _interpolate_level(levs, input_file, variable, nemo_version): + for lev in levs: + nco = Utils.nco + temp2 = TempFile.get() + nco.ncks(input=input_file, output=temp2, options='-O -d lev,{0} -v {1}'.format(lev, variable)) + nco.ncwa(input=temp2, output=temp2, options='-O -h -a lev') + namelist_file = 'scrip_use_in{0}'.format(lev) + scrip_use_in = open(namelist_file, 'w') + scrip_use_in.writelines("&remap_inputs\n") + scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" + "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(nemo_version, lev+1)) + scrip_use_in.writelines(" infile = '{0}'\n".format(temp2)) + scrip_use_in.writelines(" invertlat = FALSE\n") + scrip_use_in.writelines(" var = '{0}'\n".format(variable)) + scrip_use_in.writelines(" fromregular = FALSE\n") + scrip_use_in.writelines(" outfile = '{0}'\n".format(temp2)) + scrip_use_in.writelines("/\n") + scrip_use_in.close() + Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use ' + '{0}'.format(namelist_file), Log.NO_LOG) + os.remove(namelist_file) + nco.ncecat(input=temp2, output=temp2, options="-O -h") + shutil.move(temp2, 'tmp_{0:02d}.nc'.format(lev+1)) + Log.debug("Level {0} ready", lev) @staticmethod def cut_section(input_file, output_file, variable, zonal, value): diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 0399b9a..2d95aa0 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -73,7 +73,7 @@ class Heat(object): nco = Utils.nco - input_scratch = TempFile.get() + temp = TempFile.get() heatc_sl_out = TempFile.get() heatc_sl_top = TempFile.get() level_above = TempFile.get() @@ -85,68 +85,58 @@ class Heat(object): nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*e3t"'), - shutil.copy(input_file, input_scratch) + shutil.copy(input_file, temp) - ntime = int(cdo.ntime(input=input_scratch)[0]) + Utils.rename_variable(temp, 'thetao', 'heatc_sl') - for time in range(ntime): - Log.info('Running time {0}', time) - temp = TempFile.get() - nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) - Utils.rename_variable(temp, 'thetao', 'heatc_sl') - - nco.ncks(input=temp, output=temp, options='-O -v heatc_sl') - cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) - - # extract the data between the two given depths --> heatc_sl_top.nc - nco.ncks(input=heatc_sl_out, output=heatc_sl_top, - options='-O -d lev,{0}.0,{1}.0'.format(min_depth, max_depth)) - - # now extract a few levels below, to compute the residual ohc - # addition with float returned: - nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, - options='-O -d lev,{0}.0,{1}.0'.format(max_depth, max_depth+200)) - - # obtain the weight for the extra level containing the 300 m - # deptht in the gridT files is positive - # weight = (300.0 - depth_top)/(depth_bottom - depth_top) - # and add the thickness down to 300 m in the next layer - nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) - nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') - nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') - - handler = nco.openCdf(level_above) - lev_above = handler.variables['lev'][:] - handler.close() - - handler = nco.openCdf(level_below) - layerthcknss = handler.variables['lev'][:] - lev_above - heatc_sl_below = handler.variables['heatc_sl'][:] - handler.close() - - factor = (max_depth - lev_above) / layerthcknss - - heatc_sl_below = heatc_sl_below * factor - handler = nco.openCdf(heatc_sl_top) - heatc_sl = handler.variables['heatc_sl'][:] - handler.close() - - heatc_sl = np.sum(heatc_sl, 1) - heatc_sl = heatc_sl[:] + heatc_sl_below[:] - heatc_sl = heatc_sl[0, 0, :] * 1020 * 4000 - - if time == 0: - nco.ncks(input=heatc_sl_top_invert, output=results, options='-O -v lon,lat') - nco.ncks(input=input_scratch, output=results, options='-A -v time') - handler_results = nco.openCdf(results) - # handler_results.renameDimension('x', 'i') - # handler_results.renameDimension('y', 'j') - handler_results.createVariable('ohc', float, ('time', 'y', 'x')) - handler_results.close() - - handler_results = nco.openCdf(results) - handler_results.variables['ohc'][time, :] = heatc_sl - handler_results.close() + nco.ncks(input=temp, output=temp, options='-O -v heatc_sl') + cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) + + # extract the data between the two given depths --> heatc_sl_top.nc + nco.ncks(input=heatc_sl_out, output=heatc_sl_top, + options='-O -d lev,{0}.0,{1}.0'.format(min_depth, max_depth)) + + # now extract a few levels below, to compute the residual ohc + # addition with float returned: + nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, + options='-O -d lev,{0}.0,{1}.0'.format(max_depth, max_depth+200)) + + # obtain the weight for the extra level containing the 300 m + # deptht in the gridT files is positive + # weight = (300.0 - depth_top)/(depth_bottom - depth_top) + # and add the thickness down to 300 m in the next layer + nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) + nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') + nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') + + handler = nco.openCdf(level_above) + lev_above = handler.variables['lev'][:] + handler.close() + + handler = nco.openCdf(level_below) + layerthcknss = handler.variables['lev'][:] - lev_above + heatc_sl_below = handler.variables['heatc_sl'][:] + handler.close() + + factor = (max_depth - lev_above) / layerthcknss + + heatc_sl_below = heatc_sl_below * factor + handler = nco.openCdf(heatc_sl_top) + heatc_sl = handler.variables['heatc_sl'][:] + handler.close() + + heatc_sl = np.sum(heatc_sl, 1) + heatc_sl = heatc_sl[:] + heatc_sl_below[:, 0, :] + heatc_sl = heatc_sl[:] * 1020 * 4000 + + nco.ncks(input=heatc_sl_top_invert, output=results, options='-O -v lon,lat,time') + handler_results = nco.openCdf(results) + handler_results.createVariable('ohc', float, ('time', 'y', 'x')) + handler_results.close() + + handler_results = nco.openCdf(results) + handler_results.variables['ohc'][:] = heatc_sl + handler_results.close() Utils.setminmax(results, 'ohc') Utils.move_file(results, output_file) diff --git a/testing_diags_moore.job b/testing_diags_moore.job new file mode 100755 index 0000000..06a0aaa --- /dev/null +++ b/testing_diags_moore.job @@ -0,0 +1,17 @@ +#!/bin/bash +#SBATCH --time=24:00:00 +#SBATCH -n 2 +#SBATCH -N 1 +#SBATCH --error=/home/Earth/jvegas/job.%J.err +#SBATCH --output=/home/Earth/jvegas/job.%J.out + +module load NCO/4.5.4-foss-2015a +module load CDO +module load CDFTOOLS/3.0-foss-2015a + +source /home/Earth/jvegas/virtualenvs/diags/bin/activate + +export PYTHONPATH=$PYTHONPATH/home/Earth/jvegas/pyCharm/ocean_diagnostics/: + +cd /home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/ +./diags.py -lc DEBUG \ No newline at end of file -- GitLab From f4d220db453381c32da48348013a5df01d736bc1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 24 May 2016 10:03:36 +0200 Subject: [PATCH 062/268] Fixed bug on TempFile --- earthdiagnostics/utils.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index ba4aff5..ddd6fe2 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -1,6 +1,7 @@ import subprocess import numpy as np +import re from autosubmit.config.log import Log from cdo import Cdo from nco import Nco @@ -154,6 +155,32 @@ class Utils(object): direction = 'E' return str(abs(value)) + direction + _cpu_count = None + + @staticmethod + def available_cpu_count(): + """ Number of available virtual or physical CPUs on this system, i.e. + user/real as output by time(1) when called with an optimally scaling + userspace-only program""" + if Utils._cpu_count is None: + try: + m = re.search(r'(?m)^Cpus_allowed:\s*(.*)$', + open('/proc/self/status').read()) + if m: + res = bin(int(m.group(1).replace(',', ''), 16)).count('1') + if res > 0: + Utils._cpu_count = res + except IOError: + try: + import multiprocessing + Utils._cpu_count = multiprocessing.cpu_count() + return Utils._cpu_count + except (ImportError, NotImplementedError): + Utils._cpu_count = -1 + Log.info('Available cores: {0}', Utils._cpu_count) + return Utils._cpu_count + + class TempFile(object): """ @@ -195,7 +222,8 @@ class TempFile(object): if filename: path = os.path.join(TempFile.scratch_folder, filename) else: - path = tempfile.mkstemp(dir=TempFile.scratch_folder, prefix=TempFile.prefix, suffix='.nc')[1] + fd, path = tempfile.mkstemp(dir=TempFile.scratch_folder, prefix=TempFile.prefix, suffix='.nc') + os.close(fd) if clean: TempFile.files.append(path) -- GitLab From a2ec0c982884e32a77c9b549bb2df9f2430f91d3 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 24 May 2016 10:04:32 +0200 Subject: [PATCH 063/268] Added grid folder to be used for interpolation (as it is intended to be part of new CMOR specification) --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/datamanager.py | 101 +++++++++++++++++++------- earthdiagnostics/diags.conf | 14 ++-- earthdiagnostics/diags.py | 7 +- earthdiagnostics/ocean/circulation.py | 1 - earthdiagnostics/ocean/general.py | 26 ++++--- 6 files changed, 101 insertions(+), 50 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index a57ebce..14676e8 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('TSec_ave190-220E SSec_ave190-220E') +listpost=('max_moc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index a946a3e..626c4e9 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,4 +1,7 @@ import glob +import shutil +import threading + import os from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day @@ -19,9 +22,6 @@ class DataManager(object): self.add_startdate = True self.add_name = True - - - # noinspection PyPep8Naming def prepare_CMOR_files(self, startdates, members): # Check if cmorized and convert if not @@ -32,14 +32,70 @@ class DataManager(object): for startdate in startdates: for member in members: member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') - if not os.path.exists(os.path.join(member_path, 'output')): - Log.info('Unpacking CMOR files for startdate {0} and member {1}'.format(startdate, member)) - for filepath in glob.glob(os.path.join(member_path, '*.gz')): - Utils.execute_shell_command('gunzip {0}'.format(filepath)) - for filepath in glob.glob(os.path.join(member_path, '*.tar')): - Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) - - def get_files(self, startdate, member, chunk, domain, variables): + Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) + + threads = list() + numthreads = Utils.available_cpu_count() + filepaths = glob.glob(os.path.join(member_path, '*.gz')) + for numthread in range(0, numthreads): + t = threading.Thread(target=DataManager._unzip, + args=([filepaths[numthread::numthreads]])) + threads.append(t) + t.start() + + for t in threads: + t.join() + + filepaths = glob.glob(os.path.join(member_path, '*.tar')) + for numthread in range(0, numthreads): + t = threading.Thread(target=DataManager._untar, + args=(filepaths[numthread::numthreads], member_path)) + threads.append(t) + t.start() + + for t in threads: + t.join() + + if self.experiment_name != self.model: + bad_path = os.path.join(member_path, 'output', self.institution, self.model, self.model) + for (dirpath, dirnames, filenames) in os.walk(bad_path, False): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_output_'.format(self.model), + '_{0}_{1}_'.format(self.model, self.experiment_name)) + + good = good.replace('/{0}/{0}'.format(self.model), + '/{0}/{1}'.format(self.model, + self.experiment_name)) + + Utils.move_file(filepath, good) + os.rmdir(dirpath) + + good_dir = os.path.join(member_path, 'output', self.institution, self.model, self.experiment_name) + for sdate in os.listdir(good_dir): + for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name,sdate), + '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) + if good != filepath: + Log.info('Moving {0} to {1}'.format(filename, good)) + Utils.move_file(filepath, good) + + @staticmethod + def _unzip(files): + for filepath in files: + Log.debug('Unzipping {0}', filepath) + Utils.execute_shell_command('gunzip {0}'.format(filepath)) + + @staticmethod + def _untar(files, member_path): + for filepath in files: + Log.debug('Unpacking {0}', filepath) + Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) + os.remove(filepath) + + def get_files(self, startdate, member, chunk, domain, variables, grid=None): file_names = list() @@ -58,23 +114,18 @@ class DataManager(object): chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') - if self.add_startdate: - str_date = 'S' + startdate + '_' - else: - str_date = '' - - if self.add_name: - str_name = self.experiment_name + '_' - else: - str_name = 'output_' - var_file = list() for var in variables: - var_file.append(os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus), - '{0}_{1}{2}_{3}_{4}{5}r{6}i1p1_' + if grid: + var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) + else: + var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) + + var_file.append(os.path.join(var_path, + '{0}_{1}{2}_{3}_{4}_S{5}_r{6}i1p1_' '{7}-{8}.nc'.format(var, domain_abreviattion, - self.frequency, self.model, str_name, str_date, - member_plus, + self.frequency, self.model, self.experiment_name, + startdate, member_plus, "{0:04}{1:02}".format(chunk_start.year, chunk_start.month), "{0:04}{1:02}".format(chunk_end.year, diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index bb7d6f0..79b35c7 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,25 +2,21 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = OHC_SPECIFIED_LAYER +DIAGS = 3dsal FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin [EXPERIMENT] INSTITUTE = IC3 -EXPID = a030 -NAME = EC-EARTH3 -STARTDATES = 19900101 +EXPID = a034 +STARTDATES = 19500201 +NAME = historical CHUNK_SIZE = 3 -CHUNKS = 1 +CHUNKS = 256 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 -[CMOR] -ADD_STARTDATE = False -ADD_NAME = False - # [EXPERIMENT] # INSTITUTE = IC3 # EXPID = m04s diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 0ecb74f..4c76448 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -181,9 +181,10 @@ class Diags: Salinity.mixed_layer_content(input_file, mlotst_file, output_file) elif diag == 'interp3d': variable = diag_options[1] - variables = (variable, '{0}interp'.format(variable)) - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): - General.interpolate3d(input_file, output_file, variable, self.nemo_version) + input_files = self.datamanager.get_files(startdate, member, chunk, 'ocean', [variable]) + output_files = self.datamanager.get_files(startdate, member, chunk, 'ocean', [variable], 'regular') + for x in range(0, len(input_files[0])): + General.interpolate3d(input_files[0][x], output_files[0][x], variable, self.nemo_version) elif diag == 'cutsection': variable = diag_options[1] zonal = diag_options[2] == 'z' diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 5582069..8d7354c 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -218,7 +218,6 @@ class Circulation(object): minimum_index = np.unravel_index(np.argmin(moc), moc.shape) min_lev = handler.variables['lev'][minimum_index[1]] min_lat = handler.variables['lat'][minimum_index[2]] - handler.close() Log.info('Maximum {0} Sv, latitude {1} depth {2} m', maximum, max_lat, max_lev) diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 5cbedbf..f8658e8 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -67,12 +67,15 @@ class General(object): cdo = Utils.cdo nco = Utils.nco handler = cdo.openCdf(temp) + num_levels = handler.dimensions['lev'].size + handler.close() threads = list() - numthreads = 8 + numthreads = Utils.available_cpu_count() + for numthread in range(0, numthreads): t = threading.Thread(target=General._interpolate_level, - args=(range(numthread, handler.dimensions['lev'].size, numthreads), temp, variable, + args=(range(numthread, num_levels, numthreads), temp, variable, nemo_version)) threads.append(t) t.start() @@ -81,9 +84,9 @@ class General(object): t.join() nco.ncrcat(input='tmp_01.nc', output=temp2, - options='-n {0},2,1 -v {1}'.format(handler.dimensions['lev'].size, variable)) + options='-n {0},2,1 -v {1}'.format(num_levels, variable)) - for lev in range(0, handler.dimensions['lev'].size): + for lev in range(0, num_levels): os.remove('tmp_{0:02d}.nc'.format(lev+1)) handler = nco.openCdf(temp2) handler.renameDimension('record', 'lev') @@ -94,32 +97,33 @@ class General(object): cdo.setgrid('t106grid', input=temp2, output=temp) if nemo_version[6:9] == '025': cdo.invertlatdata(input=temp, output=temp) + os.remove(temp2) Utils.move_file(temp, output_file) @staticmethod def _interpolate_level(levs, input_file, variable, nemo_version): for lev in levs: nco = Utils.nco - temp2 = TempFile.get() - nco.ncks(input=input_file, output=temp2, options='-O -d lev,{0} -v {1}'.format(lev, variable)) - nco.ncwa(input=temp2, output=temp2, options='-O -h -a lev') + temp = TempFile.get() + nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1}'.format(lev, variable)) + nco.ncwa(input=temp, output=temp, options='-O -h -a lev') namelist_file = 'scrip_use_in{0}'.format(lev) scrip_use_in = open(namelist_file, 'w') scrip_use_in.writelines("&remap_inputs\n") scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(nemo_version, lev+1)) - scrip_use_in.writelines(" infile = '{0}'\n".format(temp2)) + scrip_use_in.writelines(" infile = '{0}'\n".format(temp)) scrip_use_in.writelines(" invertlat = FALSE\n") scrip_use_in.writelines(" var = '{0}'\n".format(variable)) scrip_use_in.writelines(" fromregular = FALSE\n") - scrip_use_in.writelines(" outfile = '{0}'\n".format(temp2)) + scrip_use_in.writelines(" outfile = '{0}'\n".format(temp)) scrip_use_in.writelines("/\n") scrip_use_in.close() Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use ' '{0}'.format(namelist_file), Log.NO_LOG) os.remove(namelist_file) - nco.ncecat(input=temp2, output=temp2, options="-O -h") - shutil.move(temp2, 'tmp_{0:02d}.nc'.format(lev+1)) + nco.ncecat(input=temp, output=temp, options="-O -h") + shutil.move(temp, 'tmp_{0:02d}.nc'.format(lev + 1)) Log.debug("Level {0} ready", lev) @staticmethod -- GitLab From 899f5fbfa0a5d18601cb56c017366a03ef966bed Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 26 May 2016 16:19:46 +0200 Subject: [PATCH 064/268] Generalized interpolation so it can be use with 2D variables --- earthdiagnostics/diags.conf | 6 ++--- earthdiagnostics/diags.py | 14 +++++++---- earthdiagnostics/ocean/general.py | 39 ++++++++++++++++++++++--------- earthdiagnostics/utils.py | 1 - 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 79b35c7..594b609 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = 3dsal +DIAGS = interp,sic,seaIce FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -41,8 +41,8 @@ LOHC = ohc,glob,0,23,46 MOHC = ohc,glob,0,18,22 UOHC = ohc,glob,0,0,17 OHC_SPECIFIED_LAYER = ohclayer,0,300 ohclayer,300,800 -3DTEMP = interp3d,thetao -3DSAL = interp3d,so +3DTEMP = interp,thetao +3DSAL = interp,so TSEC_AVE190-220E =avgsection,thetaointerp,190,220,-90,90 SSEC_AVE190-220E =avgsection,sointerp,190,220,-90,90 VERT_SSECTIONS = cutsection,so,Z,0 cutsection,so,Z,45 cutsection,so,Z,-45 cutsection,so,M,-30 cutsection,so,M,180 cutsection,so,M,80 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 4c76448..7096731 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -179,12 +179,18 @@ class Diags: for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Salinity.mixed_layer_content(input_file, mlotst_file, output_file) - elif diag == 'interp3d': + elif diag == 'interp': variable = diag_options[1] - input_files = self.datamanager.get_files(startdate, member, chunk, 'ocean', [variable]) - output_files = self.datamanager.get_files(startdate, member, chunk, 'ocean', [variable], 'regular') + if len(diag_options) == 3: + domain = diag_options[2] + if domain == 'seaice': + domain = 'seaIce' + else: + domain = 'ocean' + input_files = self.datamanager.get_files(startdate, member, chunk, domain, [variable]) + output_files = self.datamanager.get_files(startdate, member, chunk, domain, [variable], 'regular') for x in range(0, len(input_files[0])): - General.interpolate3d(input_files[0][x], output_files[0][x], variable, self.nemo_version) + General.interpolate(input_files[0][x], output_files[0][x], variable, self.nemo_version) elif diag == 'cutsection': variable = diag_options[1] zonal = diag_options[2] == 'z' diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index f8658e8..5b0be21 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -48,7 +48,7 @@ class General(object): Utils.move_file(temp2, output_file) @staticmethod - def interpolate3d(input_file, output_file, variable, nemo_version): + def interpolate(input_file, output_file, variable, nemo_version): """ 3-dimensional conservative interpolation to the regular atmospheric grid @@ -67,7 +67,12 @@ class General(object): cdo = Utils.cdo nco = Utils.nco handler = cdo.openCdf(temp) - num_levels = handler.dimensions['lev'].size + if 'lev' in handler.dimensions: + num_levels = handler.dimensions['lev'].size + has_levels = True + else: + num_levels = 1 + has_levels = False handler.close() threads = list() @@ -75,38 +80,50 @@ class General(object): for numthread in range(0, numthreads): t = threading.Thread(target=General._interpolate_level, - args=(range(numthread, num_levels, numthreads), temp, variable, + args=(range(numthread, num_levels, numthreads),has_levels, temp, variable, nemo_version)) threads.append(t) t.start() for t in threads: t.join() + if has_levels: + nco.ncrcat(input='tmp_01.nc', output=temp2, + options='-n {0},2,1 -v {1}'.format(num_levels, variable)) - nco.ncrcat(input='tmp_01.nc', output=temp2, - options='-n {0},2,1 -v {1}'.format(num_levels, variable)) + else: + Utils.move_file('tmp_01.nc', temp2) - for lev in range(0, num_levels): - os.remove('tmp_{0:02d}.nc'.format(lev+1)) handler = nco.openCdf(temp2) handler.renameDimension('record', 'lev') handler.close() nco.ncpdq(input=temp2, output=temp2, options='-O -h -a time,lev') - nco.ncks(input=temp, output=temp2, options='-A -v lev') + + if has_levels: + nco.ncks(input=temp, output=temp2, options='-A -v lev') + for lev in range(0, num_levels): + os.remove('tmp_{0:02d}.nc'.format(lev + 1)) cdo.setgrid('t106grid', input=temp2, output=temp) if nemo_version[6:9] == '025': cdo.invertlatdata(input=temp, output=temp) + if not has_levels: + nco.ncks(input=temp, output=temp, options='-O -v sic,lat,lon,time') + Utils.rename_variables(temp, {'x': 'i', 'y': 'j'}, False, True) + os.remove(temp2) Utils.move_file(temp, output_file) @staticmethod - def _interpolate_level(levs, input_file, variable, nemo_version): + def _interpolate_level(levs, has_levels, input_file, variable, nemo_version): for lev in levs: nco = Utils.nco temp = TempFile.get() - nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1}'.format(lev, variable)) - nco.ncwa(input=temp, output=temp, options='-O -h -a lev') + if has_levels: + nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1}'.format(lev, variable)) + nco.ncwa(input=temp, output=temp, options='-O -h -a lev') + else: + shutil.copy(input_file, temp) namelist_file = 'scrip_use_in{0}'.format(lev) scrip_use_in = open(namelist_file, 'w') scrip_use_in.writelines("&remap_inputs\n") diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index ddd6fe2..8487a5e 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -181,7 +181,6 @@ class Utils(object): return Utils._cpu_count - class TempFile(object): """ Class to manage temporal files -- GitLab From 52fd8cf6077e59dbeffb0aab018f81986d1cc9ac Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 27 May 2016 17:42:07 +0200 Subject: [PATCH 065/268] Fix for 2D vars interpolation --- earthdiagnostics/ocean/general.py | 1 - 1 file changed, 1 deletion(-) diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 5b0be21..d45ad46 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -109,7 +109,6 @@ class General(object): cdo.invertlatdata(input=temp, output=temp) if not has_levels: nco.ncks(input=temp, output=temp, options='-O -v sic,lat,lon,time') - Utils.rename_variables(temp, {'x': 'i', 'y': 'j'}, False, True) os.remove(temp2) Utils.move_file(temp, output_file) -- GitLab From 4b65adf2fabf0c7352f9f622d3f16cb9cd9d9cce Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 30 May 2016 14:19:52 +0200 Subject: [PATCH 066/268] Fixed psi. Line pattern was introduced only when using -full option on cdfpsi --- CHANGES | 2 +- common_ocean_post.txt | 6 ++++-- config_file-ocean_pp.bash | 6 +++--- earthdiagnostics/diags.conf | 19 +++++++++++++++---- earthdiagnostics/ocean/circulation.py | 20 +++++++++++++++++++- ocean_pp.bash | 2 +- 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index c7cdfd4..bfcabf5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ 3.0.0 Migration to Python - Move from CDFTools 2.1 to CDFTools 3.0 + Update CDFTools from version 2.1 to 3.0 Adoption of CMOR standard diff --git a/common_ocean_post.txt b/common_ocean_post.txt index 2058dbf..b1c4084 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -636,6 +636,7 @@ function psi { typeset var ntime=`cdo ntime $1` typeset var list="" typeset var jt +ncrename -d .time,time_counter -v .time,time_counter $1 for jt in $(seq 1 $ntime); do cdo seltimestep,$jt $1 intU.nc cdo seltimestep,$jt $2 intV.nc @@ -647,10 +648,11 @@ for jt in $(seq 1 $ntime); do timevar=`ncdump -h psi_$jt.nc | grep UNLIMITED | awk '{print $1}'` if [[ $timevar == 'time_counter' ]] ; then ncrename -v time_counter,time -d time_counter,time psi_$jt.nc ; fi list=$list" "psi_$jt.nc - rm -f intU.nc intV.nc psi_U.nc psi_V.nc + # rm -f intU.nc intV.nc psi_U.nc psi_V.nc done cdo cat $list ${3} -ncks -A -v time $1 ${3} +ncks -A -v time_counter $1 ${3} +ncrename -d .time_counter,time -v .time_counter,time $3 rm -f $list } ############################################################################### diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 14676e8..5371f2b 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('max_moc') +listpost=('psi gyres') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 @@ -14,12 +14,12 @@ mod='ecearth' # nemo / ecearth typeoutput='MMO' # diags / MMO #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ listmemb=( 0 ) # list of members -syeari=1990 # first start date, format "yyyy" +syeari=1990 # first start date, format "yyyy" syearf=1990 # last start date, format "yyyy" moni=01 # first month of the hindcast, format "mm", e.g. 05 for May intsdate=1 # interval between start dates chunklen=3 # length of the chunks (in months) -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< ltime0=1 # first leadtime to post-process ltimef=3 # last leadtime to postprocess # Fill up either ltime0/ltimef or year0/yearf diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 594b609..59654df 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,17 +2,28 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = interp,sic,seaIce +DIAGS = gyres FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin +# [EXPERIMENT] +# INSTITUTE = IC3 +# EXPID = a034 +# STARTDATES = 19500201 +# NAME = historical +# CHUNK_SIZE = 3 +# CHUNKS = 1 +# MEMBERS = 0 +# MODEL = EC-EARTH3 +# NEMO_VERSION = Ec3.0_O1L46 + [EXPERIMENT] INSTITUTE = IC3 -EXPID = a034 -STARTDATES = 19500201 +EXPID = a030 +STARTDATES = 19900101 NAME = historical CHUNK_SIZE = 3 -CHUNKS = 256 +CHUNKS = 1 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 8d7354c..6e9c713 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -286,8 +286,26 @@ class Circulation(object): :param output_file: output file name without nc extension (=> 2D x-y) :rtype output_file: str """ + nco = Utils.nco + cdo = Utils.cdo + ntime = int(cdo.ntime(input=input_file_u)[0]) + files = list() + + temp_uo = TempFile.get() + temp_vo = TempFile.get() + for time in range(ntime): + Log.info('Running time {0}', time) + temp = TempFile.get() + nco.ncks(input=input_file_u, output=temp_uo, options='-O -d time,{0}'.format(time)) + nco.ncks(input=input_file_v, output=temp_vo, options='-O -d time,{0}'.format(time)) + cdftools.run('cdfpsi', input=[temp_uo, temp_vo], output=temp, options='-mean') + files.append(temp) + temp = TempFile.get() - cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-full -mask -mean') + cdo.cat(input=' '.join(files), output=temp) + for file_path in files: + os.remove(file_path) + nco.ncks(input=input_file_u, output=temp, options='-A -v time') Utils.rename_variable(temp, 'sobarstf', 'msftbarot') Utils.setminmax(temp, 'msftbarot') Utils.move_file(temp, output_file) diff --git a/ocean_pp.bash b/ocean_pp.bash index d8e4a14..9d5e5d1 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash set -evx -module load CDFTOOLS/2.1-foss-2015a CDO NCO R +module load CDFTOOLS/3.0-foss-2015a CDO NCO R function delete { at now +7 days << EOF -- GitLab From 3338fb0bb5c79a5bc8e6260af87b99ffe256f830 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 31 May 2016 14:48:21 +0200 Subject: [PATCH 067/268] Minor optimizations --- config_file-ocean_pp.bash | 10 +++++----- earthdiagnostics/diags.conf | 28 +++++++++++++-------------- earthdiagnostics/ocean/circulation.py | 24 +++-------------------- earthdiagnostics/ocean/heat.py | 4 ++-- earthdiagnostics/ocean/salinity.py | 4 ++-- 5 files changed, 26 insertions(+), 44 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 5371f2b..8a31072 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('psi gyres') +listpost=('heat_sal_mxl') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 @@ -9,14 +9,14 @@ level2=14 #If temp_lev or sal_lev is chosen on listpost, the le raw_vars_ocean=( '' ) # If listpost contains "ext_raw_oce" option, this is the list ocean variables you want to extract. If nothing is specified, all variables present in input file will be treated. If raw_vars_ocean='default', sosstsst, sosaline, somixhgt and somxl010 will be extracted. raw_vars_ice=( '' ) # If listpost contains "ext_raw_ice" option, this is the list of seaice variables you want to extract. If nothing is specified, all variables will be treated. If raw_vars_ice='default', isnowthi, iicethic, ileadfra, iicetemp, and ice_pres will be extracted. raw_regions_ice=( 'North_Atlantic_Ocean' ) # If listpost contains "ohc_Arcticreg1" or "siasiesivsit_Arcticreg1" option, this is the list of sea ice regions you want to compute -expid=a030 # expid or nemovar_s4 / nemovar_combine / glorys2v1 +expid=a034 # expid or nemovar_s4 / nemovar_combine / glorys2v1 mod='ecearth' # nemo / ecearth typeoutput='MMO' # diags / MMO #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ listmemb=( 0 ) # list of members -syeari=1990 # first start date, format "yyyy" -syearf=1990 # last start date, format "yyyy" -moni=01 # first month of the hindcast, format "mm", e.g. 05 for May +syeari=1950 # first start date, format "yyyy" +syearf=1950 # last start date, format "yyyy" +moni=02 # first month of the hindcast, format "mm", e.g. 05 for May intsdate=1 # interval between start dates chunklen=3 # length of the chunks (in months) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 59654df..a8f6d81 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,25 +2,14 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = gyres +DIAGS = HEAT_SAL_MXL FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin -# [EXPERIMENT] -# INSTITUTE = IC3 -# EXPID = a034 -# STARTDATES = 19500201 -# NAME = historical -# CHUNK_SIZE = 3 -# CHUNKS = 1 -# MEMBERS = 0 -# MODEL = EC-EARTH3 -# NEMO_VERSION = Ec3.0_O1L46 - [EXPERIMENT] INSTITUTE = IC3 -EXPID = a030 -STARTDATES = 19900101 +EXPID = a034 +STARTDATES = 19500201 NAME = historical CHUNK_SIZE = 3 CHUNKS = 1 @@ -28,6 +17,17 @@ MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 +# [EXPERIMENT] +# INSTITUTE = IC3 +# EXPID = a030 +# STARTDATES = 19900101 +# NAME = historical +# CHUNK_SIZE = 3 +# CHUNKS = 1 +# MEMBERS = 0 +# MODEL = EC-EARTH3 +# NEMO_VERSION = Ec3.0_O1L46 + # [EXPERIMENT] # INSTITUTE = IC3 # EXPID = m04s diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 6e9c713..6b15766 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -286,26 +286,8 @@ class Circulation(object): :param output_file: output file name without nc extension (=> 2D x-y) :rtype output_file: str """ - nco = Utils.nco - cdo = Utils.cdo - ntime = int(cdo.ntime(input=input_file_u)[0]) - files = list() - - temp_uo = TempFile.get() - temp_vo = TempFile.get() - for time in range(ntime): - Log.info('Running time {0}', time) - temp = TempFile.get() - nco.ncks(input=input_file_u, output=temp_uo, options='-O -d time,{0}'.format(time)) - nco.ncks(input=input_file_v, output=temp_vo, options='-O -d time,{0}'.format(time)) - cdftools.run('cdfpsi', input=[temp_uo, temp_vo], output=temp, options='-mean') - files.append(temp) - temp = TempFile.get() - cdo.cat(input=' '.join(files), output=temp) - for file_path in files: - os.remove(file_path) - nco.ncks(input=input_file_u, output=temp, options='-A -v time') + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-mean -mask') Utils.rename_variable(temp, 'sobarstf', 'msftbarot') Utils.setminmax(temp, 'msftbarot') Utils.move_file(temp, output_file) @@ -330,8 +312,8 @@ class Circulation(object): subpolNAtl = [230, 275, 215, 245] subpolNPac = [70, 145, 195, 235] subtropNPac = [45, 175, 165, 220] - subtropSPac = [195, 275, 175, 225] - subtropNAtl = [70, 205, 120, 145] + subtropNAtl = [195, 275, 175, 225] + subtropSPac = [70, 205, 120, 145] subtropSAtl = [235, 300, 120, 145] subtropInd = [320, 30, 110, 180] ACC = [1, 361, 1, 65] diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 2d95aa0..4d6a2d3 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -39,8 +39,8 @@ class Heat(object): Log.info('Running time {0}', time) temp = TempFile.get() nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) - Log.info('Computing salt content') - cdftools.run('cdfmxlheatc', input=temp, options=['-full']) + Log.info('Computing heat content') + cdftools.run('cdfmxlheatc', input=temp) Utils.move_file('mxlheatc.nc', temp) files.append(temp) diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index cc505bd..fade597 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -72,8 +72,8 @@ class Salinity(object): Log.info('Running time {0}', time) temp = TempFile.get() nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) - Log.info('Computing heat content') - cdftools.run('cdfmxlsaltc', input=temp, options=['-full']) + Log.info('Computing salt content') + cdftools.run('cdfmxlsaltc', input=temp) Utils.move_file('mxlsaltc.nc', temp) files.append(temp) -- GitLab From 271e1eb88c1fe6b2de232a28d49eb1ad5108a3a1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 2 Jun 2016 16:24:17 +0200 Subject: [PATCH 068/268] Adapted siasiesiv to CMOR (variable names and also units) --- config_file-ocean_pp.bash | 10 +-- earthdiagnostics/diags.conf | 28 +++---- earthdiagnostics/diags.py | 16 ++-- earthdiagnostics/ocean/circulation.py | 1 - earthdiagnostics/ocean/ice.py | 116 +++++++++++++++++++++++++- ocean_pp.bash | 2 +- 6 files changed, 144 insertions(+), 29 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 8a31072..a3a46e9 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('heat_sal_mxl') +listpost=('siasiesiv') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 @@ -9,14 +9,14 @@ level2=14 #If temp_lev or sal_lev is chosen on listpost, the le raw_vars_ocean=( '' ) # If listpost contains "ext_raw_oce" option, this is the list ocean variables you want to extract. If nothing is specified, all variables present in input file will be treated. If raw_vars_ocean='default', sosstsst, sosaline, somixhgt and somxl010 will be extracted. raw_vars_ice=( '' ) # If listpost contains "ext_raw_ice" option, this is the list of seaice variables you want to extract. If nothing is specified, all variables will be treated. If raw_vars_ice='default', isnowthi, iicethic, ileadfra, iicetemp, and ice_pres will be extracted. raw_regions_ice=( 'North_Atlantic_Ocean' ) # If listpost contains "ohc_Arcticreg1" or "siasiesivsit_Arcticreg1" option, this is the list of sea ice regions you want to compute -expid=a034 # expid or nemovar_s4 / nemovar_combine / glorys2v1 +expid=a030 # expid or nemovar_s4 / nemovar_combine / glorys2v1 mod='ecearth' # nemo / ecearth typeoutput='MMO' # diags / MMO #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ listmemb=( 0 ) # list of members -syeari=1950 # first start date, format "yyyy" -syearf=1950 # last start date, format "yyyy" -moni=02 # first month of the hindcast, format "mm", e.g. 05 for May +syeari=1990 # first start date, format "yyyy" +syearf=1990 # last start date, format "yyyy" +moni=01 # first month of the hindcast, format "mm", e.g. 05 for May intsdate=1 # interval between start dates chunklen=3 # length of the chunks (in months) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index a8f6d81..f93a696 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,25 +2,14 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = HEAT_SAL_MXL +DIAGS = SIASIESIV FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin -[EXPERIMENT] -INSTITUTE = IC3 -EXPID = a034 -STARTDATES = 19500201 -NAME = historical -CHUNK_SIZE = 3 -CHUNKS = 1 -MEMBERS = 0 -MODEL = EC-EARTH3 -NEMO_VERSION = Ec3.0_O1L46 - # [EXPERIMENT] # INSTITUTE = IC3 -# EXPID = a030 -# STARTDATES = 19900101 +# EXPID = a034 +# STARTDATES = 19500201 # NAME = historical # CHUNK_SIZE = 3 # CHUNKS = 1 @@ -28,6 +17,17 @@ NEMO_VERSION = Ec3.0_O1L46 # MODEL = EC-EARTH3 # NEMO_VERSION = Ec3.0_O1L46 +[EXPERIMENT] +INSTITUTE = IC3 +EXPID = a030 +STARTDATES = 19900101 +NAME = historical +CHUNK_SIZE = 3 +CHUNKS = 1 +MEMBERS = 0 +MODEL = EC-EARTH3 +NEMO_VERSION = Ec3.0_O1L46 + # [EXPERIMENT] # INSTITUTE = IC3 # EXPID = m04s diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 7096731..9ff30d7 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -179,7 +179,7 @@ class Diags: for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Salinity.mixed_layer_content(input_file, mlotst_file, output_file) - elif diag == 'interp': + elif diag == 'interp3d': variable = diag_options[1] if len(diag_options) == 3: domain = diag_options[2] @@ -197,7 +197,8 @@ class Diags: value = int(diag_options[3]) coordinate = Utils.get_cardinal_coordinate(value, zonal) variables = (variable, '{0}{1}'.format(variable, coordinate)) - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables, + 'regular'): General.cut_section(input_file, output_file, variable, zonal, value) elif diag == 'avgsection': variable = diag_options[1] @@ -216,10 +217,13 @@ class Diags: elif diag == 'siasiesiv': basin = diag_options[1] - variables = ('sit', 'sic', 'siasiesiv') - for [thickness_file, fraction_file, output_file] in self.datamanager.get_files(startdate, member, chunk, - 'seaIce', variables): - Ice.siasiesiv(thickness_file, fraction_file, output_file, basin) + variables = ('sit', 'sic', 'siextents', 'sivols', 'siareas', + 'siextentn', 'sivoln', 'siarean') + for [thickness_file, fraction_file, siextents_file, sivols_file, siareas_file, + siextentn_file, sivoln_file, siarean_file] in self.datamanager.get_files(startdate, member, chunk, + 'seaIce', variables): + Ice.siasiesiv(thickness_file, fraction_file, basin, sivols_file, siareas_file, siextents_file, + sivoln_file, siarean_file, siextentn_file) else: Log.warning('Diagnostic {0} not available', diag) return diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 6b15766..618c09b 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -224,7 +224,6 @@ class Circulation(object): Log.info('Minimum {0} Sv, latitude {1} depth {2} m', minimum, min_lat, min_lev) os.remove(temp) - handler = netCDF4.Dataset(temp, 'w') var = handler.createVariable('msftmyzmax', float) diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index 17b9872..fd8ec54 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -1,3 +1,6 @@ +import netCDF4 +import os + from earthdiagnostics import Utils, cdftools, cdo, TempFile from earthdiagnostics.basins import Basins from autosubmit.config.log import Log @@ -10,7 +13,8 @@ class Ice(object): """ @staticmethod - def siasiesiv(thickness_file, fraction_file, output_file, basin): + def siasiesiv(thickness_file, fraction_file, basin, svolume_file, sarea_file, sextent_file, + nvolume_file, narea_file, nextent_file): """ Compute the sea ice extent (1000km2), area (1000km2), volume (km3) and mean thickness (m) in both hemispheres or a specified region. @@ -21,6 +25,12 @@ class Ice(object): Computation of the properties in various selected regions according to mask.regions.${NEMOVERSION}.nc (mask_regions.nc) is based on modification of mask.regions.ORCA1.noverticalinfo.Matt.nc from Matthieu Chevallier. + :param svolume_file: + :param sarea_file: + :param sextent_file: + :param nvolume_file: + :param narea_file: + :param nextent_file: :param fraction_file: :param thickness_file: :param output_file: output file name @@ -59,7 +69,109 @@ class Ice(object): raise Exception(error) temp = TempFile.get() - cdo.cat(input=' '.join(files), output=temp,) + cdo.cat(input=' '.join(files), output=temp) nco.ncks(input=input_scratch, output=temp, options='-A -v time') + + Ice.extract_variable_and_rename(temp, 'SVolume', 'sivols', svolume_file, "10^3 km3") + Ice.extract_variable_and_rename(temp, 'SArea', 'siareas', sarea_file, "10^6 km2") + Ice.extract_variable_and_rename(temp, 'SExnsidc', 'siextents', sextent_file, "10^6 km2") + + Ice.extract_variable_and_rename(temp, 'NVolume', 'sivoln', nvolume_file, "10^3 km3") + Ice.extract_variable_and_rename(temp, 'NArea', 'siarean', narea_file, "10^6 km2") + Ice.extract_variable_and_rename(temp, 'NExnsidc', 'siextentn', nextent_file, "10^6 km2") + + os.remove(temp) + + @staticmethod + def extract_variable_and_rename(input_file, variable, cmor_name, output_file, output_units): + temp = TempFile.get() + # Utils.nco.ncks(input=input_file, output=temp, options='-O -v {0},time,time_bnds'.format(variable)) + input_handler = Utils.cdo.openCdf(input_file) + + os.remove(temp) + handler = netCDF4.Dataset(temp, 'w') + + # Create dimensions + handler.createDimension('time', None) + handler.createDimension('bnds', 2) + + # Copy time variable + time_var = input_handler.variables['time'] + new_time = handler.createVariable('time', time_var.datatype, time_var.dimensions) + new_time.setncatts({k: time_var.getncattr(k) for k in time_var.ncattrs()}) + new_time[:] = time_var[:] + + original_bnds = input_handler.variables['time_bnds'] + new_bnds = handler.createVariable('time_bnds', original_bnds.datatype, original_bnds.dimensions) + new_bnds.setncatts({k: original_bnds.getncattr(k) for k in original_bnds.ncattrs()}) + new_bnds[:] = original_bnds[:] + + original_variable = input_handler.variables[variable] + values = original_variable[:, 0, 0] + + new_var = handler.createVariable(cmor_name, original_variable.datatype, 'time') + new_var.setncatts({k: original_variable.getncattr(k) for k in original_variable.ncattrs()}) + factor = Ice.get_conversion_factor(original_variable.units, output_units) + values *= factor + new_var[:] = values + new_var.units = output_units + new_var.short_name = cmor_name + handler.close() + Utils.move_file(temp, output_file) + @staticmethod + def get_conversion_factor(input_units, output_units): + units = input_units.split() + if len(units) == 1: + scale_unit = 1 + unit = units[0] + else: + if '^' in units[0]: + values = units[0].split('^') + scale_unit = pow(int(values[0]), int(values[1])) + else: + scale_unit = float(units[0]) + unit = units[1] + + units = output_units.split() + if len(units) == 1: + scale_new_unit = 1 + new_unit = units[0] + else: + if '^' in units[0]: + values = units[0].split('^') + scale_new_unit = pow(int(values[0]), int(values[1])) + else: + scale_new_unit = float(units[0]) + new_unit = units[1] + + factor = Ice.get_factor(new_unit, unit) + invert = False + if factor is None: + factor = Ice.get_factor(unit, new_unit) + invert = True + + if factor is None: + raise Exception("Conversion from {0} to {1} not supported".format(units, output_units)) + + if invert: + factor = scale_unit / float(scale_new_unit * factor) + else: + factor = (factor * scale_unit) / float(scale_new_unit) + return factor + + @staticmethod + def get_factor(new_unit, unit): + # Add only the conversions with a factor greater than 1 + if unit == new_unit: + return 1 + if unit == 'km3': + if new_unit == 'm3': + return pow(1000, 3) + elif unit == 'km2': + if new_unit == 'm2': + return pow(1000, 2) + return None + + diff --git a/ocean_pp.bash b/ocean_pp.bash index 9d5e5d1..d8e4a14 100755 --- a/ocean_pp.bash +++ b/ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash set -evx -module load CDFTOOLS/3.0-foss-2015a CDO NCO R +module load CDFTOOLS/2.1-foss-2015a CDO NCO R function delete { at now +7 days << EOF -- GitLab From 72f0da7c0bd27e847fd47596e9422147302c4da3 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 2 Jun 2016 16:56:37 +0200 Subject: [PATCH 069/268] Generalized vertmeansal so it can be used with other variables --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 6 ++--- earthdiagnostics/diags.py | 13 ++++++----- earthdiagnostics/ocean/general.py | 37 +++++++++++++++++++++++++++++- earthdiagnostics/ocean/heat.py | 1 - earthdiagnostics/ocean/salinity.py | 36 ----------------------------- 6 files changed, 47 insertions(+), 48 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index a3a46e9..e4f0872 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('siasiesiv') +listpost=('lmsalc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index f93a696..e291f1d 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = SIASIESIV +DIAGS = vertmeanmeters,thetao,300,5400 FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -44,8 +44,8 @@ MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 AREA_MOC = mocarea,40,55,1000,2000,atl mocarea,30,40,1000,2000,atl STC = mocarea,0,25,0,200,Pac mocarea,-25,0,0,200,Pac mocarea,0,25,0,200,Atl mocarea,-25,0,0,200,Atl HEAT_SAL_MXL = mlotstsc mlotsthc -LMSALC = vertmeansal,300,5400 -USALC = vertmeansal,0,300 +LMSALC = vertmeanmeters,so,300,5400 +USALC = vertmeanmeters,so,0,300 OHC = ohc,glob,0,0,10 XOHC = ohc,glob,1,0,0 LOHC = ohc,glob,0,23,46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 9ff30d7..60212cd 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -75,13 +75,14 @@ class Diags: def _execute_diagnostic(self, diag_options, startdate, member, chunk): diag = diag_options[0] - if diag == 'vertmeansal': - depth_min = int(diag_options[1]) - depth_max = int(diag_options[2]) - depth = '{0}-{1}'.format(depth_min, depth_max) - variables = ('so', 'someanm{0}'.format(depth)) + if diag == 'vertmeanmeters': + variable = diag_options[1] + depth_min = int(diag_options[2]) + depth_max = int(diag_options[3]) + depth = '{0}m-{1}m'.format(depth_min, depth_max) + variables = (variable, '{0}mean{1}'.format(variable, depth)) for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): - Salinity.vertical_mean(input_file, output_file, depth_min, depth_max) + General.vertical_mean_meters(input_file, output_file, variable, depth_min, depth_max) elif diag == 'vertmean': variable = diag_options[1] lev_min = int(diag_options[2]) diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index d45ad46..93d6c8b 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -40,13 +40,48 @@ class General(object): lev_max = handler.variables['lev'][lev_max] cdftools.run('cdfvertmean', input=temp, output=temp2, options=[variable, 'T', lev_min, lev_max, - '-full', '-debug']) + '-debug']) os.remove(temp) Utils.setminmax(temp2, '{0}_vert_mean'.format(variable)) Utils.rename_variable(temp2, '{0}_vert_mean'.format(variable), '{0}mean{1}-{2}'.format(variable, lev_min, lev_max)) Utils.move_file(temp2, output_file) + @staticmethod + def vertical_mean_meters(input_file, output_file, variable, upper, lower): + """ + Vertically averaged salt content + Created in February 2012 Author : vguemas@ic3.cat + + :param input_file: input grid_T file name + :param upper: upper depth of the layer (in meters) + :type upper: int + :param lower: lower depth of the layer (in meters) + :type lower: int + :param output_file: output file name (=> 2D) + """ + cdo = Utils.cdo + nco = Utils.nco + + temp = TempFile.get() + temp2 = TempFile.get() + # test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values + # out of that range to be replaced by NaN + # + if cdo.version() > u'1.5.6': + nco.ncatted(input=input_file, output=temp, options='-O -a valid_max,lev,d,,') + nco.ncatted(input=temp, output=temp, options='-O -a valid_min,lev,d,,') + else: + shutil.copy(input_file, temp) + + cdftools.run('cdfvertmean', input=temp, output=temp2, options=[variable, 'T', str(upper), str(lower), + '-debug']) + os.remove(temp) + Utils.setminmax(temp2, '{0}_vert_mean'.format(variable)) + Utils.rename_variable(temp2, '{0}_vert_mean'.format(variable), + '{0}mean{1}m-{2}m'.format(variable, upper, lower)) + Utils.move_file(temp2, output_file) + @staticmethod def interpolate(input_file, output_file, variable, nemo_version): """ diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 4d6a2d3..82b6e72 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -180,7 +180,6 @@ class Heat(object): try: para = list() - para.append("-full") para.append(str(basin.min_lon)) para.append(str(basin.max_lon)) para.append(str(basin.min_lat)) diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index fade597..cdaf254 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -9,43 +9,7 @@ class Salinity(object): Class containing all the diagnostics related to salinity """ - @staticmethod - def vertical_mean(input_file, output_file, upper, lower): - """ - Vertically averaged salt content - Created in February 2012 Author : vguemas@ic3.cat - - :param input_file: input grid_T file name - :param upper: upper depth of the layer (in meters) - :type upper: int - :param lower: lower depth of the layer (in meters) - :type lower: int - :param output_file: output file name (=> 2D) - """ - cdo = Utils.cdo - nco = Utils.nco - - temp = TempFile.get() - temp2 = TempFile.get() - Log.debug('Calculating vertical mean between {0} and {1}', upper, lower) - Log.debug('Input file: {0}', input_file) - Log.debug('Output file: {0}', output_file) - # test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values - # out of that range to be replaced by NaN - # - if cdo.version() > u'1.5.6': - nco.ncatted(input=input_file, output=temp, options='-O -a valid_max,lev,d,,') - nco.ncatted(input=temp, output=temp, options='-O -a valid_min,lev,d,,') - else: - shutil.copy(input_file, temp) - cdftools.run('cdfvertmean', input=temp, output=temp2, options=['so', 'T', str(upper), str(lower), - '-full', '-debug']) - os.remove(temp) - Utils.setminmax(temp2, 'so_vert_mean') - Utils.rename_variable(temp2, 'so_vert_mean', 'someanm{0}-{1}'.format(upper, lower)) - Utils.move_file(temp2, output_file) - Log.debug('Finished!') @staticmethod def mixed_layer_content(input_file, mlotst_file, output_file): -- GitLab From fff8fbbef73e5f8684cc58f52ec5cadca56c1c81 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 3 Jun 2016 15:06:02 +0200 Subject: [PATCH 070/268] Renamed some variables and splitted some files to match CMOR conventions --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/basins.py | 2 ++ earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 35 ++++++++++---------- earthdiagnostics/ocean/circulation.py | 46 +++++++++++++-------------- earthdiagnostics/ocean/heat.py | 31 +++++++++++------- 6 files changed, 65 insertions(+), 53 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index e4f0872..8a65c35 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('lmsalc') +listpost=('moc max_moc area_moc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index e6e60bd..4a5b1a8 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -117,6 +117,8 @@ class Basins(object): Arctic = Basin('Arct', 'Arctic_Ocean') """ Arctic Ocean """ + + @classmethod def parse(cls, basin): """ diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index e291f1d..8355091 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = vertmeanmeters,thetao,300,5400 +DIAGS = ohc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 60212cd..af98d4e 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -96,12 +96,12 @@ class Diags: for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.convection_sites(input_file, self.nemo_version, output_file) elif diag == 'psi': - variables = ('uo', 'vo', 'msftbarot') + variables = ('uo', 'vo', 'vsftbarot') for [u_file, v_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.psi(u_file, v_file, output_file) elif diag == 'gyres': - variables = ('msftbarot', 'msftbarotgyres') + variables = ('vsftbarot', 'vsftbarotgyres') for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.gyres(str(input_file), self.nemo_version, str(output_file)) elif diag == 'ohc': @@ -119,10 +119,11 @@ class Diags: else: mxl = 'nomlotst' depth = '' - variables = ('thetao', 'mlotst', 'ohcsum{0}{1}'.format(mxl, depth)) - for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', - variables): - Heat.total(input_file, mlotst_file, output_file, basin, mixed_layer, depth_min, depth_max) + variables = ('thetao', 'mlotst', 'ohcsum{0}{1}', 'ohcvmean{0}{1}'.format(mxl, depth)) + for [input_file, mlotst_file, ohcsum_file, ohcvmean_file] in self.datamanager.get_files(startdate, member, + chunk, 'ocean', + variables): + Heat.total(input_file, mlotst_file, ohcsum_file, ohcvmean_file, basin, mixed_layer, depth_min, depth_max) elif diag == 'ohclayer': depth_min = int(diag_options[1]) depth_max = int(diag_options[2]) @@ -131,13 +132,13 @@ class Diags: variables = ('thetao', 'ohc{0}'.format(depth)) for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Heat.layer(input_file, output_file, depth_min, depth_max) - elif diag in ['moc', 'msftmyz']: - variables = ('vo', 'msftmyz') + elif diag in ['moc', 'vsftmyz']: + variables = ('vo', 'vsftmyz') for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.moc(input_file, output_file) - elif diag in ['mocmax', 'msftmyzmax']: + elif diag in ['mocmax', 'vsftmyzmax']: if len(diag_options) != 5: - Log.warning('Moc max requires 4 arguments. Skipping!') + Log.warning('vsftmyzmax requires 4 arguments. Skipping!') return lat_min = int(diag_options[1]) @@ -147,14 +148,14 @@ class Diags: depth_min = int(diag_options[3]) depth_max = int(diag_options[4]) depth = '{0}-{1}'.format(depth_min, depth_max) - variables = ('msftmyz', 'msftmyzmax') + variables = ('vsftmyz', 'vsftmyzmax') for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.max_moc(input_file, lat_min, lat_max, - output_file.replace('msftmyzmax', 'msftmyzmax{0}-{1}'.format(lat, depth)), + output_file.replace('vsftmyzmax', 'vsftmyzmax{0}-{1}'.format(lat, depth)), depth_min, depth_max) - elif diag in ['mocarea', 'msftmyzarea']: + elif diag in ['mocarea', 'vsftmyzarea']: if len(diag_options) != 6: - Log.warning('area_moc requires between 5 arguments. Skipping!') + Log.warning('vsftmyzarea requires between 5 arguments. Skipping!') return lat_min = int(diag_options[1]) @@ -167,16 +168,16 @@ class Diags: depth = '{0}-{1}'.format(depth_min, depth_max) basin = diag_options[5] - variables = ('msftmyz', 'msftmyz{0}{1}{2}'.format(lat, depth, basin)) + variables = ('vsftmyz', 'vsftmyz{0}{1}{2}'.format(lat, depth, basin)) for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) elif diag == 'mlotsthc': - variables = ('thetao', 'mlotst', 'mlotsthc') + variables = ('thetao', 'mlotst', 'ohcvertsummlotst') for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Heat.mixed_layer_content(input_file, mlotst_file, output_file) elif diag == 'mlotstsc': - variables = ('so', 'mlotst', 'mlotstsc') + variables = ('so', 'mlotst', 'scvertsummlotst') for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Salinity.mixed_layer_content(input_file, mlotst_file, output_file) diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 618c09b..fc10054 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -48,7 +48,7 @@ class Circulation(object): Basins.Indian.fullname], dtype=object) example = handler.variables['zomsfglo'] # noinspection PyProtectedMember - moc = handler.createVariable('msftmyz', example.datatype, + moc = handler.createVariable('vsftmyz', example.datatype, ('time', 'lev', 'i', 'j', 'basin'), fill_value=example._FillValue) @@ -66,7 +66,7 @@ class Circulation(object): Utils.nco.ncks(input=temp, output=temp, options='-O -x -v zomsfglo,zomsfatl,zomsfpac,zomsfinp,zomsfind,zomsfinp0') - Utils.setminmax(temp, 'msftmyz') + Utils.setminmax(temp, 'vsftmyz') Utils.move_file(temp, output_file) @@ -121,7 +121,7 @@ class Circulation(object): # To remove basin dimension nco.ncwa(input=temp, output=temp, options='-O -a basin') - nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time,lev') + nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev') handler = Utils.nco.openCdf(temp) handler.renameDimension('j', 'lat') @@ -139,7 +139,7 @@ class Circulation(object): cdo.vertmean(input=temp2, output=temp) nco.ncap2(input=temp, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') - nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time') + nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time') Utils.move_file(temp, output_file) @staticmethod @@ -191,7 +191,7 @@ class Circulation(object): # To remove basin dimension nco.ncwa(input=temp, output=temp, options='-O -a basin') - nco.ncks(input=temp, output=temp, options='-O -v msftmyz,time,lev,lev_bnds') + nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev,lev_bnds') handler = Utils.nco.openCdf(temp) handler.renameDimension('j', 'lat') @@ -207,7 +207,7 @@ class Circulation(object): Utils.cdo.yearmean(input=temp2, output=temp) handler = nco.openCdf(temp) - moc = handler.variables['msftmyz'][:] + moc = handler.variables['vsftmyz'][:] maximum = np.amax(moc) max_index = np.unravel_index(np.argmax(moc), moc.shape) @@ -226,42 +226,42 @@ class Circulation(object): os.remove(temp) handler = netCDF4.Dataset(temp, 'w') - var = handler.createVariable('msftmyzmax', float) + var = handler.createVariable('vsftmyzmax', float) var.long_name = 'Maximum_Overturing' var.units = 'Sverdrup' var.valid_min = -1000. var.valid_max = 1000. var[:] = maximum - var = handler.createVariable('msftmyzmaxlat', float) + var = handler.createVariable('vsftmyzmaxlat', float) var.long_name = 'Latitude_of_Maximum_Overturing' var.units = 'Degrees' var.valid_min = -90. var.valid_max = 90. var[:] = lat_max - var = handler.createVariable('msftmyzmaxlev', float) + var = handler.createVariable('vsftmyzmaxlev', float) var.long_name = 'Depth_of_Maximum_Overturing' var.units = 'Meters' var.valid_min = 0. var.valid_max = 10000. var[:] = max_lev - var = handler.createVariable('msftmyzmin', float) + var = handler.createVariable('vsftmyzmin', float) var.long_name = 'Minimum_Overtuning' var.units = 'Sverdrup' var.valid_min = -1000. var.valid_max = 1000. var[:] = maximum - var = handler.createVariable('msftmyzminlat', float) + var = handler.createVariable('vsftmyzminlat', float) var.long_name = 'Latitude_of_Minimum_Overtuning' var.units = 'Degrees' var.valid_min = -90. var.valid_max = 90. var[:] = lat_max - var = handler.createVariable('msftmyzminlev', float) + var = handler.createVariable('vsftmyzminlev', float) var.long_name = 'Depth_of_Minimum_Overtuning' var.units = 'Meters' var.valid_min = 0. @@ -287,8 +287,8 @@ class Circulation(object): """ temp = TempFile.get() cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-mean -mask') - Utils.rename_variable(temp, 'sobarstf', 'msftbarot') - Utils.setminmax(temp, 'msftbarot') + Utils.rename_variable(temp, 'sobarstf', 'vsftbarot') + Utils.setminmax(temp, 'vsftbarot') Utils.move_file(temp, output_file) # noinspection PyPep8Naming @@ -326,34 +326,34 @@ class Circulation(object): temp = TempFile.get() temp2 = TempFile.get() Circulation.gyre(input_psi, subpolNAtl, temp2, invert=True) - Utils.rename_variable(temp2, 'msftbarot', 'subpolNAtl') + Utils.rename_variable(temp2, 'vsftbarot', 'subpolNAtl') Circulation.gyre(input_psi, subpolNPac, temp, invert=True) - Utils.rename_variable(temp, 'msftbarot', 'subpolNPac') + Utils.rename_variable(temp, 'vsftbarot', 'subpolNPac') Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropNPac, temp) - Utils.rename_variable(temp, 'msftbarot', 'subtropNPac') + Utils.rename_variable(temp, 'vsftbarot', 'subtropNPac') Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropSPac, temp) - Utils.rename_variable(temp, 'msftbarot', 'subtropSPac') + Utils.rename_variable(temp, 'vsftbarot', 'subtropSPac') Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropNAtl, temp) - Utils.rename_variable(temp, 'msftbarot', 'subtropNAtl') + Utils.rename_variable(temp, 'vsftbarot', 'subtropNAtl') Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropSAtl, temp) - Utils.rename_variable(temp, 'msftbarot', 'subtropSAtl') + Utils.rename_variable(temp, 'vsftbarot', 'subtropSAtl') Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, subtropInd, temp) - Utils.rename_variable(temp, 'msftbarot', 'subtropInd') + Utils.rename_variable(temp, 'vsftbarot', 'subtropInd') Utils.nco.ncks(input=temp, output=temp2, options='-A') Circulation.gyre(input_psi, ACC, temp) - Utils.rename_variable(temp, 'msftbarot', 'ACC') + Utils.rename_variable(temp, 'vsftbarot', 'ACC') Utils.nco.ncks(input=temp, output=temp2, options='-A') Utils.move_file(temp2, output_file) @@ -365,7 +365,7 @@ class Circulation(object): Created in October 2013 Author : vguemas@ic3.cat - :param input_file: input oce file name containing msftbarot + :param input_file: input oce file name containing vsftbarot :param site: site to calculate convection on :param output_file: output file name (=> index) :param invert: if True, multiplies result by -1 diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index 82b6e72..b7624fe 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -52,8 +52,8 @@ class Heat(object): os.remove(temp_file) os.remove(input_scratch) - Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlheatc': 'mlotsthc'}, False, True) - Utils.setminmax(temp, 'mlotsthc') + Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlheatc': 'ohcsummlotst'}, False, True) + Utils.setminmax(temp, 'ohcsummlotst') Utils.move_file(temp, output_file) @staticmethod @@ -142,7 +142,7 @@ class Heat(object): Utils.move_file(results, output_file) @staticmethod - def total(input_file, mlotst_file, output_file, basin=Basins.Global.shortname, mixed_layer=0, + def total(input_file, mlotst_file, ohcsum_file, ohcvmean_file, basin=Basins.Global.shortname, mixed_layer=0, upper=None, lower=None): """ Compute the total ocean heat extent @@ -160,7 +160,7 @@ class Heat(object): nco = Utils.nco temp = TempFile.get() - temp2 = TempFile.get() + shutil.copy(input_file, temp) nco.ncks(input=mlotst_file, output=temp, options='-A -v mlotst') @@ -198,18 +198,23 @@ class Heat(object): if error: raise Exception(error) - nco.ncks(input=temp, output=temp2, options='-O -v time') - output = nco.openCdf(temp2) + ohcsum_temp = TempFile.get() + ohcvmean_temp = TempFile.get() + nco.ncks(input=temp, output=ohcsum_temp, options='-O -v time') + shutil.copy(ohcsum_temp, ohcvmean_temp) - thc = output.createVariable('thc', float, 'time') + ohcsum_handler = nco.openCdf(ohcsum_temp) + thc = ohcsum_handler.createVariable('ohcsum', float, 'time') thc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" thc.long_name = "Total heat content" thc.units = "Joules" - uhc = output.createVariable('uhc', float, 'time') + ohcvmean_handler = nco.openCdf(ohcvmean_temp) + uhc = ohcvmean_handler.createVariable('ohcvmean', float, 'time') uhc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" uhc.long_name = "Heat content per unit volume" uhc.units = "Joules/m3" + time = 0 # noinspection PyUnboundLocalVariable for lines in shell_output: @@ -230,9 +235,13 @@ class Heat(object): elif line.startswith('TIME : '): Log.info(line) - output.close() - Utils.setminmax(temp2, ['thc', 'uhc']) - Utils.move_file(temp2, output_file) + ohcsum_handler.close() + ohcvmean_handler.close() + + Utils.setminmax(ohcsum_temp, 'ohcsum') + Utils.move_file(ohcsum_temp, ohcsum_file) + Utils.setminmax(ohcvmean_temp, 'ohcvmean') + Utils.move_file(ohcvmean_temp, ohcvmean_file) def main(): -- GitLab From 3f0c3f30a8c6987f53c7d4cd6f8e677ef6a3c4bf Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 3 Jun 2016 16:19:48 +0200 Subject: [PATCH 071/268] Added extra error check in CDFTools --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/cdftools.py | 3 +++ earthdiagnostics/diags.conf | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 8a65c35..ec49270 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('moc max_moc area_moc') +listpost=('xohc') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 111763e..542f5f8 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -28,6 +28,9 @@ class CDFTools(object): :type log_level: int """ line = [os.path.join(self.path, command)] + if not os.path.exists(line[0]): + raise Exception('Error executing {0}\n Command does not exist in {1}', command, self.path) + if input: if isinstance(input, basestring): line.append(input) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 8355091..e516eb0 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = ohc +DIAGS = xohc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin -- GitLab From a36c43d808b96728b53d7c68214b9b9742c740ca Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 3 Jun 2016 18:19:09 +0200 Subject: [PATCH 072/268] First version of diagnostic class created. Siasiesiv used for testing --- earthdiagnostics/datamanager.py | 66 +++++++++++++++++++- earthdiagnostics/diagnostic.py | 11 ++++ earthdiagnostics/diags.conf | 4 +- earthdiagnostics/diags.py | 25 ++++---- earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/ice.py | 96 +++++++++++++++++------------- 6 files changed, 145 insertions(+), 59 deletions(-) create mode 100644 earthdiagnostics/diagnostic.py diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 626c4e9..bda3ecb 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -6,7 +6,7 @@ import os from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day -from earthdiagnostics import Utils +from earthdiagnostics import Utils, TempFile class DataManager(object): @@ -134,6 +134,70 @@ class DataManager(object): return file_names + def get_file(self, domain, var, startdate, member, chunk, grid=None): + if domain == 'seaIce': + domain_abreviattion = 'OI' + else: + domain_abreviattion = domain[0].upper() + + start = parse_date(startdate) + member_plus = str(member + 1) + member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', + self.institution, self.model, self.experiment_name, 'S' + startdate, self.frequency, + domain) + + chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + + if grid: + var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) + else: + var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) + + filepath = os.path.join(var_path, '{0}_{1}{2}_{3}_{4}_S{5}_r{6}i1p1_' + '{7}-{8}.nc'.format(var, domain_abreviattion, self.frequency, self.model, + self.experiment_name, startdate, member_plus, + "{0:04}{1:02}".format(chunk_start.year, + chunk_start.month), + "{0:04}{1:02}".format(chunk_end.year, + chunk_end.month))) + + temp_path = TempFile.get() + shutil.copyfile(filepath, temp_path) + return temp_path + + def send_file(self, filetosend, domain, var, startdate, member, chunk, grid=None): + if domain == 'seaIce': + domain_abreviattion = 'OI' + else: + domain_abreviattion = domain[0].upper() + + start = parse_date(startdate) + member_plus = str(member + 1) + member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', + self.institution, self.model, self.experiment_name, 'S' + startdate, self.frequency, + domain) + + chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + + if grid: + var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) + else: + var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) + + filepath = os.path.join(var_path, '{0}_{1}{2}_{3}_{4}_S{5}_r{6}i1p1_' + '{7}-{8}.nc'.format(var, domain_abreviattion, self.frequency, self.model, + self.experiment_name, startdate, member_plus, + "{0:04}{1:02}".format(chunk_start.year, + chunk_start.month), + "{0:04}{1:02}".format(chunk_end.year, + chunk_end.month))) + + Utils.move_file(filetosend, filepath) + # # set -vx diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py new file mode 100644 index 0000000..85a86fe --- /dev/null +++ b/earthdiagnostics/diagnostic.py @@ -0,0 +1,11 @@ +class Diagnostic(object): + + def __init__(self, data_manager): + self.data_manager = data_manager + self.required_vars = [] + self.generated_vars = [] + self.can_run_multiple_instances = True + + + def compute(self): + pass \ No newline at end of file diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index e516eb0..4f91272 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = xohc +DIAGS = siasiesiv FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -23,7 +23,7 @@ EXPID = a030 STARTDATES = 19900101 NAME = historical CHUNK_SIZE = 3 -CHUNKS = 1 +CHUNKS = 2 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index af98d4e..e7468ba 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -3,7 +3,7 @@ import argparse from datamanager import DataManager -from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Ice +from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Siasiesiv from utils import Utils from earthdiagnostics import cdftools, TempFile from autosubmit.date.chunk_date_lib import * @@ -59,15 +59,26 @@ class Diags: # Run diagnostics Log.info('Running diagnostics') + list_jobs = list() for fulldiag in self._get_commands(): Log.info("Running {0}", fulldiag) + diag_options = fulldiag.split(',') + + if diag_options[0] == 'siasiesiv': + list_jobs += Siasiesiv.generate_jobs(self.datamanager, self.startdates, self.members, self.chunks, + diag_options) + continue + for startdate in self.startdates: for member in self.members: for chunk in range(1, self.chunks+1): - self._execute_diagnostic(fulldiag.split(','), startdate, member, chunk) + self._execute_diagnostic(diag_options, startdate, member, chunk) Log.result('Finished {0}', fulldiag) + for job in list_jobs: + job.compute() + TempFile.clean() finsih_time = datetime.datetime.now() Log.result("Diagnostics finished at {0}", finsih_time) @@ -216,16 +227,6 @@ class Diags: variables = (variable, output_name) for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): General.avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max) - - elif diag == 'siasiesiv': - basin = diag_options[1] - variables = ('sit', 'sic', 'siextents', 'sivols', 'siareas', - 'siextentn', 'sivoln', 'siarean') - for [thickness_file, fraction_file, siextents_file, sivols_file, siareas_file, - siextentn_file, sivoln_file, siarean_file] in self.datamanager.get_files(startdate, member, chunk, - 'seaIce', variables): - Ice.siasiesiv(thickness_file, fraction_file, basin, sivols_file, siareas_file, siextents_file, - sivoln_file, siarean_file, siextentn_file) else: Log.warning('Diagnostic {0} not available', diag) return diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index e22abad..3950ca3 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -2,4 +2,4 @@ from salinity import Salinity from heat import Heat from circulation import Circulation from general import General -from ice import Ice +from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index fd8ec54..48a942a 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -3,18 +3,36 @@ import os from earthdiagnostics import Utils, cdftools, cdo, TempFile from earthdiagnostics.basins import Basins +from earthdiagnostics.diagnostic import Diagnostic from autosubmit.config.log import Log import shutil -class Ice(object): +class Siasiesiv(Diagnostic): """ Class containing all the diagnostics related to ice """ + def __init__(self, data_manager, basin, startdate, member, chunk): + Diagnostic.__init__(self, data_manager) + self.basin = basin + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['sit', 'sic'] + self.generated_vars = ['siextents', 'sivols', 'siareas', 'siextentn', 'sivoln', 'siarean'] + @staticmethod - def siasiesiv(thickness_file, fraction_file, basin, svolume_file, sarea_file, sextent_file, - nvolume_file, narea_file, nextent_file): + def generate_jobs(data_manager, startdates, members, chunks, options): + basin = Basins.parse(options[1]) + job_list = list() + for startdate in startdates: + for member in members: + for chunk in range(1, chunks + 1): + job_list.append(Siasiesiv(data_manager, basin, startdate, member, chunk)) + return job_list + + def compute(self): """ Compute the sea ice extent (1000km2), area (1000km2), volume (km3) and mean thickness (m) in both hemispheres or a specified region. @@ -25,44 +43,34 @@ class Ice(object): Computation of the properties in various selected regions according to mask.regions.${NEMOVERSION}.nc (mask_regions.nc) is based on modification of mask.regions.ORCA1.noverticalinfo.Matt.nc from Matthieu Chevallier. - :param svolume_file: - :param sarea_file: - :param sextent_file: - :param nvolume_file: - :param narea_file: - :param nextent_file: - :param fraction_file: - :param thickness_file: - :param output_file: output file name - :param basin: region of interest :return: """ + nco = Utils.nco - input_scratch = TempFile.get() - shutil.copy(thickness_file, input_scratch) - nco.ncks(input=fraction_file, output=input_scratch, options='-A -v sic') - ntime = int(cdo.ntime(input=input_scratch)[0]) + sit_file = self.data_manager.get_file('seaIce', 'sit', self.startdate, self.member, self.chunk) + sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) + nco.ncks(input=sic_file, output=sit_file, options='-A -v sic') + ntime = int(cdo.ntime(input=sit_file)[0]) files = list() - basin = Basins.parse(basin) - if basin != Basins.Global: + if self.basin != Basins.Global: shutil.move('mask.nc', 'original_mask.nc') shutil.move('mask_regions.nc', 'mask.nc') - Utils.rename_variable('mask.nc', basin.fullname, 'tmask') + Utils.rename_variable('mask.nc', self.basin.fullname, 'tmask') error = None try: for time in range(ntime): Log.info('Running time {0}', time) temp = TempFile.get() - nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) + nco.ncks(input=sit_file, output=temp, options='-O -d time,{0}'.format(time)) cdftools.run('cdficediags', input=temp) Utils.move_file('icediags.nc', temp) files.append(temp) except Exception as ex: error = ex.message finally: - if basin != Basins.Global: - Utils.rename_variable('mask.nc', 'tmask', basin.fullname) + if self.basin != Basins.Global: + Utils.rename_variable('mask.nc', 'tmask', self.basin.fullname) shutil.move('mask.nc', 'mask_regions.nc') shutil.move('original_mask.nc', 'mask.nc') if error: @@ -70,20 +78,25 @@ class Ice(object): temp = TempFile.get() cdo.cat(input=' '.join(files), output=temp) - nco.ncks(input=input_scratch, output=temp, options='-A -v time') - - Ice.extract_variable_and_rename(temp, 'SVolume', 'sivols', svolume_file, "10^3 km3") - Ice.extract_variable_and_rename(temp, 'SArea', 'siareas', sarea_file, "10^6 km2") - Ice.extract_variable_and_rename(temp, 'SExnsidc', 'siextents', sextent_file, "10^6 km2") - - Ice.extract_variable_and_rename(temp, 'NVolume', 'sivoln', nvolume_file, "10^3 km3") - Ice.extract_variable_and_rename(temp, 'NArea', 'siarean', narea_file, "10^6 km2") - Ice.extract_variable_and_rename(temp, 'NExnsidc', 'siextentn', nextent_file, "10^6 km2") + nco.ncks(input=sit_file, output=temp, options='-A -v time') + + self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SVolume', 'sivols', "10^3 km3"), + 'seaIce', 'sivols', self.startdate, self.member, self.chunk) + self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SArea', 'siareas', "10^6 km2"), + 'seaIce', 'siareas', self.startdate, self.member, self.chunk) + self.data_manager.send_file( self._extract_variable_and_rename(temp, 'SExnsidc', 'siextents', "10^6 km2"), + 'seaIce', 'siextents', self.startdate, self.member, self.chunk) + + self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NVolume', 'sivoln', "10^3 km3"), + 'seaIce', 'sivoln', self.startdate, self.member, self.chunk) + self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NArea', 'siarean', "10^6 km2"), + 'seaIce', 'siarean', self.startdate, self.member, self.chunk) + self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NExnsidc', 'siextentn', "10^6 km2"), + 'seaIce', 'siextentn', self.startdate, self.member, self.chunk) os.remove(temp) - @staticmethod - def extract_variable_and_rename(input_file, variable, cmor_name, output_file, output_units): + def _extract_variable_and_rename(self, input_file, variable, cmor_name, output_units): temp = TempFile.get() # Utils.nco.ncks(input=input_file, output=temp, options='-O -v {0},time,time_bnds'.format(variable)) input_handler = Utils.cdo.openCdf(input_file) @@ -111,17 +124,15 @@ class Ice(object): new_var = handler.createVariable(cmor_name, original_variable.datatype, 'time') new_var.setncatts({k: original_variable.getncattr(k) for k in original_variable.ncattrs()}) - factor = Ice.get_conversion_factor(original_variable.units, output_units) + factor = self._get_conversion_factor(original_variable.units, output_units) values *= factor new_var[:] = values new_var.units = output_units new_var.short_name = cmor_name handler.close() + return temp - Utils.move_file(temp, output_file) - - @staticmethod - def get_conversion_factor(input_units, output_units): + def _get_conversion_factor(self, input_units, output_units): units = input_units.split() if len(units) == 1: scale_unit = 1 @@ -146,10 +157,10 @@ class Ice(object): scale_new_unit = float(units[0]) new_unit = units[1] - factor = Ice.get_factor(new_unit, unit) + factor = self._get_factor(new_unit, unit) invert = False if factor is None: - factor = Ice.get_factor(unit, new_unit) + factor = self._get_factor(unit, new_unit) invert = True if factor is None: @@ -161,8 +172,7 @@ class Ice(object): factor = (factor * scale_unit) / float(scale_new_unit) return factor - @staticmethod - def get_factor(new_unit, unit): + def _get_factor(self, new_unit, unit): # Add only the conversions with a factor greater than 1 if unit == new_unit: return 1 -- GitLab From 1e984ecac0cf303069ab7bbdcf084d8d60ca6a89 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 3 Jun 2016 18:44:41 +0200 Subject: [PATCH 073/268] Diagnostic classes now can run on parallel. Adapted siasiesiv to this --- earthdiagnostics/diagnostic.py | 1 - earthdiagnostics/diags.conf | 28 ++++++++++++++-------------- earthdiagnostics/diags.py | 18 ++++++++++++++++-- earthdiagnostics/ocean/ice.py | 11 +++++++++-- earthdiagnostics/utils.py | 1 + 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 85a86fe..7c97c72 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -6,6 +6,5 @@ class Diagnostic(object): self.generated_vars = [] self.can_run_multiple_instances = True - def compute(self): pass \ No newline at end of file diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 4f91272..a77ebeb 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -6,28 +6,28 @@ DIAGS = siasiesiv FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin -# [EXPERIMENT] -# INSTITUTE = IC3 -# EXPID = a034 -# STARTDATES = 19500201 -# NAME = historical -# CHUNK_SIZE = 3 -# CHUNKS = 1 -# MEMBERS = 0 -# MODEL = EC-EARTH3 -# NEMO_VERSION = Ec3.0_O1L46 - [EXPERIMENT] INSTITUTE = IC3 -EXPID = a030 -STARTDATES = 19900101 +EXPID = a034 +STARTDATES = 19500201 NAME = historical CHUNK_SIZE = 3 -CHUNKS = 2 +CHUNKS = 120 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 +# [EXPERIMENT] +# INSTITUTE = IC3 +# EXPID = a030 +# STARTDATES = 19900101 +# NAME = historical +# CHUNK_SIZE = 3 +# CHUNKS = 2 +# MEMBERS = 0 +# MODEL = EC-EARTH3 +# NEMO_VERSION = Ec3.0_O1L46 + # [EXPERIMENT] # INSTITUTE = IC3 # EXPID = m04s diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index e7468ba..493a444 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import argparse +import threading from datamanager import DataManager from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Siasiesiv @@ -76,14 +77,27 @@ class Diags: Log.result('Finished {0}', fulldiag) - for job in list_jobs: - job.compute() + numthreads = Utils.available_cpu_count() + threads = list() + for numthread in range(0, numthreads): + t = threading.Thread(target=Diags._run_jobs, + args=([list_jobs[numthread:len(list_jobs): numthreads]])) + threads.append(t) + t.start() + + for t in threads: + t.join() TempFile.clean() finsih_time = datetime.datetime.now() Log.result("Diagnostics finished at {0}", finsih_time) Log.result("Time ellapsed: {0}", finsih_time - time) + @staticmethod + def _run_jobs(jobs): + for job in jobs: + job.compute() + def _execute_diagnostic(self, diag_options, startdate, member, chunk): diag = diag_options[0] if diag == 'vertmeanmeters': diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index 48a942a..45369bb 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -6,6 +6,7 @@ from earthdiagnostics.basins import Basins from earthdiagnostics.diagnostic import Diagnostic from autosubmit.config.log import Log import shutil +import threading class Siasiesiv(Diagnostic): @@ -13,7 +14,7 @@ class Siasiesiv(Diagnostic): Class containing all the diagnostics related to ice """ - def __init__(self, data_manager, basin, startdate, member, chunk): + def __init__(self, data_manager, basin, startdate, member, chunk, lock): Diagnostic.__init__(self, data_manager) self.basin = basin self.startdate = startdate @@ -21,15 +22,17 @@ class Siasiesiv(Diagnostic): self.chunk = chunk self.required_vars = ['sit', 'sic'] self.generated_vars = ['siextents', 'sivols', 'siareas', 'siextentn', 'sivoln', 'siarean'] + self.lock = lock @staticmethod def generate_jobs(data_manager, startdates, members, chunks, options): basin = Basins.parse(options[1]) + lock = threading.Lock() job_list = list() for startdate in startdates: for member in members: for chunk in range(1, chunks + 1): - job_list.append(Siasiesiv(data_manager, basin, startdate, member, chunk)) + job_list.append(Siasiesiv(data_manager, basin, startdate, member, chunk, lock)) return job_list def compute(self): @@ -53,6 +56,8 @@ class Siasiesiv(Diagnostic): ntime = int(cdo.ntime(input=sit_file)[0]) files = list() + self.lock.acquire() + if self.basin != Basins.Global: shutil.move('mask.nc', 'original_mask.nc') shutil.move('mask_regions.nc', 'mask.nc') @@ -76,6 +81,8 @@ class Siasiesiv(Diagnostic): if error: raise Exception(error) + self.lock.release() + temp = TempFile.get() cdo.cat(input=' '.join(files), output=temp) nco.ncks(input=sit_file, output=temp, options='-A -v time') diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 8487a5e..1dc4307 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -221,6 +221,7 @@ class TempFile(object): if filename: path = os.path.join(TempFile.scratch_folder, filename) else: + fd, path = tempfile.mkstemp(dir=TempFile.scratch_folder, prefix=TempFile.prefix, suffix='.nc') os.close(fd) -- GitLab From ebe0ea2e751d70702fc3b7d95b8c26e71987d9f5 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 6 Jun 2016 16:02:02 +0200 Subject: [PATCH 074/268] Changed output of ice files to add region variable. Not working --- earthdiagnostics/basins.py | 115 ++++++++++++++++++++++++++ earthdiagnostics/datamanager.py | 65 ++++++++++++++- earthdiagnostics/diags.conf | 4 +- earthdiagnostics/diags.py | 6 +- earthdiagnostics/ocean/circulation.py | 12 +-- earthdiagnostics/ocean/ice.py | 18 ++-- earthdiagnostics/utils.py | 12 +++ testing_diags_moore.job | 7 +- 8 files changed, 216 insertions(+), 23 deletions(-) diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index 4a5b1a8..8b4d74d 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -19,6 +19,11 @@ class Basin(object): else: self._coordinates = [0, 0, 0, 0] + def __eq__(self, other): + if self.shortname != other.shortname or self.fullname != other.fullname: + return False + return True + @property def shortname(self): """ @@ -85,6 +90,8 @@ class Basin(object): class Basins(object): + + """ Predefined basins """ @@ -114,10 +121,118 @@ class Basins(object): Antarctic = Basin('Anta', 'Antarctic_Ocean') """ Antarctic Ocean """ + AntarcticAtlantic = Basin('AntaAtl', 'Antarctic_Atlantic_Sector') + """ Antarctic Ocean Atlantic Sector """ + AntarcticIndian = Basin('AntaInd', 'Antarctic_Indian_Sector') + """ Antarctic Ocean Indian Sector""" + Arctic = Basin('Arct', 'Arctic_Ocean') """ Arctic Ocean """ + ArcticNorthAtlantic = Basin('ArctNAtl', 'Arctic_Ocean_North_Atlantic') + """ Arctic Ocean North Atlantic""" + ArcticMarginalSeas = Basin('ArctMarg', 'Arctic_Marginal_Seas') + """ Arctic Ocean """ + # ArctOcn + Baffin = Basin('Baffin', 'Baffin') + " Baffin " + Baffin_Bay = Basin('BaffBay', 'Baffin_Bay') + " Baffin_Bay " + Baltic_Sea = Basin('Baltic', 'Baltic_Sea') + " Baltic_Sea " + BarKara = Basin('BarKara', 'BarKara') + " BarKara " + Barents_Sea = Basin('Barents', 'Barents_Sea') + " Barents_Sea " + Beaufort_Chukchi_Sea = Basin('BeaufortChukchi', 'Beaufort_Chukchi_Sea') + " Beaufort_Chukchi_Sea " + Beaufort_Sea = Basin('Beaufort', 'Beaufort_Sea') + " Beaufort_Sea " + Bellingshausen_Sea = Basin('Bellingshausen_', 'Bellingshausen_Sea') + " Bellingshausen_Sea " + Bering = Basin('Bering', 'Bering') + " Bering " + Bering_Strait = Basin('BeringStr', 'Bering_Strait') + " Bering_Strait " + CanArch = Basin('CanArch', 'CanArch') + " CanArch " + Canadian_Waters = Basin('Canadian', 'Canadian_Waters') + " Canadian_Waters " + Caspian_Sea = Basin('Caspian', 'Caspian_Sea') + " Caspian_Sea " + Central_Arctic = Basin('CArct', 'Central_Arctic') + " Central_Arctic " + Chukchi_Sea = Basin('Chukchi', 'Chukchi_Sea') + " Chukchi_Sea " + East_Siberian_Sea = Basin('ESiberian', 'East_Siberian_Sea') + " East_Siberian_Sea " + Eastern_Central_Arctic = Basin('ECArct', 'Eastern_Central_Arctic') + " Eastern_Central_Arctic " + Fram_Strait = Basin('Fram', 'Fram_Strait') + " Fram_Strait " + Global_Ocean = Basin('Global', 'Global_Ocean') + " Global_Ocean " + Greenland_Sea = Basin('Greenland', 'Greenland_Sea') + " Greenland_Sea " + Grnland = Basin('Grnland', 'Grnland') + " Grnland " + Hudson = Basin('Hudson', 'Hudson') + " Hudson " + Icelandic_Sea = Basin('Iceland', 'Icelandic_Sea') + " Icelandic_Sea " + Kara_Gate_Strait = Basin('KaraGate', 'Kara_Gate_Strait') + " Kara_Gate_Strait " + Kara_Sea = Basin('Kara', 'Kara') + " Kara_Sea " + Labrador_Sea = Basin('Labrador', 'Labrador') + " Labrador_Sea " + Laptev_East_Siberian_Chukchi_Seas = Basin('LaptevESiberianChukchi', 'Laptev_East_Siberian_Chukchi_Seas') + " Laptev_East_Siberian_Chukchi_Seas " + Laptev_East_Siberian_Seas = Basin('LaptevESiberian', 'Laptev_East_Siberian_Seas') + " Laptev_East_Siberian_Seas " + Laptev_Sea = Basin('Laptev', 'Laptev_Sea') + " Laptev_Sea " + Lincoln_Sea = Basin('Lincoln', 'Lincoln_Sea') + " Lincoln_Sea " + Mediterranean_Sea = Basin('Medit', 'Mediterranean_Sea') + " Mediterranean_Sea " + Nares_Strait = Basin('Nares', 'Nares_Strait') + " Nares_Strait " + Nordic_Barents_Seas = Basin('NordicBarents', 'Nordic_Barents_Seas') + " Nordic_Barents_Seas " + Nordic_Seas = Basin('Nordic', 'Nordic_Seas') + " Nordic_Seas " + NorthWest_Passage = Basin('NWPass', 'NorthWest_Passage') + " NorthWest_Passage " + North_Atlantic_Arctic = Basin('North_Atlantic_Arctic', 'North_Atlantic_Arctic') + " North_Atlantic_Arctic " + North_Hemisphere_Ocean = Basin('NHem', 'North_Hemisphere_Ocean') + " North_Hemisphere_Ocean " + Norwegian_Sea = Basin('Norwe', 'Norwegian_Sea') + " Norwegian_Sea " + Okhotsk = Basin('Okhotsk', 'Okhotsk') + " Okhotsk " + OpenOcean = Basin('OpenOcean', 'OpenOcean') + " OpenOcean " + Ross_Sea = Basin('Ross', 'Ross_Sea') + " Ross_Sea " + Serreze_Arctic = Basin('SerArc', 'Serreze_Arctic') + " Serreze_Arctic " + Southern_Hemisphere = Basin('SHem', 'Southern_Hemisphere') + " Southern_Hemisphere " + StLawr = Basin('StLawr', 'StLawr') + " StLawr " + Subpolar_Gyre = Basin('Subpolar', 'Subpolar_Gyre') + " Subpolar_Gyre " + TotalArc = Basin('TotalArc', 'TotalArc') + " TotalArc " + Vilkitsky_Strait = Basin('Vilkitsky', 'Vilkitsky_Strait') + " Vilkitsky_Strait " + Weddell_Sea = Basin('Weddell', 'Weddell_Sea') + " Weddell_Sea " + Western_Central_Arctic = Basin('Western_Central_Arctic', 'Western_Central_Arctic') + " Western_Central_Arctic " @classmethod def parse(cls, basin): diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index bda3ecb..22fa7ed 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -2,7 +2,9 @@ import glob import shutil import threading +import netCDF4 import os +import numpy as np from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day @@ -167,7 +169,7 @@ class DataManager(object): shutil.copyfile(filepath, temp_path) return temp_path - def send_file(self, filetosend, domain, var, startdate, member, chunk, grid=None): + def send_file(self, filetosend, domain, var, startdate, member, chunk, grid=None, region=None): if domain == 'seaIce': domain_abreviattion = 'OI' else: @@ -196,8 +198,69 @@ class DataManager(object): "{0:04}{1:02}".format(chunk_end.year, chunk_end.month))) + if region: + if not os.path.exists(filepath): + Utils.convert2netcdf4(filetosend) + + handler = Utils.cdo.openCdf(filetosend) + handler.createDimension('region') + var_region = handler.createVariable('region', str, 'region') + var_region[0] = region + + original_var = handler.variables[var] + new_var = handler.createVariable('new_var', original_var.datatype, original_var.dimensions + ('region',)) + new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) + value = original_var[:] + new_var[..., 0] = value + handler.close() + + Utils.nco.ncks(input=filetosend, output=filetosend, options='-O -x -v {0}'.format(var)) + Utils.rename_variable(filetosend, 'new_var', var) + else: + temp = TempFile.get() + shutil.copyfile(filepath, temp) + handler = Utils.cdo.openCdf(temp) + handler_send = Utils.cdo.openCdf(filetosend) + value = handler_send.variables[var][:] + var_region = handler.variables['region'] + basin_index = np.where(var_region[:] == region) + if len(basin_index[0]) == 0: + var_region[var_region.shape[0]] = region + basin_index = var_region.shape[0] - 1 + + else: + basin_index = basin_index[0][0] + + handler_send.variables[var][..., basin_index] = value + handler.close() + handler_send.close() + Utils.move_file(temp, filetosend) + Utils.move_file(filetosend, filepath) + handler = netCDF4.Dataset('temp.nc', 'w') + handler.createDimension('time') + handler.createDimension('region') + var_time = handler.createVariable('time', float, 'time') + var_time[:] = [0, 1, 2] + var_region = handler.createVariable('region', str, 'region') + var_region[0] = 'region1' + var_content = handler.createVariable('content', float, ('time', 'region')) + var_content[:, 0] = [1, 2, 3] + handler.close() + + handler = netCDF4.Dataset('temp.nc', 'a') + var_region = handler.variables['region'] + var_region[1] = 'region2' + var_content = handler.variables['content'] + var_content[..., 1] = [4, 5, 6] + handler.close() + Utils.execute_shell_command('ncdump temp.nc', Log.INFO) + + + + + # # set -vx diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index a77ebeb..4f9442d 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = siasiesiv +DIAGS = siasiesiv,glob FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -12,7 +12,7 @@ EXPID = a034 STARTDATES = 19500201 NAME = historical CHUNK_SIZE = 3 -CHUNKS = 120 +CHUNKS = 1 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 493a444..ba1c14b 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -2,7 +2,7 @@ import argparse import threading - +import netCDF4 from datamanager import DataManager from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Siasiesiv from utils import Utils @@ -48,6 +48,7 @@ class Diags: """ Run the diagnostics """ + Log.debug('Using netCDF version {0}', netCDF4.getlibversion()) time = datetime.datetime.now() Log.info("Starting diagnostics at {0}", time) if not os.path.exists(self.scratch_dir): @@ -77,7 +78,7 @@ class Diags: Log.result('Finished {0}', fulldiag) - numthreads = Utils.available_cpu_count() + numthreads = min(Utils.available_cpu_count(), self.max_cores) threads = list() for numthread in range(0, numthreads): t = threading.Thread(target=Diags._run_jobs, @@ -313,6 +314,7 @@ class Diags: self.diags = self.parser.get_option('DIAGNOSTICS', 'DIAGS').lower() self.frequency = self.parser.get_option('DIAGNOSTICS', 'FREQUENCY') self.cdftools_path = self.parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') + self.max_cores = self.parser.get_int_option('DIAGNOSTICS', 'MAX_CORES', 100000) # Read experiment config self.institute = self.parser.get_option('EXPERIMENT', 'INSTITUTE') diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index fc10054..4fd4ba7 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -30,13 +30,11 @@ class Circulation(object): if os.path.exists(output_file): os.remove(output_file) temp = TempFile.get() - temp2 = TempFile.get() + Log.debug('Computing MOC') - cdftools.run('cdfmoc', input=input_file, output=temp2) - Utils.nco.ncks(input=input_file, output=temp2, options='-A -v lev') - Log.debug('Reformating to netCDF-4') - Utils.execute_shell_command(["nccopy", "-4", temp2, temp]) - os.remove(temp2) + cdftools.run('cdfmoc', input=input_file, output=temp) + Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') + Utils.convert2netcdf4(temp) Log.debug('Reformatting variables') handler = Utils.cdo.openCdf(temp) @@ -175,8 +173,6 @@ class Circulation(object): basin_index = np.where(handler.variables['basin'][:] == basin.fullname) if len(basin_index) == 0: raise Exception("Basin {1} is not defined in {0}", input_file, basin.fullname) - if len(basin_index) == 0: - raise Exception('Basin {0} not defined in file') basin_index = basin_index[0][0] handler.close() diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index 45369bb..a5e2a5d 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -17,6 +17,10 @@ class Siasiesiv(Diagnostic): def __init__(self, data_manager, basin, startdate, member, chunk, lock): Diagnostic.__init__(self, data_manager) self.basin = basin + if basin == Basins.Global: + self._region = None + else: + self._region = basin.shortname self.startdate = startdate self.member = member self.chunk = chunk @@ -88,18 +92,18 @@ class Siasiesiv(Diagnostic): nco.ncks(input=sit_file, output=temp, options='-A -v time') self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SVolume', 'sivols', "10^3 km3"), - 'seaIce', 'sivols', self.startdate, self.member, self.chunk) + 'seaIce', 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SArea', 'siareas', "10^6 km2"), - 'seaIce', 'siareas', self.startdate, self.member, self.chunk) - self.data_manager.send_file( self._extract_variable_and_rename(temp, 'SExnsidc', 'siextents', "10^6 km2"), - 'seaIce', 'siextents', self.startdate, self.member, self.chunk) + 'seaIce', 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) + self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SExnsidc', 'siextents', "10^6 km2"), + 'seaIce', 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NVolume', 'sivoln', "10^3 km3"), - 'seaIce', 'sivoln', self.startdate, self.member, self.chunk) + 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NArea', 'siarean', "10^6 km2"), - 'seaIce', 'siarean', self.startdate, self.member, self.chunk) + 'seaIce', 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NExnsidc', 'siextentn', "10^6 km2"), - 'seaIce', 'siextentn', self.startdate, self.member, self.chunk) + 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) os.remove(temp) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 1dc4307..12bded5 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -180,6 +180,18 @@ class Utils(object): Log.info('Available cores: {0}', Utils._cpu_count) return Utils._cpu_count + @staticmethod + def convert2netcdf4(filetoconvert): + temp = TempFile.get() + handler = Utils.cdo.openCdf(filetoconvert) + if handler.file_format == 'NETCDF4': + handler.close() + return + handler.close() + Log.debug('Reformating to netCDF-4') + Utils.execute_shell_command(["nccopy", "-4", filetoconvert, temp]) + shutil.move(temp, filetoconvert) + class TempFile(object): """ diff --git a/testing_diags_moore.job b/testing_diags_moore.job index 06a0aaa..22bc711 100755 --- a/testing_diags_moore.job +++ b/testing_diags_moore.job @@ -1,17 +1,18 @@ #!/bin/bash #SBATCH --time=24:00:00 -#SBATCH -n 2 -#SBATCH -N 1 +#SBATCH -n 4 #SBATCH --error=/home/Earth/jvegas/job.%J.err #SBATCH --output=/home/Earth/jvegas/job.%J.out +set -xve + module load NCO/4.5.4-foss-2015a module load CDO module load CDFTOOLS/3.0-foss-2015a source /home/Earth/jvegas/virtualenvs/diags/bin/activate -export PYTHONPATH=$PYTHONPATH/home/Earth/jvegas/pyCharm/ocean_diagnostics/: +export PYTHONPATH=/home/Earth/jvegas/pyCharm/ocean_diagnostics/:$PYTHONPATH cd /home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/ ./diags.py -lc DEBUG \ No newline at end of file -- GitLab From 899228d907b769279b006546aba687a6a35ba1c6 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 6 Jun 2016 17:52:47 +0200 Subject: [PATCH 075/268] Changed salinity diags to the new way --- earthdiagnostics/__init__.py | 2 + earthdiagnostics/datamanager.py | 122 ++++++++++++----------------- earthdiagnostics/diagnostic.py | 31 +++++++- earthdiagnostics/diags.conf | 4 +- earthdiagnostics/diags.py | 31 ++++---- earthdiagnostics/ocean/__init__.py | 3 +- earthdiagnostics/ocean/ice.py | 13 ++- earthdiagnostics/ocean/salinity.py | 62 +++++++++------ 8 files changed, 148 insertions(+), 120 deletions(-) diff --git a/earthdiagnostics/__init__.py b/earthdiagnostics/__init__.py index 7081a60..3381e76 100644 --- a/earthdiagnostics/__init__.py +++ b/earthdiagnostics/__init__.py @@ -1,6 +1,7 @@ from cdo import Cdo from nco import Nco from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.cdftools import CDFTools import os @@ -8,3 +9,4 @@ cdo = Cdo() nco = Nco() cdftools = CDFTools('/home/Earth/jvegas/CDFTOOLS_3.0/bin') DEVNULL = open(os.devnull, 'wb') + diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 22fa7ed..f07fc20 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -31,58 +31,58 @@ class DataManager(object): raise Exception('The experiment {0} is not CMORized. ' 'Please, CMORize it and launch again.'.format(self.expid)) - for startdate in startdates: - for member in members: - member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') - Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) - - threads = list() - numthreads = Utils.available_cpu_count() - filepaths = glob.glob(os.path.join(member_path, '*.gz')) - for numthread in range(0, numthreads): - t = threading.Thread(target=DataManager._unzip, - args=([filepaths[numthread::numthreads]])) - threads.append(t) - t.start() - - for t in threads: - t.join() - - filepaths = glob.glob(os.path.join(member_path, '*.tar')) - for numthread in range(0, numthreads): - t = threading.Thread(target=DataManager._untar, - args=(filepaths[numthread::numthreads], member_path)) - threads.append(t) - t.start() - - for t in threads: - t.join() - - if self.experiment_name != self.model: - bad_path = os.path.join(member_path, 'output', self.institution, self.model, self.model) - for (dirpath, dirnames, filenames) in os.walk(bad_path, False): - for filename in filenames: - filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_output_'.format(self.model), - '_{0}_{1}_'.format(self.model, self.experiment_name)) - - good = good.replace('/{0}/{0}'.format(self.model), - '/{0}/{1}'.format(self.model, - self.experiment_name)) - - Utils.move_file(filepath, good) - os.rmdir(dirpath) - - good_dir = os.path.join(member_path, 'output', self.institution, self.model, self.experiment_name) - for sdate in os.listdir(good_dir): - for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): - for filename in filenames: - filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name,sdate), - '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) - if good != filepath: - Log.info('Moving {0} to {1}'.format(filename, good)) - Utils.move_file(filepath, good) + # for startdate in startdates: + # for member in members: + # member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') + # Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) + # + # threads = list() + # numthreads = Utils.available_cpu_count() + # filepaths = glob.glob(os.path.join(member_path, '*.gz')) + # for numthread in range(0, numthreads): + # t = threading.Thread(target=DataManager._unzip, + # args=([filepaths[numthread::numthreads]])) + # threads.append(t) + # t.start() + # + # for t in threads: + # t.join() + # + # filepaths = glob.glob(os.path.join(member_path, '*.tar')) + # for numthread in range(0, numthreads): + # t = threading.Thread(target=DataManager._untar, + # args=(filepaths[numthread::numthreads], member_path)) + # threads.append(t) + # t.start() + # + # for t in threads: + # t.join() + # + # if self.experiment_name != self.model: + # bad_path = os.path.join(member_path, 'output', self.institution, self.model, self.model) + # for (dirpath, dirnames, filenames) in os.walk(bad_path, False): + # for filename in filenames: + # filepath = os.path.join(dirpath, filename) + # good = filepath.replace('_{0}_output_'.format(self.model), + # '_{0}_{1}_'.format(self.model, self.experiment_name)) + # + # good = good.replace('/{0}/{0}'.format(self.model), + # '/{0}/{1}'.format(self.model, + # self.experiment_name)) + # + # Utils.move_file(filepath, good) + # os.rmdir(dirpath) + # + # good_dir = os.path.join(member_path, 'output', self.institution, self.model, self.experiment_name) + # for sdate in os.listdir(good_dir): + # for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): + # for filename in filenames: + # filepath = os.path.join(dirpath, filename) + # good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name,sdate), + # '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) + # if good != filepath: + # Log.info('Moving {0} to {1}'.format(filename, good)) + # Utils.move_file(filepath, good) @staticmethod def _unzip(files): @@ -238,24 +238,6 @@ class DataManager(object): Utils.move_file(filetosend, filepath) - handler = netCDF4.Dataset('temp.nc', 'w') - handler.createDimension('time') - handler.createDimension('region') - var_time = handler.createVariable('time', float, 'time') - var_time[:] = [0, 1, 2] - var_region = handler.createVariable('region', str, 'region') - var_region[0] = 'region1' - var_content = handler.createVariable('content', float, ('time', 'region')) - var_content[:, 0] = [1, 2, 3] - handler.close() - - handler = netCDF4.Dataset('temp.nc', 'a') - var_region = handler.variables['region'] - var_region[1] = 'region2' - var_content = handler.variables['content'] - var_content[..., 1] = [4, 5, 6] - handler.close() - Utils.execute_shell_command('ncdump temp.nc', Log.INFO) diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 7c97c72..fa4f94f 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -1,5 +1,30 @@ class Diagnostic(object): + @staticmethod + def register(cls, alias): + try: + Diagnostic._diag_list[alias] = cls + except AttributeError: + Diagnostic._diag_list = dict() + Diagnostic._diag_list[alias] = cls + + @staticmethod + def get_diagnostic(name): + """ + Return the class for a diagnostic given its name + + :param name: diagnostic alias + :type name: str + :return: the selected Diagnostic class, None if name can not be found + :rtype: Diagnostic + """ + try: + if name in Diagnostic._diag_list.keys(): + return Diagnostic._diag_list[name] + except AttributeError: + pass + return None + def __init__(self, data_manager): self.data_manager = data_manager self.required_vars = [] @@ -7,4 +32,8 @@ class Diagnostic(object): self.can_run_multiple_instances = True def compute(self): - pass \ No newline at end of file + pass + + @classmethod + def generate_jobs(cls, data_manager, startdates, members, chunks, options): + raise Exception("Class must override generate_jobs method") \ No newline at end of file diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 4f9442d..f0de427 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = siasiesiv,glob +DIAGS = mlotstsc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -12,7 +12,7 @@ EXPID = a034 STARTDATES = 19500201 NAME = historical CHUNK_SIZE = 3 -CHUNKS = 1 +CHUNKS = 120 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index ba1c14b..ba64e82 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,12 +1,15 @@ #!/usr/bin/env python import argparse + +from datamanager import DataManager +from earthdiagnostics.ocean import * +from earthdiagnostics import Diagnostic import threading import netCDF4 -from datamanager import DataManager -from earthdiagnostics.ocean import Salinity, Circulation, Heat, General, Siasiesiv from utils import Utils from earthdiagnostics import cdftools, TempFile +from earthdiagnostics.diagnostic import Diagnostic from autosubmit.date.chunk_date_lib import * from parser import Parser from autosubmit.config.log import Log @@ -56,7 +59,8 @@ class Diags: os.chdir(self.scratch_dir) self._prepare_mesh_files() - + Diagnostic.register(MixedLayerSaltContent, 'mlotstsc') + Diagnostic.register(Siasiesiv, 'siasiesiv') self.datamanager.prepare_CMOR_files(self.startdates, self.members) # Run diagnostics @@ -66,15 +70,15 @@ class Diags: Log.info("Running {0}", fulldiag) diag_options = fulldiag.split(',') - if diag_options[0] == 'siasiesiv': - list_jobs += Siasiesiv.generate_jobs(self.datamanager, self.startdates, self.members, self.chunks, - diag_options) + diag_class = Diagnostic.get_diagnostic(diag_options[0]) + if diag_class: + list_jobs += diag_class.generate_jobs(self.datamanager, self.startdates, self.members, self.chunks, diag_options) continue - - for startdate in self.startdates: - for member in self.members: - for chunk in range(1, self.chunks+1): - self._execute_diagnostic(diag_options, startdate, member, chunk) + else: + for startdate in self.startdates: + for member in self.members: + for chunk in range(1, self.chunks+1): + self._execute_diagnostic(diag_options, startdate, member, chunk) Log.result('Finished {0}', fulldiag) @@ -202,11 +206,6 @@ class Diags: for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Heat.mixed_layer_content(input_file, mlotst_file, output_file) - elif diag == 'mlotstsc': - variables = ('so', 'mlotst', 'scvertsummlotst') - for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', - variables): - Salinity.mixed_layer_content(input_file, mlotst_file, output_file) elif diag == 'interp3d': variable = diag_options[1] if len(diag_options) == 3: diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 3950ca3..068bc02 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,5 +1,6 @@ -from salinity import Salinity +from earthdiagnostics.diagnostic import Diagnostic from heat import Heat from circulation import Circulation from general import General +from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index a5e2a5d..420af1a 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -28,8 +28,8 @@ class Siasiesiv(Diagnostic): self.generated_vars = ['siextents', 'sivols', 'siareas', 'siextentn', 'sivoln', 'siarean'] self.lock = lock - @staticmethod - def generate_jobs(data_manager, startdates, members, chunks, options): + @classmethod + def generate_jobs(cls, data_manager, startdates, members, chunks, options): basin = Basins.parse(options[1]) lock = threading.Lock() job_list = list() @@ -71,10 +71,11 @@ class Siasiesiv(Diagnostic): for time in range(ntime): Log.info('Running time {0}', time) temp = TempFile.get() + temp2 = TempFile.get() nco.ncks(input=sit_file, output=temp, options='-O -d time,{0}'.format(time)) - cdftools.run('cdficediags', input=temp) - Utils.move_file('icediags.nc', temp) - files.append(temp) + cdftools.run('cdficediags', input=temp, output=temp2) + os.remove(temp) + files.append(temp2) except Exception as ex: error = ex.message finally: @@ -194,5 +195,3 @@ class Siasiesiv(Diagnostic): if new_unit == 'm2': return pow(1000, 2) return None - - diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index cdaf254..fe9690a 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -1,54 +1,70 @@ +import threading + +from diagnostic import Diagnostic from earthdiagnostics import Utils, cdftools, TempFile from autosubmit.config.log import Log import os -import shutil -class Salinity(object): - """ - Class containing all the diagnostics related to salinity - """ +class MixedLayerSaltContent(Diagnostic): + def __init__(self, data_manager, startdate, member, chunk, lock): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['so', 'mlotst'] + self.generated_vars = ['scvertsum'] + self.lock = lock + @classmethod + def generate_jobs(cls, data_manager, startdates, members, chunks, options): + lock = threading.Lock() + job_list = list() + for startdate in startdates: + for member in members: + for chunk in range(1, chunks + 1): + job_list.append(MixedLayerSaltContent(data_manager, startdate, member, chunk, lock)) + return job_list - @staticmethod - def mixed_layer_content(input_file, mlotst_file, output_file): + def compute(self): """ Compute mixed layer heat and salt content Created in February 2012 Author : vguemas@ic3.cat - :param mlotst_file: - :param input_file: input grid_T file name - :param output_file: output file name (=> 2D x-y ) :return: """ nco = Utils.nco cdo = Utils.cdo - input_scratch = TempFile.get() - shutil.copy(input_file, input_scratch) - Utils.nco.ncks(input=mlotst_file, output=input_scratch, options='-A -v mlotst') + salinity_file = self.data_manager.get_file('ocean', 'so', self.startdate, self.member, self.chunk) + mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) + + Utils.nco.ncks(input=mlotst_file, output=salinity_file, options='-A -v mlotst') - ntime = int(cdo.ntime(input=input_scratch)[0]) + ntime = int(cdo.ntime(input=salinity_file)[0]) files = list() for time in range(ntime): Log.info('Running time {0}', time) temp = TempFile.get() - nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) + temp2 = TempFile.get() + nco.ncks(input=salinity_file, output=temp, options='-O -d time,{0}'.format(time)) Log.info('Computing salt content') - cdftools.run('cdfmxlsaltc', input=temp) - Utils.move_file('mxlsaltc.nc', temp) - files.append(temp) + cdftools.run('cdfmxlsaltc', input=temp, output=temp2) + os.remove(temp) + files.append(temp2) temp = TempFile.get() cdo.cat(input=' '.join(files), output=temp,) - nco.ncks(input=input_scratch, output=temp, options='-A -v time') + nco.ncks(input=salinity_file, output=temp, options='-A -v time') for temp_file in files: os.remove(temp_file) - os.remove(input_scratch) + os.remove(salinity_file) + + Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'scvertsum'}, False, True) + Utils.setminmax(temp, 'scvertsum') + self.data_manager.send_file(temp, 'ocean', 'scvertsum', self.startdate, self.member, self.chunk) + - Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'mlotstsc'}, False, True) - Utils.setminmax(temp, 'mlotstsc') - Utils.move_file(temp, output_file) -- GitLab From 68e2de004dc3fb8777b3a45916e39ec991b53bb6 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 7 Jun 2016 15:12:08 +0200 Subject: [PATCH 076/268] Changed vertical mean to the new way --- common_ocean_post.txt | 4 +- config_file-ocean_pp.bash | 10 ++-- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 1 + earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/general.py | 84 +++++++++++++++++++++++------- earthdiagnostics/ocean/salinity.py | 4 +- 7 files changed, 77 insertions(+), 30 deletions(-) diff --git a/common_ocean_post.txt b/common_ocean_post.txt index b1c4084..72665f8 100644 --- a/common_ocean_post.txt +++ b/common_ocean_post.txt @@ -455,10 +455,10 @@ for jt in $(seq 1 $ntime); do ncks -A mxl.nc intheat_sal_mxl.nc rm -f mxl.nc fi - cdfmxlheatc intheat_sal_mxl.nc + cdfmxlheatc intheat_sal_mxl.nc if [[ $lstvars != ${lstvars/vosaline} ]] ; then cdfmxlsaltc intheat_sal_mxl.nc - ncks -A mxlsaltc.nc mxlheatc.nc + ncks -A mxlsaltc.nc mxlheatc.nc rm -f mxlsaltc.nc fi mv mxlheatc.nc outputintheat_sal_mxl_$jt.nc diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index ec49270..8a31072 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('xohc') +listpost=('heat_sal_mxl') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 @@ -9,14 +9,14 @@ level2=14 #If temp_lev or sal_lev is chosen on listpost, the le raw_vars_ocean=( '' ) # If listpost contains "ext_raw_oce" option, this is the list ocean variables you want to extract. If nothing is specified, all variables present in input file will be treated. If raw_vars_ocean='default', sosstsst, sosaline, somixhgt and somxl010 will be extracted. raw_vars_ice=( '' ) # If listpost contains "ext_raw_ice" option, this is the list of seaice variables you want to extract. If nothing is specified, all variables will be treated. If raw_vars_ice='default', isnowthi, iicethic, ileadfra, iicetemp, and ice_pres will be extracted. raw_regions_ice=( 'North_Atlantic_Ocean' ) # If listpost contains "ohc_Arcticreg1" or "siasiesivsit_Arcticreg1" option, this is the list of sea ice regions you want to compute -expid=a030 # expid or nemovar_s4 / nemovar_combine / glorys2v1 +expid=a034 # expid or nemovar_s4 / nemovar_combine / glorys2v1 mod='ecearth' # nemo / ecearth typeoutput='MMO' # diags / MMO #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ listmemb=( 0 ) # list of members -syeari=1990 # first start date, format "yyyy" -syearf=1990 # last start date, format "yyyy" -moni=01 # first month of the hindcast, format "mm", e.g. 05 for May +syeari=1950 # first start date, format "yyyy" +syearf=1950 # last start date, format "yyyy" +moni=02 # first month of the hindcast, format "mm", e.g. 05 for May intsdate=1 # interval between start dates chunklen=3 # length of the chunks (in months) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index f0de427..4c8d82b 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = mlotstsc +DIAGS = vertmean,so,0,23 FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index ba64e82..1ba15d7 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -61,6 +61,7 @@ class Diags: self._prepare_mesh_files() Diagnostic.register(MixedLayerSaltContent, 'mlotstsc') Diagnostic.register(Siasiesiv, 'siasiesiv') + Diagnostic.register(VerticalMean, 'vertmean') self.datamanager.prepare_CMOR_files(self.startdates, self.members) # Run diagnostics diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 068bc02..5236a55 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ from earthdiagnostics.diagnostic import Diagnostic from heat import Heat from circulation import Circulation -from general import General +from general import General, VerticalMean from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 93d6c8b..127f252 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -1,20 +1,15 @@ from autosubmit.config.log import Log from earthdiagnostics import Utils, TempFile, cdftools +from earthdiagnostics.diagnostic import Diagnostic import shutil import os import numpy as np import threading -class General(object): - """ - General diagnostics that can be used with different variables +class VerticalMean(Diagnostic): """ - - @staticmethod - def vertical_mean(input_file, output_file, variable, lev_min, lev_max): - """ Choose vertical level in ocean, or vertically average between 2 or more ocean levels @@ -30,22 +25,73 @@ class General(object): selects this layer. If its different, a vertical integral (weighted) between upper and lower level is computed """ + def __init__(self, data_manager, startdate, member, chunk, variable, min_lev, max_lev): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.min_lev = min_lev + self.max_lev = max_lev + self.required_vars = [variable] + self.generated_vars = ['scvertsum'] + + def _get_output_var(self): + return '{0}mean{1}-{2}'.format(self.variable, self.min_lev, self.max_lev) + + @classmethod + def generate_jobs(cls, data_manager, startdates, members, chunks, options): + num_options = len(options) -1 + if num_options < 1: + raise Exception('You must specify the variable to average vertically') + if num_options > 3: + raise Exception('You must specify between one and three parameters for the vertical mean') + variable = options[1] + if num_options >= 2: + min_lev = int(options[2]) + else: + min_lev = None + if num_options >= 2: + max_lev = int(options[3]) + else: + max_lev = None + + job_list = list() + for startdate in startdates: + for member in members: + for chunk in range(1, chunks + 1): + job_list.append(VerticalMean(data_manager, startdate, member, chunk, + variable, min_lev, max_lev)) + return job_list + + def compute(self): temp = TempFile.get() - temp2 = TempFile.get() + variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) - shutil.copy(input_file, temp) + handler = Utils.nco.openCdf(variable_file) + if self.min_lev is None: + lev_min = handler.variables['lev'][0] + else: + lev_min = handler.variables['lev'][self.min_lev] - handler = Utils.nco.openCdf(temp) - lev_min = handler.variables['lev'][lev_min] - lev_max = handler.variables['lev'][lev_max] + if self.min_lev is None: + lev_max = handler.variables['lev'][-1] + else: + lev_max = handler.variables['lev'][self.max_lev] + handler.close() + + cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, + '-debug']) + Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) + Utils.rename_variable(temp, '{0}_vert_mean'.format(self.variable), self._get_output_var()) + self.data_manager.send_file(temp, 'ocean', self._get_output_var(), self.startdate, self.member, self.chunk) + + +class General(object): + """ + General diagnostics that can be used with different variables + """ - cdftools.run('cdfvertmean', input=temp, output=temp2, options=[variable, 'T', lev_min, lev_max, - '-debug']) - os.remove(temp) - Utils.setminmax(temp2, '{0}_vert_mean'.format(variable)) - Utils.rename_variable(temp2, '{0}_vert_mean'.format(variable), - '{0}mean{1}-{2}'.format(variable, lev_min, lev_max)) - Utils.move_file(temp2, output_file) @staticmethod def vertical_mean_meters(input_file, output_file, variable, upper, lower): diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index fe9690a..349c8c5 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -64,7 +64,7 @@ class MixedLayerSaltContent(Diagnostic): os.remove(salinity_file) Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'scvertsum'}, False, True) - Utils.setminmax(temp, 'scvertsum') - self.data_manager.send_file(temp, 'ocean', 'scvertsum', self.startdate, self.member, self.chunk) + Utils.setminmax(temp, 'scvsum') + self.data_manager.send_file(temp, 'ocean', 'scvsum', self.startdate, self.member, self.chunk) -- GitLab From baa0bb1e750a8cb7612ca944272b5ef039fcd836 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 7 Jun 2016 15:25:06 +0200 Subject: [PATCH 077/268] Changed vertical mean meters to the new way --- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 19 +----- earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/general.py | 96 +++++++++++++++++++++--------- 4 files changed, 72 insertions(+), 47 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 4c8d82b..c0da1b7 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = vertmean,so,0,23 +DIAGS = USALC FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 1ba15d7..8556267 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -62,6 +62,7 @@ class Diags: Diagnostic.register(MixedLayerSaltContent, 'mlotstsc') Diagnostic.register(Siasiesiv, 'siasiesiv') Diagnostic.register(VerticalMean, 'vertmean') + Diagnostic.register(VerticalMeanMeters, 'vertmeanmeters') self.datamanager.prepare_CMOR_files(self.startdates, self.members) # Run diagnostics @@ -106,23 +107,7 @@ class Diags: def _execute_diagnostic(self, diag_options, startdate, member, chunk): diag = diag_options[0] - if diag == 'vertmeanmeters': - variable = diag_options[1] - depth_min = int(diag_options[2]) - depth_max = int(diag_options[3]) - depth = '{0}m-{1}m'.format(depth_min, depth_max) - variables = (variable, '{0}mean{1}'.format(variable, depth)) - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): - General.vertical_mean_meters(input_file, output_file, variable, depth_min, depth_max) - elif diag == 'vertmean': - variable = diag_options[1] - lev_min = int(diag_options[2]) - lev_max = int(diag_options[3]) - lev = '{0}-{1}'.format(lev_min, lev_max) - variables = (variable, '{0}mean{1}'.format(variable, lev)) - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): - General.vertical_mean(input_file, output_file, variable, lev_min, lev_max) - elif diag == 'convection': + if diag == 'convection': variables = ('mlotst', 'mlotstsites') for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.convection_sites(input_file, self.nemo_version, output_file) diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 5236a55..89c0e3b 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ from earthdiagnostics.diagnostic import Diagnostic from heat import Heat from circulation import Circulation -from general import General, VerticalMean +from general import General, VerticalMean, VerticalMeanMeters from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 127f252..d0177a0 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -34,7 +34,7 @@ class VerticalMean(Diagnostic): self.min_lev = min_lev self.max_lev = max_lev self.required_vars = [variable] - self.generated_vars = ['scvertsum'] + self.generated_vars = [self._get_output_var()] def _get_output_var(self): return '{0}mean{1}-{2}'.format(self.variable, self.min_lev, self.max_lev) @@ -87,15 +87,8 @@ class VerticalMean(Diagnostic): self.data_manager.send_file(temp, 'ocean', self._get_output_var(), self.startdate, self.member, self.chunk) -class General(object): - """ - General diagnostics that can be used with different variables +class VerticalMeanMeters(Diagnostic): """ - - - @staticmethod - def vertical_mean_meters(input_file, output_file, variable, upper, lower): - """ Vertically averaged salt content Created in February 2012 Author : vguemas@ic3.cat @@ -105,28 +98,75 @@ class General(object): :param lower: lower depth of the layer (in meters) :type lower: int :param output_file: output file name (=> 2D) - """ - cdo = Utils.cdo - nco = Utils.nco + """ + + def __init__(self, data_manager, startdate, member, chunk, variable, min_depth, max_depth): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.min_depth = min_depth + self.max_depth = max_depth + self.required_vars = [variable] + self.generated_vars = [self._get_output_var()] + + def _get_output_var(self): + return '{0}mean{1}m-{2}m'.format(self.variable, self.min_depth, self.max_depth) + @classmethod + def generate_jobs(cls, data_manager, startdates, members, chunks, options): + num_options = len(options) - 1 + if num_options < 1: + raise Exception('You must specify the variable to average vertically') + if num_options > 3: + raise Exception('You must specify between one and three parameters for the vertical mean') + variable = options[1] + if num_options >= 2: + min_lev = float(options[2]) + else: + min_lev = None + if num_options >= 2: + max_lev = float(options[3]) + else: + max_lev = None + + job_list = list() + for startdate in startdates: + for member in members: + for chunk in range(1, chunks + 1): + job_list.append(VerticalMeanMeters(data_manager, startdate, member, chunk, + variable, min_lev, max_lev)) + return job_list + + def compute(self): temp = TempFile.get() - temp2 = TempFile.get() - # test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values - # out of that range to be replaced by NaN - # - if cdo.version() > u'1.5.6': - nco.ncatted(input=input_file, output=temp, options='-O -a valid_max,lev,d,,') - nco.ncatted(input=temp, output=temp, options='-O -a valid_min,lev,d,,') + variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) + + handler = Utils.nco.openCdf(variable_file) + if self.min_depth is None: + lev_min = handler.variables['lev'][0] else: - shutil.copy(input_file, temp) - - cdftools.run('cdfvertmean', input=temp, output=temp2, options=[variable, 'T', str(upper), str(lower), - '-debug']) - os.remove(temp) - Utils.setminmax(temp2, '{0}_vert_mean'.format(variable)) - Utils.rename_variable(temp2, '{0}_vert_mean'.format(variable), - '{0}mean{1}m-{2}m'.format(variable, upper, lower)) - Utils.move_file(temp2, output_file) + lev_min = self.min_depth + + if self.min_depth is None: + lev_max = handler.variables['lev'][-1] + else: + lev_max = self.max_depth + handler.close() + + cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, + '-debug']) + Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) + Utils.rename_variable(temp, '{0}_vert_mean'.format(self.variable), self._get_output_var()) + self.data_manager.send_file(temp, 'ocean', self._get_output_var(), self.startdate, self.member, self.chunk) + + +class General(object): + """ + General diagnostics that can be used with different variables + """ + @staticmethod def interpolate(input_file, output_file, variable, nemo_version): -- GitLab From 7309e2b621106a3d4040747055bf81c3df6da9fb Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 8 Jun 2016 13:10:40 +0200 Subject: [PATCH 078/268] Changed interpolation to the new way --- earthdiagnostics/basins.py | 2 - earthdiagnostics/datamanager.py | 24 ++- earthdiagnostics/diagnostic.py | 2 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 62 ++++--- earthdiagnostics/ocean/__init__.py | 4 +- earthdiagnostics/ocean/circulation.py | 16 +- earthdiagnostics/ocean/general.py | 224 ++++++++++++++------------ earthdiagnostics/ocean/heat.py | 20 +-- earthdiagnostics/ocean/ice.py | 30 ++-- earthdiagnostics/ocean/salinity.py | 10 +- earthdiagnostics/utils.py | 16 +- 12 files changed, 218 insertions(+), 194 deletions(-) diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index 8b4d74d..528a692 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -90,8 +90,6 @@ class Basin(object): class Basins(object): - - """ Predefined basins """ diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index f07fc20..0fe5cf6 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,8 +1,8 @@ -import glob +# import glob import shutil -import threading - -import netCDF4 +# import threading +# +# import netCDF4 import os import numpy as np from autosubmit.config.log import Log @@ -170,6 +170,9 @@ class DataManager(object): return temp_path def send_file(self, filetosend, domain, var, startdate, member, chunk, grid=None, region=None): + + Utils.convert2netcdf4(filetosend) + if domain == 'seaIce': domain_abreviattion = 'OI' else: @@ -200,9 +203,8 @@ class DataManager(object): if region: if not os.path.exists(filepath): - Utils.convert2netcdf4(filetosend) - handler = Utils.cdo.openCdf(filetosend) + handler = Utils.openCdf(filetosend) handler.createDimension('region') var_region = handler.createVariable('region', str, 'region') var_region[0] = region @@ -219,8 +221,8 @@ class DataManager(object): else: temp = TempFile.get() shutil.copyfile(filepath, temp) - handler = Utils.cdo.openCdf(temp) - handler_send = Utils.cdo.openCdf(filetosend) + handler = Utils.openCdf(temp) + handler_send = Utils.openCdf(filetosend) value = handler_send.variables[var][:] var_region = handler.variables['region'] basin_index = np.where(var_region[:] == region) @@ -238,12 +240,6 @@ class DataManager(object): Utils.move_file(filetosend, filepath) - - - - - - # # set -vx # diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index fa4f94f..2e20251 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -35,5 +35,5 @@ class Diagnostic(object): pass @classmethod - def generate_jobs(cls, data_manager, startdates, members, chunks, options): + def generate_jobs(cls, diags, options): raise Exception("Class must override generate_jobs method") \ No newline at end of file diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index c0da1b7..9452b95 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = USALC +DIAGS = 3dsal FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 8556267..c788135 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -27,10 +27,10 @@ class Diags: def __init__(self, config_file): Log.debug('Initialising Diags') self._read_config(config_file) - self.datamanager = DataManager(self.institute, self.model, self.expid, self.data_dir, - self.frequency, self.chunk_size, self.experiment_name) - self.datamanager.add_startdate = self.add_startdate - self.datamanager.add_name = self.add_name + self.data_manager = DataManager(self.institute, self.model, self.expid, self.data_dir, + self.frequency, self.chunk_size, self.experiment_name) + self.data_manager.add_startdate = self.add_startdate + self.data_manager.add_name = self.add_name TempFile.scratch_folder = self.scratch_dir cdftools.path = self.cdftools_path self._create_dic_variables() @@ -59,11 +59,15 @@ class Diags: os.chdir(self.scratch_dir) self._prepare_mesh_files() + Diagnostic.register(MixedLayerSaltContent, 'mlotstsc') Diagnostic.register(Siasiesiv, 'siasiesiv') Diagnostic.register(VerticalMean, 'vertmean') Diagnostic.register(VerticalMeanMeters, 'vertmeanmeters') - self.datamanager.prepare_CMOR_files(self.startdates, self.members) + Diagnostic.register(Interpolate, 'interp') + parse_date('20000101') + + self.data_manager.prepare_CMOR_files(self.startdates, self.members) # Run diagnostics Log.info('Running diagnostics') @@ -74,7 +78,7 @@ class Diags: diag_class = Diagnostic.get_diagnostic(diag_options[0]) if diag_class: - list_jobs += diag_class.generate_jobs(self.datamanager, self.startdates, self.members, self.chunks, diag_options) + list_jobs += diag_class.generate_jobs(self, diag_options) continue else: for startdate in self.startdates: @@ -109,16 +113,16 @@ class Diags: diag = diag_options[0] if diag == 'convection': variables = ('mlotst', 'mlotstsites') - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.convection_sites(input_file, self.nemo_version, output_file) elif diag == 'psi': variables = ('uo', 'vo', 'vsftbarot') - for [u_file, v_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', - variables): + for [u_file, v_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', + variables): Circulation.psi(u_file, v_file, output_file) elif diag == 'gyres': variables = ('vsftbarot', 'vsftbarotgyres') - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.gyres(str(input_file), self.nemo_version, str(output_file)) elif diag == 'ohc': basin = diag_options[1] @@ -136,9 +140,9 @@ class Diags: mxl = 'nomlotst' depth = '' variables = ('thetao', 'mlotst', 'ohcsum{0}{1}', 'ohcvmean{0}{1}'.format(mxl, depth)) - for [input_file, mlotst_file, ohcsum_file, ohcvmean_file] in self.datamanager.get_files(startdate, member, - chunk, 'ocean', - variables): + for [input_file, mlotst_file, ohcsum_file, ohcvmean_file] in self.data_manager.get_files(startdate, member, + chunk, 'ocean', + variables): Heat.total(input_file, mlotst_file, ohcsum_file, ohcvmean_file, basin, mixed_layer, depth_min, depth_max) elif diag == 'ohclayer': depth_min = int(diag_options[1]) @@ -146,11 +150,11 @@ class Diags: depth = '{0}-{1}'.format(depth_min, depth_max) variables = ('thetao', 'ohc{0}'.format(depth)) - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Heat.layer(input_file, output_file, depth_min, depth_max) elif diag in ['moc', 'vsftmyz']: variables = ('vo', 'vsftmyz') - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.moc(input_file, output_file) elif diag in ['mocmax', 'vsftmyzmax']: if len(diag_options) != 5: @@ -165,7 +169,7 @@ class Diags: depth_max = int(diag_options[4]) depth = '{0}-{1}'.format(depth_min, depth_max) variables = ('vsftmyz', 'vsftmyzmax') - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.max_moc(input_file, lat_min, lat_max, output_file.replace('vsftmyzmax', 'vsftmyzmax{0}-{1}'.format(lat, depth)), depth_min, depth_max) @@ -185,33 +189,21 @@ class Diags: basin = diag_options[5] variables = ('vsftmyz', 'vsftmyz{0}{1}{2}'.format(lat, depth, basin)) - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) elif diag == 'mlotsthc': variables = ('thetao', 'mlotst', 'ohcvertsummlotst') - for [input_file, mlotst_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', - variables): + for [input_file, mlotst_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', + variables): Heat.mixed_layer_content(input_file, mlotst_file, output_file) - elif diag == 'interp3d': - variable = diag_options[1] - if len(diag_options) == 3: - domain = diag_options[2] - if domain == 'seaice': - domain = 'seaIce' - else: - domain = 'ocean' - input_files = self.datamanager.get_files(startdate, member, chunk, domain, [variable]) - output_files = self.datamanager.get_files(startdate, member, chunk, domain, [variable], 'regular') - for x in range(0, len(input_files[0])): - General.interpolate(input_files[0][x], output_files[0][x], variable, self.nemo_version) elif diag == 'cutsection': variable = diag_options[1] zonal = diag_options[2] == 'z' value = int(diag_options[3]) coordinate = Utils.get_cardinal_coordinate(value, zonal) variables = (variable, '{0}{1}'.format(variable, coordinate)) - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables, - 'regular'): + for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables, + 'regular'): General.cut_section(input_file, output_file, variable, zonal, value) elif diag == 'avgsection': variable = diag_options[1] @@ -225,7 +217,7 @@ class Diags: Utils.get_cardinal_coordinate(lat_min, True), Utils.get_cardinal_coordinate(lat_max, True)) variables = (variable, output_name) - for [input_file, output_file] in self.datamanager.get_files(startdate, member, chunk, 'ocean', variables): + for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): General.avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max) else: Log.warning('Diagnostic {0} not available', diag) @@ -237,7 +229,7 @@ class Diags: for alias, added_commands in self._aliases.items(): if alias in commands: - Log.debug('Changing alias {0} for {1}', alias, ' '.join(added_commands)) + Log.info('Changing alias {0} for {1}', alias, ' '.join(added_commands)) commands.remove(alias) for add_command in added_commands: commands.append(add_command) diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 89c0e3b..83c177b 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ -from earthdiagnostics.diagnostic import Diagnostic +# from earthdiagnostics.diagnostic import Diagnostic from heat import Heat from circulation import Circulation -from general import General, VerticalMean, VerticalMeanMeters +from general import General, VerticalMean, VerticalMeanMeters, Interpolate from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 4fd4ba7..ed0eb1d 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -37,7 +37,7 @@ class Circulation(object): Utils.convert2netcdf4(temp) Log.debug('Reformatting variables') - handler = Utils.cdo.openCdf(temp) + handler = Utils.openCdf(temp) handler.createDimension('basin', 5) handler.createVariable('basin', str, 'basin') @@ -94,11 +94,11 @@ class Circulation(object): shutil.copy(input_file, temp) - handler = Utils.nco.openCdf(temp) + handler = Utils.openCdf(temp) if 'i' in handler.dimensions: handler.close() nco.ncwa(input=temp, output=temp, options='-O -a i') - handler = Utils.cdo.openCdf(temp) + handler = Utils.openCdf(temp) basin_instance = Basins.parse(basin) if not basin_instance: @@ -121,7 +121,7 @@ class Circulation(object): nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev') - handler = Utils.nco.openCdf(temp) + handler = Utils.openCdf(temp) handler.renameDimension('j', 'lat') lat_variable = handler.createVariable('lat', lat_type, 'lat') lat_variable[:] = lat_values[:] @@ -165,7 +165,7 @@ class Circulation(object): basin = Basins.parse(basin) shutil.copy(input_file, temp) - handler = Utils.cdo.openCdf(temp) + handler = Utils.openCdf(temp) if 'i' in handler.dimensions: nco.ncwa(input=temp, output=temp, options='-O -a i') else: @@ -177,7 +177,7 @@ class Circulation(object): handler.close() # Utils.rename_variable(temp, 'record', 'x') - handler = Utils.nco.openCdf(temp) + handler = Utils.openCdf(temp) lat_values = handler.variables['lat'][:] lat_type = handler.variables['lat'].dtype lat_units = handler.variables['lat'].units @@ -189,7 +189,7 @@ class Circulation(object): nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev,lev_bnds') - handler = Utils.nco.openCdf(temp) + handler = Utils.openCdf(temp) handler.renameDimension('j', 'lat') lat_variable = handler.createVariable('lat', lat_type, 'lat') lat_variable[:] = lat_values[:] @@ -201,7 +201,7 @@ class Circulation(object): options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(depth_min, depth_max, lat_min, lat_max)) Utils.cdo.yearmean(input=temp2, output=temp) - handler = nco.openCdf(temp) + handler = Utils.openCdf(temp) moc = handler.variables['vsftmyz'][:] diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index d0177a0..698411c 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -5,7 +5,6 @@ from earthdiagnostics.diagnostic import Diagnostic import shutil import os import numpy as np -import threading class VerticalMean(Diagnostic): @@ -17,11 +16,11 @@ class VerticalMean(Diagnostic): Modified (more generic, i.e. for any input var) in December 2014 Author : eleftheria.exarchou@ic3.cat - :param input_file: input file name - :param output_file: output file name (=> 2D field ) - :param variable: variable name - :param lev_min: upper depth of the layer (in level number) - :param lev_max: lower depth of the layer (in level number. If same as the upper layer, then the script just + # :param input_file: input file name + # :param output_file: output file name (=> 2D field ) + # :param variable: variable name + # :param lev_min: upper depth of the layer (in level number) + # :param lev_max: lower depth of the layer (in level number. If same as the upper layer, then the script just selects this layer. If its different, a vertical integral (weighted) between upper and lower level is computed """ @@ -40,7 +39,7 @@ class VerticalMean(Diagnostic): return '{0}mean{1}-{2}'.format(self.variable, self.min_lev, self.max_lev) @classmethod - def generate_jobs(cls, data_manager, startdates, members, chunks, options): + def generate_jobs(cls, diags, options): num_options = len(options) -1 if num_options < 1: raise Exception('You must specify the variable to average vertically') @@ -57,10 +56,10 @@ class VerticalMean(Diagnostic): max_lev = None job_list = list() - for startdate in startdates: - for member in members: - for chunk in range(1, chunks + 1): - job_list.append(VerticalMean(data_manager, startdate, member, chunk, + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(VerticalMean(diags.data_manager, startdate, member, chunk, variable, min_lev, max_lev)) return job_list @@ -68,7 +67,7 @@ class VerticalMean(Diagnostic): temp = TempFile.get() variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) - handler = Utils.nco.openCdf(variable_file) + handler = Utils.openCdf(variable_file) if self.min_lev is None: lev_min = handler.variables['lev'][0] else: @@ -92,12 +91,12 @@ class VerticalMeanMeters(Diagnostic): Vertically averaged salt content Created in February 2012 Author : vguemas@ic3.cat - :param input_file: input grid_T file name - :param upper: upper depth of the layer (in meters) - :type upper: int - :param lower: lower depth of the layer (in meters) - :type lower: int - :param output_file: output file name (=> 2D) + # :param input_file: input grid_T file name + # :param upper: upper depth of the layer (in meters) + # :type upper: int + # :param lower: lower depth of the layer (in meters) + # :type lower: int + # :param output_file: output file name (=> 2D) """ def __init__(self, data_manager, startdate, member, chunk, variable, min_depth, max_depth): @@ -115,7 +114,7 @@ class VerticalMeanMeters(Diagnostic): return '{0}mean{1}m-{2}m'.format(self.variable, self.min_depth, self.max_depth) @classmethod - def generate_jobs(cls, data_manager, startdates, members, chunks, options): + def generate_jobs(cls, diags, options): num_options = len(options) - 1 if num_options < 1: raise Exception('You must specify the variable to average vertically') @@ -132,10 +131,10 @@ class VerticalMeanMeters(Diagnostic): max_lev = None job_list = list() - for startdate in startdates: - for member in members: - for chunk in range(1, chunks + 1): - job_list.append(VerticalMeanMeters(data_manager, startdate, member, chunk, + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(VerticalMeanMeters(diags.data_manager, startdate, member, chunk, variable, min_lev, max_lev)) return job_list @@ -143,7 +142,7 @@ class VerticalMeanMeters(Diagnostic): temp = TempFile.get() variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) - handler = Utils.nco.openCdf(variable_file) + handler = Utils.openCdf(variable_file) if self.min_depth is None: lev_min = handler.variables['lev'][0] else: @@ -162,32 +161,57 @@ class VerticalMeanMeters(Diagnostic): self.data_manager.send_file(temp, 'ocean', self._get_output_var(), self.startdate, self.member, self.chunk) -class General(object): - """ - General diagnostics that can be used with different variables +class Interpolate(Diagnostic): """ - - - @staticmethod - def interpolate(input_file, output_file, variable, nemo_version): - """ 3-dimensional conservative interpolation to the regular atmospheric grid Created in November 2012 Author : vguemas@ic3.cat - :param nemo_version: - :param input_file: - :param output_file: - :param variable: + # :param nemo_version: + # :param input_file: + # :param output_file: + # :param variable: :return: - """ - temp = TempFile.get() - temp2 = TempFile.get() - shutil.copy(input_file, temp) + """ + + def __init__(self, data_manager, startdate, member, chunk, variable, domain, nemo_version): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.nemo_version = nemo_version + self.required_vars = [variable] + self.generated_vars = [variable] + self.tempTemplate = '' + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 1: + raise Exception('You must specify the variable to average vertically') + if num_options > 2: + raise Exception('You must specify between 1 and 2 parameters for the interpolation diagnostic') + variable = options[1] + if num_options >= 2: + domain = int(options[2]) + else: + domain = 'ocean' + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Interpolate(diags.data_manager, startdate, member, chunk, + variable, domain, diags.nemo_version)) + return job_list + + def compute(self): + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) cdo = Utils.cdo nco = Utils.nco - handler = cdo.openCdf(temp) + handler = Utils.openCdf(variable_file) if 'lev' in handler.dimensions: num_levels = handler.dimensions['lev'].size has_levels = True @@ -195,73 +219,75 @@ class General(object): num_levels = 1 has_levels = False handler.close() + for lev in range(0, num_levels): + self._interpolate_level(lev, has_levels, variable_file) - threads = list() - numthreads = Utils.available_cpu_count() - - for numthread in range(0, numthreads): - t = threading.Thread(target=General._interpolate_level, - args=(range(numthread, num_levels, numthreads),has_levels, temp, variable, - nemo_version)) - threads.append(t) - t.start() - - for t in threads: - t.join() + temp = TempFile.get() if has_levels: - nco.ncrcat(input='tmp_01.nc', output=temp2, - options='-n {0},2,1 -v {1}'.format(num_levels, variable)) + nco.ncrcat(input=self._get_level_file(0), output=temp, + options="-n {0},2,1 -v '{1}'".format(num_levels, self.variable)) else: - Utils.move_file('tmp_01.nc', temp2) + Utils.move_file(self._get_level_file(0), temp) - handler = nco.openCdf(temp2) + handler = Utils.openCdf(temp) handler.renameDimension('record', 'lev') handler.close() - nco.ncpdq(input=temp2, output=temp2, options='-O -h -a time,lev') + nco.ncpdq(input=temp, output=temp, options='-O -h -a time,lev') if has_levels: - nco.ncks(input=temp, output=temp2, options='-A -v lev') + nco.ncks(input=variable_file, output=temp, options='-A -v lev') for lev in range(0, num_levels): - os.remove('tmp_{0:02d}.nc'.format(lev + 1)) - - cdo.setgrid('t106grid', input=temp2, output=temp) - if nemo_version[6:9] == '025': - cdo.invertlatdata(input=temp, output=temp) + os.remove(self._get_level_file(lev)) + temp2 = TempFile.get() + cdo.setgrid('t106grid', input=temp, output=temp2) + os.remove(temp) + if self.nemo_version[6:9] == '025': + cdo.invertlatdata(input=temp2, output=temp2) if not has_levels: - nco.ncks(input=temp, output=temp, options='-O -v sic,lat,lon,time') + nco.ncks(input=temp2, output=temp2, options='-O -v sic,lat,lon,time') - os.remove(temp2) - Utils.move_file(temp, output_file) + self.data_manager.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, + grid='regular') - @staticmethod - def _interpolate_level(levs, has_levels, input_file, variable, nemo_version): - for lev in levs: - nco = Utils.nco - temp = TempFile.get() - if has_levels: - nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1}'.format(lev, variable)) - nco.ncwa(input=temp, output=temp, options='-O -h -a lev') - else: - shutil.copy(input_file, temp) - namelist_file = 'scrip_use_in{0}'.format(lev) - scrip_use_in = open(namelist_file, 'w') - scrip_use_in.writelines("&remap_inputs\n") - scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" - "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(nemo_version, lev+1)) - scrip_use_in.writelines(" infile = '{0}'\n".format(temp)) - scrip_use_in.writelines(" invertlat = FALSE\n") - scrip_use_in.writelines(" var = '{0}'\n".format(variable)) - scrip_use_in.writelines(" fromregular = FALSE\n") - scrip_use_in.writelines(" outfile = '{0}'\n".format(temp)) - scrip_use_in.writelines("/\n") - scrip_use_in.close() - Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use ' - '{0}'.format(namelist_file), Log.NO_LOG) - os.remove(namelist_file) - nco.ncecat(input=temp, output=temp, options="-O -h") - shutil.move(temp, 'tmp_{0:02d}.nc'.format(lev + 1)) - Log.debug("Level {0} ready", lev) + def _get_level_file(self, lev): + if not self.tempTemplate: + self.tempTemplate = TempFile.get(suffix='_01.nc') + # self.tempTemplate = 'temp_01.nc' + return self.tempTemplate.replace('_01.nc', '_{0:02d}.nc'.format(lev +1)) + + def _interpolate_level(self, lev, has_levels, input_file): + nco = Utils.nco + temp = TempFile.get() + if has_levels: + nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1}'.format(lev, self.variable)) + nco.ncwa(input=temp, output=temp, options='-O -h -a lev') + else: + shutil.copy(input_file, temp) + namelist_file = TempFile.get(suffix='') + scrip_use_in = open(namelist_file, 'w') + scrip_use_in.writelines("&remap_inputs\n") + scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" + "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(self.nemo_version, lev + 1)) + scrip_use_in.writelines(" infile = '{0}'\n".format(temp)) + scrip_use_in.writelines(" invertlat = FALSE\n") + scrip_use_in.writelines(" var = '{0}'\n".format(self.variable)) + scrip_use_in.writelines(" fromregular = FALSE\n") + scrip_use_in.writelines(" outfile = '{0}'\n".format(temp)) + scrip_use_in.writelines("/\n") + scrip_use_in.close() + Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use ' + '{0}'.format(namelist_file), Log.NO_LOG) + os.remove(namelist_file) + nco.ncecat(input=temp, output=temp, options="-O -h") + shutil.move(temp, self._get_level_file(lev)) + Log.debug("Level {0} ready", lev) + + +class General(object): + """ + General diagnostics that can be used with different variables + """ @staticmethod def cut_section(input_file, output_file, variable, zonal, value): @@ -279,7 +305,7 @@ class General(object): nco = Utils.nco - handler = nco.openCdf('mesh_hgr.nc') + handler = Utils.openCdf('mesh_hgr.nc') dimi = handler.dimensions['i'].size dimj = handler.dimensions['j'].size dimlev = handler.dimensions['lev'].size @@ -288,7 +314,7 @@ class General(object): lat = handler.variables['lat'][:] handler.close() - handler = nco.openCdf('mask.nc') + handler = Utils.openCdf('mask.nc') mask_lev = handler.variables['tmask'][:] mask_lev = mask_lev.astype(float) # noinspection PyTypeChecker @@ -328,7 +354,7 @@ class General(object): temp = TempFile.get() shutil.copy(input_file, temp) - handler = nco.openCdf(temp) + handler = Utils.openCdf(temp) dimtime = handler.dimensions['time'].size var_array = handler.variables[variable][:] handler.close() @@ -348,7 +374,7 @@ class General(object): nco.ncks(input=temp, output=temp, options='-O -v lev,time') - handler = nco.openCdf(temp) + handler = Utils.openCdf(temp) if not zonal: handler.createDimension('lat', size) coord_var = handler.createVariable('lat', float, 'lat') diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index b7624fe..beb1b44 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -109,11 +109,11 @@ class Heat(object): nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') - handler = nco.openCdf(level_above) + handler = Utils.openCdf(level_above) lev_above = handler.variables['lev'][:] handler.close() - handler = nco.openCdf(level_below) + handler = Utils.openCdf(level_below) layerthcknss = handler.variables['lev'][:] - lev_above heatc_sl_below = handler.variables['heatc_sl'][:] handler.close() @@ -121,7 +121,7 @@ class Heat(object): factor = (max_depth - lev_above) / layerthcknss heatc_sl_below = heatc_sl_below * factor - handler = nco.openCdf(heatc_sl_top) + handler = Utils.openCdf(heatc_sl_top) heatc_sl = handler.variables['heatc_sl'][:] handler.close() @@ -130,11 +130,11 @@ class Heat(object): heatc_sl = heatc_sl[:] * 1020 * 4000 nco.ncks(input=heatc_sl_top_invert, output=results, options='-O -v lon,lat,time') - handler_results = nco.openCdf(results) + handler_results = Utils.openCdf(results) handler_results.createVariable('ohc', float, ('time', 'y', 'x')) handler_results.close() - handler_results = nco.openCdf(results) + handler_results = Utils.openCdf(results) handler_results.variables['ohc'][:] = heatc_sl handler_results.close() @@ -149,9 +149,10 @@ class Heat(object): Created in May 2012 Author : vguemas@ic3.cat + :param ohcvmean_file: + :param ohcsum_file: :param mlotst_file: :param input_file: input temperature file name - :param output_file: output file name ( => 2D x-y :param basin: basin name (default: global) :param mixed_layer: mixed layer (1=only, 0=included, -1=without) :param upper: upper level of the layer (optional) Default : top @@ -161,13 +162,12 @@ class Heat(object): nco = Utils.nco temp = TempFile.get() - shutil.copy(input_file, temp) nco.ncks(input=mlotst_file, output=temp, options='-A -v mlotst') basin = Basins.parse(basin) - handler = nco.openCdf('mask_regions.3d.nc') + handler = Utils.openCdf('mask_regions.3d.nc') if basin.fullname not in handler.variables: raise Exception('Basin {0} is not defined on mask_regions.nc'.format(basin.fullname)) @@ -203,13 +203,13 @@ class Heat(object): nco.ncks(input=temp, output=ohcsum_temp, options='-O -v time') shutil.copy(ohcsum_temp, ohcvmean_temp) - ohcsum_handler = nco.openCdf(ohcsum_temp) + ohcsum_handler = Utils.openCdf(ohcsum_temp) thc = ohcsum_handler.createVariable('ohcsum', float, 'time') thc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" thc.long_name = "Total heat content" thc.units = "Joules" - ohcvmean_handler = nco.openCdf(ohcvmean_temp) + ohcvmean_handler = Utils.openCdf(ohcvmean_temp) uhc = ohcvmean_handler.createVariable('ohcvmean', float, 'time') uhc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" uhc.long_name = "Heat content per unit volume" diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/ice.py index 420af1a..083de1c 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/ice.py @@ -29,14 +29,14 @@ class Siasiesiv(Diagnostic): self.lock = lock @classmethod - def generate_jobs(cls, data_manager, startdates, members, chunks, options): + def generate_jobs(cls, diags, options): basin = Basins.parse(options[1]) lock = threading.Lock() job_list = list() - for startdate in startdates: - for member in members: - for chunk in range(1, chunks + 1): - job_list.append(Siasiesiv(data_manager, basin, startdate, member, chunk, lock)) + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk, lock)) return job_list def compute(self): @@ -93,25 +93,31 @@ class Siasiesiv(Diagnostic): nco.ncks(input=sit_file, output=temp, options='-A -v time') self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SVolume', 'sivols', "10^3 km3"), - 'seaIce', 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) + 'seaIce', 'sivols', self.startdate, self.member, self.chunk, + region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SArea', 'siareas', "10^6 km2"), - 'seaIce', 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) + 'seaIce', 'siareas', self.startdate, self.member, self.chunk, + region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SExnsidc', 'siextents', "10^6 km2"), - 'seaIce', 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) + 'seaIce', 'siextents', self.startdate, self.member, self.chunk, + region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NVolume', 'sivoln', "10^3 km3"), - 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) + 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, + region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NArea', 'siarean', "10^6 km2"), - 'seaIce', 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) + 'seaIce', 'siarean', self.startdate, self.member, self.chunk, + region=self.basin.fullname) self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NExnsidc', 'siextentn', "10^6 km2"), - 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) + 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, + region=self.basin.fullname) os.remove(temp) def _extract_variable_and_rename(self, input_file, variable, cmor_name, output_units): temp = TempFile.get() # Utils.nco.ncks(input=input_file, output=temp, options='-O -v {0},time,time_bnds'.format(variable)) - input_handler = Utils.cdo.openCdf(input_file) + input_handler = Utils.openCdf(input_file) os.remove(temp) handler = netCDF4.Dataset(temp, 'w') diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/salinity.py index 349c8c5..7af984e 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/salinity.py @@ -18,13 +18,13 @@ class MixedLayerSaltContent(Diagnostic): self.lock = lock @classmethod - def generate_jobs(cls, data_manager, startdates, members, chunks, options): + def generate_jobs(cls, diags, options): lock = threading.Lock() job_list = list() - for startdate in startdates: - for member in members: - for chunk in range(1, chunks + 1): - job_list.append(MixedLayerSaltContent(data_manager, startdate, member, chunk, lock)) + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(MixedLayerSaltContent(diags.datamanager, startdate, member, chunk, lock)) return job_list def compute(self): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 12bded5..639f47c 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -1,5 +1,6 @@ import subprocess +import netCDF4 import numpy as np import re from autosubmit.config.log import Log @@ -74,7 +75,7 @@ class Utils(object): :param rename_dimension: if True, also rename dimensions with the same name :type rename_dimension: bool """ - handler = Utils.nco.openCdf(filepath) + handler = Utils.openCdf(filepath) for old_name, new_name in dic_names.items(): if old_name in handler.variables: @@ -183,15 +184,19 @@ class Utils(object): @staticmethod def convert2netcdf4(filetoconvert): temp = TempFile.get() - handler = Utils.cdo.openCdf(filetoconvert) + handler = Utils.openCdf(filetoconvert) if handler.file_format == 'NETCDF4': handler.close() return handler.close() - Log.debug('Reformating to netCDF-4') + Log.debug('Reformatting to netCDF-4') Utils.execute_shell_command(["nccopy", "-4", filetoconvert, temp]) shutil.move(temp, filetoconvert) + @staticmethod + def openCdf(filepath, mode='a'): + return netCDF4.Dataset(filepath, mode) + class TempFile(object): """ @@ -216,10 +221,11 @@ class TempFile(object): """ @staticmethod - def get(filename=None, clean=None): + def get(filename=None, clean=None, suffix='.nc'): """ Gets a new temporal filename, storing it for automated cleaning + :param suffix: :param filename: if it is not none, the function will use this filename instead of a random one :type filename: str :param clean: if true, stores filename for cleaning @@ -234,7 +240,7 @@ class TempFile(object): path = os.path.join(TempFile.scratch_folder, filename) else: - fd, path = tempfile.mkstemp(dir=TempFile.scratch_folder, prefix=TempFile.prefix, suffix='.nc') + fd, path = tempfile.mkstemp(dir=TempFile.scratch_folder, prefix=TempFile.prefix, suffix=suffix) os.close(fd) if clean: -- GitLab From b7f7a69744859d93db707bbb9ee20e845438057d Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 8 Jun 2016 14:48:46 +0200 Subject: [PATCH 079/268] Changed moc to the new way --- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 2 + earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/circulation.py | 57 ++++++++++++++++++--------- earthdiagnostics/utils.py | 5 ++- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 9452b95..4b02d00 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = 3dsal +DIAGS = moc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index c788135..aa917b7 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -65,6 +65,8 @@ class Diags: Diagnostic.register(VerticalMean, 'vertmean') Diagnostic.register(VerticalMeanMeters, 'vertmeanmeters') Diagnostic.register(Interpolate, 'interp') + Diagnostic.register(Moc, 'moc') + parse_date('20000101') self.data_manager.prepare_CMOR_files(self.startdates, self.members) diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 83c177b..2bcfc08 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ # from earthdiagnostics.diagnostic import Diagnostic from heat import Heat -from circulation import Circulation +from circulation import Circulation, Moc from general import General, VerticalMean, VerticalMeanMeters, Interpolate from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index ed0eb1d..652e656 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -1,6 +1,7 @@ from earthdiagnostics import Utils, cdftools, TempFile from earthdiagnostics.basins import Basins from earthdiagnostics.models import Models +from earthdiagnostics.diagnostic import Diagnostic from autosubmit.config.log import Log import numpy as np import os @@ -8,29 +9,41 @@ import shutil import netCDF4 -class Circulation(object): +class Moc(Diagnostic): """ - Class containing all the diagnostics related to circulation + Compute the MOC for oceanic basins + Created in March 2012 + Author : vguemas@ic3.cat + + # :param input_file: input grid_V file namez + # :type input_file: str + # :param output_file: output file name (=> 2D, depth-y) + # :param output_file: str + # :return: """ - @staticmethod - def moc(input_file, output_file): - """ - Compute the MOC for oceanic basins - Created in March 2012 - Author : vguemas@ic3.cat - - :param input_file: input grid_V file namez - :type input_file: str - :param output_file: output file name (=> 2D, depth-y) - :param output_file: str - :return: - """ - - if os.path.exists(output_file): - os.remove(output_file) + def __init__(self, data_manager, startdate, member, chunk): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['vo'] + self.generated_vars = ['vsftmyz'] + + @classmethod + def generate_jobs(cls, diags, options): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Moc(diags.data_manager, startdate, member, chunk)) + return job_list + + def compute(self): temp = TempFile.get() + input_file = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) + Log.debug('Computing MOC') cdftools.run('cdfmoc', input=input_file, output=temp) Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') @@ -66,7 +79,13 @@ class Circulation(object): options='-O -x -v zomsfglo,zomsfatl,zomsfpac,zomsfinp,zomsfind,zomsfinp0') Utils.setminmax(temp, 'vsftmyz') - Utils.move_file(temp, output_file) + self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk) + + +class Circulation(object): + """ + Class containing all the diagnostics related to circulation + """ @staticmethod def area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 639f47c..0f7715a 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -36,14 +36,15 @@ class Utils(object): Log.info('Getting max and min values for {0}', ' '.join(variable_list)) - dataset = Utils.nco.readCdf(filename) + handler = Utils.openCdf(filename) for variable in variable_list: - var = dataset.variables[variable] + var = handler.variables[variable] values = [np.max(var), np.min(var)] Utils.nco.ncatted(input=filename, output=filename, options='-h -a valid_max,{0},m,f,{1}'.format(variable, values[0])) Utils.nco.ncatted(input=filename, output=filename, options='-h -a valid_min,{0},m,f,{1}'.format(variable, values[1])) + handler.close() @staticmethod def rename_variable(filepath, old_name, new_name, must_exist=True, rename_dimension=False): -- GitLab From 37fe9ba50dfedf280a707bfdbeaeeae3bde7d11e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 9 Jun 2016 10:03:30 +0200 Subject: [PATCH 080/268] Changed areamoc to the new way. Added box class to manage sections --- earthdiagnostics/box.py | 104 +++++++++++++++++++++++ earthdiagnostics/datamanager.py | 9 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 18 +--- earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/circulation.py | 117 ++++++++++++++++++++++++++ earthdiagnostics/ocean/general.py | 69 +++++++-------- earthdiagnostics/utils.py | 24 ------ 8 files changed, 261 insertions(+), 84 deletions(-) create mode 100644 earthdiagnostics/box.py diff --git a/earthdiagnostics/box.py b/earthdiagnostics/box.py new file mode 100644 index 0000000..0d9a93a --- /dev/null +++ b/earthdiagnostics/box.py @@ -0,0 +1,104 @@ + +class Box(object): + def __init__(self, depth_in_meters=False): + self.depth_in_meters = depth_in_meters + self._max_lat = None + self._min_lat = None + self._max_lon = None + self._min_lon = None + self.max_depth = None + self.min_depth = None + + @property + def max_lat(self): + return self._max_lat + + @max_lat.setter + def max_lat(self, value): + if value > 90 or value < -90: + raise ValueError('{0} is not a valid latitude. Must be between -90 and -90') + self._max_lat = value + + @property + def min_lat(self): + return self._min_lat + + @min_lat.setter + def min_lat(self, value): + if value > 90 or value < -90: + raise ValueError('{0} is not a valid latitude. Must be between -90 and 90') + self._min_lat = value + + @property + def max_lon(self): + return self._max_lon + + @max_lon.setter + def max_lon(self, value): + if value > 180 or value < -180: + raise ValueError('{0} is not a valid longitude. Must be between -180 and 180') + self._min_lat = value + + @property + def min_lon(self): + return self._min_lon + + @min_lon.setter + def min_lon(self, value): + if value > 180 or value < -180: + raise ValueError('{0} is not a valid longitude. Must be between -180 and 180') + self._min_lon = value + + def get_lat_str(self): + if self.max_lat is None or self.min_lat is None: + return '' + if self.min_lat < 0: + direction = 'S' + else: + direction = 'N' + + string = str(abs(self.min_lat)) + direction + + if self.max_lat != self.min_lat: + if self.max_lat < 0: + direction = 'S' + else: + direction = 'N' + string += str(abs(self.max_lat)) + direction + + return string + + def get_lon_str(self): + if self.max_lon is None or self.min_lon is None: + return '' + if self.min_lon < 0: + direction = 'W' + else: + direction = 'N' + + string = str(abs(self.min_lon)) + direction + + if self.max_lon != self.min_lon: + if self.max_lon < 0: + direction = 'S' + else: + direction = 'N' + string += str(abs(self.max_lon)) + direction + return string + + def get_depth_str(self): + if self.max_depth is None or self.min_depth is None: + return '' + + if self.depth_in_meters: + suffix = 'm' + else: + suffix = '' + + string = str(abs(self.min_depth)) + suffix + + if self.min_depth != self.max_depth: + string += '-' + str(abs(self.max_depth)) + suffix + return string + + diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 0fe5cf6..d9bd956 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -169,7 +169,8 @@ class DataManager(object): shutil.copyfile(filepath, temp_path) return temp_path - def send_file(self, filetosend, domain, var, startdate, member, chunk, grid=None, region=None): + def send_file(self, filetosend, domain, var, startdate, member, chunk, grid=None, region=None, box=None, + rename_var=None ): Utils.convert2netcdf4(filetosend) @@ -178,6 +179,12 @@ class DataManager(object): else: domain_abreviattion = domain[0].upper() + if box: + var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() + + if rename_var: + Utils.rename_variable(filetosend, rename_var, var) + start = parse_date(startdate) member_plus = str(member + 1) member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 4b02d00..1029909 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = moc +DIAGS = USALC vertmean,so,10,20 FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index aa917b7..5b2f5c6 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -66,6 +66,7 @@ class Diags: Diagnostic.register(VerticalMeanMeters, 'vertmeanmeters') Diagnostic.register(Interpolate, 'interp') Diagnostic.register(Moc, 'moc') + Diagnostic.register(AreaMoc, 'mocarea') parse_date('20000101') @@ -175,24 +176,7 @@ class Diags: Circulation.max_moc(input_file, lat_min, lat_max, output_file.replace('vsftmyzmax', 'vsftmyzmax{0}-{1}'.format(lat, depth)), depth_min, depth_max) - elif diag in ['mocarea', 'vsftmyzarea']: - if len(diag_options) != 6: - Log.warning('vsftmyzarea requires between 5 arguments. Skipping!') - return - lat_min = int(diag_options[1]) - lat_max = int(diag_options[2]) - lat = '{0}{1}'.format(Utils.get_cardinal_coordinate(lat_min, True), - Utils.get_cardinal_coordinate(lat_max, True)) - - depth_min = int(diag_options[3]) - depth_max = int(diag_options[4]) - depth = '{0}-{1}'.format(depth_min, depth_max) - - basin = diag_options[5] - variables = ('vsftmyz', 'vsftmyz{0}{1}{2}'.format(lat, depth, basin)) - for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): - Circulation.area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin) elif diag == 'mlotsthc': variables = ('thetao', 'mlotst', 'ohcvertsummlotst') for [input_file, mlotst_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 2bcfc08..55348e4 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ # from earthdiagnostics.diagnostic import Diagnostic from heat import Heat -from circulation import Circulation, Moc +from circulation import Circulation, Moc, AreaMoc from general import General, VerticalMean, VerticalMeanMeters, Interpolate from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 652e656..3671332 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -2,6 +2,7 @@ from earthdiagnostics import Utils, cdftools, TempFile from earthdiagnostics.basins import Basins from earthdiagnostics.models import Models from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.box import Box from autosubmit.config.log import Log import numpy as np import os @@ -82,6 +83,122 @@ class Moc(Diagnostic): self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk) +class AreaMoc(Diagnostic): + """ + Compute the MOC for oceanic basins + Created in March 2012 + Author : vguemas@ic3.cat + + # :param input_file: input grid_V file namez + # :type input_file: str + # :param output_file: output file name (=> 2D, depth-y) + # :param output_file: str + # :return: + """ + + def __init__(self, data_manager, startdate, member, chunk, basin, box): + Diagnostic.__init__(self, data_manager) + self.basin = basin + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['vo'] + self.generated_vars = ['vsftmyz'] + self.box = box + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 4: + raise Exception('You must specify the box to use') + if num_options > 5: + raise Exception('You must specify between 4 and 5 parameters for area moc diagnostic') + box = Box() + box.min_lat = int(options[1]) + box.max_lat = int(options[2]) + box.min_depth = int(options[3]) + box.max_depth = int(options[4]) + if num_options > 4: + basin = Basins.parse(options[5]) + else: + basin = Basins.Global + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(AreaMoc(diags.data_manager, startdate, member, chunk, basin, box)) + return job_list + + def compute(self): + """ + Compute an Atlantic MOC index by averaging the meridional overturning + in a latitude band between 1km and 2km + or any other index averaging the meridional overturning in + a given basin and a given domain + + Created in March 2012 Author : vguemas@ic3.cat + + :param input_file: input moc file name + :param lat_min: latitude min + :param lat_max: latitude max + :param output_file: output file name ( => index ) + :param depth_min: depth min + :param depth_max: depth max + :param basin: basin + :return: + """ + nco = Utils.nco + cdo = Utils.cdo + temp2 = TempFile.get() + + temp = self.data_manager.get_file('ocean', 'vsftmyz', self.startdate, self.member, self.chunk) + + handler = Utils.openCdf(temp) + if 'i' in handler.dimensions: + handler.close() + nco.ncwa(input=temp, output=temp, options='-O -a i') + handler = Utils.openCdf(temp) + + basin_index = np.where(handler.variables['basin'][:] == self.basin.fullname) + lat_values = handler.variables['lat'][:] + lat_type = handler.variables['lat'].dtype + lat_units = handler.variables['lat'].units + lat_long_name = handler.variables['lat'].long_name + + handler.close() + + if len(basin_index) == 0: + raise Exception('Basin {0} not defined in file') + basin_index = basin_index[0][0] + nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) + # To remove basin dimension + nco.ncwa(input=temp, output=temp, options='-O -a basin') + + nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev') + + handler = Utils.openCdf(temp) + handler.renameDimension('j', 'lat') + lat_variable = handler.createVariable('lat', lat_type, 'lat') + lat_variable[:] = lat_values[:] + lat_variable.units = lat_units + lat_variable.long_name = lat_long_name + + handler.close() + + nco.ncks(input=temp, output=temp2, + options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(self.box.min_depth, self.box.max_depth, + self.box.min_lat, self.box.max_lat)) + + cdo.vertmean(input=temp2, output=temp) + nco.ncap2(input=temp, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') + nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') + nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time') + self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, box=self.box) + + + + class Circulation(object): """ Class containing all the diagnostics related to circulation diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 698411c..17fd471 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -1,5 +1,6 @@ from autosubmit.config.log import Log +from box import Box from earthdiagnostics import Utils, TempFile, cdftools from earthdiagnostics.diagnostic import Diagnostic import shutil @@ -24,43 +25,37 @@ class VerticalMean(Diagnostic): selects this layer. If its different, a vertical integral (weighted) between upper and lower level is computed """ - def __init__(self, data_manager, startdate, member, chunk, variable, min_lev, max_lev): + def __init__(self, data_manager, startdate, member, chunk, variable, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.variable = variable - self.min_lev = min_lev - self.max_lev = max_lev + self.box = box self.required_vars = [variable] - self.generated_vars = [self._get_output_var()] - - def _get_output_var(self): - return '{0}mean{1}-{2}'.format(self.variable, self.min_lev, self.max_lev) + self.generated_vars = [variable + 'vmean'] @classmethod def generate_jobs(cls, diags, options): - num_options = len(options) -1 + num_options = len(options) - 1 if num_options < 1: raise Exception('You must specify the variable to average vertically') if num_options > 3: raise Exception('You must specify between one and three parameters for the vertical mean') variable = options[1] + + box = Box(True) if num_options >= 2: - min_lev = int(options[2]) - else: - min_lev = None + box.min_depth = float(options[2]) if num_options >= 2: - max_lev = int(options[3]) - else: - max_lev = None + box.max_depth = float(options[3]) job_list = list() for startdate in diags.startdates: for member in diags.members: for chunk in range(1, diags.chunks + 1): job_list.append(VerticalMean(diags.data_manager, startdate, member, chunk, - variable, min_lev, max_lev)) + variable, box)) return job_list def compute(self): @@ -68,22 +63,22 @@ class VerticalMean(Diagnostic): variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) handler = Utils.openCdf(variable_file) - if self.min_lev is None: + if self.box.min_depth is None: lev_min = handler.variables['lev'][0] else: - lev_min = handler.variables['lev'][self.min_lev] + lev_min = self.box.min_depth - if self.min_lev is None: + if self.box.max_depth is None: lev_max = handler.variables['lev'][-1] else: - lev_max = handler.variables['lev'][self.max_lev] + lev_max = self.box.max_depth handler.close() cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, '-debug']) Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) - Utils.rename_variable(temp, '{0}_vert_mean'.format(self.variable), self._get_output_var()) - self.data_manager.send_file(temp, 'ocean', self._get_output_var(), self.startdate, self.member, self.chunk) + self.data_manager.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, + box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) class VerticalMeanMeters(Diagnostic): @@ -99,19 +94,16 @@ class VerticalMeanMeters(Diagnostic): # :param output_file: output file name (=> 2D) """ - def __init__(self, data_manager, startdate, member, chunk, variable, min_depth, max_depth): + def __init__(self, data_manager, startdate, member, chunk, variable, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.variable = variable - self.min_depth = min_depth - self.max_depth = max_depth + self.box = box self.required_vars = [variable] - self.generated_vars = [self._get_output_var()] + self.generated_vars = [variable + 'vmean'] - def _get_output_var(self): - return '{0}mean{1}m-{2}m'.format(self.variable, self.min_depth, self.max_depth) @classmethod def generate_jobs(cls, diags, options): @@ -121,21 +113,18 @@ class VerticalMeanMeters(Diagnostic): if num_options > 3: raise Exception('You must specify between one and three parameters for the vertical mean') variable = options[1] + box = Box(True) if num_options >= 2: - min_lev = float(options[2]) - else: - min_lev = None + box.min_depth = float(options[2]) if num_options >= 2: - max_lev = float(options[3]) - else: - max_lev = None + box.max_depth = float(options[3]) job_list = list() for startdate in diags.startdates: for member in diags.members: for chunk in range(1, diags.chunks + 1): job_list.append(VerticalMeanMeters(diags.data_manager, startdate, member, chunk, - variable, min_lev, max_lev)) + variable, box)) return job_list def compute(self): @@ -143,22 +132,22 @@ class VerticalMeanMeters(Diagnostic): variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) handler = Utils.openCdf(variable_file) - if self.min_depth is None: + if self.box.min_depth is None: lev_min = handler.variables['lev'][0] else: - lev_min = self.min_depth + lev_min = self.box.min_depth - if self.min_depth is None: + if self.box.max_depth is None: lev_max = handler.variables['lev'][-1] else: - lev_max = self.max_depth + lev_max = self.box.max_depth handler.close() cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, '-debug']) Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) - Utils.rename_variable(temp, '{0}_vert_mean'.format(self.variable), self._get_output_var()) - self.data_manager.send_file(temp, 'ocean', self._get_output_var(), self.startdate, self.member, self.chunk) + self.data_manager.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, + box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) class Interpolate(Diagnostic): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 0f7715a..317a321 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -133,30 +133,6 @@ class Utils(object): raise Exception('Error executing {0}\n Return code: {1}', ' '.join(command), process.returncode) return output - @staticmethod - def get_cardinal_coordinate(value, latitude): - """ - Translates a degree value into degrees NSEO - - :param value: value in degress - :type value: float - :param latitude: if True, value is latitude, Otherwise value is longitude - :type latitude: bool - :return: transformed value - :rtype: str - """ - if latitude: - if value < 0: - direction = 'S' - else: - direction = 'N' - else: - if value < 0: - direction = 'W' - else: - direction = 'E' - return str(abs(value)) + direction - _cpu_count = None @staticmethod -- GitLab From f62a229d501a786fdb2fa7e3808b78a0d989f772 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 9 Jun 2016 18:14:21 +0200 Subject: [PATCH 081/268] Changed maxmoc to the new way and increased use of numpy within it --- earthdiagnostics/datamanager.py | 112 +++++++++-- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 7 +- earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/circulation.py | 266 ++++++++++++-------------- earthdiagnostics/utils.py | 18 +- 6 files changed, 243 insertions(+), 164 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index d9bd956..013c992 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -13,7 +13,8 @@ from earthdiagnostics import Utils, TempFile class DataManager(object): - def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name): + def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name, num_chunks, + calendar='standard'): self.institution = institution self.model = model self.expid = expid @@ -23,6 +24,8 @@ class DataManager(object): self.experiment_name = experiment_name self.add_startdate = True self.add_name = True + self.num_chunks = num_chunks + self.calendar = calendar # noinspection PyPep8Naming def prepare_CMOR_files(self, startdates, members): @@ -136,29 +139,35 @@ class DataManager(object): return file_names - def get_file(self, domain, var, startdate, member, chunk, grid=None): + def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): if domain == 'seaIce': domain_abreviattion = 'OI' else: domain_abreviattion = domain[0].upper() + if not frequency: + frequency = self.frequency + start = parse_date(startdate) member_plus = str(member + 1) member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', - self.institution, self.model, self.experiment_name, 'S' + startdate, self.frequency, + self.institution, self.model, self.experiment_name, 'S' + startdate, frequency, domain) chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') + if box: + var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() + if grid: var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) else: var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) filepath = os.path.join(var_path, '{0}_{1}{2}_{3}_{4}_S{5}_r{6}i1p1_' - '{7}-{8}.nc'.format(var, domain_abreviattion, self.frequency, self.model, + '{7}-{8}.nc'.format(var, domain_abreviattion, frequency, self.model, self.experiment_name, startdate, member_plus, "{0:04}{1:02}".format(chunk_start.year, chunk_start.month), @@ -169,8 +178,8 @@ class DataManager(object): shutil.copyfile(filepath, temp_path) return temp_path - def send_file(self, filetosend, domain, var, startdate, member, chunk, grid=None, region=None, box=None, - rename_var=None ): + def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, + rename_var=None, frequency=None, year=None): Utils.convert2netcdf4(filetosend) @@ -185,15 +194,30 @@ class DataManager(object): if rename_var: Utils.rename_variable(filetosend, rename_var, var) + if not frequency: + frequency = self.frequency + start = parse_date(startdate) member_plus = str(member + 1) member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', - self.institution, self.model, self.experiment_name, 'S' + startdate, self.frequency, + self.institution, self.model, self.experiment_name, 'S' + startdate, frequency, domain) - chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') + if chunk is not None: + chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + + time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, + chunk_end.month) + + elif year is not None: + if frequency is not 'yr': + raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') + time_bound = str(year) + + else: + raise ValueError('Chunk and year can not be None at the same time') if grid: var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) @@ -201,12 +225,8 @@ class DataManager(object): var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) filepath = os.path.join(var_path, '{0}_{1}{2}_{3}_{4}_S{5}_r{6}i1p1_' - '{7}-{8}.nc'.format(var, domain_abreviattion, self.frequency, self.model, - self.experiment_name, startdate, member_plus, - "{0:04}{1:02}".format(chunk_start.year, - chunk_start.month), - "{0:04}{1:02}".format(chunk_end.year, - chunk_end.month))) + '{7}.nc'.format(var, domain_abreviattion, frequency, self.model, + self.experiment_name, startdate, member_plus, time_bound)) if region: if not os.path.exists(filepath): @@ -247,6 +267,66 @@ class DataManager(object): Utils.move_file(filetosend, filepath) + def get_year(self, domain, var, startdate, member, year, grid=None, box=None): + chunk_files = list() + for chunk in self.get_year_chunks(startdate, year): + chunk_files.append(self.get_file(domain, var, startdate, member, chunk, grid=grid, box=box)) + + if len(chunk_files) > 1: + temp = TempFile.get() + Utils.nco.ncrcat(input=' '.join(chunk_files), output=temp) + for chunk_file in chunk_files: + os.remove(chunk_file) + else: + temp = chunk_files[0] + temp2 = TempFile.get() + handler = Utils.openCdf(temp) + time = Utils.get_datetime_from_netcdf(handler) + handler.close() + for x in range(0, len(time)): + date = time[x] + if date.year == year: + if date.month == 1: + start = x + elif date.month == 12: + end = x + + Utils.nco.ncks(input=temp, output=temp2, options='-O -d time,{0},{1}'.format(start, end)) + os.remove(temp) + return temp2 + + def get_year_chunks(self, startdate, year): + date = parse_date(startdate) + chunks = list() + for chunk in range(1, self.num_chunks+1): + chunk_start = chunk_start_date(date, chunk, self.chunk_size, 'month', self.calendar) + if chunk_start.year > year: + break + elif chunk_start.year == year or chunk_end_date(chunk_start, self.chunk_size, 'month', + self.calendar).year == year: + chunks.append(chunk) + + return chunks + + def get_full_years(self, startdate): + chunks_per_year = 12 / self.chunk_size + date = parse_date(startdate) + first_january = 0 + first_year = date.year + if date.month != 1: + month = date.month + first_year += 1 + while month + self.chunk_size < 12: + month += self.chunk_size + first_january += 1 + + years = list() + for chunk in range(first_january, self.num_chunks - chunks_per_year, chunks_per_year): + years.append(first_year) + first_year += 1 + return years + + # # set -vx # diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 1029909..4b02d00 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = USALC vertmean,so,10,20 +DIAGS = moc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 5b2f5c6..7947ea7 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -28,7 +28,8 @@ class Diags: Log.debug('Initialising Diags') self._read_config(config_file) self.data_manager = DataManager(self.institute, self.model, self.expid, self.data_dir, - self.frequency, self.chunk_size, self.experiment_name) + self.frequency, self.chunk_size, self.experiment_name, self.chunks, + self.calendar) self.data_manager.add_startdate = self.add_startdate self.data_manager.add_name = self.add_name TempFile.scratch_folder = self.scratch_dir @@ -67,6 +68,7 @@ class Diags: Diagnostic.register(Interpolate, 'interp') Diagnostic.register(Moc, 'moc') Diagnostic.register(AreaMoc, 'mocarea') + Diagnostic.register(MaxMoc, 'mocmax') parse_date('20000101') @@ -91,7 +93,7 @@ class Diags: Log.result('Finished {0}', fulldiag) - numthreads = min(Utils.available_cpu_count(), self.max_cores) + numthreads = min(Utils.available_cpu_count(), self.max_cores, len(list_jobs)) threads = list() for numthread in range(0, numthreads): t = threading.Thread(target=Diags._run_jobs, @@ -291,6 +293,7 @@ class Diags: self.startdates = self.parser.get_option('EXPERIMENT', 'STARTDATES').split() self.chunk_size = self.parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') self.chunks = self.parser.get_int_option('EXPERIMENT', 'CHUNKS') + self.calendar = self.parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') self.model = self.parser.get_option('EXPERIMENT', 'MODEL') self.nemo_version = self.parser.get_option('EXPERIMENT', 'NEMO_VERSION') diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 55348e4..5bfe661 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ # from earthdiagnostics.diagnostic import Diagnostic from heat import Heat -from circulation import Circulation, Moc, AreaMoc +from circulation import Circulation, Moc, AreaMoc, MaxMoc from general import General, VerticalMean, VerticalMeanMeters, Interpolate from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 3671332..8e90ebd 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -197,211 +197,191 @@ class AreaMoc(Diagnostic): self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, box=self.box) +class MaxMoc(Diagnostic): + def __init__(self, data_manager, startdate, member, year, basin, box): + Diagnostic.__init__(self, data_manager) + self.basin = basin + self.startdate = startdate + self.member = member + self.year = year + self.required_vars = ['vo'] + self.generated_vars = ['vsftmyz'] + self.box = box -class Circulation(object): - """ - Class containing all the diagnostics related to circulation - """ + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 4: + raise Exception('You must specify the box to use') + if num_options > 5: + raise Exception('You must specify between 4 and 5 parameters for area moc diagnostic') + box = Box() + box.min_lat = int(options[1]) + box.max_lat = int(options[2]) + box.min_depth = int(options[3]) + box.max_depth = int(options[4]) + if num_options > 4: + basin = Basins.parse(options[5]) + else: + basin = Basins.Global - @staticmethod - def area_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + years = diags.data_manager.get_full_years(startdate) + if len(years) == 0: + Log.user_warning('No complete years are available with the given configuration. ' + 'MaxMoc can not be computed') + for year in years: + job_list.append(MaxMoc(diags.data_manager, startdate, member, year, basin, box)) + return job_list + + def compute(self): """ - Compute an Atlantic MOC index by averaging the meridional overturning - in a latitude band between 1km and 2km - or any other index averaging the meridional overturning in - a given basin and a given domain + Compute an Atlantic MOC index by finding the maximum of the annual + mean meridional overturning in a latitude / depth region - Created in March 2012 Author : vguemas@ic3.cat + Created in March 2012 Author : vguemas@ic3.cat - :param input_file: input moc file name - :param lat_min: latitude min - :param lat_max: latitude max - :param output_file: output file name ( => index ) - :param depth_min: depth min - :param depth_max: depth max - :param basin: basin - :return: - """ + :param basin: basin + :param input_file: input moc file name + :param lat_min: latitude min + :param lat_max: latitude max + :param output_file: output file name + :param depth_min: depth mean + :param depth_max: depth max + :return: + """ nco = Utils.nco - cdo = Utils.cdo - temp = TempFile.get() - temp2 = TempFile.get() - shutil.copy(input_file, temp) + temp = self.data_manager.get_year('ocean', 'vsftmyz', self.startdate, self.member, self.year) handler = Utils.openCdf(temp) if 'i' in handler.dimensions: handler.close() nco.ncwa(input=temp, output=temp, options='-O -a i') - handler = Utils.openCdf(temp) - - basin_instance = Basins.parse(basin) - if not basin_instance: - raise Exception("Basin {0} not recognized".format(basin)) - - basin_index = np.where(handler.variables['basin'][:] == basin_instance.fullname) - lat_values = handler.variables['lat'][:] - lat_type = handler.variables['lat'].dtype - lat_units = handler.variables['lat'].units - lat_long_name = handler.variables['lat'].long_name - - handler.close() - + else: + handler.close() + handler = Utils.openCdf(temp) + basin_index = np.where(handler.variables['basin'][:] == self.basin.fullname) if len(basin_index) == 0: - raise Exception('Basin {0} not defined in file') + raise Exception("Basin {1} is not defined in {0}", temp, self.basin.fullname) basin_index = basin_index[0][0] - nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) - # To remove basin dimension - nco.ncwa(input=temp, output=temp, options='-O -a basin') - nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev') + lev = handler.variables['lev'][:] + lat = handler.variables['lat'][:] - handler = Utils.openCdf(temp) - handler.renameDimension('j', 'lat') - lat_variable = handler.createVariable('lat', lat_type, 'lat') - lat_variable[:] = lat_values[:] - lat_variable.units = lat_units - lat_variable.long_name = lat_long_name - - handler.close() - - nco.ncks(input=temp, output=temp2, - options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(depth_min, depth_max, - lat_min, lat_max)) - - cdo.vertmean(input=temp2, output=temp) - nco.ncap2(input=temp, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') - nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') - nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time') - Utils.move_file(temp, output_file) - - @staticmethod - def max_moc(input_file, lat_min, lat_max, output_file, depth_min, depth_max, basin=None): - """ - Compute an Atlantic MOC index by finding the maximum of the annual - mean meridional overturning in a latitude / depth region - - Created in March 2012 Author : vguemas@ic3.cat - - :param basin: basin - :param input_file: input moc file name - :param lat_min: latitude min - :param lat_max: latitude max - :param output_file: output file name - :param depth_min: depth mean - :param depth_max: depth max - :return: - """ - nco = Utils.nco - temp = TempFile.get() - temp2 = TempFile.get() - if not basin: - basin = Basins.Global - basin = Basins.parse(basin) - - shutil.copy(input_file, temp) - handler = Utils.openCdf(temp) - if 'i' in handler.dimensions: - nco.ncwa(input=temp, output=temp, options='-O -a i') + if self.box.min_lat == self.box.max_lat: + lat_inds = ((np.abs(lat-self.box.min_lat)).argmin(),) else: - shutil.copy(temp, temp) - basin_index = np.where(handler.variables['basin'][:] == basin.fullname) - if len(basin_index) == 0: - raise Exception("Basin {1} is not defined in {0}", input_file, basin.fullname) - basin_index = basin_index[0][0] - handler.close() + lat_inds = np.where((lat > self.box.min_lat) & (lat < self.box.max_lat))[0] - # Utils.rename_variable(temp, 'record', 'x') - handler = Utils.openCdf(temp) - lat_values = handler.variables['lat'][:] - lat_type = handler.variables['lat'].dtype - lat_units = handler.variables['lat'].units - lat_long_name = handler.variables['lat'].long_name - handler.close() - nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) - # To remove basin dimension - nco.ncwa(input=temp, output=temp, options='-O -a basin') - - nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev,lev_bnds') + if self.box.min_depth == self.box.max_depth: + lev_inds = ((np.abs(lev - self.box.min_depth)).argmin(),) + else: + lev_inds = np.where((lev > self.box.min_depth) & (lev < self.box.max_depth))[0] - handler = Utils.openCdf(temp) - handler.renameDimension('j', 'lat') - lat_variable = handler.createVariable('lat', lat_type, 'lat') - lat_variable[:] = lat_values[:] - lat_variable.units = lat_units - lat_variable.long_name = lat_long_name + Log.info('Computing year {0}', str(self.year)) + moc = handler.variables['vsftmyz'][:, lev_inds, lat_inds, basin_index] handler.close() + os.remove(temp) - nco.ncks(input=temp, output=temp2, - options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(depth_min, depth_max, - lat_min, lat_max)) - Utils.cdo.yearmean(input=temp2, output=temp) - handler = Utils.openCdf(temp) - - moc = handler.variables['vsftmyz'][:] + moc = np.mean(moc, 0) maximum = np.amax(moc) max_index = np.unravel_index(np.argmax(moc), moc.shape) - max_lev = handler.variables['lev'][max_index[1]] - max_lat = handler.variables['lat'][max_index[2]] + max_lev = lev[lev_inds[max_index[0]]] + max_lat = lat[lat_inds[max_index[1]]] minimum = np.amin(moc) minimum_index = np.unravel_index(np.argmin(moc), moc.shape) - min_lev = handler.variables['lev'][minimum_index[1]] - min_lat = handler.variables['lat'][minimum_index[2]] - handler.close() + min_lev = lev[lev_inds[minimum_index[0]]] + min_lat = lat[lat_inds[minimum_index[1]]] Log.info('Maximum {0} Sv, latitude {1} depth {2} m', maximum, max_lat, max_lev) Log.info('Minimum {0} Sv, latitude {1} depth {2} m', minimum, min_lat, min_lev) - os.remove(temp) - handler = netCDF4.Dataset(temp, 'w') - - var = handler.createVariable('vsftmyzmax', float) + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzmax', float, ('time',)) var.long_name = 'Maximum_Overturing' var.units = 'Sverdrup' var.valid_min = -1000. var.valid_max = 1000. - var[:] = maximum + var[0] = maximum + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) - var = handler.createVariable('vsftmyzmaxlat', float) + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzmaxlat', float, ('time',)) var.long_name = 'Latitude_of_Maximum_Overturing' var.units = 'Degrees' var.valid_min = -90. var.valid_max = 90. - var[:] = lat_max + var[0] = max_lat + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) - var = handler.createVariable('vsftmyzmaxlev', float) + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzmaxlev', float, ('time',)) var.long_name = 'Depth_of_Maximum_Overturing' var.units = 'Meters' var.valid_min = 0. var.valid_max = 10000. - var[:] = max_lev + var[0] = max_lev + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) - var = handler.createVariable('vsftmyzmin', float) + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzmin', float, ('time',)) var.long_name = 'Minimum_Overtuning' var.units = 'Sverdrup' var.valid_min = -1000. var.valid_max = 1000. - var[:] = maximum + var[0] = minimum + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) - var = handler.createVariable('vsftmyzminlat', float) + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzminlat', float, ('time',)) var.long_name = 'Latitude_of_Minimum_Overtuning' var.units = 'Degrees' var.valid_min = -90. var.valid_max = 90. - var[:] = lat_max + var[0] = min_lat + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) - var = handler.createVariable('vsftmyzminlev', float) + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzminlev', float, ('time',)) var.long_name = 'Depth_of_Minimum_Overtuning' var.units = 'Meters' var.valid_min = 0. var.valid_max = 10000. - var[:] = max_lev - + var[0] = min_lev handler.close() - Utils.move_file(temp, output_file) + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) + + def _create_output_file(self, temp): + handler = netCDF4.Dataset(temp, 'w') + handler.createDimension('time') + + time = handler.createVariable('time', 'i2', ('time',)) + time.calendar = 'gregorian' + time.units = 'days since January 1, {0}'.format(self.year) + return handler + + +class Circulation(object): + """ + Class containing all the diagnostics related to circulation + """ @staticmethod def psi(input_file_u, input_file_v, output_file): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 317a321..2cbd952 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -104,7 +104,12 @@ class Utils(object): :type destiny: str """ if not os.path.exists(os.path.dirname(destiny)): - os.makedirs(os.path.dirname(destiny)) + try: + os.makedirs(os.path.dirname(destiny)) + except OSError as ex: + # This can be due to a race condition. If directory already exists, we don have to do nothing + if not os.path.exists(os.path.dirname(destiny)): + raise ex shutil.move(source, destiny) @staticmethod @@ -174,6 +179,17 @@ class Utils(object): def openCdf(filepath, mode='a'): return netCDF4.Dataset(filepath, mode) + @staticmethod + def get_datetime_from_netcdf(handler, time_variable='time'): + nctime = handler.variables[time_variable][:] # get values + units = handler.variables[time_variable].units # get unit "days since 1950-01-01T00:00:00Z" + + try: + cal_temps = handler.variables[time_variable].calendar + except AttributeError: # Attribute doesn't exist + cal_temps = u"gregorian" # or standard + return netCDF4.num2date(nctime, units=units, calendar=cal_temps) + class TempFile(object): """ -- GitLab From e0bd867cc2758c7e83c1e7cb73c682967408d8d0 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 10 Jun 2016 15:22:28 +0200 Subject: [PATCH 082/268] Changed mechanism for running tasks --- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 4b02d00..6c05e16 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = moc +DIAGS = max_moc FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 7947ea7..b732ea1 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -4,6 +4,7 @@ import argparse from datamanager import DataManager from earthdiagnostics.ocean import * +import Queue from earthdiagnostics import Diagnostic import threading import netCDF4 @@ -76,14 +77,15 @@ class Diags: # Run diagnostics Log.info('Running diagnostics') - list_jobs = list() + list_jobs = Queue.Queue() for fulldiag in self._get_commands(): Log.info("Running {0}", fulldiag) diag_options = fulldiag.split(',') diag_class = Diagnostic.get_diagnostic(diag_options[0]) if diag_class: - list_jobs += diag_class.generate_jobs(self, diag_options) + for job in diag_class.generate_jobs(self, diag_options): + list_jobs.put(job) continue else: for startdate in self.startdates: @@ -93,16 +95,14 @@ class Diags: Log.result('Finished {0}', fulldiag) - numthreads = min(Utils.available_cpu_count(), self.max_cores, len(list_jobs)) + numthreads = min(Utils.available_cpu_count(), self.max_cores) threads = list() for numthread in range(0, numthreads): - t = threading.Thread(target=Diags._run_jobs, - args=([list_jobs[numthread:len(list_jobs): numthreads]])) + t = threading.Thread(target=Diags._run_jobs, args=(list_jobs, numthread)) threads.append(t) t.start() - for t in threads: - t.join() + list_jobs.join() TempFile.clean() finsih_time = datetime.datetime.now() @@ -110,9 +110,19 @@ class Diags: Log.result("Time ellapsed: {0}", finsih_time - time) @staticmethod - def _run_jobs(jobs): - for job in jobs: - job.compute() + def _run_jobs(queue, numthread): + count = 0 + + while not queue.empty(): + try: + queue.get(timeout=1).compute() + queue.task_done() + count += 1 + except Queue.Empty: + # No more work to do + continue + Log.result('Thread {0} finished after taking care of {1} tasks', numthread, count) + return def _execute_diagnostic(self, diag_options, startdate, member, chunk): diag = diag_options[0] -- GitLab From a517f37e79ed9726eb4afd1228547165e2ab9da7 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 10 Jun 2016 16:00:53 +0200 Subject: [PATCH 083/268] Changed PSI to the new way --- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 28 +----------------------- earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/circulation.py | 31 +++++++++++++++++++++------ 4 files changed, 27 insertions(+), 36 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 6c05e16..ad7af26 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = max_moc +DIAGS = psi FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index b732ea1..fd757c5 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -70,6 +70,7 @@ class Diags: Diagnostic.register(Moc, 'moc') Diagnostic.register(AreaMoc, 'mocarea') Diagnostic.register(MaxMoc, 'mocmax') + Diagnostic.register(Psi, 'psi') parse_date('20000101') @@ -130,11 +131,6 @@ class Diags: variables = ('mlotst', 'mlotstsites') for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.convection_sites(input_file, self.nemo_version, output_file) - elif diag == 'psi': - variables = ('uo', 'vo', 'vsftbarot') - for [u_file, v_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', - variables): - Circulation.psi(u_file, v_file, output_file) elif diag == 'gyres': variables = ('vsftbarot', 'vsftbarotgyres') for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): @@ -167,28 +163,6 @@ class Diags: variables = ('thetao', 'ohc{0}'.format(depth)) for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Heat.layer(input_file, output_file, depth_min, depth_max) - elif diag in ['moc', 'vsftmyz']: - variables = ('vo', 'vsftmyz') - for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): - Circulation.moc(input_file, output_file) - elif diag in ['mocmax', 'vsftmyzmax']: - if len(diag_options) != 5: - Log.warning('vsftmyzmax requires 4 arguments. Skipping!') - return - - lat_min = int(diag_options[1]) - lat_max = int(diag_options[2]) - lat = '{0}-{1}'.format(lat_min, lat_max) - - depth_min = int(diag_options[3]) - depth_max = int(diag_options[4]) - depth = '{0}-{1}'.format(depth_min, depth_max) - variables = ('vsftmyz', 'vsftmyzmax') - for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): - Circulation.max_moc(input_file, lat_min, lat_max, - output_file.replace('vsftmyzmax', 'vsftmyzmax{0}-{1}'.format(lat, depth)), - depth_min, depth_max) - elif diag == 'mlotsthc': variables = ('thetao', 'mlotst', 'ohcvertsummlotst') for [input_file, mlotst_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 5bfe661..85a8812 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ # from earthdiagnostics.diagnostic import Diagnostic from heat import Heat -from circulation import Circulation, Moc, AreaMoc, MaxMoc +from circulation import Circulation, Moc, AreaMoc, MaxMoc, Psi from general import General, VerticalMean, VerticalMeanMeters, Interpolate from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 8e90ebd..2453222 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -378,13 +378,25 @@ class MaxMoc(Diagnostic): return handler -class Circulation(object): - """ - Class containing all the diagnostics related to circulation - """ +class Psi(Diagnostic): + def __init__(self, data_manager, startdate, member, chunk): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['vo', 'uo'] + self.generated_vars = ['vsftbarot'] - @staticmethod - def psi(input_file_u, input_file_v, output_file): + @classmethod + def generate_jobs(cls, diags, options): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Psi(diags.data_manager, startdate, member, chunk)) + return job_list + + def compute(self): """ Compute the barotropic stream function @@ -398,10 +410,15 @@ class Circulation(object): :rtype output_file: str """ temp = TempFile.get() + input_file_u = self.data_manager.get_file('ocean', 'uo', self.startdate, self.member, self.chunk) + input_file_v = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-mean -mask') Utils.rename_variable(temp, 'sobarstf', 'vsftbarot') Utils.setminmax(temp, 'vsftbarot') - Utils.move_file(temp, output_file) + self.data_manager.send_file(temp, 'ocean', 'vsftbarot', self.startdate, self.member, self.chunk) + +class Circulation(object): + # noinspection PyPep8Naming @staticmethod -- GitLab From 3fe8470733718ca50ba11037d1e21c16949a1f56 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 13 Jun 2016 12:04:35 +0200 Subject: [PATCH 084/268] Changed gyres to the new way --- earthdiagnostics/datamanager.py | 7 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 24 ++-- earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/circulation.py | 155 +++++++++++++++++--------- earthdiagnostics/utils.py | 7 ++ 6 files changed, 135 insertions(+), 62 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 013c992..bebbde6 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -246,6 +246,7 @@ class DataManager(object): Utils.nco.ncks(input=filetosend, output=filetosend, options='-O -x -v {0}'.format(var)) Utils.rename_variable(filetosend, 'new_var', var) else: + temp = TempFile.get() shutil.copyfile(filepath, temp) handler = Utils.openCdf(temp) @@ -259,8 +260,10 @@ class DataManager(object): else: basin_index = basin_index[0][0] - - handler_send.variables[var][..., basin_index] = value + try: + handler.variables[var][..., basin_index] = value + except Exception: + error = True handler.close() handler_send.close() Utils.move_file(temp, filetosend) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index ad7af26..ff71e47 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = psi +DIAGS = gyres FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index fd757c5..994d4ee 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -71,6 +71,7 @@ class Diags: Diagnostic.register(AreaMoc, 'mocarea') Diagnostic.register(MaxMoc, 'mocmax') Diagnostic.register(Psi, 'psi') + Diagnostic.register(Gyres, 'gyres') parse_date('20000101') @@ -112,16 +113,29 @@ class Diags: @staticmethod def _run_jobs(queue, numthread): + + def _run_job(job, retrials=1): + while retrials > 0: + try: + job.compute() + return True + except Exception as ex: + retrials -= 1 + Log.error('Diagnostic {0} something failed: {1}', job, ex.message) + return False + + count = 0 while not queue.empty(): try: - queue.get(timeout=1).compute() + job = queue.get(timeout=1) + if _run_job(job): + count += 1 queue.task_done() - count += 1 except Queue.Empty: - # No more work to do continue + Log.result('Thread {0} finished after taking care of {1} tasks', numthread, count) return @@ -131,10 +145,6 @@ class Diags: variables = ('mlotst', 'mlotstsites') for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Circulation.convection_sites(input_file, self.nemo_version, output_file) - elif diag == 'gyres': - variables = ('vsftbarot', 'vsftbarotgyres') - for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): - Circulation.gyres(str(input_file), self.nemo_version, str(output_file)) elif diag == 'ohc': basin = diag_options[1] mixed_layer = int(diag_options[2]) diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 85a8812..c5a56b2 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ # from earthdiagnostics.diagnostic import Diagnostic from heat import Heat -from circulation import Circulation, Moc, AreaMoc, MaxMoc, Psi +from circulation import Circulation, Moc, AreaMoc, MaxMoc, Psi, Gyres from general import General, VerticalMean, VerticalMeanMeters, Interpolate from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 2453222..77e863b 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -417,26 +417,42 @@ class Psi(Diagnostic): Utils.setminmax(temp, 'vsftbarot') self.data_manager.send_file(temp, 'ocean', 'vsftbarot', self.startdate, self.member, self.chunk) -class Circulation(object): +class Gyres(Diagnostic): + def __init__(self, data_manager, startdate, member, chunk, nemo_version): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.nemo_version = nemo_version + self.required_vars = ['vsftbarot'] + self.generated_vars = ['gyres'] - # noinspection PyPep8Naming - @staticmethod - def gyres(input_psi, input_grid, output_file): + @classmethod + def generate_jobs(cls, diags, options): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.nemo_version)) + return job_list + + def compute(self): """ - Compute the intensity of the subtropical and subpolar gyres + Compute the intensity of the subtropical and subpolar gyres - Created in October 2013 Author : vguemas@ic3.cat + Created in October 2013 Author : vguemas@ic3.cat - :param input_psi: input psi file name - :param input_grid: input grid - :param output_file: output file name ( => index ) - :return: + :param input_psi: input psi file name + :param input_grid: input grid + :param output_file: output file name ( => index ) + :return: """ - if input_grid in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, - Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, - Models.NEMOVAR_O1L42]: + if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, + Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, + Models.NEMOVAR_O1L42]: + subpolNAtl = [230, 275, 215, 245] subpolNPac = [70, 145, 195, 235] subtropNPac = [45, 175, 165, 220] @@ -446,49 +462,81 @@ class Circulation(object): subtropInd = [320, 30, 110, 180] ACC = [1, 361, 1, 65] - elif input_grid in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, - Models.GLORYS2_V1_O25L75]: - raise Exception("Option gyres not available yet for {0}".format(input_grid)) + elif self in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, + Models.GLORYS2_V1_O25L75]: + raise Exception("Option gyres not available yet for {0}".format(self.nemo_version)) else: - raise Exception("Input grid {0} not recognized".format(input_grid)) + raise Exception("Input grid {0} not recognized".format(self.nemo_version)) temp = TempFile.get() - temp2 = TempFile.get() - Circulation.gyre(input_psi, subpolNAtl, temp2, invert=True) - Utils.rename_variable(temp2, 'vsftbarot', 'subpolNAtl') - - Circulation.gyre(input_psi, subpolNPac, temp, invert=True) - Utils.rename_variable(temp, 'vsftbarot', 'subpolNPac') - Utils.nco.ncks(input=temp, output=temp2, options='-A') - - Circulation.gyre(input_psi, subtropNPac, temp) - Utils.rename_variable(temp, 'vsftbarot', 'subtropNPac') - Utils.nco.ncks(input=temp, output=temp2, options='-A') - - Circulation.gyre(input_psi, subtropSPac, temp) - Utils.rename_variable(temp, 'vsftbarot', 'subtropSPac') - Utils.nco.ncks(input=temp, output=temp2, options='-A') - - Circulation.gyre(input_psi, subtropNAtl, temp) - Utils.rename_variable(temp, 'vsftbarot', 'subtropNAtl') - Utils.nco.ncks(input=temp, output=temp2, options='-A') + output= TempFile.get() + vsftbarot_file = self.data_manager.get_file('ocean', 'vsftbarot', self.startdate, self.member, self.chunk) + + self._gyre(vsftbarot_file, subpolNAtl, temp, invert=True) + handler_original = Utils.openCdf(temp) + handler = Utils.openCdf(output, 'w') + handler.createDimension('time', handler_original.variables['time'].shape[0]) + handler.createDimension('region', 8) + Utils.copy_variable(handler_original, handler, 'time') + var_region = handler.createVariable('region', str, 'region') + var_region[0] = 'subpolNAtl' + + var_gyre = handler.createVariable('gyre', 'f', ('time', 'region')) + var_gyre.short_name = 'gyre' + var_gyre.long_name = 'gyre' + var_gyre.units = 'm^3/s' + + handler_original = Utils.openCdf(temp) + var_gyre[:, 0] = handler_original.variables['vsftbarot'][:, 0, 0] + handler_original.close() + + self._gyre(vsftbarot_file, subpolNPac, temp, invert=True) + var_region[1] = 'subpolNPac' + handler_original = Utils.openCdf(temp) + var_gyre[:, 1] = handler_original.variables['vsftbarot'][:, 0, 0] + handler_original.close() + + self._gyre(vsftbarot_file, subtropNPac, temp) + var_region[2] = 'subtropNPac' + handler_original = Utils.openCdf(temp) + var_gyre[:, 2] = handler_original.variables['vsftbarot'][:, 0, 0] + handler_original.close() + + self._gyre(vsftbarot_file, subtropSPac, temp) + var_region[3] = 'subtropSPac' + handler_original = Utils.openCdf(temp) + var_gyre[:, 3] = handler_original.variables['vsftbarot'][:, 0, 0] + handler_original.close() + + self._gyre(vsftbarot_file, subtropNAtl, temp) + var_region[4] = 'subtropNAtl' + handler_original = Utils.openCdf(temp) + var_gyre[:, 4] = handler_original.variables['vsftbarot'][:, 0, 0] + handler_original.close() + + self._gyre(vsftbarot_file, subtropSAtl, temp) + var_region[5] = 'subtropSAtl' + handler_original = Utils.openCdf(temp) + var_gyre[:, 5] = handler_original.variables['vsftbarot'][:, 0, 0] + handler_original.close() + + self._gyre(vsftbarot_file, subtropInd, temp) + var_region[6] = 'subtropInd' + handler_original = Utils.openCdf(temp) + var_gyre[:, 6] = handler_original.variables['vsftbarot'][:, 0, 0] + handler_original.close() + + self._gyre(vsftbarot_file, ACC, temp) + var_region[7] = 'ACC' + handler_original = Utils.openCdf(temp) + var_gyre[:, 7] = handler_original.variables['vsftbarot'][:, 0, 0] + handler_original.close() - Circulation.gyre(input_psi, subtropSAtl, temp) - Utils.rename_variable(temp, 'vsftbarot', 'subtropSAtl') - Utils.nco.ncks(input=temp, output=temp2, options='-A') - - Circulation.gyre(input_psi, subtropInd, temp) - Utils.rename_variable(temp, 'vsftbarot', 'subtropInd') - Utils.nco.ncks(input=temp, output=temp2, options='-A') - - Circulation.gyre(input_psi, ACC, temp) - Utils.rename_variable(temp, 'vsftbarot', 'ACC') - Utils.nco.ncks(input=temp, output=temp2, options='-A') - - Utils.move_file(temp2, output_file) + handler.close() + self.data_manager.send_file(output, 'ocean', 'gyre', self.startdate, self.member, self.chunk) + Log.info('Finished gyres for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) - @staticmethod - def gyre(input_file, site, output_file, invert=False): + def _gyre(self, input_file, site, output_file, invert=False): """ Compute the intensity of a given gyre @@ -500,6 +548,7 @@ class Circulation(object): :param invert: if True, multiplies result by -1 :return: """ + temp = TempFile.get() if invert: Utils.cdo.fldmin(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), @@ -510,6 +559,10 @@ class Circulation(object): Utils.cdo.fldmax(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), output=output_file) + + +class Circulation(object): + @staticmethod def convection_sites(input_file, input_grid, output_file): """ diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 2cbd952..77221d8 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -190,6 +190,13 @@ class Utils(object): cal_temps = u"gregorian" # or standard return netCDF4.num2date(nctime, units=units, calendar=cal_temps) + @staticmethod + def copy_variable(source, destiny, variable): + original_var = source.variables[variable] + new_var = destiny.createVariable(variable, original_var.datatype, original_var.dimensions) + new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) + new_var[:] = original_var[:] + class TempFile(object): """ -- GitLab From 5da1f364c9560f4db59fb69b2d0e245c2a933c05 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 13 Jun 2016 14:59:41 +0200 Subject: [PATCH 085/268] Changed sites to the new way and moved to numpy. Also moved gyres to numpy --- config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 7 +- earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/circulation.py | 182 ++++++++++++++------------ 5 files changed, 102 insertions(+), 93 deletions(-) diff --git a/config_file-ocean_pp.bash b/config_file-ocean_pp.bash index 8a31072..ea65b2a 100644 --- a/config_file-ocean_pp.bash +++ b/config_file-ocean_pp.bash @@ -1,7 +1,7 @@ #!/bin/bash # This is an example of a configuration_file needed to launch ocean_pp.bash. For any other information about how to use it, you can refer to the README or the cfu wiki (http://ic3.cat/wikicfu/index.php/Tools#update_February_2013). -listpost=('heat_sal_mxl') +listpost=('convection') # Valid options : ('siasiesiv' 'ohc' 'moc' 'max_moc' 'area_moc' 'ext_raw_ice' (previously 'ice') 'ext_raw_oce' (previously 'sstsssmld') 'heat_sal_mxl' 'psi' 'usalc' 'lmsalc' 'uohc' 'mohc' 'lohc' 'xohc' 'ohc_specified_layer' 'stc' 'vert_Tsections' 'vert_Ssections' '3dtemp' '3dsal' 'TSec_ave190-220E' 'SSec_ave190-220E' 'NAtlohc' 'xNAtlohc' 'uNAtlohc' 'mNAtlohc' 'lNAtlohc' 'NPacohc' 'xNPacohc' 'uNPacohc' 'mNPacohc' 'lNPacohc' 'TAtlohc' 'xTAtlohc' 'uTAtlohc' 'mTAtlohc' 'lTAtlohc' 'TPacohc' 'xTPacohc' 'uTPacohc' 'mTPacohc' 'lTPacohc' 'TIndohc' 'xTIndohc' 'uTIndohc' 'mTIndohc' 'lTIndohc' 'Antaohc' 'xAntaohc' 'uAntaohc' 'mAntaohc' 'lAntaohc' 'Arctohc' 'xArctohc' 'uArctohc' 'mArctohc' 'lArctohc' ) # Beware that the max_moc diagnostics can not be computed if you don't process complete years (because that's a diagnostic computed from annual means) level1=1 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index ff71e47..ef574ae 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -12,7 +12,7 @@ EXPID = a034 STARTDATES = 19500201 NAME = historical CHUNK_SIZE = 3 -CHUNKS = 120 +CHUNKS = 1 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 994d4ee..e19d9d2 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -72,6 +72,7 @@ class Diags: Diagnostic.register(MaxMoc, 'mocmax') Diagnostic.register(Psi, 'psi') Diagnostic.register(Gyres, 'gyres') + Diagnostic.register(ConvectionSites, 'convection') parse_date('20000101') @@ -141,11 +142,7 @@ class Diags: def _execute_diagnostic(self, diag_options, startdate, member, chunk): diag = diag_options[0] - if diag == 'convection': - variables = ('mlotst', 'mlotstsites') - for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): - Circulation.convection_sites(input_file, self.nemo_version, output_file) - elif diag == 'ohc': + if diag == 'ohc': basin = diag_options[1] mixed_layer = int(diag_options[2]) depth_min = int(diag_options[3]) diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index c5a56b2..ac78c2a 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ # from earthdiagnostics.diagnostic import Diagnostic from heat import Heat -from circulation import Circulation, Moc, AreaMoc, MaxMoc, Psi, Gyres +from circulation import ConvectionSites, Moc, AreaMoc, MaxMoc, Psi, Gyres from general import General, VerticalMean, VerticalMeanMeters, Interpolate from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 77e863b..159335f 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -468,75 +468,60 @@ class Gyres(Diagnostic): else: raise Exception("Input grid {0} not recognized".format(self.nemo_version)) - temp = TempFile.get() - output= TempFile.get() + output = TempFile.get() vsftbarot_file = self.data_manager.get_file('ocean', 'vsftbarot', self.startdate, self.member, self.chunk) - self._gyre(vsftbarot_file, subpolNAtl, temp, invert=True) - handler_original = Utils.openCdf(temp) + handler_original = Utils.openCdf(vsftbarot_file) + self.var_vsftbarot = handler_original.variables['vsftbarot'] handler = Utils.openCdf(output, 'w') - handler.createDimension('time', handler_original.variables['time'].shape[0]) + handler.createDimension('time') handler.createDimension('region', 8) Utils.copy_variable(handler_original, handler, 'time') var_region = handler.createVariable('region', str, 'region') - var_region[0] = 'subpolNAtl' var_gyre = handler.createVariable('gyre', 'f', ('time', 'region')) var_gyre.short_name = 'gyre' var_gyre.long_name = 'gyre' var_gyre.units = 'm^3/s' - handler_original = Utils.openCdf(temp) - var_gyre[:, 0] = handler_original.variables['vsftbarot'][:, 0, 0] - handler_original.close() + var_region[0] = 'subpolNAtl' + var_gyre[:, 0] = self._gyre(subpolNAtl, True) + Log.info('subpolNAtl: {0}', var_gyre[:, 0]) - self._gyre(vsftbarot_file, subpolNPac, temp, invert=True) var_region[1] = 'subpolNPac' - handler_original = Utils.openCdf(temp) - var_gyre[:, 1] = handler_original.variables['vsftbarot'][:, 0, 0] - handler_original.close() + var_gyre[:, 1] = self._gyre(subpolNPac, True) + Log.info('subpolNPac: {0}', var_gyre[:, 1]) - self._gyre(vsftbarot_file, subtropNPac, temp) var_region[2] = 'subtropNPac' - handler_original = Utils.openCdf(temp) - var_gyre[:, 2] = handler_original.variables['vsftbarot'][:, 0, 0] - handler_original.close() + var_gyre[:, 2] = self._gyre(subtropNPac) + Log.info('subtropNPac: {0}', var_gyre[:, 2]) - self._gyre(vsftbarot_file, subtropSPac, temp) var_region[3] = 'subtropSPac' - handler_original = Utils.openCdf(temp) - var_gyre[:, 3] = handler_original.variables['vsftbarot'][:, 0, 0] - handler_original.close() + var_gyre[:, 3] = self._gyre(subtropSPac) + Log.info('subtropSPac: {0}', var_gyre[:, 3]) - self._gyre(vsftbarot_file, subtropNAtl, temp) var_region[4] = 'subtropNAtl' - handler_original = Utils.openCdf(temp) - var_gyre[:, 4] = handler_original.variables['vsftbarot'][:, 0, 0] - handler_original.close() + var_gyre[:, 4] = self._gyre(subtropNAtl) + Log.info('subtropNAtl: {0}', var_gyre[:, 4]) - self._gyre(vsftbarot_file, subtropSAtl, temp) var_region[5] = 'subtropSAtl' - handler_original = Utils.openCdf(temp) - var_gyre[:, 5] = handler_original.variables['vsftbarot'][:, 0, 0] - handler_original.close() + var_gyre[:, 5] = self._gyre(subtropSAtl) + Log.info('subtropSAtl: {0}', var_gyre[:, 5]) - self._gyre(vsftbarot_file, subtropInd, temp) var_region[6] = 'subtropInd' - handler_original = Utils.openCdf(temp) - var_gyre[:, 6] = handler_original.variables['vsftbarot'][:, 0, 0] - handler_original.close() + var_gyre[:, 6] = self._gyre(subtropInd) + Log.info('subtropInd: {0}', var_gyre[:, 6]) - self._gyre(vsftbarot_file, ACC, temp) var_region[7] = 'ACC' - handler_original = Utils.openCdf(temp) - var_gyre[:, 7] = handler_original.variables['vsftbarot'][:, 0, 0] - handler_original.close() + var_gyre[:, 7] = self._gyre(ACC) + Log.info('ACC: {0}', var_gyre[:, 7]) handler.close() + handler_original.close() self.data_manager.send_file(output, 'ocean', 'gyre', self.startdate, self.member, self.chunk) Log.info('Finished gyres for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) - def _gyre(self, input_file, site, output_file, invert=False): + def _gyre(self, site, invert=False): """ Compute the intensity of a given gyre @@ -549,22 +534,52 @@ class Gyres(Diagnostic): :return: """ - temp = TempFile.get() if invert: - Utils.cdo.fldmin(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), - output=temp) - Utils.cdo.mulc(-1, input=temp, output=output_file) + return np.min(self._extract_section(site), (1, 2)) * -1 + else: + return np.max(self._extract_section(site), (1, 2)) + + def _extract_section(self, site): + if site[2] <= site[3]: + if site[0] <= site[1]: + return self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0] - 1:site[1] - 1] + else: + return np.concatenate((self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0]-1:], + self.var_vsftbarot[:, site[2] - 1:site[3] - 1, :site[1] - 1]), axis=2) + else: + if site[0] <= site[1]: + return np.concatenate((self.var_vsftbarot[:, site[2] - 1:, site[0] - 1: site[1] - 1], + self.var_vsftbarot[:, :site[3] - 1, site[0] - 1: site[1] - 1]), axis=1) + else: + temp = np.concatenate((self.var_vsftbarot[:, site[2] - 1:, :], + self.var_vsftbarot[:, :site[3] - 1, :]), axis=1) + return np.concatenate((temp[:, :, site[0] - 1:], + temp[:, :, :site[1] - 1]), axis=2) + - Utils.cdo.fldmax(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), - output=output_file) +class ConvectionSites(Diagnostic): + def __init__(self, data_manager, startdate, member, chunk, nemo_version): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.nemo_version = nemo_version + self.required_vars = ['vsftbarot'] + self.generated_vars = ['gyres'] -class Circulation(object): + @classmethod + def generate_jobs(cls, diags, options): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.nemo_version)) + return job_list - @staticmethod - def convection_sites(input_file, input_grid, output_file): + def compute(self): """ Compute the intensity of convection in the four main convection sites @@ -575,56 +590,53 @@ class Circulation(object): :param output_file: output file name (=> index) :return: """ - if input_grid in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, - Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, - Models.NEMOVAR_O1L42]: - labrador = [255, 245, 215, 255] + if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, + Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, + Models.NEMOVAR_O1L42]: + labrador = [225, 245, 215, 255] irminger = [245, 290, 215, 245] gin = [260, 310, 245, 291] wedell = [225, 280, 1, 50] - elif input_grid in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, - Models.GLORYS2_V1_O25L75]: - raise Exception("Option convection not available yet for {0}".format(input_grid)) + elif self.nemo_version in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, + Models.GLORYS2_V1_O25L75]: + raise Exception("Option convection not available yet for {0}".format(self.nemo_version)) else: - raise Exception("Input grid {0} not recognized".format(input_grid)) - - labrador_file = TempFile.get() - Circulation.convection_site(input_file, labrador, labrador_file) + raise Exception("Input grid {0} not recognized".format(self.nemo_version)) - irminger_file = TempFile.get() - Circulation.convection_site(input_file, irminger, irminger_file) + mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) + output = TempFile.get() - gin_file = TempFile.get() - Circulation.convection_site(input_file, gin, gin_file) + self.mlotst_handler = Utils.openCdf(mlotst_file) + handler = Utils.openCdf(output, 'w') + handler.createDimension('time') + handler.createDimension('region', 4) + Utils.copy_variable(self.mlotst_handler, handler, 'time') + var_region = handler.createVariable('region', str, 'region') + var_gyre = handler.createVariable('site', 'f', ('time', 'region')) + var_gyre.short_name = 'site' + var_gyre.long_name = 'convection sites' + var_gyre.units = 'm^3/s' - wedell_file = TempFile.get() - Circulation.convection_site(input_file, wedell, wedell_file) + var_region[0] = 'labrador' + var_gyre[:, 0] = self._convection_site(labrador) - nco = Utils.nco - Utils.rename_variable(labrador_file, 'mlotst', 'mlotstLabrador') - Utils.rename_variable(irminger_file, 'mlotst', 'mlotstIrminger') - Utils.rename_variable(gin_file, 'mlotst', 'mlotstGIN') - Utils.rename_variable(wedell_file, 'mlotst', 'mlotstWedell') + var_region[1] = 'irminger' + var_gyre[:, 1] = self._convection_site(irminger) - nco.ncks(input=irminger_file, output=labrador_file, options='-A -v mlotstIrminger') - nco.ncks(input=gin_file, output=labrador_file, options='-A -v mlotstGIN') - nco.ncks(input=wedell_file, output=labrador_file, options='-A -v mlotstWedell') + var_region[2] = 'gin' + var_gyre[:, 2] = self._convection_site(gin) - Utils.move_file(labrador_file, output_file) + var_region[3] = 'wedell' + var_gyre[:, 3] = self._convection_site(wedell) - @staticmethod - def convection_site(input_file, site, output_file): - """ - Compute the intensity of convection at one site + self.mlotst_handler.close() + handler.close() - Created in October 2013 Author : vguemas@ic3.cat + self.data_manager.send_file(output, 'ocean', 'site', self.startdate, self.member, self.chunk) + Log.info('Finished convection sites for startdate {0}, member {1}, chunk {2}', + self.startdate, self.member, self.chunk) - :param input_file: input oce file name containing somxl010 - :param site: site to calculate convection on - :param output_file: output file name (=> index) - :return: - """ + def _convection_site(self, site): + return np.max(self.mlotst_handler.variables['mlotst'][:, site[2]-1:site[3]-1, site[0]-1:site[1]-1], (1, 2)) - Utils.cdo.fldmax(input='-selindexbox,{0[0]},{0[1]},{0[2]},{0[3]} {1}'.format(site, input_file), - output=output_file) -- GitLab From 912bd74d34317778c4e6c007d7a5e2e37689b7e8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 13 Jun 2016 16:29:59 +0200 Subject: [PATCH 086/268] Changed average section and cut section to the new way --- earthdiagnostics/box.py | 14 +-- earthdiagnostics/datamanager.py | 110 +++++++++--------- earthdiagnostics/diags.conf | 8 +- earthdiagnostics/diags.py | 26 +---- earthdiagnostics/ocean/__init__.py | 2 +- earthdiagnostics/ocean/circulation.py | 17 ++- earthdiagnostics/ocean/general.py | 156 ++++++++++++++++++++------ 7 files changed, 197 insertions(+), 136 deletions(-) diff --git a/earthdiagnostics/box.py b/earthdiagnostics/box.py index 0d9a93a..072a798 100644 --- a/earthdiagnostics/box.py +++ b/earthdiagnostics/box.py @@ -16,7 +16,7 @@ class Box(object): @max_lat.setter def max_lat(self, value): if value > 90 or value < -90: - raise ValueError('{0} is not a valid latitude. Must be between -90 and -90') + raise ValueError('{0} is not a valid latitude. Must be between -90 and -90'.format(value)) self._max_lat = value @property @@ -26,7 +26,7 @@ class Box(object): @min_lat.setter def min_lat(self, value): if value > 90 or value < -90: - raise ValueError('{0} is not a valid latitude. Must be between -90 and 90') + raise ValueError('{0} is not a valid latitude. Must be between -90 and 90'.format(value)) self._min_lat = value @property @@ -35,9 +35,9 @@ class Box(object): @max_lon.setter def max_lon(self, value): - if value > 180 or value < -180: - raise ValueError('{0} is not a valid longitude. Must be between -180 and 180') - self._min_lat = value + if value > 360 or value < -360: + raise ValueError('{0} is not a valid longitude. Must be between -360 and 360'.format(value)) + self._max_lon = value @property def min_lon(self): @@ -45,8 +45,8 @@ class Box(object): @min_lon.setter def min_lon(self, value): - if value > 180 or value < -180: - raise ValueError('{0} is not a valid longitude. Must be between -180 and 180') + if value >= 360 or value <= -360: + raise ValueError('{0} is not a valid longitude. Must be between -360 and 360'.format(value)) self._min_lon = value def get_lat_str(self): diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index bebbde6..f1fdefd 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,8 +1,8 @@ -# import glob +import glob import shutil -# import threading +import threading # -# import netCDF4 +import netCDF4 import os import numpy as np from autosubmit.config.log import Log @@ -34,58 +34,58 @@ class DataManager(object): raise Exception('The experiment {0} is not CMORized. ' 'Please, CMORize it and launch again.'.format(self.expid)) - # for startdate in startdates: - # for member in members: - # member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') - # Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) - # - # threads = list() - # numthreads = Utils.available_cpu_count() - # filepaths = glob.glob(os.path.join(member_path, '*.gz')) - # for numthread in range(0, numthreads): - # t = threading.Thread(target=DataManager._unzip, - # args=([filepaths[numthread::numthreads]])) - # threads.append(t) - # t.start() - # - # for t in threads: - # t.join() - # - # filepaths = glob.glob(os.path.join(member_path, '*.tar')) - # for numthread in range(0, numthreads): - # t = threading.Thread(target=DataManager._untar, - # args=(filepaths[numthread::numthreads], member_path)) - # threads.append(t) - # t.start() - # - # for t in threads: - # t.join() - # - # if self.experiment_name != self.model: - # bad_path = os.path.join(member_path, 'output', self.institution, self.model, self.model) - # for (dirpath, dirnames, filenames) in os.walk(bad_path, False): - # for filename in filenames: - # filepath = os.path.join(dirpath, filename) - # good = filepath.replace('_{0}_output_'.format(self.model), - # '_{0}_{1}_'.format(self.model, self.experiment_name)) - # - # good = good.replace('/{0}/{0}'.format(self.model), - # '/{0}/{1}'.format(self.model, - # self.experiment_name)) - # - # Utils.move_file(filepath, good) - # os.rmdir(dirpath) - # - # good_dir = os.path.join(member_path, 'output', self.institution, self.model, self.experiment_name) - # for sdate in os.listdir(good_dir): - # for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): - # for filename in filenames: - # filepath = os.path.join(dirpath, filename) - # good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name,sdate), - # '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) - # if good != filepath: - # Log.info('Moving {0} to {1}'.format(filename, good)) - # Utils.move_file(filepath, good) + for startdate in startdates: + for member in members: + member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') + Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) + + threads = list() + numthreads = Utils.available_cpu_count() + filepaths = glob.glob(os.path.join(member_path, '*.gz')) + for numthread in range(0, numthreads): + t = threading.Thread(target=DataManager._unzip, + args=([filepaths[numthread::numthreads]])) + threads.append(t) + t.start() + + for t in threads: + t.join() + + filepaths = glob.glob(os.path.join(member_path, '*.tar')) + for numthread in range(0, numthreads): + t = threading.Thread(target=DataManager._untar, + args=(filepaths[numthread::numthreads], member_path)) + threads.append(t) + t.start() + + for t in threads: + t.join() + + if self.experiment_name != self.model: + bad_path = os.path.join(member_path, 'output', self.institution, self.model, self.model) + for (dirpath, dirnames, filenames) in os.walk(bad_path, False): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_output_'.format(self.model), + '_{0}_{1}_'.format(self.model, self.experiment_name)) + + good = good.replace('/{0}/{0}'.format(self.model), + '/{0}/{1}'.format(self.model, + self.experiment_name)) + + Utils.move_file(filepath, good) + os.rmdir(dirpath) + + good_dir = os.path.join(member_path, 'output', self.institution, self.model, self.experiment_name) + for sdate in os.listdir(good_dir): + for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name,sdate), + '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) + if good != filepath: + Log.info('Moving {0} to {1}'.format(filename, good)) + Utils.move_file(filepath, good) @staticmethod def _unzip(files): diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index ef574ae..8eefb41 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = gyres +DIAGS = SSEC_AVE190-220E FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -12,7 +12,7 @@ EXPID = a034 STARTDATES = 19500201 NAME = historical CHUNK_SIZE = 3 -CHUNKS = 1 +CHUNKS = 122 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 @@ -54,8 +54,8 @@ UOHC = ohc,glob,0,0,17 OHC_SPECIFIED_LAYER = ohclayer,0,300 ohclayer,300,800 3DTEMP = interp,thetao 3DSAL = interp,so -TSEC_AVE190-220E =avgsection,thetaointerp,190,220,-90,90 -SSEC_AVE190-220E =avgsection,sointerp,190,220,-90,90 +TSEC_AVE190-220E =avgsection,thetao,190,220,-90,90 +SSEC_AVE190-220E =avgsection,so,190,220,-90,90 VERT_SSECTIONS = cutsection,so,Z,0 cutsection,so,Z,45 cutsection,so,Z,-45 cutsection,so,M,-30 cutsection,so,M,180 cutsection,so,M,80 VERT_TSECTIONS = cutsection,thetao,Z,0 cutsection,thetao,Z,45 cutsection,thetao,Z,-45 cutsection,thetao,M,-30 cutsection,thetao,M,180 cutsection,thetao,M,80 SIASIESIV = siasiesiv,glob diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index e19d9d2..03c74b3 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -73,6 +73,8 @@ class Diags: Diagnostic.register(Psi, 'psi') Diagnostic.register(Gyres, 'gyres') Diagnostic.register(ConvectionSites, 'convection') + Diagnostic.register(CutSection, 'cutsection') + Diagnostic.register(AverageSection, 'avgsection') parse_date('20000101') @@ -125,7 +127,6 @@ class Diags: Log.error('Diagnostic {0} something failed: {1}', job, ex.message) return False - count = 0 while not queue.empty(): @@ -175,29 +176,6 @@ class Diags: for [input_file, mlotst_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): Heat.mixed_layer_content(input_file, mlotst_file, output_file) - elif diag == 'cutsection': - variable = diag_options[1] - zonal = diag_options[2] == 'z' - value = int(diag_options[3]) - coordinate = Utils.get_cardinal_coordinate(value, zonal) - variables = (variable, '{0}{1}'.format(variable, coordinate)) - for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables, - 'regular'): - General.cut_section(input_file, output_file, variable, zonal, value) - elif diag == 'avgsection': - variable = diag_options[1] - lon_min = int(diag_options[2]) - lon_max = int(diag_options[3]) - lat_min = int(diag_options[4]) - lat_max = int(diag_options[5]) - - output_name = '{0}{1}{2}{3}{4}'.format(variable, Utils.get_cardinal_coordinate(lon_min, False), - Utils.get_cardinal_coordinate(lon_max, False), - Utils.get_cardinal_coordinate(lat_min, True), - Utils.get_cardinal_coordinate(lat_max, True)) - variables = (variable, output_name) - for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): - General.avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max) else: Log.warning('Diagnostic {0} not available', diag) return diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index ac78c2a..d54acf5 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,6 @@ # from earthdiagnostics.diagnostic import Diagnostic from heat import Heat from circulation import ConvectionSites, Moc, AreaMoc, MaxMoc, Psi, Gyres -from general import General, VerticalMean, VerticalMeanMeters, Interpolate +from general import VerticalMean, VerticalMeanMeters, Interpolate, AverageSection, CutSection from salinity import MixedLayerSaltContent from ice import Siasiesiv diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py index 159335f..34b57ed 100644 --- a/earthdiagnostics/ocean/circulation.py +++ b/earthdiagnostics/ocean/circulation.py @@ -486,35 +486,35 @@ class Gyres(Diagnostic): var_region[0] = 'subpolNAtl' var_gyre[:, 0] = self._gyre(subpolNAtl, True) - Log.info('subpolNAtl: {0}', var_gyre[:, 0]) + Log.debug('subpolNAtl: {0}', var_gyre[:, 0]) var_region[1] = 'subpolNPac' var_gyre[:, 1] = self._gyre(subpolNPac, True) - Log.info('subpolNPac: {0}', var_gyre[:, 1]) + Log.debug('subpolNPac: {0}', var_gyre[:, 1]) var_region[2] = 'subtropNPac' var_gyre[:, 2] = self._gyre(subtropNPac) - Log.info('subtropNPac: {0}', var_gyre[:, 2]) + Log.debug('subtropNPac: {0}', var_gyre[:, 2]) var_region[3] = 'subtropSPac' var_gyre[:, 3] = self._gyre(subtropSPac) - Log.info('subtropSPac: {0}', var_gyre[:, 3]) + Log.debug('subtropSPac: {0}', var_gyre[:, 3]) var_region[4] = 'subtropNAtl' var_gyre[:, 4] = self._gyre(subtropNAtl) - Log.info('subtropNAtl: {0}', var_gyre[:, 4]) + Log.debug('subtropNAtl: {0}', var_gyre[:, 4]) var_region[5] = 'subtropSAtl' var_gyre[:, 5] = self._gyre(subtropSAtl) - Log.info('subtropSAtl: {0}', var_gyre[:, 5]) + Log.debug('subtropSAtl: {0}', var_gyre[:, 5]) var_region[6] = 'subtropInd' var_gyre[:, 6] = self._gyre(subtropInd) - Log.info('subtropInd: {0}', var_gyre[:, 6]) + Log.debug('subtropInd: {0}', var_gyre[:, 6]) var_region[7] = 'ACC' var_gyre[:, 7] = self._gyre(ACC) - Log.info('ACC: {0}', var_gyre[:, 7]) + Log.debug('ACC: {0}', var_gyre[:, 7]) handler.close() handler_original.close() @@ -558,7 +558,6 @@ class Gyres(Diagnostic): temp[:, :, :site[1] - 1]), axis=2) - class ConvectionSites(Diagnostic): def __init__(self, data_manager, startdate, member, chunk, nemo_version): diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 17fd471..6105a3a 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -104,7 +104,6 @@ class VerticalMeanMeters(Diagnostic): self.required_vars = [variable] self.generated_vars = [variable + 'vmean'] - @classmethod def generate_jobs(cls, diags, options): num_options = len(options) - 1 @@ -273,24 +272,53 @@ class Interpolate(Diagnostic): Log.debug("Level {0} ready", lev) -class General(object): - """ - General diagnostics that can be used with different variables - """ +class CutSection(Diagnostic): - @staticmethod - def cut_section(input_file, output_file, variable, zonal, value): - """ - Cut a meridional or zonal section - - Created in September 2012 Author : vguemas@ic3.cat - :param input_file: input file - :param output_file: output file ( => 2D ) - :param variable: input var - :param zonal: (zonal / meridional section) - :param value: lat/lon - :return: + def __init__(self, data_manager, startdate, member, chunk, variable, domain, zonal, value): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.zonal = True + self.value = value + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 3: + raise Exception('You must specify the variable, coordinate and coordinate value') + if num_options > 4: + raise Exception('You must specify between 3 and 4 parameters for the interpolation diagnostic') + variable = options[1] + zonal = options[2].lower() == 'true' + value = int(options[3]) + if num_options >= 4: + domain = options[4] + else: + domain = 'ocean' + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(CutSection(diags.data_manager, startdate, member, chunk, + variable, domain, zonal, value)) + return job_list + + def compute(self): """ + Cut a meridional or zonal section + + Created in September 2012 Author : vguemas@ic3.cat + :param input_file: input file + :param output_file: output file ( => 2D ) + :param variable: input var + :param zonal: (zonal / meridional section) + :param value: lat/lon + :return: + """ nco = Utils.nco @@ -311,8 +339,8 @@ class General(object): handler.close() # Latitude / longitude of the zonal / meridional section - exactpos = value - if not zonal: + exactpos = self.value + if not self.zonal: while exactpos < np.min(lon): exactpos += 360 while exactpos > np.max(lon): @@ -327,36 +355,34 @@ class General(object): listj = np.empty(size, dtype=int) for jpt in range(0, size): - if not zonal: + if not self.zonal: vector = lon[jpt, :] else: vector = lat[:, jpt] distance = abs(vector - exactpos) pos = np.where(distance == min(distance)) - if not zonal: + if not self.zonal: listi[jpt] = pos[0][0] listj[jpt] = jpt else: listi[jpt] = jpt listj[jpt] = pos[0][0] - temp = TempFile.get() - shutil.copy(input_file, temp) + temp = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) handler = Utils.openCdf(temp) dimtime = handler.dimensions['time'].size - var_array = handler.variables[variable][:] + var_array = handler.variables[self.variable][:] handler.close() - var = np.empty([dimtime, dimlev, size], dtype=handler.variables[variable].dtype) + var = np.empty([dimtime, dimlev, size], dtype=handler.variables[self.variable].dtype) new_coord = np.empty(size, dtype=float) - if zonal: + if self.zonal: old_coord = lon else: old_coord = lat for jpt in range(0, size): - Log.info(str(jpt)) var[:, :, jpt] = np.maximum(var_array[:, :, listj[jpt], listi[jpt]], mask_lev[:, :, listj[jpt], listi[jpt]]) new_coord[jpt] = old_coord[listj[jpt], listi[jpt]] @@ -364,26 +390,84 @@ class General(object): nco.ncks(input=temp, output=temp, options='-O -v lev,time') handler = Utils.openCdf(temp) - if not zonal: + if not self.zonal: handler.createDimension('lat', size) coord_var = handler.createVariable('lat', float, 'lat') - file_var = handler.createVariable(variable, float, ('time', 'lev', 'lat')) + file_var = handler.createVariable(self.variable, float, ('time', 'lev', 'lat')) else: handler.createDimension('lon', size) coord_var = handler.createVariable('lon', float, 'lon') - file_var = handler.createVariable(variable, float, ('time', 'lev', 'lon')) + file_var = handler.createVariable(self.variable, float, ('time', 'lev', 'lon')) coord_var[:] = new_coord[:] file_var[:] = var[:] file_var.missing_value = 1e20 handler.close() - Utils.move_file(temp, output_file) - @staticmethod - def avgsection(input_file, output_file, lon_min, lon_max, lat_min, lat_max): + box = Box() + if self.zonal: + box.max_lon = self.value + box.min_lon = self.value + else: + box.max_lat = self.value + box.min_lat = self.value + + self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, + box=box) + Log.info('Finished cut section for startdate {0}, member {1}, chunk {2}', + self.startdate, self.member, self.chunk) + + +class AverageSection(Diagnostic): + + def __init__(self, data_manager, startdate, member, chunk, variable, domain, box): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.box = box + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 5: + raise Exception('You must specify the variable and the box to average') + if num_options > 6: + raise Exception('You must specify between 5 and 6 parameters for the section average diagnostic') + variable = options[1] + box = Box() + box.min_lon = int(options[2]) + box.max_lon = int(options[3]) + box.min_lat = int(options[4]) + box.max_lat = int(options[5]) + if num_options >= 6: + domain = options[6] + else: + domain = 'ocean' + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, + variable, domain, box)) + return job_list + + def compute(self): temp = TempFile.get() - Utils.cdo.zonmean(input='-sellonlatbox,{0},{1},{2},{3} {4}'.format(lon_min, lon_max, lat_min, lat_max, - input_file), + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk, + grid='regular') + Utils.cdo.zonmean(input='-sellonlatbox,{0},{1},{2},{3} {4}'.format(self.box.min_lon, self.box.max_lon, + self.box.min_lat, self.box.max_lat, + variable_file), output=temp) - Utils.move_file(temp, output_file) + os.remove(variable_file) + self.data_manager.send_file(temp, self.domain, self.variable + 'mean', self.startdate, self.member, self.chunk, + box=self.box, grid='regular') + Log.info('Finished section average for startdate {0}, member {1}, chunk {2}', + self.startdate, self.member, self.chunk) + + -- GitLab From fa4dd1a338a64131a91d5d09bbfe301e960ff342 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 13 Jun 2016 16:50:31 +0200 Subject: [PATCH 087/268] Extracted some classes to its own files --- earthdiagnostics/datamanager.py | 97 +-- earthdiagnostics/diagnostic.py | 3 +- earthdiagnostics/diags.py | 28 +- earthdiagnostics/ocean/__init__.py | 17 +- earthdiagnostics/ocean/areamoc.py | 121 ++++ earthdiagnostics/ocean/averagesection.py | 57 ++ earthdiagnostics/ocean/circulation.py | 641 ------------------ earthdiagnostics/ocean/convectionsites.py | 87 +++ earthdiagnostics/ocean/cutsection.py | 150 ++++ earthdiagnostics/ocean/general.py | 468 ------------- earthdiagnostics/ocean/gyres.py | 146 ++++ earthdiagnostics/ocean/interpolate.py | 129 ++++ earthdiagnostics/ocean/maxmoc.py | 189 ++++++ .../{salinity.py => mixedlayersaltcontent.py} | 8 +- earthdiagnostics/ocean/moc.py | 78 +++ earthdiagnostics/ocean/psi.py | 41 ++ .../ocean/{ice.py => siasiesiv.py} | 15 +- earthdiagnostics/ocean/vertcalmean.py | 76 +++ earthdiagnostics/ocean/verticalmeanmeters.py | 70 ++ earthdiagnostics/utils.py | 1 + 20 files changed, 1194 insertions(+), 1228 deletions(-) create mode 100644 earthdiagnostics/ocean/areamoc.py create mode 100644 earthdiagnostics/ocean/averagesection.py delete mode 100644 earthdiagnostics/ocean/circulation.py create mode 100644 earthdiagnostics/ocean/convectionsites.py create mode 100644 earthdiagnostics/ocean/cutsection.py create mode 100644 earthdiagnostics/ocean/gyres.py create mode 100644 earthdiagnostics/ocean/interpolate.py create mode 100644 earthdiagnostics/ocean/maxmoc.py rename earthdiagnostics/ocean/{salinity.py => mixedlayersaltcontent.py} (96%) create mode 100644 earthdiagnostics/ocean/moc.py create mode 100644 earthdiagnostics/ocean/psi.py rename earthdiagnostics/ocean/{ice.py => siasiesiv.py} (97%) create mode 100644 earthdiagnostics/ocean/vertcalmean.py create mode 100644 earthdiagnostics/ocean/verticalmeanmeters.py diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index f1fdefd..9aa15dc 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -81,7 +81,7 @@ class DataManager(object): for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): for filename in filenames: filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name,sdate), + good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name, sdate), '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) if good != filepath: Log.info('Moving {0} to {1}'.format(filename, good)) @@ -237,7 +237,8 @@ class DataManager(object): var_region[0] = region original_var = handler.variables[var] - new_var = handler.createVariable('new_var', original_var.datatype, original_var.dimensions + ('region',)) + new_var = handler.createVariable('new_var', original_var.datatype, + original_var.dimensions + ('region',)) new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) value = original_var[:] new_var[..., 0] = value @@ -260,10 +261,8 @@ class DataManager(object): else: basin_index = basin_index[0][0] - try: - handler.variables[var][..., basin_index] = value - except Exception: - error = True + + handler.variables[var][..., basin_index] = value handler.close() handler_send.close() Utils.move_file(temp, filetosend) @@ -286,6 +285,8 @@ class DataManager(object): handler = Utils.openCdf(temp) time = Utils.get_datetime_from_netcdf(handler) handler.close() + start = None + end = None for x in range(0, len(time)): date = time[x] if date.year == year: @@ -307,7 +308,7 @@ class DataManager(object): break elif chunk_start.year == year or chunk_end_date(chunk_start, self.chunk_size, 'month', self.calendar).year == year: - chunks.append(chunk) + chunks.append(chunk) return chunks @@ -328,85 +329,3 @@ class DataManager(object): years.append(first_year) first_year += 1 return years - - -# -# set -vx -# -# exp=a034 -# dir=/group_workspaces/jasmin2/primavera1/WP2/CPL/EC-EARTH3.1/HIST_T511ORCA025 -# res=$( echo $dir | cut -f3 -d"_" ) -# model=$(echo $dir | cut -f7 -d"/" ) -# -# cd /esnas/exp/ecearth/$exp/ -# -# for sd in [1-2]* -# do -# cd /esnas/exp/ecearth/$exp/$sd -# for fc in * -# do -# cd /esnas/exp/ecearth/$exp/$sd/$fc/outputs -# realization=$(( $(echo $fc | cut -c 3-) + 1 )) -# outdir=/esnas/exp/ecearth/$exp/$sd/$fc/outputs/primavera -# mkdir -p $outdir -# for tarfile in MMO*tar -# do -# lt=$(echo $tarfile | cut -f 5-6 -d"_" | cut -f1 -d"." ) -# tar kxvf $tarfile -C $outdir -# cd $outdir -# for file in ${exp}_1m_*grid*gz ${exp}_*icemod*gz -# do -# echo $file -# gunzip $file -# for var in $( cdo showvar ${file%???} ) -# do -# varnew="" -# case $var in -# votemper) varnew=thetao; realm=Omon ; modeling_realm="ocean" ; units="C";; -# vosaline) varnew=so; realm=Omon ; modeling_realm="ocean" ;; -# sosstsst) varnew=tos; realm=Omon ; modeling_realm="ocean" ; units="C";; -# sosaline) varnew=sos; realm=Omon ; modeling_realm="ocean" ;; -# sossheig) varnew=zos; realm=Omon ; modeling_realm="ocean" ;; -# vozocrtx) varnew=uo; realm=Omon ; modeling_realm="ocean" ;; -# vomecrty) varnew=vo; realm=Omon ; modeling_realm="ocean" ;; -# iiceconc) varnew=sic; realm=OImon ; modeling_realm="seaIce" ;; -# iicethic) varnew=sit; realm=OImon ; modeling_realm="seaIce" ;; -# isnowthi) varnew=snd; realm=OImon ; modeling_realm="seaIce" ;; -# iicesurt) varnew=tsice; realm=OImon ; modeling_realm="seaIce" ; units="C";; -# esac -# outfile=$(echo ${varnew}_${realm}_${model}_${res}_BSC_${realization}_${lt}.nc ) -# if [[ ! -z $varnew ]] && [[ ! -f ${outdir}/${outfile} ]]; then #check if var belongs to list -# cdo selvar,$var ${file%???} ${outdir}/$outfile -# ncrename -v .time_counter,time -d time_counter,time -v nav_lon,longitude -v nav_lat,latitude -v .${var},${varnew} ${outdir}/${outfile} -# for att in institution institute_id experiment_id model_id contact experiment frequency creation_date project_id modeling_realm realization -# do -# case $att in -# institution) att_val="Barcelona Supercomputing Center - Centro Nacional de Supercomputacion" ;; -# institute_id) att_val="BSC-CNS" ;; -# experiment_id) att_val=$(echo $dir | cut -f7 -d"/") ;; -# model_id) att_val="$model" ;; -# contact) att_val="pierre-antoine.bretonniere@bsc.es" ;; -# experiment) att_val=$(echo $dir | cut -f7 -d"/") ;; -# frequency) att_val="mon" ;; -# creation_date) att_val="$(echo $(date --rfc-3339=seconds | cut -f1 -d"+" | sed -e 's/ /T/')Z)" ;; -# project_id) att_val="PRIMAVERA" ;; -# modeling_realm) att_val="$modeling_realm" ;; -# realization) att_val="$realization" ;; -# esac -# ncatted -O -h -a ${att},global,c,c,"${att_val}" ${outdir}/$outfile -# if [[ "$units" == "C" ]]; then -# cdo addc,273.25 ${outdir}/$outfile ${outdir}/${outfile}.tmp -# mv ${outdir}/${outfile}.tmp ${outdir}/${outfile} -# ncatted -O -h -a units,${varnew},m,c,"K" ${outdir}/$outfile -# fi #temp from C to K -# done #attributes -# fi -# done #var -# rm ${file%???} -# done #file -# cd /esnas/exp/ecearth/$exp/$sd/$fc/outputs -# done #tarfile -# scp -i ~/.ssh/id_rsa_jasmin ${outdir}/*Omon*nc pabretonniere@jasmin-xfer1.ceda.ac.uk:$dir/. -# scp -i ~/.ssh/id_rsa_jasmin ${outdir}/*OImon*nc pabretonniere@jasmin-xfer1.ceda.ac.uk:$dir/. -# done #fc -# done #sd diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 2e20251..fb24d06 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -8,6 +8,7 @@ class Diagnostic(object): Diagnostic._diag_list = dict() Diagnostic._diag_list[alias] = cls + # noinspection PyProtectedMember @staticmethod def get_diagnostic(name): """ @@ -36,4 +37,4 @@ class Diagnostic(object): @classmethod def generate_jobs(cls, diags, options): - raise Exception("Class must override generate_jobs method") \ No newline at end of file + raise Exception("Class must override generate_jobs method") diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 03c74b3..2e2f451 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,21 +1,22 @@ #!/usr/bin/env python -import argparse - -from datamanager import DataManager -from earthdiagnostics.ocean import * import Queue -from earthdiagnostics import Diagnostic +import argparse +import shutil import threading + import netCDF4 -from utils import Utils +import os +from autosubmit.date.chunk_date_lib import * + +from datamanager import DataManager from earthdiagnostics import cdftools, TempFile from earthdiagnostics.diagnostic import Diagnostic -from autosubmit.date.chunk_date_lib import * +from earthdiagnostics.ocean import * +from ocean import ConvectionSites, Gyres, Psi, MaxMoc, AreaMoc, Moc, VerticalMean, VerticalMeanMeters, Interpolate, \ + AverageSection, CutSection, MixedLayerSaltContent, Siasiesiv from parser import Parser -from autosubmit.config.log import Log -import shutil -import os +from utils import Utils class Diags: @@ -117,10 +118,10 @@ class Diags: @staticmethod def _run_jobs(queue, numthread): - def _run_job(job, retrials=1): + def _run_job(current_job, retrials=1): while retrials > 0: try: - job.compute() + current_job.compute() return True except Exception as ex: retrials -= 1 @@ -162,7 +163,8 @@ class Diags: for [input_file, mlotst_file, ohcsum_file, ohcvmean_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): - Heat.total(input_file, mlotst_file, ohcsum_file, ohcvmean_file, basin, mixed_layer, depth_min, depth_max) + Heat.total(input_file, mlotst_file, ohcsum_file, ohcvmean_file, basin, mixed_layer, + depth_min, depth_max) elif diag == 'ohclayer': depth_min = int(diag_options[1]) depth_max = int(diag_options[2]) diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index d54acf5..657b875 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,6 +1,15 @@ # from earthdiagnostics.diagnostic import Diagnostic from heat import Heat -from circulation import ConvectionSites, Moc, AreaMoc, MaxMoc, Psi, Gyres -from general import VerticalMean, VerticalMeanMeters, Interpolate, AverageSection, CutSection -from salinity import MixedLayerSaltContent -from ice import Siasiesiv +from ocean.moc import Moc +from ocean.areamoc import AreaMoc +from ocean.maxmoc import MaxMoc +from ocean.psi import Psi +from ocean.gyres import Gyres +from ocean.convectionsites import ConvectionSites +from ocean.cutsection import CutSection +from ocean.averagesection import AverageSection +from ocean.interpolate import Interpolate +from ocean.verticalmeanmeters import VerticalMeanMeters +from ocean.vertcalmean import VerticalMean +from ocean.mixedlayersaltcontent import MixedLayerSaltContent +from ocean.siasiesiv import Siasiesiv diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py new file mode 100644 index 0000000..880751e --- /dev/null +++ b/earthdiagnostics/ocean/areamoc.py @@ -0,0 +1,121 @@ +import numpy as np + +from basins import Basins +from box import Box +from earthdiagnostics import Diagnostic, Utils, TempFile + + +class AreaMoc(Diagnostic): + """ + Compute the MOC for oceanic basins + Created in March 2012 + Author : vguemas@ic3.cat + + # :param input_file: input grid_V file namez + # :type input_file: str + # :param output_file: output file name (=> 2D, depth-y) + # :param output_file: str + # :return: + """ + + def __init__(self, data_manager, startdate, member, chunk, basin, box): + Diagnostic.__init__(self, data_manager) + self.basin = basin + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['vo'] + self.generated_vars = ['vsftmyz'] + self.box = box + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 4: + raise Exception('You must specify the box to use') + if num_options > 5: + raise Exception('You must specify between 4 and 5 parameters for area moc diagnostic') + box = Box() + box.min_lat = int(options[1]) + box.max_lat = int(options[2]) + box.min_depth = int(options[3]) + box.max_depth = int(options[4]) + if num_options > 4: + basin = Basins.parse(options[5]) + else: + basin = Basins.Global + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(AreaMoc(diags.data_manager, startdate, member, chunk, basin, box)) + return job_list + + def compute(self): + """ + Compute an Atlantic MOC index by averaging the meridional overturning + in a latitude band between 1km and 2km + or any other index averaging the meridional overturning in + a given basin and a given domain + + Created in March 2012 Author : vguemas@ic3.cat + + :param input_file: input moc file name + :param lat_min: latitude min + :param lat_max: latitude max + :param output_file: output file name ( => index ) + :param depth_min: depth min + :param depth_max: depth max + :param basin: basin + :return: + """ + nco = Utils.nco + cdo = Utils.cdo + temp2 = TempFile.get() + + temp = self.data_manager.get_file('ocean', 'vsftmyz', self.startdate, self.member, self.chunk) + + handler = Utils.openCdf(temp) + if 'i' in handler.dimensions: + handler.close() + nco.ncwa(input=temp, output=temp, options='-O -a i') + handler = Utils.openCdf(temp) + + basin_index = np.where(handler.variables['basin'][:] == self.basin.fullname) + lat_values = handler.variables['lat'][:] + lat_type = handler.variables['lat'].dtype + lat_units = handler.variables['lat'].units + lat_long_name = handler.variables['lat'].long_name + + handler.close() + + if len(basin_index) == 0: + raise Exception('Basin {0} not defined in file') + basin_index = basin_index[0][0] + nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) + # To remove basin dimension + nco.ncwa(input=temp, output=temp, options='-O -a basin') + + nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev') + + handler = Utils.openCdf(temp) + handler.renameDimension('j', 'lat') + lat_variable = handler.createVariable('lat', lat_type, 'lat') + lat_variable[:] = lat_values[:] + lat_variable.units = lat_units + lat_variable.long_name = lat_long_name + + handler.close() + + nco.ncks(input=temp, output=temp2, + options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(self.box.min_depth, + self.box.max_depth, + self.box.min_lat, + self.box.max_lat)) + + cdo.vertmean(input=temp2, output=temp) + nco.ncap2(input=temp, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') + nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') + nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time') + self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, box=self.box) diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py new file mode 100644 index 0000000..93048bb --- /dev/null +++ b/earthdiagnostics/ocean/averagesection.py @@ -0,0 +1,57 @@ +import os +from autosubmit.config.log import Log + +from box import Box +from earthdiagnostics import Diagnostic, TempFile, Utils + + +class AverageSection(Diagnostic): + + def __init__(self, data_manager, startdate, member, chunk, variable, domain, box): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.box = box + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 5: + raise Exception('You must specify the variable and the box to average') + if num_options > 6: + raise Exception('You must specify between 5 and 6 parameters for the section average diagnostic') + variable = options[1] + box = Box() + box.min_lon = int(options[2]) + box.max_lon = int(options[3]) + box.min_lat = int(options[4]) + box.max_lat = int(options[5]) + if num_options >= 6: + domain = options[6] + else: + domain = 'ocean' + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, + variable, domain, box)) + return job_list + + def compute(self): + temp = TempFile.get() + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk, + grid='regular') + Utils.cdo.zonmean(input='-sellonlatbox,{0},{1},{2},{3} {4}'.format(self.box.min_lon, self.box.max_lon, + self.box.min_lat, self.box.max_lat, + variable_file), + output=temp) + os.remove(variable_file) + self.data_manager.send_file(temp, self.domain, self.variable + 'mean', self.startdate, self.member, self.chunk, + box=self.box, grid='regular') + Log.info('Finished section average for startdate {0}, member {1}, chunk {2}', + self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/circulation.py b/earthdiagnostics/ocean/circulation.py deleted file mode 100644 index 34b57ed..0000000 --- a/earthdiagnostics/ocean/circulation.py +++ /dev/null @@ -1,641 +0,0 @@ -from earthdiagnostics import Utils, cdftools, TempFile -from earthdiagnostics.basins import Basins -from earthdiagnostics.models import Models -from earthdiagnostics.diagnostic import Diagnostic -from earthdiagnostics.box import Box -from autosubmit.config.log import Log -import numpy as np -import os -import shutil -import netCDF4 - - -class Moc(Diagnostic): - """ - Compute the MOC for oceanic basins - Created in March 2012 - Author : vguemas@ic3.cat - - # :param input_file: input grid_V file namez - # :type input_file: str - # :param output_file: output file name (=> 2D, depth-y) - # :param output_file: str - # :return: - """ - - def __init__(self, data_manager, startdate, member, chunk): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.required_vars = ['vo'] - self.generated_vars = ['vsftmyz'] - - @classmethod - def generate_jobs(cls, diags, options): - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Moc(diags.data_manager, startdate, member, chunk)) - return job_list - - def compute(self): - temp = TempFile.get() - - input_file = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) - - Log.debug('Computing MOC') - cdftools.run('cdfmoc', input=input_file, output=temp) - Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') - Utils.convert2netcdf4(temp) - - Log.debug('Reformatting variables') - handler = Utils.openCdf(temp) - - handler.createDimension('basin', 5) - handler.createVariable('basin', str, 'basin') - handler.variables['basin'][:] = np.array([Basins.Global.fullname, Basins.Atlantic.fullname, - Basins.Pacific.fullname, Basins.IndoPacific.fullname, - Basins.Indian.fullname], dtype=object) - example = handler.variables['zomsfglo'] - # noinspection PyProtectedMember - moc = handler.createVariable('vsftmyz', example.datatype, - ('time', 'lev', 'i', 'j', 'basin'), - fill_value=example._FillValue) - - moc.units = example.units - moc.add_offset = example.add_offset - moc.scale_factor = example.scale_factor - - moc[:, :, :, :, 0] = handler.variables['zomsfglo'][:] - moc[:, :, :, :, 1] = handler.variables['zomsfatl'][:] - moc[:, :, :, :, 2] = handler.variables['zomsfpac'][:] - moc[:, :, :, :, 3] = handler.variables['zomsfinp'][:] - moc[:, :, :, :, 4] = handler.variables['zomsfind'][:] - - handler.close() - - Utils.nco.ncks(input=temp, output=temp, - options='-O -x -v zomsfglo,zomsfatl,zomsfpac,zomsfinp,zomsfind,zomsfinp0') - Utils.setminmax(temp, 'vsftmyz') - - self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk) - - -class AreaMoc(Diagnostic): - """ - Compute the MOC for oceanic basins - Created in March 2012 - Author : vguemas@ic3.cat - - # :param input_file: input grid_V file namez - # :type input_file: str - # :param output_file: output file name (=> 2D, depth-y) - # :param output_file: str - # :return: - """ - - def __init__(self, data_manager, startdate, member, chunk, basin, box): - Diagnostic.__init__(self, data_manager) - self.basin = basin - self.startdate = startdate - self.member = member - self.chunk = chunk - self.required_vars = ['vo'] - self.generated_vars = ['vsftmyz'] - self.box = box - - @classmethod - def generate_jobs(cls, diags, options): - num_options = len(options) - 1 - if num_options < 4: - raise Exception('You must specify the box to use') - if num_options > 5: - raise Exception('You must specify between 4 and 5 parameters for area moc diagnostic') - box = Box() - box.min_lat = int(options[1]) - box.max_lat = int(options[2]) - box.min_depth = int(options[3]) - box.max_depth = int(options[4]) - if num_options > 4: - basin = Basins.parse(options[5]) - else: - basin = Basins.Global - - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(AreaMoc(diags.data_manager, startdate, member, chunk, basin, box)) - return job_list - - def compute(self): - """ - Compute an Atlantic MOC index by averaging the meridional overturning - in a latitude band between 1km and 2km - or any other index averaging the meridional overturning in - a given basin and a given domain - - Created in March 2012 Author : vguemas@ic3.cat - - :param input_file: input moc file name - :param lat_min: latitude min - :param lat_max: latitude max - :param output_file: output file name ( => index ) - :param depth_min: depth min - :param depth_max: depth max - :param basin: basin - :return: - """ - nco = Utils.nco - cdo = Utils.cdo - temp2 = TempFile.get() - - temp = self.data_manager.get_file('ocean', 'vsftmyz', self.startdate, self.member, self.chunk) - - handler = Utils.openCdf(temp) - if 'i' in handler.dimensions: - handler.close() - nco.ncwa(input=temp, output=temp, options='-O -a i') - handler = Utils.openCdf(temp) - - basin_index = np.where(handler.variables['basin'][:] == self.basin.fullname) - lat_values = handler.variables['lat'][:] - lat_type = handler.variables['lat'].dtype - lat_units = handler.variables['lat'].units - lat_long_name = handler.variables['lat'].long_name - - handler.close() - - if len(basin_index) == 0: - raise Exception('Basin {0} not defined in file') - basin_index = basin_index[0][0] - nco.ncks(input=temp, output=temp, options='-O -d basin,{0}'.format(basin_index)) - # To remove basin dimension - nco.ncwa(input=temp, output=temp, options='-O -a basin') - - nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev') - - handler = Utils.openCdf(temp) - handler.renameDimension('j', 'lat') - lat_variable = handler.createVariable('lat', lat_type, 'lat') - lat_variable[:] = lat_values[:] - lat_variable.units = lat_units - lat_variable.long_name = lat_long_name - - handler.close() - - nco.ncks(input=temp, output=temp2, - options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(self.box.min_depth, self.box.max_depth, - self.box.min_lat, self.box.max_lat)) - - cdo.vertmean(input=temp2, output=temp) - nco.ncap2(input=temp, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') - nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') - nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time') - self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, box=self.box) - - -class MaxMoc(Diagnostic): - - def __init__(self, data_manager, startdate, member, year, basin, box): - Diagnostic.__init__(self, data_manager) - self.basin = basin - self.startdate = startdate - self.member = member - self.year = year - self.required_vars = ['vo'] - self.generated_vars = ['vsftmyz'] - self.box = box - - @classmethod - def generate_jobs(cls, diags, options): - num_options = len(options) - 1 - if num_options < 4: - raise Exception('You must specify the box to use') - if num_options > 5: - raise Exception('You must specify between 4 and 5 parameters for area moc diagnostic') - box = Box() - box.min_lat = int(options[1]) - box.max_lat = int(options[2]) - box.min_depth = int(options[3]) - box.max_depth = int(options[4]) - if num_options > 4: - basin = Basins.parse(options[5]) - else: - basin = Basins.Global - - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - years = diags.data_manager.get_full_years(startdate) - if len(years) == 0: - Log.user_warning('No complete years are available with the given configuration. ' - 'MaxMoc can not be computed') - for year in years: - job_list.append(MaxMoc(diags.data_manager, startdate, member, year, basin, box)) - return job_list - - def compute(self): - """ - Compute an Atlantic MOC index by finding the maximum of the annual - mean meridional overturning in a latitude / depth region - - Created in March 2012 Author : vguemas@ic3.cat - - :param basin: basin - :param input_file: input moc file name - :param lat_min: latitude min - :param lat_max: latitude max - :param output_file: output file name - :param depth_min: depth mean - :param depth_max: depth max - :return: - """ - nco = Utils.nco - - temp = self.data_manager.get_year('ocean', 'vsftmyz', self.startdate, self.member, self.year) - - handler = Utils.openCdf(temp) - if 'i' in handler.dimensions: - handler.close() - nco.ncwa(input=temp, output=temp, options='-O -a i') - else: - handler.close() - handler = Utils.openCdf(temp) - basin_index = np.where(handler.variables['basin'][:] == self.basin.fullname) - if len(basin_index) == 0: - raise Exception("Basin {1} is not defined in {0}", temp, self.basin.fullname) - basin_index = basin_index[0][0] - - lev = handler.variables['lev'][:] - lat = handler.variables['lat'][:] - - if self.box.min_lat == self.box.max_lat: - lat_inds = ((np.abs(lat-self.box.min_lat)).argmin(),) - else: - lat_inds = np.where((lat > self.box.min_lat) & (lat < self.box.max_lat))[0] - - if self.box.min_depth == self.box.max_depth: - lev_inds = ((np.abs(lev - self.box.min_depth)).argmin(),) - else: - lev_inds = np.where((lev > self.box.min_depth) & (lev < self.box.max_depth))[0] - - Log.info('Computing year {0}', str(self.year)) - moc = handler.variables['vsftmyz'][:, lev_inds, lat_inds, basin_index] - handler.close() - os.remove(temp) - - moc = np.mean(moc, 0) - - maximum = np.amax(moc) - max_index = np.unravel_index(np.argmax(moc), moc.shape) - max_lev = lev[lev_inds[max_index[0]]] - max_lat = lat[lat_inds[max_index[1]]] - - minimum = np.amin(moc) - minimum_index = np.unravel_index(np.argmin(moc), moc.shape) - min_lev = lev[lev_inds[minimum_index[0]]] - min_lat = lat[lat_inds[minimum_index[1]]] - - Log.info('Maximum {0} Sv, latitude {1} depth {2} m', maximum, max_lat, max_lev) - Log.info('Minimum {0} Sv, latitude {1} depth {2} m', minimum, min_lat, min_lev) - - handler = self._create_output_file(temp) - var = handler.createVariable('vsftmyzmax', float, ('time',)) - var.long_name = 'Maximum_Overturing' - var.units = 'Sverdrup' - var.valid_min = -1000. - var.valid_max = 1000. - var[0] = maximum - handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) - - handler = self._create_output_file(temp) - var = handler.createVariable('vsftmyzmaxlat', float, ('time',)) - var.long_name = 'Latitude_of_Maximum_Overturing' - var.units = 'Degrees' - var.valid_min = -90. - var.valid_max = 90. - var[0] = max_lat - handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) - - handler = self._create_output_file(temp) - var = handler.createVariable('vsftmyzmaxlev', float, ('time',)) - var.long_name = 'Depth_of_Maximum_Overturing' - var.units = 'Meters' - var.valid_min = 0. - var.valid_max = 10000. - var[0] = max_lev - handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) - - handler = self._create_output_file(temp) - var = handler.createVariable('vsftmyzmin', float, ('time',)) - var.long_name = 'Minimum_Overtuning' - var.units = 'Sverdrup' - var.valid_min = -1000. - var.valid_max = 1000. - var[0] = minimum - handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) - - handler = self._create_output_file(temp) - var = handler.createVariable('vsftmyzminlat', float, ('time',)) - var.long_name = 'Latitude_of_Minimum_Overtuning' - var.units = 'Degrees' - var.valid_min = -90. - var.valid_max = 90. - var[0] = min_lat - handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) - - handler = self._create_output_file(temp) - var = handler.createVariable('vsftmyzminlev', float, ('time',)) - var.long_name = 'Depth_of_Minimum_Overtuning' - var.units = 'Meters' - var.valid_min = 0. - var.valid_max = 10000. - var[0] = min_lev - handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) - - def _create_output_file(self, temp): - handler = netCDF4.Dataset(temp, 'w') - handler.createDimension('time') - - time = handler.createVariable('time', 'i2', ('time',)) - time.calendar = 'gregorian' - time.units = 'days since January 1, {0}'.format(self.year) - return handler - - -class Psi(Diagnostic): - def __init__(self, data_manager, startdate, member, chunk): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.required_vars = ['vo', 'uo'] - self.generated_vars = ['vsftbarot'] - - @classmethod - def generate_jobs(cls, diags, options): - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Psi(diags.data_manager, startdate, member, chunk)) - return job_list - - def compute(self): - """ - Compute the barotropic stream function - - Created in March 2012 Author : vguemas@ic3.cat - z - :param input_file_u: input grid_U file name - :rtype input_file_U: str - :param input_file_v: input grid_V file name - :rtype input_file_V: str - :param output_file: output file name without nc extension (=> 2D x-y) - :rtype output_file: str - """ - temp = TempFile.get() - input_file_u = self.data_manager.get_file('ocean', 'uo', self.startdate, self.member, self.chunk) - input_file_v = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) - cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-mean -mask') - Utils.rename_variable(temp, 'sobarstf', 'vsftbarot') - Utils.setminmax(temp, 'vsftbarot') - self.data_manager.send_file(temp, 'ocean', 'vsftbarot', self.startdate, self.member, self.chunk) - - -class Gyres(Diagnostic): - def __init__(self, data_manager, startdate, member, chunk, nemo_version): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.nemo_version = nemo_version - self.required_vars = ['vsftbarot'] - self.generated_vars = ['gyres'] - - @classmethod - def generate_jobs(cls, diags, options): - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.nemo_version)) - return job_list - - def compute(self): - """ - Compute the intensity of the subtropical and subpolar gyres - - Created in October 2013 Author : vguemas@ic3.cat - - :param input_psi: input psi file name - :param input_grid: input grid - :param output_file: output file name ( => index ) - :return: - """ - - if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, - Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, - Models.NEMOVAR_O1L42]: - - subpolNAtl = [230, 275, 215, 245] - subpolNPac = [70, 145, 195, 235] - subtropNPac = [45, 175, 165, 220] - subtropNAtl = [195, 275, 175, 225] - subtropSPac = [70, 205, 120, 145] - subtropSAtl = [235, 300, 120, 145] - subtropInd = [320, 30, 110, 180] - ACC = [1, 361, 1, 65] - - elif self in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, - Models.GLORYS2_V1_O25L75]: - raise Exception("Option gyres not available yet for {0}".format(self.nemo_version)) - else: - raise Exception("Input grid {0} not recognized".format(self.nemo_version)) - - output = TempFile.get() - vsftbarot_file = self.data_manager.get_file('ocean', 'vsftbarot', self.startdate, self.member, self.chunk) - - handler_original = Utils.openCdf(vsftbarot_file) - self.var_vsftbarot = handler_original.variables['vsftbarot'] - handler = Utils.openCdf(output, 'w') - handler.createDimension('time') - handler.createDimension('region', 8) - Utils.copy_variable(handler_original, handler, 'time') - var_region = handler.createVariable('region', str, 'region') - - var_gyre = handler.createVariable('gyre', 'f', ('time', 'region')) - var_gyre.short_name = 'gyre' - var_gyre.long_name = 'gyre' - var_gyre.units = 'm^3/s' - - var_region[0] = 'subpolNAtl' - var_gyre[:, 0] = self._gyre(subpolNAtl, True) - Log.debug('subpolNAtl: {0}', var_gyre[:, 0]) - - var_region[1] = 'subpolNPac' - var_gyre[:, 1] = self._gyre(subpolNPac, True) - Log.debug('subpolNPac: {0}', var_gyre[:, 1]) - - var_region[2] = 'subtropNPac' - var_gyre[:, 2] = self._gyre(subtropNPac) - Log.debug('subtropNPac: {0}', var_gyre[:, 2]) - - var_region[3] = 'subtropSPac' - var_gyre[:, 3] = self._gyre(subtropSPac) - Log.debug('subtropSPac: {0}', var_gyre[:, 3]) - - var_region[4] = 'subtropNAtl' - var_gyre[:, 4] = self._gyre(subtropNAtl) - Log.debug('subtropNAtl: {0}', var_gyre[:, 4]) - - var_region[5] = 'subtropSAtl' - var_gyre[:, 5] = self._gyre(subtropSAtl) - Log.debug('subtropSAtl: {0}', var_gyre[:, 5]) - - var_region[6] = 'subtropInd' - var_gyre[:, 6] = self._gyre(subtropInd) - Log.debug('subtropInd: {0}', var_gyre[:, 6]) - - var_region[7] = 'ACC' - var_gyre[:, 7] = self._gyre(ACC) - Log.debug('ACC: {0}', var_gyre[:, 7]) - - handler.close() - handler_original.close() - self.data_manager.send_file(output, 'ocean', 'gyre', self.startdate, self.member, self.chunk) - Log.info('Finished gyres for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) - - def _gyre(self, site, invert=False): - """ - Compute the intensity of a given gyre - - Created in October 2013 Author : vguemas@ic3.cat - - :param input_file: input oce file name containing vsftbarot - :param site: site to calculate convection on - :param output_file: output file name (=> index) - :param invert: if True, multiplies result by -1 - :return: - """ - - if invert: - return np.min(self._extract_section(site), (1, 2)) * -1 - else: - return np.max(self._extract_section(site), (1, 2)) - - def _extract_section(self, site): - if site[2] <= site[3]: - if site[0] <= site[1]: - return self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0] - 1:site[1] - 1] - else: - return np.concatenate((self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0]-1:], - self.var_vsftbarot[:, site[2] - 1:site[3] - 1, :site[1] - 1]), axis=2) - - else: - if site[0] <= site[1]: - return np.concatenate((self.var_vsftbarot[:, site[2] - 1:, site[0] - 1: site[1] - 1], - self.var_vsftbarot[:, :site[3] - 1, site[0] - 1: site[1] - 1]), axis=1) - else: - temp = np.concatenate((self.var_vsftbarot[:, site[2] - 1:, :], - self.var_vsftbarot[:, :site[3] - 1, :]), axis=1) - return np.concatenate((temp[:, :, site[0] - 1:], - temp[:, :, :site[1] - 1]), axis=2) - - -class ConvectionSites(Diagnostic): - - def __init__(self, data_manager, startdate, member, chunk, nemo_version): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.nemo_version = nemo_version - self.required_vars = ['vsftbarot'] - self.generated_vars = ['gyres'] - - @classmethod - def generate_jobs(cls, diags, options): - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.nemo_version)) - return job_list - - def compute(self): - """ - Compute the intensity of convection in the four main convection sites - - Created in October 2013 Author : vguemas@ic3.cat - - :param input_file: input oce file name containing mlotst - :param input_grid: input grid - :param output_file: output file name (=> index) - :return: - """ - if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, - Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, - Models.NEMOVAR_O1L42]: - labrador = [225, 245, 215, 255] - irminger = [245, 290, 215, 245] - gin = [260, 310, 245, 291] - wedell = [225, 280, 1, 50] - - elif self.nemo_version in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, - Models.GLORYS2_V1_O25L75]: - raise Exception("Option convection not available yet for {0}".format(self.nemo_version)) - else: - raise Exception("Input grid {0} not recognized".format(self.nemo_version)) - - mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) - output = TempFile.get() - - self.mlotst_handler = Utils.openCdf(mlotst_file) - handler = Utils.openCdf(output, 'w') - handler.createDimension('time') - handler.createDimension('region', 4) - Utils.copy_variable(self.mlotst_handler, handler, 'time') - var_region = handler.createVariable('region', str, 'region') - var_gyre = handler.createVariable('site', 'f', ('time', 'region')) - var_gyre.short_name = 'site' - var_gyre.long_name = 'convection sites' - var_gyre.units = 'm^3/s' - - var_region[0] = 'labrador' - var_gyre[:, 0] = self._convection_site(labrador) - - var_region[1] = 'irminger' - var_gyre[:, 1] = self._convection_site(irminger) - - var_region[2] = 'gin' - var_gyre[:, 2] = self._convection_site(gin) - - var_region[3] = 'wedell' - var_gyre[:, 3] = self._convection_site(wedell) - - self.mlotst_handler.close() - handler.close() - - self.data_manager.send_file(output, 'ocean', 'site', self.startdate, self.member, self.chunk) - Log.info('Finished convection sites for startdate {0}, member {1}, chunk {2}', - self.startdate, self.member, self.chunk) - - def _convection_site(self, site): - return np.max(self.mlotst_handler.variables['mlotst'][:, site[2]-1:site[3]-1, site[0]-1:site[1]-1], (1, 2)) - diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py new file mode 100644 index 0000000..a0b02e7 --- /dev/null +++ b/earthdiagnostics/ocean/convectionsites.py @@ -0,0 +1,87 @@ +import numpy as np +from autosubmit.config.log import Log + +from earthdiagnostics import Diagnostic, TempFile, Utils +from models import Models + + +class ConvectionSites(Diagnostic): + + def __init__(self, data_manager, startdate, member, chunk, nemo_version): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.nemo_version = nemo_version + self.required_vars = ['vsftbarot'] + self.generated_vars = ['gyres'] + + @classmethod + def generate_jobs(cls, diags, options): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.nemo_version)) + return job_list + + def compute(self): + """ + Compute the intensity of convection in the four main convection sites + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_file: input oce file name containing mlotst + :param input_grid: input grid + :param output_file: output file name (=> index) + :return: + """ + if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, + Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, + Models.NEMOVAR_O1L42]: + labrador = [225, 245, 215, 255] + irminger = [245, 290, 215, 245] + gin = [260, 310, 245, 291] + wedell = [225, 280, 1, 50] + + elif self.nemo_version in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, + Models.GLORYS2_V1_O25L75]: + raise Exception("Option convection not available yet for {0}".format(self.nemo_version)) + else: + raise Exception("Input grid {0} not recognized".format(self.nemo_version)) + + mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) + output = TempFile.get() + + self.mlotst_handler = Utils.openCdf(mlotst_file) + handler = Utils.openCdf(output, 'w') + handler.createDimension('time') + handler.createDimension('region', 4) + Utils.copy_variable(self.mlotst_handler, handler, 'time') + var_region = handler.createVariable('region', str, 'region') + var_gyre = handler.createVariable('site', 'f', ('time', 'region')) + var_gyre.short_name = 'site' + var_gyre.long_name = 'convection sites' + var_gyre.units = 'm^3/s' + + var_region[0] = 'labrador' + var_gyre[:, 0] = self._convection_site(labrador) + + var_region[1] = 'irminger' + var_gyre[:, 1] = self._convection_site(irminger) + + var_region[2] = 'gin' + var_gyre[:, 2] = self._convection_site(gin) + + var_region[3] = 'wedell' + var_gyre[:, 3] = self._convection_site(wedell) + + self.mlotst_handler.close() + handler.close() + + self.data_manager.send_file(output, 'ocean', 'site', self.startdate, self.member, self.chunk) + Log.info('Finished convection sites for startdate {0}, member {1}, chunk {2}', + self.startdate, self.member, self.chunk) + + def _convection_site(self, site): + return np.max(self.mlotst_handler.variables['mlotst'][:, site[2]-1:site[3]-1, site[0]-1:site[1]-1], (1, 2)) diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py new file mode 100644 index 0000000..84c6fe9 --- /dev/null +++ b/earthdiagnostics/ocean/cutsection.py @@ -0,0 +1,150 @@ +import numpy as np +from autosubmit.config.log import Log + +from box import Box +from earthdiagnostics import Diagnostic, Utils + + +class CutSection(Diagnostic): + + def __init__(self, data_manager, startdate, member, chunk, variable, domain, zonal, value): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.zonal = zonal + self.value = value + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 3: + raise Exception('You must specify the variable, coordinate and coordinate value') + if num_options > 4: + raise Exception('You must specify between 3 and 4 parameters for the interpolation diagnostic') + variable = options[1] + zonal = options[2].lower() == 'true' + value = int(options[3]) + if num_options >= 4: + domain = options[4] + else: + domain = 'ocean' + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(CutSection(diags.data_manager, startdate, member, chunk, + variable, domain, zonal, value)) + return job_list + + def compute(self): + """ + Cut a meridional or zonal section + + Created in September 2012 Author : vguemas@ic3.cat + :param input_file: input file + :param output_file: output file ( => 2D ) + :param variable: input var + :param zonal: (zonal / meridional section) + :param value: lat/lon + :return: + """ + + nco = Utils.nco + + handler = Utils.openCdf('mesh_hgr.nc') + dimi = handler.dimensions['i'].size + dimj = handler.dimensions['j'].size + dimlev = handler.dimensions['lev'].size + + lon = handler.variables['lon'][:] + lat = handler.variables['lat'][:] + handler.close() + + handler = Utils.openCdf('mask.nc') + mask_lev = handler.variables['tmask'][:] + mask_lev = mask_lev.astype(float) + # noinspection PyTypeChecker + np.place(mask_lev, mask_lev == 0, [1e20]) + handler.close() + + # Latitude / longitude of the zonal / meridional section + exactpos = self.value + if not self.zonal: + while exactpos < np.min(lon): + exactpos += 360 + while exactpos > np.max(lon): + exactpos -= 360 + size = dimj + else: + size = dimi + + # Collect the indexes defining the section + + listi = np.empty(size, dtype=int) + listj = np.empty(size, dtype=int) + + for jpt in range(0, size): + if not self.zonal: + vector = lon[jpt, :] + else: + vector = lat[:, jpt] + distance = abs(vector - exactpos) + pos = np.where(distance == min(distance)) + if not self.zonal: + listi[jpt] = pos[0][0] + listj[jpt] = jpt + else: + listi[jpt] = jpt + listj[jpt] = pos[0][0] + + temp = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + + handler = Utils.openCdf(temp) + dimtime = handler.dimensions['time'].size + var_array = handler.variables[self.variable][:] + handler.close() + + var = np.empty([dimtime, dimlev, size], dtype=handler.variables[self.variable].dtype) + new_coord = np.empty(size, dtype=float) + if self.zonal: + old_coord = lon + else: + old_coord = lat + + for jpt in range(0, size): + var[:, :, jpt] = np.maximum(var_array[:, :, listj[jpt], listi[jpt]], + mask_lev[:, :, listj[jpt], listi[jpt]]) + new_coord[jpt] = old_coord[listj[jpt], listi[jpt]] + + nco.ncks(input=temp, output=temp, options='-O -v lev,time') + + handler = Utils.openCdf(temp) + if not self.zonal: + handler.createDimension('lat', size) + coord_var = handler.createVariable('lat', float, 'lat') + file_var = handler.createVariable(self.variable, float, ('time', 'lev', 'lat')) + else: + handler.createDimension('lon', size) + coord_var = handler.createVariable('lon', float, 'lon') + file_var = handler.createVariable(self.variable, float, ('time', 'lev', 'lon')) + coord_var[:] = new_coord[:] + file_var[:] = var[:] + file_var.missing_value = 1e20 + handler.close() + + box = Box() + if self.zonal: + box.max_lon = self.value + box.min_lon = self.value + else: + box.max_lat = self.value + box.min_lat = self.value + + self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, + box=box) + Log.info('Finished cut section for startdate {0}, member {1}, chunk {2}', + self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py index 6105a3a..3f2ff2d 100644 --- a/earthdiagnostics/ocean/general.py +++ b/earthdiagnostics/ocean/general.py @@ -1,472 +1,4 @@ -from autosubmit.config.log import Log -from box import Box -from earthdiagnostics import Utils, TempFile, cdftools -from earthdiagnostics.diagnostic import Diagnostic -import shutil -import os -import numpy as np - - -class VerticalMean(Diagnostic): - """ - Choose vertical level in ocean, or vertically average between - 2 or more ocean levels - - Created in February 2012 Author : vguemas@ic3.cat - Modified (more generic, i.e. for any input var) in December 2014 - Author : eleftheria.exarchou@ic3.cat - - # :param input_file: input file name - # :param output_file: output file name (=> 2D field ) - # :param variable: variable name - # :param lev_min: upper depth of the layer (in level number) - # :param lev_max: lower depth of the layer (in level number. If same as the upper layer, then the script just - selects this layer. If its different, a vertical integral (weighted) between upper and lower level is computed - """ - - def __init__(self, data_manager, startdate, member, chunk, variable, box): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.variable = variable - self.box = box - self.required_vars = [variable] - self.generated_vars = [variable + 'vmean'] - - @classmethod - def generate_jobs(cls, diags, options): - num_options = len(options) - 1 - if num_options < 1: - raise Exception('You must specify the variable to average vertically') - if num_options > 3: - raise Exception('You must specify between one and three parameters for the vertical mean') - variable = options[1] - - box = Box(True) - if num_options >= 2: - box.min_depth = float(options[2]) - if num_options >= 2: - box.max_depth = float(options[3]) - - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(VerticalMean(diags.data_manager, startdate, member, chunk, - variable, box)) - return job_list - - def compute(self): - temp = TempFile.get() - variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) - - handler = Utils.openCdf(variable_file) - if self.box.min_depth is None: - lev_min = handler.variables['lev'][0] - else: - lev_min = self.box.min_depth - - if self.box.max_depth is None: - lev_max = handler.variables['lev'][-1] - else: - lev_max = self.box.max_depth - handler.close() - - cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, - '-debug']) - Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) - self.data_manager.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, - box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) - - -class VerticalMeanMeters(Diagnostic): - """ - Vertically averaged salt content - Created in February 2012 Author : vguemas@ic3.cat - - # :param input_file: input grid_T file name - # :param upper: upper depth of the layer (in meters) - # :type upper: int - # :param lower: lower depth of the layer (in meters) - # :type lower: int - # :param output_file: output file name (=> 2D) - """ - - def __init__(self, data_manager, startdate, member, chunk, variable, box): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.variable = variable - self.box = box - self.required_vars = [variable] - self.generated_vars = [variable + 'vmean'] - - @classmethod - def generate_jobs(cls, diags, options): - num_options = len(options) - 1 - if num_options < 1: - raise Exception('You must specify the variable to average vertically') - if num_options > 3: - raise Exception('You must specify between one and three parameters for the vertical mean') - variable = options[1] - box = Box(True) - if num_options >= 2: - box.min_depth = float(options[2]) - if num_options >= 2: - box.max_depth = float(options[3]) - - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(VerticalMeanMeters(diags.data_manager, startdate, member, chunk, - variable, box)) - return job_list - - def compute(self): - temp = TempFile.get() - variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) - - handler = Utils.openCdf(variable_file) - if self.box.min_depth is None: - lev_min = handler.variables['lev'][0] - else: - lev_min = self.box.min_depth - - if self.box.max_depth is None: - lev_max = handler.variables['lev'][-1] - else: - lev_max = self.box.max_depth - handler.close() - - cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, - '-debug']) - Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) - self.data_manager.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, - box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) - - -class Interpolate(Diagnostic): - """ - 3-dimensional conservative interpolation to the regular atmospheric grid - - Created in November 2012 Author : vguemas@ic3.cat - - # :param nemo_version: - # :param input_file: - # :param output_file: - # :param variable: - :return: - """ - - def __init__(self, data_manager, startdate, member, chunk, variable, domain, nemo_version): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.variable = variable - self.domain = domain - self.nemo_version = nemo_version - self.required_vars = [variable] - self.generated_vars = [variable] - self.tempTemplate = '' - - @classmethod - def generate_jobs(cls, diags, options): - num_options = len(options) - 1 - if num_options < 1: - raise Exception('You must specify the variable to average vertically') - if num_options > 2: - raise Exception('You must specify between 1 and 2 parameters for the interpolation diagnostic') - variable = options[1] - if num_options >= 2: - domain = int(options[2]) - else: - domain = 'ocean' - - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Interpolate(diags.data_manager, startdate, member, chunk, - variable, domain, diags.nemo_version)) - return job_list - - def compute(self): - variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) - cdo = Utils.cdo - nco = Utils.nco - handler = Utils.openCdf(variable_file) - if 'lev' in handler.dimensions: - num_levels = handler.dimensions['lev'].size - has_levels = True - else: - num_levels = 1 - has_levels = False - handler.close() - for lev in range(0, num_levels): - self._interpolate_level(lev, has_levels, variable_file) - - temp = TempFile.get() - if has_levels: - nco.ncrcat(input=self._get_level_file(0), output=temp, - options="-n {0},2,1 -v '{1}'".format(num_levels, self.variable)) - - else: - Utils.move_file(self._get_level_file(0), temp) - - handler = Utils.openCdf(temp) - handler.renameDimension('record', 'lev') - handler.close() - nco.ncpdq(input=temp, output=temp, options='-O -h -a time,lev') - - if has_levels: - nco.ncks(input=variable_file, output=temp, options='-A -v lev') - for lev in range(0, num_levels): - os.remove(self._get_level_file(lev)) - temp2 = TempFile.get() - cdo.setgrid('t106grid', input=temp, output=temp2) - os.remove(temp) - if self.nemo_version[6:9] == '025': - cdo.invertlatdata(input=temp2, output=temp2) - if not has_levels: - nco.ncks(input=temp2, output=temp2, options='-O -v sic,lat,lon,time') - - self.data_manager.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, - grid='regular') - - def _get_level_file(self, lev): - if not self.tempTemplate: - self.tempTemplate = TempFile.get(suffix='_01.nc') - # self.tempTemplate = 'temp_01.nc' - return self.tempTemplate.replace('_01.nc', '_{0:02d}.nc'.format(lev +1)) - - def _interpolate_level(self, lev, has_levels, input_file): - nco = Utils.nco - temp = TempFile.get() - if has_levels: - nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1}'.format(lev, self.variable)) - nco.ncwa(input=temp, output=temp, options='-O -h -a lev') - else: - shutil.copy(input_file, temp) - namelist_file = TempFile.get(suffix='') - scrip_use_in = open(namelist_file, 'w') - scrip_use_in.writelines("&remap_inputs\n") - scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" - "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(self.nemo_version, lev + 1)) - scrip_use_in.writelines(" infile = '{0}'\n".format(temp)) - scrip_use_in.writelines(" invertlat = FALSE\n") - scrip_use_in.writelines(" var = '{0}'\n".format(self.variable)) - scrip_use_in.writelines(" fromregular = FALSE\n") - scrip_use_in.writelines(" outfile = '{0}'\n".format(temp)) - scrip_use_in.writelines("/\n") - scrip_use_in.close() - Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use ' - '{0}'.format(namelist_file), Log.NO_LOG) - os.remove(namelist_file) - nco.ncecat(input=temp, output=temp, options="-O -h") - shutil.move(temp, self._get_level_file(lev)) - Log.debug("Level {0} ready", lev) - - -class CutSection(Diagnostic): - - def __init__(self, data_manager, startdate, member, chunk, variable, domain, zonal, value): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.variable = variable - self.domain = domain - self.zonal = True - self.value = value - - @classmethod - def generate_jobs(cls, diags, options): - num_options = len(options) - 1 - if num_options < 3: - raise Exception('You must specify the variable, coordinate and coordinate value') - if num_options > 4: - raise Exception('You must specify between 3 and 4 parameters for the interpolation diagnostic') - variable = options[1] - zonal = options[2].lower() == 'true' - value = int(options[3]) - if num_options >= 4: - domain = options[4] - else: - domain = 'ocean' - - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(CutSection(diags.data_manager, startdate, member, chunk, - variable, domain, zonal, value)) - return job_list - - def compute(self): - """ - Cut a meridional or zonal section - - Created in September 2012 Author : vguemas@ic3.cat - :param input_file: input file - :param output_file: output file ( => 2D ) - :param variable: input var - :param zonal: (zonal / meridional section) - :param value: lat/lon - :return: - """ - - nco = Utils.nco - - handler = Utils.openCdf('mesh_hgr.nc') - dimi = handler.dimensions['i'].size - dimj = handler.dimensions['j'].size - dimlev = handler.dimensions['lev'].size - - lon = handler.variables['lon'][:] - lat = handler.variables['lat'][:] - handler.close() - - handler = Utils.openCdf('mask.nc') - mask_lev = handler.variables['tmask'][:] - mask_lev = mask_lev.astype(float) - # noinspection PyTypeChecker - np.place(mask_lev, mask_lev == 0, [1e20]) - handler.close() - - # Latitude / longitude of the zonal / meridional section - exactpos = self.value - if not self.zonal: - while exactpos < np.min(lon): - exactpos += 360 - while exactpos > np.max(lon): - exactpos -= 360 - size = dimj - else: - size = dimi - - # Collect the indexes defining the section - - listi = np.empty(size, dtype=int) - listj = np.empty(size, dtype=int) - - for jpt in range(0, size): - if not self.zonal: - vector = lon[jpt, :] - else: - vector = lat[:, jpt] - distance = abs(vector - exactpos) - pos = np.where(distance == min(distance)) - if not self.zonal: - listi[jpt] = pos[0][0] - listj[jpt] = jpt - else: - listi[jpt] = jpt - listj[jpt] = pos[0][0] - - temp = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) - - handler = Utils.openCdf(temp) - dimtime = handler.dimensions['time'].size - var_array = handler.variables[self.variable][:] - handler.close() - - var = np.empty([dimtime, dimlev, size], dtype=handler.variables[self.variable].dtype) - new_coord = np.empty(size, dtype=float) - if self.zonal: - old_coord = lon - else: - old_coord = lat - - for jpt in range(0, size): - var[:, :, jpt] = np.maximum(var_array[:, :, listj[jpt], listi[jpt]], - mask_lev[:, :, listj[jpt], listi[jpt]]) - new_coord[jpt] = old_coord[listj[jpt], listi[jpt]] - - nco.ncks(input=temp, output=temp, options='-O -v lev,time') - - handler = Utils.openCdf(temp) - if not self.zonal: - handler.createDimension('lat', size) - coord_var = handler.createVariable('lat', float, 'lat') - file_var = handler.createVariable(self.variable, float, ('time', 'lev', 'lat')) - else: - handler.createDimension('lon', size) - coord_var = handler.createVariable('lon', float, 'lon') - file_var = handler.createVariable(self.variable, float, ('time', 'lev', 'lon')) - coord_var[:] = new_coord[:] - file_var[:] = var[:] - file_var.missing_value = 1e20 - handler.close() - - box = Box() - if self.zonal: - box.max_lon = self.value - box.min_lon = self.value - else: - box.max_lat = self.value - box.min_lat = self.value - - self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, - box=box) - Log.info('Finished cut section for startdate {0}, member {1}, chunk {2}', - self.startdate, self.member, self.chunk) - - -class AverageSection(Diagnostic): - - def __init__(self, data_manager, startdate, member, chunk, variable, domain, box): - Diagnostic.__init__(self, data_manager) - self.startdate = startdate - self.member = member - self.chunk = chunk - self.variable = variable - self.domain = domain - self.box = box - - @classmethod - def generate_jobs(cls, diags, options): - num_options = len(options) - 1 - if num_options < 5: - raise Exception('You must specify the variable and the box to average') - if num_options > 6: - raise Exception('You must specify between 5 and 6 parameters for the section average diagnostic') - variable = options[1] - box = Box() - box.min_lon = int(options[2]) - box.max_lon = int(options[3]) - box.min_lat = int(options[4]) - box.max_lat = int(options[5]) - if num_options >= 6: - domain = options[6] - else: - domain = 'ocean' - - job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, - variable, domain, box)) - return job_list - - def compute(self): - temp = TempFile.get() - variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk, - grid='regular') - Utils.cdo.zonmean(input='-sellonlatbox,{0},{1},{2},{3} {4}'.format(self.box.min_lon, self.box.max_lon, - self.box.min_lat, self.box.max_lat, - variable_file), - output=temp) - os.remove(variable_file) - self.data_manager.send_file(temp, self.domain, self.variable + 'mean', self.startdate, self.member, self.chunk, - box=self.box, grid='regular') - Log.info('Finished section average for startdate {0}, member {1}, chunk {2}', - self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py new file mode 100644 index 0000000..c0f6009 --- /dev/null +++ b/earthdiagnostics/ocean/gyres.py @@ -0,0 +1,146 @@ +import numpy as np +from autosubmit.config.log import Log + +from earthdiagnostics import Diagnostic, TempFile, Utils +from models import Models + + +class Gyres(Diagnostic): + def __init__(self, data_manager, startdate, member, chunk, nemo_version): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.nemo_version = nemo_version + self.required_vars = ['vsftbarot'] + self.generated_vars = ['gyres'] + + @classmethod + def generate_jobs(cls, diags, options): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.nemo_version)) + return job_list + + # noinspection PyPep8Naming + def compute(self): + """ + Compute the intensity of the subtropical and subpolar gyres + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_psi: input psi file name + :param input_grid: input grid + :param output_file: output file name ( => index ) + :return: + """ + + if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, + Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, + Models.NEMOVAR_O1L42]: + + subpolNAtl = [230, 275, 215, 245] + subpolNPac = [70, 145, 195, 235] + subtropNPac = [45, 175, 165, 220] + subtropNAtl = [195, 275, 175, 225] + subtropSPac = [70, 205, 120, 145] + subtropSAtl = [235, 300, 120, 145] + subtropInd = [320, 30, 110, 180] + ACC = [1, 361, 1, 65] + + elif self in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, + Models.GLORYS2_V1_O25L75]: + raise Exception("Option gyres not available yet for {0}".format(self.nemo_version)) + else: + raise Exception("Input grid {0} not recognized".format(self.nemo_version)) + + output = TempFile.get() + vsftbarot_file = self.data_manager.get_file('ocean', 'vsftbarot', self.startdate, self.member, self.chunk) + + handler_original = Utils.openCdf(vsftbarot_file) + self.var_vsftbarot = handler_original.variables['vsftbarot'] + handler = Utils.openCdf(output, 'w') + handler.createDimension('time') + handler.createDimension('region', 8) + Utils.copy_variable(handler_original, handler, 'time') + var_region = handler.createVariable('region', str, 'region') + + var_gyre = handler.createVariable('gyre', 'f', ('time', 'region')) + var_gyre.short_name = 'gyre' + var_gyre.long_name = 'gyre' + var_gyre.units = 'm^3/s' + + var_region[0] = 'subpolNAtl' + var_gyre[:, 0] = self._gyre(subpolNAtl, True) + Log.debug('subpolNAtl: {0}', var_gyre[:, 0]) + + var_region[1] = 'subpolNPac' + var_gyre[:, 1] = self._gyre(subpolNPac, True) + Log.debug('subpolNPac: {0}', var_gyre[:, 1]) + + var_region[2] = 'subtropNPac' + var_gyre[:, 2] = self._gyre(subtropNPac) + Log.debug('subtropNPac: {0}', var_gyre[:, 2]) + + var_region[3] = 'subtropSPac' + var_gyre[:, 3] = self._gyre(subtropSPac) + Log.debug('subtropSPac: {0}', var_gyre[:, 3]) + + var_region[4] = 'subtropNAtl' + var_gyre[:, 4] = self._gyre(subtropNAtl) + Log.debug('subtropNAtl: {0}', var_gyre[:, 4]) + + var_region[5] = 'subtropSAtl' + var_gyre[:, 5] = self._gyre(subtropSAtl) + Log.debug('subtropSAtl: {0}', var_gyre[:, 5]) + + var_region[6] = 'subtropInd' + var_gyre[:, 6] = self._gyre(subtropInd) + Log.debug('subtropInd: {0}', var_gyre[:, 6]) + + var_region[7] = 'ACC' + var_gyre[:, 7] = self._gyre(ACC) + Log.debug('ACC: {0}', var_gyre[:, 7]) + + handler.close() + handler_original.close() + self.data_manager.send_file(output, 'ocean', 'gyre', self.startdate, self.member, self.chunk) + Log.info('Finished gyres for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) + + def _gyre(self, site, invert=False): + """ + Compute the intensity of a given gyre + + Created in October 2013 Author : vguemas@ic3.cat + + :param input_file: input oce file name containing vsftbarot + :param site: site to calculate convection on + :param output_file: output file name (=> index) + :param invert: if True, multiplies result by -1 + :return: + """ + + if invert: + return np.min(self._extract_section(site), (1, 2)) * -1 + else: + return np.max(self._extract_section(site), (1, 2)) + + def _extract_section(self, site): + if site[2] <= site[3]: + if site[0] <= site[1]: + return self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0] - 1:site[1] - 1] + else: + return np.concatenate((self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0]-1:], + self.var_vsftbarot[:, site[2] - 1:site[3] - 1, :site[1] - 1]), axis=2) + + else: + if site[0] <= site[1]: + return np.concatenate((self.var_vsftbarot[:, site[2] - 1:, site[0] - 1: site[1] - 1], + self.var_vsftbarot[:, :site[3] - 1, site[0] - 1: site[1] - 1]), axis=1) + else: + temp = np.concatenate((self.var_vsftbarot[:, site[2] - 1:, :], + self.var_vsftbarot[:, :site[3] - 1, :]), axis=1) + return np.concatenate((temp[:, :, site[0] - 1:], + temp[:, :, :site[1] - 1]), axis=2) diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py new file mode 100644 index 0000000..b778bdf --- /dev/null +++ b/earthdiagnostics/ocean/interpolate.py @@ -0,0 +1,129 @@ +import shutil + +import os +from autosubmit.config.log import Log + +from earthdiagnostics import Diagnostic, Utils, TempFile + + +class Interpolate(Diagnostic): + """ + 3-dimensional conservative interpolation to the regular atmospheric grid + + Created in November 2012 Author : vguemas@ic3.cat + + # :param nemo_version: + # :param input_file: + # :param output_file: + # :param variable: + :return: + """ + + def __init__(self, data_manager, startdate, member, chunk, variable, domain, nemo_version): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.nemo_version = nemo_version + self.required_vars = [variable] + self.generated_vars = [variable] + self.tempTemplate = '' + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 1: + raise Exception('You must specify the variable to average vertically') + if num_options > 2: + raise Exception('You must specify between 1 and 2 parameters for the interpolation diagnostic') + variable = options[1] + if num_options >= 2: + domain = int(options[2]) + else: + domain = 'ocean' + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Interpolate(diags.data_manager, startdate, member, chunk, + variable, domain, diags.nemo_version)) + return job_list + + def compute(self): + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + cdo = Utils.cdo + nco = Utils.nco + handler = Utils.openCdf(variable_file) + if 'lev' in handler.dimensions: + num_levels = handler.dimensions['lev'].size + has_levels = True + else: + num_levels = 1 + has_levels = False + handler.close() + for lev in range(0, num_levels): + self._interpolate_level(lev, has_levels, variable_file) + + temp = TempFile.get() + if has_levels: + nco.ncrcat(input=self._get_level_file(0), output=temp, + options="-n {0},2,1 -v '{1}'".format(num_levels, self.variable)) + + else: + Utils.move_file(self._get_level_file(0), temp) + + handler = Utils.openCdf(temp) + handler.renameDimension('record', 'lev') + handler.close() + nco.ncpdq(input=temp, output=temp, options='-O -h -a time,lev') + + if has_levels: + nco.ncks(input=variable_file, output=temp, options='-A -v lev') + for lev in range(0, num_levels): + os.remove(self._get_level_file(lev)) + temp2 = TempFile.get() + cdo.setgrid('t106grid', input=temp, output=temp2) + os.remove(temp) + if self.nemo_version[6:9] == '025': + cdo.invertlatdata(input=temp2, output=temp2) + if not has_levels: + nco.ncks(input=temp2, output=temp2, options='-O -v sic,lat,lon,time') + + self.data_manager.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, + grid='regular') + + def _get_level_file(self, lev): + if not self.tempTemplate: + self.tempTemplate = TempFile.get(suffix='_01.nc') + # self.tempTemplate = 'temp_01.nc' + return self.tempTemplate.replace('_01.nc', '_{0:02d}.nc'.format(lev + 1)) + + def _interpolate_level(self, lev, has_levels, input_file): + nco = Utils.nco + temp = TempFile.get() + if has_levels: + nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1}'.format(lev, self.variable)) + nco.ncwa(input=temp, output=temp, options='-O -h -a lev') + else: + shutil.copy(input_file, temp) + namelist_file = TempFile.get(suffix='') + scrip_use_in = open(namelist_file, 'w') + scrip_use_in.writelines("&remap_inputs\n") + scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" + "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(self.nemo_version, lev + 1)) + scrip_use_in.writelines(" infile = '{0}'\n".format(temp)) + scrip_use_in.writelines(" invertlat = FALSE\n") + scrip_use_in.writelines(" var = '{0}'\n".format(self.variable)) + scrip_use_in.writelines(" fromregular = FALSE\n") + scrip_use_in.writelines(" outfile = '{0}'\n".format(temp)) + scrip_use_in.writelines("/\n") + scrip_use_in.close() + Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use ' + '{0}'.format(namelist_file), Log.NO_LOG) + os.remove(namelist_file) + nco.ncecat(input=temp, output=temp, options="-O -h") + shutil.move(temp, self._get_level_file(lev)) + Log.debug("Level {0} ready", lev) diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py new file mode 100644 index 0000000..b2d0626 --- /dev/null +++ b/earthdiagnostics/ocean/maxmoc.py @@ -0,0 +1,189 @@ +import netCDF4 +import numpy as np +import os +from autosubmit.config.log import Log + +from basins import Basins +from box import Box +from earthdiagnostics import Diagnostic, Utils + + +class MaxMoc(Diagnostic): + + def __init__(self, data_manager, startdate, member, year, basin, box): + Diagnostic.__init__(self, data_manager) + self.basin = basin + self.startdate = startdate + self.member = member + self.year = year + self.required_vars = ['vo'] + self.generated_vars = ['vsftmyz'] + self.box = box + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 4: + raise Exception('You must specify the box to use') + if num_options > 5: + raise Exception('You must specify between 4 and 5 parameters for area moc diagnostic') + box = Box() + box.min_lat = int(options[1]) + box.max_lat = int(options[2]) + box.min_depth = int(options[3]) + box.max_depth = int(options[4]) + if num_options > 4: + basin = Basins.parse(options[5]) + else: + basin = Basins.Global + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + years = diags.data_manager.get_full_years(startdate) + if len(years) == 0: + Log.user_warning('No complete years are available with the given configuration. ' + 'MaxMoc can not be computed') + for year in years: + job_list.append(MaxMoc(diags.data_manager, startdate, member, year, basin, box)) + return job_list + + def compute(self): + """ + Compute an Atlantic MOC index by finding the maximum of the annual + mean meridional overturning in a latitude / depth region + + Created in March 2012 Author : vguemas@ic3.cat + + :param basin: basin + :param input_file: input moc file name + :param lat_min: latitude min + :param lat_max: latitude max + :param output_file: output file name + :param depth_min: depth mean + :param depth_max: depth max + :return: + """ + nco = Utils.nco + + temp = self.data_manager.get_year('ocean', 'vsftmyz', self.startdate, self.member, self.year) + + handler = Utils.openCdf(temp) + if 'i' in handler.dimensions: + handler.close() + nco.ncwa(input=temp, output=temp, options='-O -a i') + else: + handler.close() + handler = Utils.openCdf(temp) + basin_index = np.where(handler.variables['basin'][:] == self.basin.fullname) + if len(basin_index) == 0: + raise Exception("Basin {1} is not defined in {0}", temp, self.basin.fullname) + basin_index = basin_index[0][0] + + lev = handler.variables['lev'][:] + lat = handler.variables['lat'][:] + + if self.box.min_lat == self.box.max_lat: + lat_inds = ((np.abs(lat-self.box.min_lat)).argmin(),) + else: + lat_inds = np.where((lat > self.box.min_lat) & (lat < self.box.max_lat))[0] + + if self.box.min_depth == self.box.max_depth: + lev_inds = ((np.abs(lev - self.box.min_depth)).argmin(),) + else: + lev_inds = np.where((lev > self.box.min_depth) & (lev < self.box.max_depth))[0] + + Log.info('Computing year {0}', str(self.year)) + moc = handler.variables['vsftmyz'][:, lev_inds, lat_inds, basin_index] + handler.close() + os.remove(temp) + + moc = np.mean(moc, 0) + + maximum = np.amax(moc) + max_index = np.unravel_index(np.argmax(moc), moc.shape) + max_lev = lev[lev_inds[max_index[0]]] + max_lat = lat[lat_inds[max_index[1]]] + + minimum = np.amin(moc) + minimum_index = np.unravel_index(np.argmin(moc), moc.shape) + min_lev = lev[lev_inds[minimum_index[0]]] + min_lat = lat[lat_inds[minimum_index[1]]] + + Log.info('Maximum {0} Sv, latitude {1} depth {2} m', maximum, max_lat, max_lev) + Log.info('Minimum {0} Sv, latitude {1} depth {2} m', minimum, min_lat, min_lev) + + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzmax', float, ('time',)) + var.long_name = 'Maximum_Overturing' + var.units = 'Sverdrup' + var.valid_min = -1000. + var.valid_max = 1000. + var[0] = maximum + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) + + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzmaxlat', float, ('time',)) + var.long_name = 'Latitude_of_Maximum_Overturing' + var.units = 'Degrees' + var.valid_min = -90. + var.valid_max = 90. + var[0] = max_lat + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) + + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzmaxlev', float, ('time',)) + var.long_name = 'Depth_of_Maximum_Overturing' + var.units = 'Meters' + var.valid_min = 0. + var.valid_max = 10000. + var[0] = max_lev + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) + + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzmin', float, ('time',)) + var.long_name = 'Minimum_Overtuning' + var.units = 'Sverdrup' + var.valid_min = -1000. + var.valid_max = 1000. + var[0] = minimum + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) + + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzminlat', float, ('time',)) + var.long_name = 'Latitude_of_Minimum_Overtuning' + var.units = 'Degrees' + var.valid_min = -90. + var.valid_max = 90. + var[0] = min_lat + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) + + handler = self._create_output_file(temp) + var = handler.createVariable('vsftmyzminlev', float, ('time',)) + var.long_name = 'Depth_of_Minimum_Overtuning' + var.units = 'Meters' + var.valid_min = 0. + var.valid_max = 10000. + var[0] = min_lev + handler.close() + self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) + + def _create_output_file(self, temp): + handler = netCDF4.Dataset(temp, 'w') + handler.createDimension('time') + + time = handler.createVariable('time', 'i2', ('time',)) + time.calendar = 'gregorian' + time.units = 'days since January 1, {0}'.format(self.year) + return handler diff --git a/earthdiagnostics/ocean/salinity.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py similarity index 96% rename from earthdiagnostics/ocean/salinity.py rename to earthdiagnostics/ocean/mixedlayersaltcontent.py index 7af984e..7d77aa4 100644 --- a/earthdiagnostics/ocean/salinity.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -1,9 +1,9 @@ import threading -from diagnostic import Diagnostic -from earthdiagnostics import Utils, cdftools, TempFile -from autosubmit.config.log import Log import os +from autosubmit.config.log import Log + +from earthdiagnostics import Diagnostic, Utils, TempFile, cdftools class MixedLayerSaltContent(Diagnostic): @@ -66,5 +66,3 @@ class MixedLayerSaltContent(Diagnostic): Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'scvertsum'}, False, True) Utils.setminmax(temp, 'scvsum') self.data_manager.send_file(temp, 'ocean', 'scvsum', self.startdate, self.member, self.chunk) - - diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py new file mode 100644 index 0000000..7823161 --- /dev/null +++ b/earthdiagnostics/ocean/moc.py @@ -0,0 +1,78 @@ +import numpy as np +from autosubmit.config.log import Log + +from basins import Basins +from earthdiagnostics import Diagnostic, TempFile, cdftools, Utils + + +class Moc(Diagnostic): + """ + Compute the MOC for oceanic basins + Created in March 2012 + Author : vguemas@ic3.cat + + # :param input_file: input grid_V file namez + # :type input_file: str + # :param output_file: output file name (=> 2D, depth-y) + # :param output_file: str + # :return: + """ + + def __init__(self, data_manager, startdate, member, chunk): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['vo'] + self.generated_vars = ['vsftmyz'] + + @classmethod + def generate_jobs(cls, diags, options): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Moc(diags.data_manager, startdate, member, chunk)) + return job_list + + def compute(self): + temp = TempFile.get() + + input_file = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) + + Log.debug('Computing MOC') + cdftools.run('cdfmoc', input=input_file, output=temp) + Utils.nco.ncks(input=input_file, output=temp, options='-A -v lev') + Utils.convert2netcdf4(temp) + + Log.debug('Reformatting variables') + handler = Utils.openCdf(temp) + + handler.createDimension('basin', 5) + handler.createVariable('basin', str, 'basin') + handler.variables['basin'][:] = np.array([Basins.Global.fullname, Basins.Atlantic.fullname, + Basins.Pacific.fullname, Basins.IndoPacific.fullname, + Basins.Indian.fullname], dtype=object) + example = handler.variables['zomsfglo'] + # noinspection PyProtectedMember + moc = handler.createVariable('vsftmyz', example.datatype, + ('time', 'lev', 'i', 'j', 'basin'), + fill_value=example._FillValue) + + moc.units = example.units + moc.add_offset = example.add_offset + moc.scale_factor = example.scale_factor + + moc[:, :, :, :, 0] = handler.variables['zomsfglo'][:] + moc[:, :, :, :, 1] = handler.variables['zomsfatl'][:] + moc[:, :, :, :, 2] = handler.variables['zomsfpac'][:] + moc[:, :, :, :, 3] = handler.variables['zomsfinp'][:] + moc[:, :, :, :, 4] = handler.variables['zomsfind'][:] + + handler.close() + + Utils.nco.ncks(input=temp, output=temp, + options='-O -x -v zomsfglo,zomsfatl,zomsfpac,zomsfinp,zomsfind,zomsfinp0') + Utils.setminmax(temp, 'vsftmyz') + + self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py new file mode 100644 index 0000000..506560f --- /dev/null +++ b/earthdiagnostics/ocean/psi.py @@ -0,0 +1,41 @@ +from earthdiagnostics import Diagnostic, TempFile, cdftools, Utils + + +class Psi(Diagnostic): + def __init__(self, data_manager, startdate, member, chunk): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['vo', 'uo'] + self.generated_vars = ['vsftbarot'] + + @classmethod + def generate_jobs(cls, diags, options): + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(Psi(diags.data_manager, startdate, member, chunk)) + return job_list + + def compute(self): + """ + Compute the barotropic stream function + + Created in March 2012 Author : vguemas@ic3.cat + z + :param input_file_u: input grid_U file name + :rtype input_file_U: str + :param input_file_v: input grid_V file name + :rtype input_file_V: str + :param output_file: output file name without nc extension (=> 2D x-y) + :rtype output_file: str + """ + temp = TempFile.get() + input_file_u = self.data_manager.get_file('ocean', 'uo', self.startdate, self.member, self.chunk) + input_file_v = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) + cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-mean -mask') + Utils.rename_variable(temp, 'sobarstf', 'vsftbarot') + Utils.setminmax(temp, 'vsftbarot') + self.data_manager.send_file(temp, 'ocean', 'vsftbarot', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/ice.py b/earthdiagnostics/ocean/siasiesiv.py similarity index 97% rename from earthdiagnostics/ocean/ice.py rename to earthdiagnostics/ocean/siasiesiv.py index 083de1c..a5f0c7b 100644 --- a/earthdiagnostics/ocean/ice.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -1,12 +1,12 @@ +import shutil +import threading + import netCDF4 import os - -from earthdiagnostics import Utils, cdftools, cdo, TempFile -from earthdiagnostics.basins import Basins -from earthdiagnostics.diagnostic import Diagnostic from autosubmit.config.log import Log -import shutil -import threading + +from basins import Basins +from earthdiagnostics import Diagnostic, Utils, cdo, TempFile, cdftools class Siasiesiv(Diagnostic): @@ -190,7 +190,8 @@ class Siasiesiv(Diagnostic): factor = (factor * scale_unit) / float(scale_new_unit) return factor - def _get_factor(self, new_unit, unit): + @staticmethod + def _get_factor(new_unit, unit): # Add only the conversions with a factor greater than 1 if unit == new_unit: return 1 diff --git a/earthdiagnostics/ocean/vertcalmean.py b/earthdiagnostics/ocean/vertcalmean.py new file mode 100644 index 0000000..b68e6f5 --- /dev/null +++ b/earthdiagnostics/ocean/vertcalmean.py @@ -0,0 +1,76 @@ +from box import Box +from earthdiagnostics import Diagnostic, TempFile, Utils, cdftools + + +class VerticalMean(Diagnostic): + """ + Choose vertical level in ocean, or vertically average between + 2 or more ocean levels + + Created in February 2012 Author : vguemas@ic3.cat + Modified (more generic, i.e. for any input var) in December 2014 + Author : eleftheria.exarchou@ic3.cat + + # :param input_file: input file name + # :param output_file: output file name (=> 2D field ) + # :param variable: variable name + # :param lev_min: upper depth of the layer (in level number) + # :param lev_max: lower depth of the layer (in level number. If same as the upper layer, then the script just + selects this layer. If its different, a vertical integral (weighted) between upper and lower level is computed + """ + + def __init__(self, data_manager, startdate, member, chunk, variable, box): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.box = box + self.required_vars = [variable] + self.generated_vars = [variable + 'vmean'] + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 1: + raise Exception('You must specify the variable to average vertically') + if num_options > 3: + raise Exception('You must specify between one and three parameters for the vertical mean') + variable = options[1] + + box = Box(True) + if num_options >= 2: + box.min_depth = float(options[2]) + if num_options >= 2: + box.max_depth = float(options[3]) + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(VerticalMean(diags.data_manager, startdate, member, chunk, + variable, box)) + return job_list + + def compute(self): + temp = TempFile.get() + variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) + + handler = Utils.openCdf(variable_file) + if self.box.min_depth is None: + lev_min = handler.variables['lev'][0] + else: + lev_min = self.box.min_depth + + if self.box.max_depth is None: + lev_max = handler.variables['lev'][-1] + else: + lev_max = self.box.max_depth + handler.close() + + cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, + '-debug']) + Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) + self.data_manager.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, + box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) + diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py new file mode 100644 index 0000000..13d9189 --- /dev/null +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -0,0 +1,70 @@ +from box import Box +from earthdiagnostics import Diagnostic, TempFile, Utils, cdftools + + +class VerticalMeanMeters(Diagnostic): + """ + Vertically averaged salt content + Created in February 2012 Author : vguemas@ic3.cat + + # :param input_file: input grid_T file name + # :param upper: upper depth of the layer (in meters) + # :type upper: int + # :param lower: lower depth of the layer (in meters) + # :type lower: int + # :param output_file: output file name (=> 2D) + """ + + def __init__(self, data_manager, startdate, member, chunk, variable, box): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.box = box + self.required_vars = [variable] + self.generated_vars = [variable + 'vmean'] + + @classmethod + def generate_jobs(cls, diags, options): + num_options = len(options) - 1 + if num_options < 1: + raise Exception('You must specify the variable to average vertically') + if num_options > 3: + raise Exception('You must specify between one and three parameters for the vertical mean') + variable = options[1] + box = Box(True) + if num_options >= 2: + box.min_depth = float(options[2]) + if num_options >= 2: + box.max_depth = float(options[3]) + + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(VerticalMeanMeters(diags.data_manager, startdate, member, chunk, + variable, box)) + return job_list + + def compute(self): + temp = TempFile.get() + variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) + + handler = Utils.openCdf(variable_file) + if self.box.min_depth is None: + lev_min = handler.variables['lev'][0] + else: + lev_min = self.box.min_depth + + if self.box.max_depth is None: + lev_max = handler.variables['lev'][-1] + else: + lev_max = self.box.max_depth + handler.close() + + cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, + '-debug']) + Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) + self.data_manager.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, + box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 77221d8..9764934 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -175,6 +175,7 @@ class Utils(object): Utils.execute_shell_command(["nccopy", "-4", filetoconvert, temp]) shutil.move(temp, filetoconvert) + # noinspection PyPep8Naming @staticmethod def openCdf(filepath, mode='a'): return netCDF4.Dataset(filepath, mode) -- GitLab From 4f5a6da1bf82088ec9f56fc303a35db6889fd722 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 15 Jun 2016 12:14:27 +0200 Subject: [PATCH 088/268] Updated doc --- doc/source/codedoc/basin.rst | 2 +- doc/source/codedoc/cdftools.rst | 2 +- doc/source/codedoc/diagnostic.rst | 7 ++ doc/source/codedoc/diags.rst | 2 +- doc/source/codedoc/main.rst | 1 + doc/source/codedoc/models.rst | 2 +- doc/source/codedoc/ocean.rst | 51 ++++++++--- doc/source/codedoc/utils.rst | 4 +- doc/source/conf.py | 2 +- earthdiagnostics/__init__.py | 2 - earthdiagnostics/box.py | 3 + earthdiagnostics/cdftools.py | 2 +- earthdiagnostics/datamanager.py | 15 ++-- earthdiagnostics/diagnostic.py | 44 ++++++++- earthdiagnostics/diags.conf | 4 +- earthdiagnostics/diags.py | 6 +- earthdiagnostics/ocean/__init__.py | 28 +++--- earthdiagnostics/ocean/areamoc.py | 58 ++++++------ earthdiagnostics/ocean/averagesection.py | 23 +++-- earthdiagnostics/ocean/convectionsites.py | 31 ++++--- earthdiagnostics/ocean/cutsection.py | 32 ++++--- earthdiagnostics/ocean/general.py | 5 -- earthdiagnostics/ocean/gyres.py | 48 +++++----- earthdiagnostics/ocean/heat.py | 5 +- earthdiagnostics/ocean/interpolate.py | 23 ++--- earthdiagnostics/ocean/maxmoc.py | 42 +++++---- .../ocean/mixedlayersaltcontent.py | 26 ++++-- earthdiagnostics/ocean/moc.py | 24 ++--- earthdiagnostics/ocean/psi.py | 29 +++--- earthdiagnostics/ocean/siasiesiv.py | 89 +++++++++++-------- .../ocean/{vertcalmean.py => verticalmean.py} | 31 ++++--- earthdiagnostics/ocean/verticalmeanmeters.py | 25 +++--- 32 files changed, 400 insertions(+), 268 deletions(-) create mode 100644 doc/source/codedoc/diagnostic.rst delete mode 100644 earthdiagnostics/ocean/general.py rename earthdiagnostics/ocean/{vertcalmean.py => verticalmean.py} (73%) diff --git a/doc/source/codedoc/basin.rst b/doc/source/codedoc/basin.rst index f0d2fac..4ae2dfd 100644 --- a/doc/source/codedoc/basin.rst +++ b/doc/source/codedoc/basin.rst @@ -1,4 +1,4 @@ -earthdiagnsotics.basins +earthdiagnostics.basins ======================= .. automodule:: earthdiagnostics.basins diff --git a/doc/source/codedoc/cdftools.rst b/doc/source/codedoc/cdftools.rst index cdc6305..e19d174 100644 --- a/doc/source/codedoc/cdftools.rst +++ b/doc/source/codedoc/cdftools.rst @@ -1,4 +1,4 @@ -earthdiagnsotics.cdftools +earthdiagnostics.cdftools ========================= .. automodule:: earthdiagnostics.cdftools diff --git a/doc/source/codedoc/diagnostic.rst b/doc/source/codedoc/diagnostic.rst new file mode 100644 index 0000000..077ba3d --- /dev/null +++ b/doc/source/codedoc/diagnostic.rst @@ -0,0 +1,7 @@ +earthdiagnostics.diagnostic +=========================== + +.. automodule:: earthdiagnostics.diagnostic + :show-inheritance: + :inherited-members: + :members: \ No newline at end of file diff --git a/doc/source/codedoc/diags.rst b/doc/source/codedoc/diags.rst index d64bb81..39bc557 100644 --- a/doc/source/codedoc/diags.rst +++ b/doc/source/codedoc/diags.rst @@ -1,4 +1,4 @@ -earthdiagnsotics.diags +earthdiagnostics.diags ====================== .. automodule:: earthdiagnostics.diags diff --git a/doc/source/codedoc/main.rst b/doc/source/codedoc/main.rst index 4f323a2..26e3da2 100644 --- a/doc/source/codedoc/main.rst +++ b/doc/source/codedoc/main.rst @@ -10,4 +10,5 @@ Module documentation utils basin cdftools + diagnostic ocean \ No newline at end of file diff --git a/doc/source/codedoc/models.rst b/doc/source/codedoc/models.rst index c52eb16..ca5cc92 100644 --- a/doc/source/codedoc/models.rst +++ b/doc/source/codedoc/models.rst @@ -1,4 +1,4 @@ -earthdiagnsotics.models +earthdiagnostics.models ======================= .. automodule:: earthdiagnostics.models diff --git a/doc/source/codedoc/ocean.rst b/doc/source/codedoc/ocean.rst index b5bffb6..e8a8bb2 100644 --- a/doc/source/codedoc/ocean.rst +++ b/doc/source/codedoc/ocean.rst @@ -1,27 +1,54 @@ -earthdiagnsotics.Ocean -======================= +earthdiagnostics.Ocean +====================== -.. automodule:: earthdiagnostics.ocean.general +.. automodule:: earthdiagnostics.ocean.areamoc :show-inheritance: - :inherited-members: :members: -.. automodule:: earthdiagnostics.ocean.circulation +.. automodule:: earthdiagnostics.ocean.averagesection :show-inheritance: - :inherited-members: :members: -.. automodule:: earthdiagnostics.ocean.heat +.. automodule:: earthdiagnostics.ocean.convectionsites :show-inheritance: - :inherited-members: :members: -.. automodule:: earthdiagnostics.ocean.salinity +.. automodule:: earthdiagnostics.ocean.cutsection :show-inheritance: - :inherited-members: :members: -.. automodule:: earthdiagnostics.ocean.ice +.. automodule:: earthdiagnostics.ocean.gyres + :show-inheritance: + :members: + +.. automodule:: earthdiagnostics.ocean.interpolate + :show-inheritance: + :members: + +.. automodule:: earthdiagnostics.ocean.maxmoc + :show-inheritance: + :members: + +.. automodule:: earthdiagnostics.ocean.mixedlayersaltcontent + :show-inheritance: + :members: + +.. automodule:: earthdiagnostics.ocean.moc + :show-inheritance: + :members: + +.. automodule:: earthdiagnostics.ocean.psi + :show-inheritance: + :members: + +.. automodule:: earthdiagnostics.ocean.siasiesiv + :show-inheritance: + :members: + +.. automodule:: earthdiagnostics.ocean.verticalmean + :show-inheritance: + :members: + +.. automodule:: earthdiagnostics.ocean.verticalmeanmeters :show-inheritance: - :inherited-members: :members: diff --git a/doc/source/codedoc/utils.rst b/doc/source/codedoc/utils.rst index c0878f9..7836560 100644 --- a/doc/source/codedoc/utils.rst +++ b/doc/source/codedoc/utils.rst @@ -1,5 +1,5 @@ -earthdiagnsotics.utils -======================= +earthdiagnostics.utils +====================== .. automodule:: earthdiagnostics.utils :show-inheritance: diff --git a/doc/source/conf.py b/doc/source/conf.py index a3963dd..01d7691 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -93,7 +93,7 @@ exclude_patterns = [] # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +show_authors = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' diff --git a/earthdiagnostics/__init__.py b/earthdiagnostics/__init__.py index 3381e76..74efa4c 100644 --- a/earthdiagnostics/__init__.py +++ b/earthdiagnostics/__init__.py @@ -1,7 +1,5 @@ from cdo import Cdo from nco import Nco -from earthdiagnostics.utils import Utils, TempFile -from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.cdftools import CDFTools import os diff --git a/earthdiagnostics/box.py b/earthdiagnostics/box.py index 072a798..99763db 100644 --- a/earthdiagnostics/box.py +++ b/earthdiagnostics/box.py @@ -9,6 +9,9 @@ class Box(object): self.max_depth = None self.min_depth = None + def __str__(self): + return self.get_lat_str() + self.get_lon_str() + self.get_depth_str() + @property def max_lat(self): return self._max_lat diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 542f5f8..08a2f81 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -1,4 +1,4 @@ -from earthdiagnostics import Utils +from earthdiagnostics.utils import Utils import os from autosubmit.config.log import Log diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 9aa15dc..6baf68c 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,14 +1,12 @@ import glob import shutil import threading -# -import netCDF4 import os import numpy as np from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day -from earthdiagnostics import Utils, TempFile +from earthdiagnostics.utils import Utils, TempFile class DataManager(object): @@ -39,9 +37,14 @@ class DataManager(object): member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) + filepaths = glob.glob(os.path.join(member_path, '*.gz')) + + if len(filepaths) == 0: + continue + threads = list() numthreads = Utils.available_cpu_count() - filepaths = glob.glob(os.path.join(member_path, '*.gz')) + for numthread in range(0, numthreads): t = threading.Thread(target=DataManager._unzip, args=([filepaths[numthread::numthreads]])) @@ -233,7 +236,7 @@ class DataManager(object): handler = Utils.openCdf(filetosend) handler.createDimension('region') - var_region = handler.createVariable('region', str, 'region') + var_region = handler.createVariable('region', str, 'region', fill_value='') var_region[0] = region original_var = handler.variables[var] @@ -250,6 +253,7 @@ class DataManager(object): temp = TempFile.get() shutil.copyfile(filepath, temp) + Utils.nco.ncks(input=temp, output=temp, options='-O --mk_rec_dmn region') handler = Utils.openCdf(temp) handler_send = Utils.openCdf(filetosend) value = handler_send.variables[var][:] @@ -266,6 +270,7 @@ class DataManager(object): handler.close() handler_send.close() Utils.move_file(temp, filetosend) + Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') Utils.move_file(filetosend, filepath) diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index fb24d06..8e2c3a9 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -1,7 +1,18 @@ class Diagnostic(object): + """ + Base classs for the diagnostics. Provides a common interface for them and also + has a mechanism that allows diagnostic retrieval by name. + """ @staticmethod def register(cls, alias): + """ + Register a new diagnostic using the given alias. It must be call using the derived class. + :param cls: diagnostic class to register + :type cls: Diagnostic + :param alias: alias for the diagnostic + :type alias: str + """ try: Diagnostic._diag_list[alias] = cls except AttributeError: @@ -27,14 +38,43 @@ class Diagnostic(object): return None def __init__(self, data_manager): + """ + Creates a new instance of the diagnostic. It must be called on the derived class initializers + + :param data_manager: data manager that will be used to store and retrieve the necessary data + :type data_manager: DataManager + """ self.data_manager = data_manager self.required_vars = [] self.generated_vars = [] self.can_run_multiple_instances = True def compute(self): - pass + """ + Calculates the diagnostic and stores the output + + Must be implemented by derived classes + """ + raise NotImplementedError("Class must override compute method") @classmethod def generate_jobs(cls, diags, options): - raise Exception("Class must override generate_jobs method") + """ + Generate the instances of the diagnostics that will be run by the manager + + Must be implemented by derived classes. + + :param diags: diagnostics manager + :type diags: Diags + :param options: list of strings containing the options passed to the diagnostic + :type options: List[str] + :return: + """ + raise NotImplementedError("Class must override generate_jobs class method") + + def __str__(self): + """ + Must be implemented by derived classes + :return: + """ + return 'Developer must override base class __str__ method' diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 8eefb41..de5f7db 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/ecearth/cmorfiles CON_FILES = /esnas/autosubmit/con_files/ -DIAGS = SSEC_AVE190-220E +DIAGS = siasiesiv FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin @@ -12,7 +12,7 @@ EXPID = a034 STARTDATES = 19500201 NAME = historical CHUNK_SIZE = 3 -CHUNKS = 122 +CHUNKS = 1 MEMBERS = 0 MODEL = EC-EARTH3 NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 2e2f451..0b65fb8 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -10,7 +10,8 @@ import os from autosubmit.date.chunk_date_lib import * from datamanager import DataManager -from earthdiagnostics import cdftools, TempFile +from earthdiagnostics import cdftools +from earthdiagnostics.utils import TempFile from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.ocean import * from ocean import ConvectionSites, Gyres, Psi, MaxMoc, AreaMoc, Moc, VerticalMean, VerticalMeanMeters, Interpolate, \ @@ -122,10 +123,11 @@ class Diags: while retrials > 0: try: current_job.compute() + Log.result('Finished {0}', current_job) return True except Exception as ex: retrials -= 1 - Log.error('Diagnostic {0} something failed: {1}', job, ex.message) + Log.error('Job {0} failed: {1}', job, ex) return False count = 0 diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 657b875..8dbb420 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,15 +1,15 @@ # from earthdiagnostics.diagnostic import Diagnostic -from heat import Heat -from ocean.moc import Moc -from ocean.areamoc import AreaMoc -from ocean.maxmoc import MaxMoc -from ocean.psi import Psi -from ocean.gyres import Gyres -from ocean.convectionsites import ConvectionSites -from ocean.cutsection import CutSection -from ocean.averagesection import AverageSection -from ocean.interpolate import Interpolate -from ocean.verticalmeanmeters import VerticalMeanMeters -from ocean.vertcalmean import VerticalMean -from ocean.mixedlayersaltcontent import MixedLayerSaltContent -from ocean.siasiesiv import Siasiesiv +from earthdiagnostics.ocean.heat import Heat +from earthdiagnostics.ocean.moc import Moc +from earthdiagnostics.ocean.areamoc import AreaMoc +from earthdiagnostics.ocean.maxmoc import MaxMoc +from earthdiagnostics.ocean.psi import Psi +from earthdiagnostics.ocean.gyres import Gyres +from earthdiagnostics.ocean.convectionsites import ConvectionSites +from earthdiagnostics.ocean.cutsection import CutSection +from earthdiagnostics.ocean.averagesection import AverageSection +from earthdiagnostics.ocean.interpolate import Interpolate +from earthdiagnostics.ocean.verticalmeanmeters import VerticalMeanMeters +from earthdiagnostics.ocean.verticalmean import VerticalMean +from earthdiagnostics.ocean.mixedlayersaltcontent import MixedLayerSaltContent +from earthdiagnostics.ocean.siasiesiv import Siasiesiv diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 880751e..ed2c9bb 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -1,21 +1,23 @@ import numpy as np - -from basins import Basins -from box import Box -from earthdiagnostics import Diagnostic, Utils, TempFile +from earthdiagnostics.basins import Basins +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.box import Box +from earthdiagnostics.utils import Utils, TempFile class AreaMoc(Diagnostic): """ - Compute the MOC for oceanic basins - Created in March 2012 - Author : vguemas@ic3.cat - - # :param input_file: input grid_V file namez - # :type input_file: str - # :param output_file: output file name (=> 2D, depth-y) - # :param output_file: str - # :return: + Compute an Atlantic MOC index by averaging the meridional overturning + in a latitude band between 1km and 2km + or any other index averaging the meridional overturning in + a given basin and a given domain + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: March 2012 + :last modified: June 2016 + """ def __init__(self, data_manager, startdate, member, chunk, basin, box): @@ -28,8 +30,21 @@ class AreaMoc(Diagnostic): self.generated_vars = ['vsftmyz'] self.box = box + def __str__(self): + return 'Area MOC Startdate: {0} Member: {1} Chunk: {2} Box: {3}'.format(self.startdate, self.member, + self.chunk, self.box) + @classmethod def generate_jobs(cls, diags, options): + """ + Cretas a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: minimum latitude, maximum latitude, minimum depth, maximum depth, basin=Global + :type options: tuple + :return: + """ num_options = len(options) - 1 if num_options < 4: raise Exception('You must specify the box to use') @@ -53,23 +68,6 @@ class AreaMoc(Diagnostic): return job_list def compute(self): - """ - Compute an Atlantic MOC index by averaging the meridional overturning - in a latitude band between 1km and 2km - or any other index averaging the meridional overturning in - a given basin and a given domain - - Created in March 2012 Author : vguemas@ic3.cat - - :param input_file: input moc file name - :param lat_min: latitude min - :param lat_max: latitude max - :param output_file: output file name ( => index ) - :param depth_min: depth min - :param depth_max: depth max - :param basin: basin - :return: - """ nco = Utils.nco cdo = Utils.cdo temp2 = TempFile.get() diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 93048bb..db262b7 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -1,11 +1,20 @@ import os -from autosubmit.config.log import Log - -from box import Box -from earthdiagnostics import Diagnostic, TempFile, Utils +from earthdiagnostics.box import Box +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile class AverageSection(Diagnostic): + """ + Compute an average of a given zone. The variable MUST be in a regular grid + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: March 2012 + :last modified: June 2016 + + """ def __init__(self, data_manager, startdate, member, chunk, variable, domain, box): Diagnostic.__init__(self, data_manager) @@ -16,6 +25,10 @@ class AverageSection(Diagnostic): self.domain = domain self.box = box + def __str__(self): + return 'Average section Startdate: {0} Member: {1} Chunk: {2} Box: {3} ' \ + 'Variable: {4}:{5}'.format(self.startdate, self.member, self.chunk, self.box, self.domain, self.variable) + @classmethod def generate_jobs(cls, diags, options): num_options = len(options) - 1 @@ -53,5 +66,3 @@ class AverageSection(Diagnostic): os.remove(variable_file) self.data_manager.send_file(temp, self.domain, self.variable + 'mean', self.startdate, self.member, self.chunk, box=self.box, grid='regular') - Log.info('Finished section average for startdate {0}, member {1}, chunk {2}', - self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index a0b02e7..7786d54 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -1,11 +1,21 @@ import numpy as np from autosubmit.config.log import Log - -from earthdiagnostics import Diagnostic, TempFile, Utils -from models import Models +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.models import Models class ConvectionSites(Diagnostic): + """ + Compute the intensity of convection in the four main convection sites + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: October 2013 + :last modified: June 2016 + + """ def __init__(self, data_manager, startdate, member, chunk, nemo_version): Diagnostic.__init__(self, data_manager) @@ -16,6 +26,9 @@ class ConvectionSites(Diagnostic): self.required_vars = ['vsftbarot'] self.generated_vars = ['gyres'] + def __str__(self): + return 'Convection sites Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) + @classmethod def generate_jobs(cls, diags, options): job_list = list() @@ -26,16 +39,6 @@ class ConvectionSites(Diagnostic): return job_list def compute(self): - """ - Compute the intensity of convection in the four main convection sites - - Created in October 2013 Author : vguemas@ic3.cat - - :param input_file: input oce file name containing mlotst - :param input_grid: input grid - :param output_file: output file name (=> index) - :return: - """ if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, Models.NEMOVAR_O1L42]: @@ -55,7 +58,7 @@ class ConvectionSites(Diagnostic): self.mlotst_handler = Utils.openCdf(mlotst_file) handler = Utils.openCdf(output, 'w') - handler.createDimension('time') + handler.createDimension('time', self.mlotst_handler.variables['time'].shape[0]) handler.createDimension('region', 4) Utils.copy_variable(self.mlotst_handler, handler, 'time') var_region = handler.createVariable('region', str, 'region') diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index 84c6fe9..acc9c12 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -1,11 +1,22 @@ import numpy as np from autosubmit.config.log import Log -from box import Box -from earthdiagnostics import Diagnostic, Utils +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.box import Box +from earthdiagnostics.utils import Utils class CutSection(Diagnostic): + """ + Cuts a meridional or zonal section + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: September 2012 + :last modified: June 2016 + + """ def __init__(self, data_manager, startdate, member, chunk, variable, domain, zonal, value): Diagnostic.__init__(self, data_manager) @@ -17,6 +28,11 @@ class CutSection(Diagnostic): self.zonal = zonal self.value = value + def __str__(self): + return 'Cut section Startdate: {0} Member: {1} Chunk: {2} Variable: {3}:{4}' \ + 'Zonal: {5} Value: {6}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable, + self.zonal, self.value) + @classmethod def generate_jobs(cls, diags, options): num_options = len(options) - 1 @@ -41,18 +57,6 @@ class CutSection(Diagnostic): return job_list def compute(self): - """ - Cut a meridional or zonal section - - Created in September 2012 Author : vguemas@ic3.cat - :param input_file: input file - :param output_file: output file ( => 2D ) - :param variable: input var - :param zonal: (zonal / meridional section) - :param value: lat/lon - :return: - """ - nco = Utils.nco handler = Utils.openCdf('mesh_hgr.nc') diff --git a/earthdiagnostics/ocean/general.py b/earthdiagnostics/ocean/general.py deleted file mode 100644 index 3f2ff2d..0000000 --- a/earthdiagnostics/ocean/general.py +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index c0f6009..19290c8 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -1,11 +1,22 @@ import numpy as np from autosubmit.config.log import Log -from earthdiagnostics import Diagnostic, TempFile, Utils -from models import Models +from earthdiagnostics.models import Models +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile class Gyres(Diagnostic): + """ + Compute the intensity of the subtropical and subpolar gyres + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: October 2013 + :last modified: June 2016 + + """ def __init__(self, data_manager, startdate, member, chunk, nemo_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate @@ -15,6 +26,10 @@ class Gyres(Diagnostic): self.required_vars = ['vsftbarot'] self.generated_vars = ['gyres'] + def __str__(self): + return 'Gyres Startdate: {0} Member: {1} Chunk: {2} '.format(self.startdate, self.member, + self.chunk) + @classmethod def generate_jobs(cls, diags, options): job_list = list() @@ -26,17 +41,6 @@ class Gyres(Diagnostic): # noinspection PyPep8Naming def compute(self): - """ - Compute the intensity of the subtropical and subpolar gyres - - Created in October 2013 Author : vguemas@ic3.cat - - :param input_psi: input psi file name - :param input_grid: input grid - :param output_file: output file name ( => index ) - :return: - """ - if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, Models.NEMOVAR_O1L42]: @@ -62,12 +66,14 @@ class Gyres(Diagnostic): handler_original = Utils.openCdf(vsftbarot_file) self.var_vsftbarot = handler_original.variables['vsftbarot'] handler = Utils.openCdf(output, 'w') - handler.createDimension('time') + handler.createDimension('time', handler_original.variables['time'].shape[0]) handler.createDimension('region', 8) Utils.copy_variable(handler_original, handler, 'time') var_region = handler.createVariable('region', str, 'region') - var_gyre = handler.createVariable('gyre', 'f', ('time', 'region')) + var_gyre = handler.createVariable('gyre', 'f', ('time', 'region'), fill_value=0.0) + var_gyre.valid_max = 2e8 + var_gyre.valid_min = 0.0 var_gyre.short_name = 'gyre' var_gyre.long_name = 'gyre' var_gyre.units = 'm^3/s' @@ -110,18 +116,6 @@ class Gyres(Diagnostic): Log.info('Finished gyres for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) def _gyre(self, site, invert=False): - """ - Compute the intensity of a given gyre - - Created in October 2013 Author : vguemas@ic3.cat - - :param input_file: input oce file name containing vsftbarot - :param site: site to calculate convection on - :param output_file: output file name (=> index) - :param invert: if True, multiplies result by -1 - :return: - """ - if invert: return np.min(self._extract_section(site), (1, 2)) * -1 else: diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index beb1b44..d1922fc 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -1,4 +1,5 @@ -from earthdiagnostics import Utils, cdftools, cdo, TempFile +from earthdiagnostics import cdftools, cdo +from earthdiagnostics.utils import Utils, TempFile from earthdiagnostics.basins import Basins from autosubmit.config.log import Log import os @@ -45,7 +46,7 @@ class Heat(object): files.append(temp) temp = TempFile.get() - cdo.cat(input=' '.join(files), output=temp,) + nco.ncrcat(input=' '.join(files), output=temp,) nco.ncks(input=input_scratch, output=temp, options='-A -v time') for temp_file in files: diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index b778bdf..380efdf 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -2,23 +2,22 @@ import shutil import os from autosubmit.config.log import Log - -from earthdiagnostics import Diagnostic, Utils, TempFile +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile class Interpolate(Diagnostic): """ - 3-dimensional conservative interpolation to the regular atmospheric grid + 3-dimensional conservative interpolation to the regular atmospheric grid. + It can also be used for 2D (i,j) variables - Created in November 2012 Author : vguemas@ic3.cat + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor - # :param nemo_version: - # :param input_file: - # :param output_file: - # :param variable: - :return: - """ + :created: November 2012 + :last modified: June 2016 + """ def __init__(self, data_manager, startdate, member, chunk, variable, domain, nemo_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate @@ -31,6 +30,10 @@ class Interpolate(Diagnostic): self.generated_vars = [variable] self.tempTemplate = '' + def __str__(self): + return 'Interpolate Startdate: {0} Member: {1} Chunk: {2} ' \ + 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + @classmethod def generate_jobs(cls, diags, options): num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index b2d0626..87013d7 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -2,13 +2,24 @@ import netCDF4 import numpy as np import os from autosubmit.config.log import Log - -from basins import Basins -from box import Box -from earthdiagnostics import Diagnostic, Utils +from earthdiagnostics.basins import Basins +from earthdiagnostics.box import Box +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils class MaxMoc(Diagnostic): + """ + Compute an Atlantic MOC index by finding the maximum of the annual + mean meridional overturning in a latitude / depth region + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: March 2012 + :last modified: June 2016 + + """ def __init__(self, data_manager, startdate, member, year, basin, box): Diagnostic.__init__(self, data_manager) @@ -20,6 +31,10 @@ class MaxMoc(Diagnostic): self.generated_vars = ['vsftmyz'] self.box = box + def __str__(self): + return 'Max moc Startdate: {0} Member: {1} Year: {2} Basin: {3}'.format(self.startdate, self.member, + self.year, self.box) + @classmethod def generate_jobs(cls, diags, options): num_options = len(options) - 1 @@ -49,21 +64,6 @@ class MaxMoc(Diagnostic): return job_list def compute(self): - """ - Compute an Atlantic MOC index by finding the maximum of the annual - mean meridional overturning in a latitude / depth region - - Created in March 2012 Author : vguemas@ic3.cat - - :param basin: basin - :param input_file: input moc file name - :param lat_min: latitude min - :param lat_max: latitude max - :param output_file: output file name - :param depth_min: depth mean - :param depth_max: depth max - :return: - """ nco = Utils.nco temp = self.data_manager.get_year('ocean', 'vsftmyz', self.startdate, self.member, self.year) @@ -102,12 +102,16 @@ class MaxMoc(Diagnostic): maximum = np.amax(moc) max_index = np.unravel_index(np.argmax(moc), moc.shape) + # noinspection PyUnresolvedReferences max_lev = lev[lev_inds[max_index[0]]] + # noinspection PyUnresolvedReferences max_lat = lat[lat_inds[max_index[1]]] minimum = np.amin(moc) minimum_index = np.unravel_index(np.argmin(moc), moc.shape) + # noinspection PyUnresolvedReferences min_lev = lev[lev_inds[minimum_index[0]]] + # noinspection PyUnresolvedReferences min_lat = lat[lat_inds[minimum_index[1]]] Log.info('Maximum {0} Sv, latitude {1} depth {2} m', maximum, max_lat, max_lev) diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 7d77aa4..bf4485e 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -2,11 +2,22 @@ import threading import os from autosubmit.config.log import Log - -from earthdiagnostics import Diagnostic, Utils, TempFile, cdftools +from earthdiagnostics import cdftools +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile class MixedLayerSaltContent(Diagnostic): + """ + Compute mixed layer salt content + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: February 2012 + :last modified: June 2016 + + """ def __init__(self, data_manager, startdate, member, chunk, lock): Diagnostic.__init__(self, data_manager) @@ -17,6 +28,10 @@ class MixedLayerSaltContent(Diagnostic): self.generated_vars = ['scvertsum'] self.lock = lock + def __str__(self): + return 'Mixed layer salt content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, + self.chunk) + @classmethod def generate_jobs(cls, diags, options): lock = threading.Lock() @@ -28,13 +43,6 @@ class MixedLayerSaltContent(Diagnostic): return job_list def compute(self): - """ - Compute mixed layer heat and salt content - - Created in February 2012 Author : vguemas@ic3.cat - - :return: - """ nco = Utils.nco cdo = Utils.cdo salinity_file = self.data_manager.get_file('ocean', 'so', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index 7823161..24c86a8 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -1,21 +1,22 @@ import numpy as np from autosubmit.config.log import Log -from basins import Basins -from earthdiagnostics import Diagnostic, TempFile, cdftools, Utils +from earthdiagnostics import cdftools +from earthdiagnostics.basins import Basins +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile class Moc(Diagnostic): """ Compute the MOC for oceanic basins - Created in March 2012 - Author : vguemas@ic3.cat - - # :param input_file: input grid_V file namez - # :type input_file: str - # :param output_file: output file name (=> 2D, depth-y) - # :param output_file: str - # :return: + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: March 2012 + :last modified: June 2016 + """ def __init__(self, data_manager, startdate, member, chunk): @@ -26,6 +27,9 @@ class Moc(Diagnostic): self.required_vars = ['vo'] self.generated_vars = ['vsftmyz'] + def __str__(self): + return 'MOC Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) + @classmethod def generate_jobs(cls, diags, options): job_list = list() diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 506560f..429c6b4 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -1,7 +1,19 @@ -from earthdiagnostics import Diagnostic, TempFile, cdftools, Utils +from earthdiagnostics import cdftools +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile class Psi(Diagnostic): + """ + Compute the barotropic stream function + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: March 2012 + :last modified: June 2016 + + """ def __init__(self, data_manager, startdate, member, chunk): Diagnostic.__init__(self, data_manager) self.startdate = startdate @@ -10,6 +22,9 @@ class Psi(Diagnostic): self.required_vars = ['vo', 'uo'] self.generated_vars = ['vsftbarot'] + def __str__(self): + return 'PSI Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) + @classmethod def generate_jobs(cls, diags, options): job_list = list() @@ -20,18 +35,6 @@ class Psi(Diagnostic): return job_list def compute(self): - """ - Compute the barotropic stream function - - Created in March 2012 Author : vguemas@ic3.cat - z - :param input_file_u: input grid_U file name - :rtype input_file_U: str - :param input_file_v: input grid_V file name - :rtype input_file_V: str - :param output_file: output file name without nc extension (=> 2D x-y) - :rtype output_file: str - """ temp = TempFile.get() input_file_u = self.data_manager.get_file('ocean', 'uo', self.startdate, self.member, self.chunk) input_file_v = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index a5f0c7b..1157872 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -4,16 +4,27 @@ import threading import netCDF4 import os from autosubmit.config.log import Log - -from basins import Basins -from earthdiagnostics import Diagnostic, Utils, cdo, TempFile, cdftools +from earthdiagnostics import cdo, cdftools +from earthdiagnostics.basins import Basins +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile +import numpy as np class Siasiesiv(Diagnostic): """ - Class containing all the diagnostics related to ice - """ + Compute the sea ice extent , area and volume in both hemispheres or a specified region. + + + :original author: Virginie Guemas + :contributor: Neven Fuckar + :contributor: Ruben Cruz + :contributor: Javier Vegas-Regidor + + :created: April 2012 + :last modified: June 2016 + """ def __init__(self, data_manager, basin, startdate, member, chunk, lock): Diagnostic.__init__(self, data_manager) self.basin = basin @@ -28,6 +39,10 @@ class Siasiesiv(Diagnostic): self.generated_vars = ['siextents', 'sivols', 'siareas', 'siextentn', 'sivoln', 'siarean'] self.lock = lock + def __str__(self): + return 'Siasiesiv Startdate: {0} Member: {1} Chunk: {2} Basin: {3}'.format(self.startdate, self.member, + self.chunk, self.basin.fullname) + @classmethod def generate_jobs(cls, diags, options): basin = Basins.parse(options[1]) @@ -40,19 +55,6 @@ class Siasiesiv(Diagnostic): return job_list def compute(self): - """ - Compute the sea ice extent (1000km2), area (1000km2), volume (km3) - and mean thickness (m) in both hemispheres or a specified region. - - Created in April 2012 Author : vguemas@ic3.cat - Modified in June 2014 Author : neven.fuckar@ic3.cat - - Computation of the properties in various selected regions according to - mask.regions.${NEMOVERSION}.nc (mask_regions.nc) is based on modification - of mask.regions.ORCA1.noverticalinfo.Matt.nc from Matthieu Chevallier. - :return: - """ - nco = Utils.nco sit_file = self.data_manager.get_file('seaIce', 'sit', self.startdate, self.member, self.chunk) sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) @@ -89,64 +91,75 @@ class Siasiesiv(Diagnostic): self.lock.release() temp = TempFile.get() - cdo.cat(input=' '.join(files), output=temp) - nco.ncks(input=sit_file, output=temp, options='-A -v time') + nco.ncrcat(input=' '.join(files), output=temp) - self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SVolume', 'sivols', "10^3 km3"), + self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'SVolume', 'sivols', + "10^3 km3"), 'seaIce', 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SArea', 'siareas', "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'SArea', 'siareas', + "10^6 km2"), 'seaIce', 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, 'SExnsidc', 'siextents', "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'SExnsidc', 'siextents', + "10^6 km2"), 'seaIce', 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NVolume', 'sivoln', "10^3 km3"), + self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'NVolume', 'sivoln', + "10^3 km3"), 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NArea', 'siarean', "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'NArea', 'siarean', "10^6 km2"), 'seaIce', 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, 'NExnsidc', 'siextentn', "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'NExnsidc', 'siextentn', + "10^6 km2"), 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) os.remove(temp) - def _extract_variable_and_rename(self, input_file, variable, cmor_name, output_units): + def _extract_variable_and_rename(self, input_file, reference_file, variable, cmor_name, output_units): temp = TempFile.get() - # Utils.nco.ncks(input=input_file, output=temp, options='-O -v {0},time,time_bnds'.format(variable)) input_handler = Utils.openCdf(input_file) + reference_handler = Utils.openCdf(reference_file) os.remove(temp) handler = netCDF4.Dataset(temp, 'w') # Create dimensions - handler.createDimension('time', None) + handler.createDimension('time') handler.createDimension('bnds', 2) # Copy time variable - time_var = input_handler.variables['time'] - new_time = handler.createVariable('time', time_var.datatype, time_var.dimensions) - new_time.setncatts({k: time_var.getncattr(k) for k in time_var.ncattrs()}) - new_time[:] = time_var[:] - original_bnds = input_handler.variables['time_bnds'] - new_bnds = handler.createVariable('time_bnds', original_bnds.datatype, original_bnds.dimensions) - new_bnds.setncatts({k: original_bnds.getncattr(k) for k in original_bnds.ncattrs()}) - new_bnds[:] = original_bnds[:] + Utils.copy_variable(reference_handler, handler, 'time') + Utils.copy_variable(reference_handler, handler, 'time_bnds') + Utils.copy_variable(reference_handler, handler, 'leadtime') + reference_handler.close() + # time_var = input_handler.variables['time'] + # new_time = handler.createVariable('time', time_var.datatype, time_var.dimensions) + # new_time.setncatts({k: time_var.getncattr(k) for k in time_var.ncattrs()}) + # new_time[:] = time_var[:] + # + # original_bnds = input_handler.variables['time_bnds'] + # new_bnds = handler.createVariable('time_bnds', original_bnds.datatype, original_bnds.dimensions) + # new_bnds.setncatts({k: original_bnds.getncattr(k) for k in original_bnds.ncattrs()}) + # new_bnds[:] = original_bnds[:] original_variable = input_handler.variables[variable] values = original_variable[:, 0, 0] - new_var = handler.createVariable(cmor_name, original_variable.datatype, 'time') + new_var = handler.createVariable(cmor_name, original_variable.datatype, 'time', fill_value=0.0) new_var.setncatts({k: original_variable.getncattr(k) for k in original_variable.ncattrs()}) factor = self._get_conversion_factor(original_variable.units, output_units) values *= factor new_var[:] = values new_var.units = output_units new_var.short_name = cmor_name + new_var.valid_min = 0.0 + new_var.valid_max = np.max(values) handler.close() return temp diff --git a/earthdiagnostics/ocean/vertcalmean.py b/earthdiagnostics/ocean/verticalmean.py similarity index 73% rename from earthdiagnostics/ocean/vertcalmean.py rename to earthdiagnostics/ocean/verticalmean.py index b68e6f5..5393dbc 100644 --- a/earthdiagnostics/ocean/vertcalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -1,23 +1,22 @@ -from box import Box -from earthdiagnostics import Diagnostic, TempFile, Utils, cdftools +from earthdiagnostics import cdftools +from earthdiagnostics.box import Box +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile class VerticalMean(Diagnostic): """ - Choose vertical level in ocean, or vertically average between - 2 or more ocean levels + Chooses vertical level in ocean, or vertically averages between + 2 or more ocean levels - Created in February 2012 Author : vguemas@ic3.cat - Modified (more generic, i.e. for any input var) in December 2014 - Author : eleftheria.exarchou@ic3.cat + :original author: Virginie Guemas + :contributor: Eleftheria Exarchou + :contributor: Javier Vegas-Regidor - # :param input_file: input file name - # :param output_file: output file name (=> 2D field ) - # :param variable: variable name - # :param lev_min: upper depth of the layer (in level number) - # :param lev_max: lower depth of the layer (in level number. If same as the upper layer, then the script just - selects this layer. If its different, a vertical integral (weighted) between upper and lower level is computed - """ + :created: February 2012 + :last modified: June 2016 + + """ def __init__(self, data_manager, startdate, member, chunk, variable, box): Diagnostic.__init__(self, data_manager) @@ -29,6 +28,10 @@ class VerticalMean(Diagnostic): self.required_vars = [variable] self.generated_vars = [variable + 'vmean'] + def __str__(self): + return 'Vertical mean Startdate: {0} Member: {1} Chunk: {2} Variable: {3} ' \ + 'Box: {4}'.format(self.startdate, self.member, self.chunk, self.variable, self.box) + @classmethod def generate_jobs(cls, diags, options): num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 13d9189..509e743 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -1,18 +1,19 @@ -from box import Box -from earthdiagnostics import Diagnostic, TempFile, Utils, cdftools +from earthdiagnostics import cdftools +from earthdiagnostics.box import Box +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile class VerticalMeanMeters(Diagnostic): """ - Vertically averaged salt content - Created in February 2012 Author : vguemas@ic3.cat + Averages vertically any given variable + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: February 2012 + :last modified: June 2016 - # :param input_file: input grid_T file name - # :param upper: upper depth of the layer (in meters) - # :type upper: int - # :param lower: lower depth of the layer (in meters) - # :type lower: int - # :param output_file: output file name (=> 2D) """ def __init__(self, data_manager, startdate, member, chunk, variable, box): @@ -25,6 +26,10 @@ class VerticalMeanMeters(Diagnostic): self.required_vars = [variable] self.generated_vars = [variable + 'vmean'] + def __str__(self): + return 'Vertical mean meters Startdate: {0} Member: {1} Chunk: {2} Variable: {3} ' \ + 'Box: {4}'.format(self.startdate, self.member, self.chunk, self.variable, self.box) + @classmethod def generate_jobs(cls, diags, options): num_options = len(options) - 1 -- GitLab From 8bd3b4d9963746113c26a089ba35554b6082ed38 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 15 Jun 2016 12:38:41 +0200 Subject: [PATCH 089/268] Modified siasiesiv so it is not longer needed to split for each timestep --- earthdiagnostics/datamanager.py | 2 +- earthdiagnostics/ocean/mixedlayersaltcontent.py | 6 ++---- earthdiagnostics/ocean/siasiesiv.py | 15 ++------------- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6baf68c..0cef6ca 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -236,7 +236,7 @@ class DataManager(object): handler = Utils.openCdf(filetosend) handler.createDimension('region') - var_region = handler.createVariable('region', str, 'region', fill_value='') + var_region = handler.createVariable('region', str, 'region') var_region[0] = region original_var = handler.variables[var] diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index bf4485e..42f8eb5 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -19,14 +19,13 @@ class MixedLayerSaltContent(Diagnostic): """ - def __init__(self, data_manager, startdate, member, chunk, lock): + def __init__(self, data_manager, startdate, member, chunk): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.required_vars = ['so', 'mlotst'] self.generated_vars = ['scvertsum'] - self.lock = lock def __str__(self): return 'Mixed layer salt content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, @@ -34,12 +33,11 @@ class MixedLayerSaltContent(Diagnostic): @classmethod def generate_jobs(cls, diags, options): - lock = threading.Lock() job_list = list() for startdate in diags.startdates: for member in diags.members: for chunk in range(1, diags.chunks + 1): - job_list.append(MixedLayerSaltContent(diags.datamanager, startdate, member, chunk, lock)) + job_list.append(MixedLayerSaltContent(diags.datamanager, startdate, member, chunk)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 1157872..679425f 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -59,10 +59,9 @@ class Siasiesiv(Diagnostic): sit_file = self.data_manager.get_file('seaIce', 'sit', self.startdate, self.member, self.chunk) sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) nco.ncks(input=sic_file, output=sit_file, options='-A -v sic') - ntime = int(cdo.ntime(input=sit_file)[0]) - files = list() self.lock.acquire() + temp = TempFile.get() if self.basin != Basins.Global: shutil.move('mask.nc', 'original_mask.nc') @@ -70,14 +69,7 @@ class Siasiesiv(Diagnostic): Utils.rename_variable('mask.nc', self.basin.fullname, 'tmask') error = None try: - for time in range(ntime): - Log.info('Running time {0}', time) - temp = TempFile.get() - temp2 = TempFile.get() - nco.ncks(input=sit_file, output=temp, options='-O -d time,{0}'.format(time)) - cdftools.run('cdficediags', input=temp, output=temp2) - os.remove(temp) - files.append(temp2) + cdftools.run('cdficediags', input=sit_file, output=temp) except Exception as ex: error = ex.message finally: @@ -90,9 +82,6 @@ class Siasiesiv(Diagnostic): self.lock.release() - temp = TempFile.get() - nco.ncrcat(input=' '.join(files), output=temp) - self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'SVolume', 'sivols', "10^3 km3"), 'seaIce', 'sivols', self.startdate, self.member, self.chunk, -- GitLab From dc69e325a4b759d59f307a01ab7b0c56088e306b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 16 Jun 2016 11:27:29 +0200 Subject: [PATCH 090/268] Added docstrings fot the generate_jobs methods --- earthdiagnostics/ocean/areamoc.py | 4 ++-- earthdiagnostics/ocean/averagesection.py | 9 +++++++++ earthdiagnostics/ocean/convectionsites.py | 11 +++++++++++ earthdiagnostics/ocean/cutsection.py | 9 +++++++++ earthdiagnostics/ocean/gyres.py | 11 +++++++++++ earthdiagnostics/ocean/interpolate.py | 9 +++++++++ earthdiagnostics/ocean/maxmoc.py | 9 +++++++++ .../ocean/mixedlayersaltcontent.py | 19 +++++++++++++------ earthdiagnostics/ocean/moc.py | 11 +++++++++++ earthdiagnostics/ocean/psi.py | 11 +++++++++++ earthdiagnostics/ocean/siasiesiv.py | 11 +++++++++++ earthdiagnostics/ocean/verticalmean.py | 9 +++++++++ earthdiagnostics/ocean/verticalmeanmeters.py | 9 +++++++++ 13 files changed, 124 insertions(+), 8 deletions(-) diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index ed2c9bb..1df1abd 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -37,12 +37,12 @@ class AreaMoc(Diagnostic): @classmethod def generate_jobs(cls, diags, options): """ - Cretas a job for each chunk to compute the diagnostic + Creates a job for each chunk to compute the diagnostic :param diags: Diagnostics manager class :type diags: Diags :param options: minimum latitude, maximum latitude, minimum depth, maximum depth, basin=Global - :type options: tuple + :type options: List[str] :return: """ num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index db262b7..75cb1dc 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -31,6 +31,15 @@ class AverageSection(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, minimun longitude, maximun longitude, minimum latitude, maximum latitude, domain=ocean + :type options: List[str] + :return: + """ num_options = len(options) - 1 if num_options < 5: raise Exception('You must specify the variable and the box to average') diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 7786d54..f436b4c 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -31,6 +31,17 @@ class ConvectionSites(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: None + :type options: List[str] + :return: + """ + if len(options) > 1: + raise Exception('The convection sites diagnostic has no options') job_list = list() for startdate in diags.startdates: for member in diags.members: diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index acc9c12..6f858f6 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -35,6 +35,15 @@ class CutSection(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, zonal, value, domain=ocean + :type options: List[str] + :return: + """ num_options = len(options) - 1 if num_options < 3: raise Exception('You must specify the variable, coordinate and coordinate value') diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 19290c8..ea46abf 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -32,6 +32,17 @@ class Gyres(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: None + :type options: List[str] + :return: + """ + if len(options) > 1: + raise Exception('The gyres diagnostic has no options') job_list = list() for startdate in diags.startdates: for member in diags.members: diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 380efdf..a5a1ae6 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -36,6 +36,15 @@ class Interpolate(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, domain=ocean + :type options: List[str] + :return: + """ num_options = len(options) - 1 if num_options < 1: raise Exception('You must specify the variable to average vertically') diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 87013d7..f59d266 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -37,6 +37,15 @@ class MaxMoc(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each complete year to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: minimum latitude, maximum latitude, minimum depth, maximum depth, basin=global + :type options: List[str] + :return: + """ num_options = len(options) - 1 if num_options < 4: raise Exception('You must specify the box to use') diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index bf4485e..ae8eb7e 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -1,5 +1,3 @@ -import threading - import os from autosubmit.config.log import Log from earthdiagnostics import cdftools @@ -19,14 +17,13 @@ class MixedLayerSaltContent(Diagnostic): """ - def __init__(self, data_manager, startdate, member, chunk, lock): + def __init__(self, data_manager, startdate, member, chunk): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.required_vars = ['so', 'mlotst'] self.generated_vars = ['scvertsum'] - self.lock = lock def __str__(self): return 'Mixed layer salt content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, @@ -34,12 +31,22 @@ class MixedLayerSaltContent(Diagnostic): @classmethod def generate_jobs(cls, diags, options): - lock = threading.Lock() + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: None + :type options: List[str] + :return: + """ + if len(options) > 1: + raise Exception('The mixed layer salt content diagnostic has no options') job_list = list() for startdate in diags.startdates: for member in diags.members: for chunk in range(1, diags.chunks + 1): - job_list.append(MixedLayerSaltContent(diags.datamanager, startdate, member, chunk, lock)) + job_list.append(MixedLayerSaltContent(diags.datamanager, startdate, member, chunk)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index 24c86a8..9f9a5fc 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -32,6 +32,17 @@ class Moc(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: None + :type options: List[str] + :return: + """ + if len(options) > 1: + raise Exception('The MOC diagnostic has no options') job_list = list() for startdate in diags.startdates: for member in diags.members: diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 429c6b4..1f3e0ca 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -27,6 +27,17 @@ class Psi(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: None + :type options: List[str] + :return: + """ + if len(options) > 1: + raise Exception('The PSI diagnostic has no options') job_list = list() for startdate in diags.startdates: for member in diags.members: diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 1157872..a55ebb4 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -45,6 +45,17 @@ class Siasiesiv(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: basin + :type options: List[str] + :return: + """ + if len(options) != 2: + raise Exception('You must specify the basin for the siasiesiv diagnostic (and nothing else)') basin = Basins.parse(options[1]) lock = threading.Lock() job_list = list() diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 5393dbc..2b4914d 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -34,6 +34,15 @@ class VerticalMean(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, minimum depth (level), maximum depth (level) + :type options: List[str] + :return: + """ num_options = len(options) - 1 if num_options < 1: raise Exception('You must specify the variable to average vertically') diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 509e743..e772c5a 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -32,6 +32,15 @@ class VerticalMeanMeters(Diagnostic): @classmethod def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, minimum depth (meters), maximum depth (meters) + :type options: List[str] + :return: + """ num_options = len(options) - 1 if num_options < 1: raise Exception('You must specify the variable to average vertically') -- GitLab From 50467eeb695ed0132b60e185369a9bf8ec0a4f8e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 16 Jun 2016 14:36:10 +0200 Subject: [PATCH 091/268] Added docstrings --- earthdiagnostics/basins.py | 15 ++-- earthdiagnostics/box.py | 56 +++++++++++++- earthdiagnostics/datamanager.py | 126 ++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 8 deletions(-) diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index 528a692..6fa489b 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -1,3 +1,5 @@ +from earthdiagnostics.box import Box + class Basin(object): """ Class representing a given basin @@ -11,13 +13,16 @@ class Basin(object): :type coordinates: tuple """ - def __init__(self, shortname, fullname, coordinates=None): + def __init__(self, shortname, fullname, box=None): self._shortname = shortname self._fullname = fullname - if coordinates: - self._coordinates = coordinates - else: - self._coordinates = [0, 0, 0, 0] + if not box: + box = Box() + + self.box = box + """ + Box representing the basin + """ def __eq__(self, other): if self.shortname != other.shortname or self.fullname != other.fullname: diff --git a/earthdiagnostics/box.py b/earthdiagnostics/box.py index 99763db..f097936 100644 --- a/earthdiagnostics/box.py +++ b/earthdiagnostics/box.py @@ -1,19 +1,39 @@ class Box(object): + """ + Represents a box in the 3D space. Also allows easy conversion from the coordinate values to significant string + representations + """ def __init__(self, depth_in_meters=False): self.depth_in_meters = depth_in_meters + """ + If True, treats the depth as if it is given in meters. If False, as it is given in levels + :rtype: bool + """ self._max_lat = None self._min_lat = None self._max_lon = None self._min_lon = None self.max_depth = None + """ + Maximum depth + :rtype: float + """ self.min_depth = None + """ + Minimum depth + :rtype: float + """ def __str__(self): return self.get_lat_str() + self.get_lon_str() + self.get_depth_str() @property def max_lat(self): + """ + Maximum latitude + :rtype: float + """ return self._max_lat @max_lat.setter @@ -24,6 +44,10 @@ class Box(object): @property def min_lat(self): + """ + Minimum latitude + :rtype: float + """ return self._min_lat @min_lat.setter @@ -34,6 +58,10 @@ class Box(object): @property def max_lon(self): + """ + Maximum longitude + :rtype: float + """ return self._max_lon @max_lon.setter @@ -44,6 +72,10 @@ class Box(object): @property def min_lon(self): + """ + Minimum longitude + :rtype: float + """ return self._min_lon @min_lon.setter @@ -53,6 +85,12 @@ class Box(object): self._min_lon = value def get_lat_str(self): + """ + Gets a string representation of the latitude in the format XX{N/S}. + If min_lat is different from max_lat, it concatenates the two values + :return: string representation for latitude + :rtype: str + """ if self.max_lat is None or self.min_lat is None: return '' if self.min_lat < 0: @@ -72,24 +110,36 @@ class Box(object): return string def get_lon_str(self): + """ + Gets a string representation of the longitude in the format XX{E/W}. + If min_lon is different from max_lon, it concatenates the two values + :return: string representation for longitude + :rtype: str + """ if self.max_lon is None or self.min_lon is None: return '' if self.min_lon < 0: direction = 'W' else: - direction = 'N' + direction = 'E' string = str(abs(self.min_lon)) + direction if self.max_lon != self.min_lon: if self.max_lon < 0: - direction = 'S' + direction = 'W' else: - direction = 'N' + direction = 'E' string += str(abs(self.max_lon)) + direction return string def get_depth_str(self): + """ + Gets a string representation of depth. For depth expressed in meters, it adds th character 'm' to the end + If min_depth is different from max_depth, it concatenates the two values + :return: string representation for depth + :rtype: str + """ if self.max_depth is None or self.min_depth is None: return '' diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6baf68c..0d9ed44 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -13,6 +13,18 @@ class DataManager(object): def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name, num_chunks, calendar='standard'): + """ + + :param institution: + :param model: + :param expid: + :param datafolder: + :param frequency: + :param chunk_size: + :param experiment_name: + :param num_chunks: + :param calendar: + """ self.institution = institution self.model = model self.expid = expid @@ -27,6 +39,20 @@ class DataManager(object): # noinspection PyPep8Naming def prepare_CMOR_files(self, startdates, members): + """ + Prepares the data to be used by the diagnostic. + + If CMOR data is not created, it show a warning and closes. In the future, an automatic cmorization procedure + will be launched + + If CMOR data is available but packed, the procedure will unpack it. + + :param startdates: list of startdates that will be used by the diagnostics + :type startdates: list[str] + :param members: lists of members that will be used by the diagnostics + :type members: list[int] + :return: + """ # Check if cmorized and convert if not if not os.path.exists(os.path.join(self.data_dir, self.expid)): raise Exception('The experiment {0} is not CMORized. ' @@ -104,6 +130,23 @@ class DataManager(object): os.remove(filepath) def get_files(self, startdate, member, chunk, domain, variables, grid=None): + """ + Returns a list of filenames for different variables + + :param startdate: startdate to retrieve + :type startdate: str + :param member: member to retrieve + :type member: int + :param chunk: chunk to retrieve + :type chunk: int + :param domain: variable's CMOR domain + :type domain:str + :param variables: variables list + :type variables: list[str] + :param grid: specifies if the variable must be in a interpolated grid + :type grid: str + :return: + """ file_names = list() @@ -143,6 +186,28 @@ class DataManager(object): return file_names def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): + """ + Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy + + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ if domain == 'seaIce': domain_abreviattion = 'OI' else: @@ -183,6 +248,38 @@ class DataManager(object): def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, rename_var=None, frequency=None, year=None): + """ + Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge + with already existing ones as needed + + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int + :param rename_var: if exists, the given variable will be renamed to the one given by var + :type rename_var: str + :param filetosend: path to the file to send to the CMOR repository + :type filetosend: str + :param region: specifies the region represented by the file. If it is defined, the data will be appended to the + CMOR repository as a new region in the file or will overwrite if region was already present + :type region: str + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ Utils.convert2netcdf4(filetosend) @@ -275,6 +372,27 @@ class DataManager(object): Utils.move_file(filetosend, filepath) def get_year(self, domain, var, startdate, member, year, grid=None, box=None): + """ + Gets all the data corresponfing to a given year from the CMOR repository to the scratch folder as one file and + returns the path to the scratch's copy. + + :param year: year to retrieve + :type year: int + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :return: path to the copy created on the scratch folder + :rtype: str + """ chunk_files = list() for chunk in self.get_year_chunks(startdate, year): chunk_files.append(self.get_file(domain, var, startdate, member, chunk, grid=grid, box=box)) @@ -305,6 +423,14 @@ class DataManager(object): return temp2 def get_year_chunks(self, startdate, year): + """ + Get the list of chunks containing timesteps from the given year + :param startdate: startdate to use + :type startdate: str + :param year: reference year + :type year: int + :return: + """ date = parse_date(startdate) chunks = list() for chunk in range(1, self.num_chunks+1): -- GitLab From d7b749e3192c069c3f39f20a22fe9bb9a92b28f7 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 16 Jun 2016 16:35:45 +0200 Subject: [PATCH 092/268] Commit to merge work from home --- doc/source/developers.rst | 6 +++++ doc/source/index.rst | 1 + doc/source/tutorial.rst | 44 +++++++++++++++++++++++++++++++++++++ earthdiagnostics/diags.conf | 27 ++++++++++++++++++++--- 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 doc/source/developers.rst create mode 100644 doc/source/tutorial.rst diff --git a/doc/source/developers.rst b/doc/source/developers.rst new file mode 100644 index 0000000..ed73d57 --- /dev/null +++ b/doc/source/developers.rst @@ -0,0 +1,6 @@ +Developer's guide +================= + +The tool provides a set of useful diagnostics, but of course that a lot more can be needed at anytime. +If you miss something and are able to develop it, you are more than welcome to collaborate + diff --git a/doc/source/index.rst b/doc/source/index.rst index 23e5ce1..bebfdc6 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -9,4 +9,5 @@ Welcome to Earth Diagnostics's documentation! .. toctree:: :maxdepth: 2 + tutorial codedoc/main diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst new file mode 100644 index 0000000..179e823 --- /dev/null +++ b/doc/source/tutorial.rst @@ -0,0 +1,44 @@ +Tutorial +======== + +So, you are planning to use the Earth Diagnostics? You don't know how to use them? This is the place to go. +From now on this tutorial will guide you through all the process from installation to running. + +.. Hint:: + If you have any problem with this tutorial, please report it to so it can be corrected. + A lof of people will benefit from it and you will be mentioned here. + +Installation +------------ + +For now, you only have an option: dowload the diagnostics directly from BSC-ES's Gitlab: + +.. code-block:: sh + + git clone https://earth.bsc.es/gitlab/es/ocean_diagnostics.git + +You will also need + +* CDO version 1.6.9 (other versions could work, but this is the one we use) +* NCO version 4.5.4 or newer +* Python 2.7 or newer (but no 3.x) with Autosubmit, CDO and NCO packages +* Acces to CDFTOOLS_3.0 executables for BSC-ES. At this point, those are located at /home/Earth/jvegas/CDFTOOLS_CMOR/bin. + +Creating a config file +---------------------- + +If you go into the earthdiagnsotics foldeer in the git repository, you will see a diags.conf that can be used as a model +for your config file. It contains commentaries explaining what represents each one of its parameters, so please read it +carefully. + +Once you have configured your experiment you can execute any diagnostic by calling this command (substitue the variables +for the real paths before launching, please) + +.. code-block:: sh + + ${PATH_TO_REPOSITORY}/earthdiagnostics.diags.py ${PATH_TO_MY_CONF_FILE} + +And... that's it. You will find your results inside CMOR's folder tree and a folder for the temp files in the scratch. +This folder is named after the EXPID. + + diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index de5f7db..5bcb3c2 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -1,20 +1,37 @@ [DIAGNOSTICS] +# Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/jvegas +# Root path for the cmorized data to use DATA_DIR = /esnas/exp/ecearth/cmorfiles +# Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ +# Diagnostics to run DIAGS = siasiesiv +# Frequency of the data you want to use FREQUENCY = mon +# Path to CDFTOOLS binaries CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin [EXPERIMENT] +# Experiments parameters as defined in CMOR standard INSTITUTE = IC3 +MODEL = EC-EARTH3 +NAME = historical + +# For those who use Autosubmit, this no need documentation +# For those who not, EXPID is the unique identifier of the experiment. +# STARTDATES is the list of start dates +# MEMBERS is the list of members of your experiment +# CHUNK_SIZE is the size of each data file, given in months +# CHUNKS is the number of chunks to process + EXPID = a034 STARTDATES = 19500201 -NAME = historical +MEMBERS = 0 CHUNK_SIZE = 3 CHUNKS = 1 -MEMBERS = 0 -MODEL = EC-EARTH3 + +# Model version NEMO_VERSION = Ec3.0_O1L46 # [EXPERIMENT] @@ -39,6 +56,10 @@ NEMO_VERSION = Ec3.0_O1L46 # MODEL = EC-EARTH3 # NEMO_VERSION = Ec3.0_O25L75 + +# This ALIAS section is a bit different +# Inside this, you can provide. + [ALIAS] MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 AREA_MOC = mocarea,40,55,1000,2000,atl mocarea,30,40,1000,2000,atl -- GitLab From 5dc40623c3c15297aad9dd89f9ffb7f0cfdd0e69 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 17 Jun 2016 12:49:42 +0200 Subject: [PATCH 093/268] Updated doc --- .idea/codeStyleSettings.xml | 9 +++ .idea/dictionaries/jvegas.xml | 8 +++ doc/source/codedoc/basin.rst | 7 --- doc/source/codedoc/cdftools.rst | 7 --- doc/source/codedoc/diagnostic.rst | 7 --- doc/source/codedoc/diags.rst | 7 --- doc/source/codedoc/earthdiagnostics.rst | 59 +++++++++++++++++++ doc/source/codedoc/main.rst | 7 +-- doc/source/codedoc/models.rst | 7 --- doc/source/codedoc/ocean.rst | 28 ++++++++- doc/source/codedoc/utils.rst | 7 --- doc/source/errors.rst | 33 +++++++++++ doc/source/faq.rst | 4 ++ doc/source/index.rst | 4 ++ doc/source/tips.rst | 23 ++++++++ earthdiagnostics/basins.py | 54 +---------------- earthdiagnostics/datamanager.py | 12 +++- earthdiagnostics/diagnostic.py | 2 +- earthdiagnostics/diags.py | 15 ++++- earthdiagnostics/ocean/areamoc.py | 2 +- earthdiagnostics/ocean/averagesection.py | 2 +- earthdiagnostics/ocean/convectionsites.py | 2 +- earthdiagnostics/ocean/cutsection.py | 2 +- earthdiagnostics/ocean/gyres.py | 2 +- earthdiagnostics/ocean/heat.py | 8 +-- earthdiagnostics/ocean/interpolate.py | 2 +- earthdiagnostics/ocean/maxmoc.py | 2 +- .../ocean/mixedlayersaltcontent.py | 2 +- earthdiagnostics/ocean/moc.py | 2 +- earthdiagnostics/ocean/psi.py | 2 +- earthdiagnostics/ocean/siasiesiv.py | 5 +- earthdiagnostics/ocean/verticalmean.py | 2 +- earthdiagnostics/ocean/verticalmeanmeters.py | 2 +- 33 files changed, 213 insertions(+), 124 deletions(-) create mode 100644 .idea/codeStyleSettings.xml create mode 100644 .idea/dictionaries/jvegas.xml delete mode 100644 doc/source/codedoc/basin.rst delete mode 100644 doc/source/codedoc/cdftools.rst delete mode 100644 doc/source/codedoc/diagnostic.rst delete mode 100644 doc/source/codedoc/diags.rst create mode 100644 doc/source/codedoc/earthdiagnostics.rst delete mode 100644 doc/source/codedoc/models.rst delete mode 100644 doc/source/codedoc/utils.rst create mode 100644 doc/source/errors.rst create mode 100644 doc/source/faq.rst create mode 100644 doc/source/tips.rst diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 0000000..c4c9543 --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/.idea/dictionaries/jvegas.xml b/.idea/dictionaries/jvegas.xml new file mode 100644 index 0000000..bc7a994 --- /dev/null +++ b/.idea/dictionaries/jvegas.xml @@ -0,0 +1,8 @@ + + + + nemo + orca + + + \ No newline at end of file diff --git a/doc/source/codedoc/basin.rst b/doc/source/codedoc/basin.rst deleted file mode 100644 index 4ae2dfd..0000000 --- a/doc/source/codedoc/basin.rst +++ /dev/null @@ -1,7 +0,0 @@ -earthdiagnostics.basins -======================= - -.. automodule:: earthdiagnostics.basins - :show-inheritance: - :inherited-members: - :members: \ No newline at end of file diff --git a/doc/source/codedoc/cdftools.rst b/doc/source/codedoc/cdftools.rst deleted file mode 100644 index e19d174..0000000 --- a/doc/source/codedoc/cdftools.rst +++ /dev/null @@ -1,7 +0,0 @@ -earthdiagnostics.cdftools -========================= - -.. automodule:: earthdiagnostics.cdftools - :show-inheritance: - :inherited-members: - :members: \ No newline at end of file diff --git a/doc/source/codedoc/diagnostic.rst b/doc/source/codedoc/diagnostic.rst deleted file mode 100644 index 077ba3d..0000000 --- a/doc/source/codedoc/diagnostic.rst +++ /dev/null @@ -1,7 +0,0 @@ -earthdiagnostics.diagnostic -=========================== - -.. automodule:: earthdiagnostics.diagnostic - :show-inheritance: - :inherited-members: - :members: \ No newline at end of file diff --git a/doc/source/codedoc/diags.rst b/doc/source/codedoc/diags.rst deleted file mode 100644 index 39bc557..0000000 --- a/doc/source/codedoc/diags.rst +++ /dev/null @@ -1,7 +0,0 @@ -earthdiagnostics.diags -====================== - -.. automodule:: earthdiagnostics.diags - :show-inheritance: - :inherited-members: - :members: \ No newline at end of file diff --git a/doc/source/codedoc/earthdiagnostics.rst b/doc/source/codedoc/earthdiagnostics.rst new file mode 100644 index 0000000..b516ff9 --- /dev/null +++ b/doc/source/codedoc/earthdiagnostics.rst @@ -0,0 +1,59 @@ +earthdiagnostics +================ + +earthdiagnostics.ocean.basins +----------------------------- +.. automodule:: earthdiagnostics.basins + :show-inheritance: + :inherited-members: + :members: + +earthdiagnostics.ocean.box +-------------------------- +.. automodule:: earthdiagnostics.box + :show-inheritance: + :inherited-members: + :members: + +earthdiagnostics.ocean.cdftools +------------------------------- +.. automodule:: earthdiagnostics.cdftools + :show-inheritance: + :inherited-members: + :members: + +earthdiagnostics.ocean.datamanager +---------------------------------- +.. automodule:: earthdiagnostics.datamanager + :show-inheritance: + :inherited-members: + :members: + + +earthdiagnostics.ocean.diagnostic +--------------------------------- +.. automodule:: earthdiagnostics.diagnostic + :show-inheritance: + :inherited-members: + :members: + +earthdiagnostics.ocean.diags +---------------------------- +.. automodule:: earthdiagnostics.diags + :show-inheritance: + :inherited-members: + :members: + +earthdiagnostics.ocean.models +----------------------------- +.. automodule:: earthdiagnostics.models + :show-inheritance: + :inherited-members: + :members: + +earthdiagnostics.ocean.utils +---------------------------- +.. automodule:: earthdiagnostics.utils + :show-inheritance: + :inherited-members: + :members: diff --git a/doc/source/codedoc/main.rst b/doc/source/codedoc/main.rst index 26e3da2..8755b7d 100644 --- a/doc/source/codedoc/main.rst +++ b/doc/source/codedoc/main.rst @@ -5,10 +5,5 @@ Module documentation .. toctree:: :titlesonly: - diags - models - utils - basin - cdftools - diagnostic + earthdiagnostics ocean \ No newline at end of file diff --git a/doc/source/codedoc/models.rst b/doc/source/codedoc/models.rst deleted file mode 100644 index ca5cc92..0000000 --- a/doc/source/codedoc/models.rst +++ /dev/null @@ -1,7 +0,0 @@ -earthdiagnostics.models -======================= - -.. automodule:: earthdiagnostics.models - :show-inheritance: - :inherited-members: - :members: \ No newline at end of file diff --git a/doc/source/codedoc/ocean.rst b/doc/source/codedoc/ocean.rst index e8a8bb2..9370d77 100644 --- a/doc/source/codedoc/ocean.rst +++ b/doc/source/codedoc/ocean.rst @@ -1,54 +1,80 @@ -earthdiagnostics.Ocean +earthdiagnostics.ocean ====================== +earthdiagnostics.ocean.areamoc +------------------------------ .. automodule:: earthdiagnostics.ocean.areamoc :show-inheritance: :members: +earthdiagnostics.ocean.averagesection +------------------------------------- .. automodule:: earthdiagnostics.ocean.averagesection :show-inheritance: :members: +earthdiagnostics.ocean.convectionsites +-------------------------------------- .. automodule:: earthdiagnostics.ocean.convectionsites :show-inheritance: :members: +earthdiagnostics.ocean.cutsection +--------------------------------- .. automodule:: earthdiagnostics.ocean.cutsection :show-inheritance: :members: +earthdiagnostics.ocean.gyres +---------------------------- .. automodule:: earthdiagnostics.ocean.gyres :show-inheritance: :members: +earthdiagnostics.ocean.interpolate +---------------------------------- .. automodule:: earthdiagnostics.ocean.interpolate :show-inheritance: :members: +earthdiagnostics.ocean.maxmoc +----------------------------- .. automodule:: earthdiagnostics.ocean.maxmoc :show-inheritance: :members: +earthdiagnostics.ocean.mixedlayersaltcontent +-------------------------------------------- .. automodule:: earthdiagnostics.ocean.mixedlayersaltcontent :show-inheritance: :members: +earthdiagnostics.ocean.moc +-------------------------- .. automodule:: earthdiagnostics.ocean.moc :show-inheritance: :members: +earthdiagnostics.ocean.psi +-------------------------- .. automodule:: earthdiagnostics.ocean.psi :show-inheritance: :members: +earthdiagnostics.ocean.siasiesiv +-------------------------------- .. automodule:: earthdiagnostics.ocean.siasiesiv :show-inheritance: :members: +earthdiagnostics.ocean.verticalmean +----------------------------------- .. automodule:: earthdiagnostics.ocean.verticalmean :show-inheritance: :members: +earthdiagnostics.ocean.verticalmeanmeters +----------------------------------------- .. automodule:: earthdiagnostics.ocean.verticalmeanmeters :show-inheritance: :members: diff --git a/doc/source/codedoc/utils.rst b/doc/source/codedoc/utils.rst deleted file mode 100644 index 7836560..0000000 --- a/doc/source/codedoc/utils.rst +++ /dev/null @@ -1,7 +0,0 @@ -earthdiagnostics.utils -====================== - -.. automodule:: earthdiagnostics.utils - :show-inheritance: - :inherited-members: - :members: \ No newline at end of file diff --git a/doc/source/errors.rst b/doc/source/errors.rst new file mode 100644 index 0000000..3c68133 --- /dev/null +++ b/doc/source/errors.rst @@ -0,0 +1,33 @@ +What to do if you have an error +=============================== + +Sometimes, the program may crash and you will not know why. This section will give you a procedure to follow before +reporting the issue. This procedure is intended to solve some common problems or, at least, to help you in creating +good issue reports. Remember: a good issue report implies less time to solve it! + +.. hint:: + + Reading is good. Most times the error message will point you to the problem's source and sometimes even give you + a hint of how to solve it by yourself. + +Try this simple steps BEFORE reporting an issue + +* Clean scratch folder +* Update to the latest compatible tag: maybe your issue is already solved in it +* If you get the error for the first chunk of a given diagnostic, change configuration so this will be the only one + that will run +* Call the diags with the -lc DEBUG -log log.txt options + +Now, you have two options: if everything is fine, the error was probably due to some corrupted files or some unstable +machine state. Nevertheless, try running the diagnostic with -lc DEBUG for all the chunks. If everything it's fine that's +all. + +If you experienced the same problem again, go to the GitLab portal and look into the open issues +( https://earth.bsc.es/gitlab/es/ocean_diagnostics/issues ). If you find your issue or a very similar one, use it to +report your problems. If you can not find an open one that suites your problem, create a new one and explain what is +happening to you. + +In any case, it will be very useful if you can attach your diags.conf and log.txt files. + +After that, it's just a matter of waiting for the developers to do its work and answering the questions that they may +have. Please, be patient. diff --git a/doc/source/faq.rst b/doc/source/faq.rst new file mode 100644 index 0000000..656a2a6 --- /dev/null +++ b/doc/source/faq.rst @@ -0,0 +1,4 @@ +Frequently Asked Questions +========================== + +Here will be the answers to the most usual questions. For the moment, there is nothing to see here... \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst index bebfdc6..3b25442 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -10,4 +10,8 @@ Welcome to Earth Diagnostics's documentation! :maxdepth: 2 tutorial + tips + errors + developers + faq codedoc/main diff --git a/doc/source/tips.rst b/doc/source/tips.rst new file mode 100644 index 0000000..e4a5eaf --- /dev/null +++ b/doc/source/tips.rst @@ -0,0 +1,23 @@ +Tips and tricks +=============== + +Working with ORCA1 +------------------ + +If you plan to run diagnostics for ORCA1 resolution, be aware that your workstation will be more than capable to run +them. At this resolution, memory and time consumption is low enough to allow you keep using the machine while running. + +Configuring core usage +---------------------- + +By default, the Earth Diagnostics creates a thread for each available core for the execution. If you are using a queueing +system, the diagnostics will always use the number of cores that you reserved. If you are running outside a queueing +system, the diagnostics will try to use all the cores on the machine. To avoid this, add the MAX_CORES parameter to the +to the DIAGNOSTICS section inside the diags.conf file that you are using. + +NEMO files +---------- + +Unlike the bash version of the ocean diagnostics, this program keeps the NEMO files in the scratch folder so you can +launch different configurations with reduced start time. You will need to remove the experiment's folder in the scratch +directory at the end of the experiment to avoid wasting resources. diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index 6fa489b..d5eb291 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -1,5 +1,6 @@ from earthdiagnostics.box import Box + class Basin(object): """ Class representing a given basin @@ -8,15 +9,12 @@ class Basin(object): :type shortname: str :param fullname: full basin's name :type fullname: str - :param coordinates: list of coordinates for the basin in the order: min longitude, max longitude, min latitude, - max latitude - :type coordinates: tuple """ def __init__(self, shortname, fullname, box=None): self._shortname = shortname self._fullname = fullname - if not box: + if not box: box = Box() self.box = box @@ -45,54 +43,6 @@ class Basin(object): """ return self._fullname - @property - def min_lon(self): - """ - Minimum longitude - :rtype: int - """ - return self._coordinates[0] - - @property - def max_lon(self): - """ - Maximum longitude - :rtype: int - """ - return self._coordinates[1] - - @property - def min_lat(self): - """ - Minimum latitude - :rtype: int - """ - return self._coordinates[2] - - @property - def max_lat(self): - """ - Maximum latitude - :rtype: int - """ - return self._coordinates[3] - - @property - def lon(self): - """ - Longitude limits of the basin - :rtype: tuple - """ - return self._coordinates[0:2] - - @property - def lat(self): - """ - Latitude limits of the basin - :rtype: tuple - """ - return self._coordinates[2:] - class Basins(object): """ diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 57c20fb..5bca21d 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -142,7 +142,7 @@ class DataManager(object): :param domain: variable's CMOR domain :type domain:str :param variables: variables list - :type variables: list[str] + :type variables: list[str] | tuple[str] :param grid: specifies if the variable must be in a interpolated grid :type grid: str :return: @@ -429,7 +429,8 @@ class DataManager(object): :type startdate: str :param year: reference year :type year: int - :return: + :return: list of chunks containing data from the given year + :rtype: list[int] """ date = parse_date(startdate) chunks = list() @@ -444,6 +445,13 @@ class DataManager(object): return chunks def get_full_years(self, startdate): + """ + Returns the list of full years that are in the given startdate + :param startdate: startdate to use + :type startdate: str + :return: list of full years + :rtype: list[int] + """ chunks_per_year = 12 / self.chunk_size date = parse_date(startdate) first_january = 0 diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 8e2c3a9..1aa3110 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -67,7 +67,7 @@ class Diagnostic(object): :param diags: diagnostics manager :type diags: Diags :param options: list of strings containing the options passed to the diagnostic - :type options: List[str] + :type options: list[str] :return: """ raise NotImplementedError("Class must override generate_jobs class method") diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 0b65fb8..18187b0 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -131,17 +131,26 @@ class Diags: return False count = 0 + failed_jobs = list() while not queue.empty(): try: job = queue.get(timeout=1) if _run_job(job): count += 1 + else: + failed_jobs.append(str(job)) queue.task_done() except Queue.Empty: continue - Log.result('Thread {0} finished after taking care of {1} tasks', numthread, count) + if len(failed_jobs) == 0: + Log.result('Thread {0} finished after taking care of {1} tasks', numthread, count) + else: + Log.result('Thread {0} finished after running successfully {1} of {2} tasks', numthread, count, + count + len(failed_jobs)) + for job in failed_jobs: + Log.error('Job {0} could not be run', job) return def _execute_diagnostic(self, diag_options, startdate, member, chunk): @@ -298,11 +307,15 @@ def main(): default='INFO', type=str, help="sets console's log level") + parser.add_argument('-log', '--logfilepath', default=None, type=str) + parser.add_argument('-f', '--configfile', default='diags.conf', type=str) args = parser.parse_args() Log.set_console_level(args.logconsole) Log.set_file_level(args.logfile) + if args.logfilepath: + Log.set_file(args.logfilepath) diags = Diags(args.configfile) diags.run() diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 1df1abd..d0d4cf8 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -42,7 +42,7 @@ class AreaMoc(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: minimum latitude, maximum latitude, minimum depth, maximum depth, basin=Global - :type options: List[str] + :type options: list[str] :return: """ num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 75cb1dc..6601c85 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -37,7 +37,7 @@ class AverageSection(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: variable, minimun longitude, maximun longitude, minimum latitude, maximum latitude, domain=ocean - :type options: List[str] + :type options: list[str] :return: """ num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index f436b4c..cb7c2d9 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -37,7 +37,7 @@ class ConvectionSites(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: None - :type options: List[str] + :type options: list[str] :return: """ if len(options) > 1: diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index 6f858f6..cfcf2a4 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -41,7 +41,7 @@ class CutSection(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: variable, zonal, value, domain=ocean - :type options: List[str] + :type options: list[str] :return: """ num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index ea46abf..910f7dc 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -38,7 +38,7 @@ class Gyres(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: None - :type options: List[str] + :type options: list[str] :return: """ if len(options) > 1: diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py index d1922fc..101f4d0 100644 --- a/earthdiagnostics/ocean/heat.py +++ b/earthdiagnostics/ocean/heat.py @@ -181,10 +181,10 @@ class Heat(object): try: para = list() - para.append(str(basin.min_lon)) - para.append(str(basin.max_lon)) - para.append(str(basin.min_lat)) - para.append(str(basin.max_lat)) + para.append(str(basin.box.min_lon)) + para.append(str(basin.box.max_lon)) + para.append(str(basin.box.min_lat)) + para.append(str(basin.box.max_lat)) para.append(upper) para.append(lower) para.append(str(mixed_layer)) diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index a5a1ae6..75fb5e4 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -42,7 +42,7 @@ class Interpolate(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: variable, domain=ocean - :type options: List[str] + :type options: list[str] :return: """ num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index f59d266..070d2a6 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -43,7 +43,7 @@ class MaxMoc(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: minimum latitude, maximum latitude, minimum depth, maximum depth, basin=global - :type options: List[str] + :type options: list[str] :return: """ num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index ae8eb7e..ed849f3 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -37,7 +37,7 @@ class MixedLayerSaltContent(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: None - :type options: List[str] + :type options: list[str] :return: """ if len(options) > 1: diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index 9f9a5fc..f5d6b5b 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -38,7 +38,7 @@ class Moc(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: None - :type options: List[str] + :type options: list[str] :return: """ if len(options) > 1: diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 1f3e0ca..8523b2a 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -33,7 +33,7 @@ class Psi(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: None - :type options: List[str] + :type options: list[str] :return: """ if len(options) > 1: diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 3dafa69..4f9aa92 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -3,8 +3,7 @@ import threading import netCDF4 import os -from autosubmit.config.log import Log -from earthdiagnostics import cdo, cdftools +from earthdiagnostics import cdftools from earthdiagnostics.basins import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile @@ -51,7 +50,7 @@ class Siasiesiv(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: basin - :type options: List[str] + :type options: list[str] :return: """ if len(options) != 2: diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 2b4914d..4cdaa46 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -40,7 +40,7 @@ class VerticalMean(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: variable, minimum depth (level), maximum depth (level) - :type options: List[str] + :type options: list[str] :return: """ num_options = len(options) - 1 diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index e772c5a..7da1185 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -38,7 +38,7 @@ class VerticalMeanMeters(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags :param options: variable, minimum depth (meters), maximum depth (meters) - :type options: List[str] + :type options: list[str] :return: """ num_options = len(options) - 1 -- GitLab From 0283bcdcaa0f08521e5b31ba4edd9e7b481b31c3 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 17 Jun 2016 15:51:02 +0200 Subject: [PATCH 094/268] modified siasiesiv to take advantage of the modifications made to cdficediags --- earthdiagnostics/diags.conf | 8 ++++---- earthdiagnostics/ocean/siasiesiv.py | 31 ++++++----------------------- testing_diags_moore.job | 2 +- 3 files changed, 11 insertions(+), 30 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 5bcb3c2..4122527 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -6,7 +6,7 @@ DATA_DIR = /esnas/exp/ecearth/cmorfiles # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run -DIAGS = siasiesiv +DIAGS = siasiesiv,baffin # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -29,7 +29,7 @@ EXPID = a034 STARTDATES = 19500201 MEMBERS = 0 CHUNK_SIZE = 3 -CHUNKS = 1 +CHUNKS = 256 # Model version NEMO_VERSION = Ec3.0_O1L46 @@ -40,7 +40,7 @@ NEMO_VERSION = Ec3.0_O1L46 # STARTDATES = 19900101 # NAME = historical # CHUNK_SIZE = 3 -# CHUNKS = 2 +# CHUNKS = 120 # MEMBERS = 0 # MODEL = EC-EARTH3 # NEMO_VERSION = Ec3.0_O1L46 @@ -51,7 +51,7 @@ NEMO_VERSION = Ec3.0_O1L46 # NAME = horizlResImpact_series2 # STARTDATES = 19930501 # CHUNK_SIZE = 4 -# CHUNKS = 1 +# CHUNKS = 120 # MEMBERS = 0 1 2 3 4 # MODEL = EC-EARTH3 # NEMO_VERSION = Ec3.0_O25L75 diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 4f9aa92..808e86d 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -1,6 +1,3 @@ -import shutil -import threading - import netCDF4 import os from earthdiagnostics import cdftools @@ -24,7 +21,7 @@ class Siasiesiv(Diagnostic): :last modified: June 2016 """ - def __init__(self, data_manager, basin, startdate, member, chunk, lock): + def __init__(self, data_manager, basin, startdate, member, chunk): Diagnostic.__init__(self, data_manager) self.basin = basin if basin == Basins.Global: @@ -36,7 +33,6 @@ class Siasiesiv(Diagnostic): self.chunk = chunk self.required_vars = ['sit', 'sic'] self.generated_vars = ['siextents', 'sivols', 'siareas', 'siextentn', 'sivoln', 'siarean'] - self.lock = lock def __str__(self): return 'Siasiesiv Startdate: {0} Member: {1} Chunk: {2} Basin: {3}'.format(self.startdate, self.member, @@ -56,12 +52,11 @@ class Siasiesiv(Diagnostic): if len(options) != 2: raise Exception('You must specify the basin for the siasiesiv diagnostic (and nothing else)') basin = Basins.parse(options[1]) - lock = threading.Lock() job_list = list() for startdate in diags.startdates: for member in diags.members: for chunk in range(1, diags.chunks + 1): - job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk, lock)) + job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk)) return job_list def compute(self): @@ -70,27 +65,13 @@ class Siasiesiv(Diagnostic): sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) nco.ncks(input=sic_file, output=sit_file, options='-A -v sic') - self.lock.acquire() temp = TempFile.get() if self.basin != Basins.Global: - shutil.move('mask.nc', 'original_mask.nc') - shutil.move('mask_regions.nc', 'mask.nc') - Utils.rename_variable('mask.nc', self.basin.fullname, 'tmask') - error = None - try: - cdftools.run('cdficediags', input=sit_file, output=temp) - except Exception as ex: - error = ex.message - finally: - if self.basin != Basins.Global: - Utils.rename_variable('mask.nc', 'tmask', self.basin.fullname) - shutil.move('mask.nc', 'mask_regions.nc') - shutil.move('original_mask.nc', 'mask.nc') - if error: - raise Exception(error) - - self.lock.release() + options = '-mask {0} -maskfile mask_regions.nc'.format(self.basin.fullname) + else: + options = '' + cdftools.run('cdficediags', input=sit_file, output=temp, options=options) self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'SVolume', 'sivols', "10^3 km3"), diff --git a/testing_diags_moore.job b/testing_diags_moore.job index 22bc711..96333e4 100755 --- a/testing_diags_moore.job +++ b/testing_diags_moore.job @@ -1,6 +1,6 @@ #!/bin/bash #SBATCH --time=24:00:00 -#SBATCH -n 4 +#SBATCH -n 15 #SBATCH --error=/home/Earth/jvegas/job.%J.err #SBATCH --output=/home/Earth/jvegas/job.%J.out -- GitLab From c137395216f78349f253df772a41133b45f0f2e5 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 21 Jun 2016 10:11:28 +0200 Subject: [PATCH 095/268] modified siasiesiv to use f2py wrapper for cdficediags --- cdftoolspython.so | Bin 0 -> 419104 bytes config_file-ocean_pp.bash | 2 +- earthdiagnostics/diags.conf | 4 ++-- earthdiagnostics/ocean/siasiesiv.py | 34 +++++++++++++++++++++++----- 4 files changed, 31 insertions(+), 9 deletions(-) create mode 100755 cdftoolspython.so diff --git a/cdftoolspython.so b/cdftoolspython.so new file mode 100755 index 0000000000000000000000000000000000000000..86585a2d990a4eed4a630300682dc1b81283132b GIT binary patch literal 419104 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 mV_`|T_(`^zauh9Z! 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 wGsB|;rx3gx(rI;gOKQLNh^m&3Oz<(Um=?nM`c Date: Tue, 21 Jun 2016 10:49:44 +0200 Subject: [PATCH 096/268] some bugs fixed --- cdftoolspython.so | Bin 419104 -> 419104 bytes earthdiagnostics/ocean/siasiesiv.py | 26 ++++++++++++-------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/cdftoolspython.so b/cdftoolspython.so index 86585a2d990a4eed4a630300682dc1b81283132b..1d8daccff7f34ecd59492bc199c8e5b8213e1af2 100755 GIT binary patch delta 95455 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 z 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≫)q4{q~I;z5dOA_59Jld3pQW zUiN#(%N;8BzvJ|OaKyX5ohN3v#Xd;ehpXhNn=#7IRe8S3sqgy!?Aqe}?Nb?T)%aWe z_U2~KcdGnKWtVL}|7N|J%$?+aDc`R$rFWKl{N4LosQ06mt6Zsa)lRp4cxSz5!mXp8 z%DL~7ulyvHr>Z=Em$%=z&*#gfuD6wQed#0RpQ+rdvfbCdKU}0ZMlVuu1){(50+r|g z+s7-`k98ANUZQfc%F9&#MCFw#e|AV4TOV^5YrXs?t~xXtn_H~)y`1`%F;dHh&Ps93%P1PahM#mD3#Gb*#(G zYc1&N^%`=G=(IQ2G;TXK>YJ0ZyfNqaXlPE(()f%Mq_+j}iW4N^f_U2r(PSCI(fN`I zhi)R(ckn(o#?|@J*q#Mf`_5nA&MR!z&1P5pdVW-tQ_$GsyV0~9`wF@1`$t7>OwahG z{?REpP4T||GAhN5qffLMjEd6(B=qve2L{OSw=wU=C!QQVCGU6Kd2;k;d6VG-r$oP( zUX=`t#`fUq-2@-mtUgkE6|Wd5c`t~&6hw=p7t0D{BzDE=LTN0HHy26|7sMrlBpKSP{PiI<%beI{(lFj-QP^DyaAQ{(1gvSj)h sJz!^KaoE4(kMl`)zSr{=an6Y7W}CtYv6|BO_y{{e&5fH!Mq~5;3s5PYxc~qF diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index b805560..407755b 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -50,8 +50,6 @@ class Siasiesiv(Diagnostic): :type options: list[str] :return: """ - print cdftoolspython.__doc__ - if len(options) != 2: raise Exception('You must specify the basin for the siasiesiv diagnostic (and nothing else)') basin = Basins.parse(options[1]) @@ -64,11 +62,7 @@ class Siasiesiv(Diagnostic): def compute(self): nco = Utils.nco - sit_file = self.data_manager.get_file('seaIce', 'sit', self.startdate, self.member, self.chunk) - sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) - sit_handler = Utils.openCdf(sit_file) - sic_handler = Utils.openCdf(sic_file) mesh_handler = Utils.openCdf('mesh_hgr.nc') e1t = mesh_handler.variables['e1t'][0, :] e2t = mesh_handler.variables['e2t'][0, :] @@ -83,14 +77,18 @@ class Siasiesiv(Diagnostic): mask = mask_handler.variables['tmask'][0, 0, :] mask_handler.close() - temp = TempFile.get() - - try: - sit = sit_handler.variables['sit'][0, :] - sic = sic_handler.variables['sic'][0, :] - results = cdftoolspython.icediag.icediags(e1t, e2t, gphit, mask, sic, sit) - except Exception as ex: - print ex + sit_file = self.data_manager.get_file('seaIce', 'sit', self.startdate, self.member, self.chunk) + sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) + sit_handler = Utils.openCdf(sit_file) + sic_handler = Utils.openCdf(sic_file) + results = list() + for t in range(0, sit_handler.dimensions['time'].size): + try: + sit = sit_handler.variables['sit'][t, :] + sic = sic_handler.variables['sic'][t, :] + results.append(cdftoolspython.icediag.icediags(e1t, e2t, mask, gphit, sit, sic)) + except Exception as ex: + print ex sit_handler.close() sic_handler.close() -- GitLab From 0111f8787c578445d2cd9e256ee3910536700024 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 22 Jun 2016 15:12:46 +0200 Subject: [PATCH 097/268] Automated CMOR for ocean --- .idea/dictionaries/jvegas.xml | 2 + earthdiagnostics/cmor_table.csv | 103 ++++++++ earthdiagnostics/datamanager.py | 378 +++++++++++++++++++++------- earthdiagnostics/diags.conf | 4 +- earthdiagnostics/diags.py | 5 +- earthdiagnostics/ocean/siasiesiv.py | 37 +-- earthdiagnostics/utils.py | 6 +- 7 files changed, 421 insertions(+), 114 deletions(-) create mode 100644 earthdiagnostics/cmor_table.csv diff --git a/.idea/dictionaries/jvegas.xml b/.idea/dictionaries/jvegas.xml index bc7a994..9ff66da 100644 --- a/.idea/dictionaries/jvegas.xml +++ b/.idea/dictionaries/jvegas.xml @@ -1,6 +1,8 @@ + cmor + leadtime nemo orca diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv new file mode 100644 index 0000000..da6928b --- /dev/null +++ b/earthdiagnostics/cmor_table.csv @@ -0,0 +1,103 @@ +Variable,Shortname,Name,Long name,Domain,Basin +hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic Northward Ocean Heat Transport,ocean, +ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce, +iice_etd,iice_etd,brine_volume_distribution,Brine volume distribution,seaIce, +iice_hid,iice_hid,ice_thicknesss_in_categories,Ice thickness in categories,seaIce, +iice_hsd,iice_hsd,snow_depth_in_categories,Snow depth in in categories,seaIce, +iice_itd,iice_itd,ice_area_in_categories,Ice area in categories,seaIce, +iice_otd,ageice,age_of_sea_ice,Age of Sea Ice,seaIce, +iice_std,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce, +iiceages,ageice,age_of_sea_ice,Age of Sea Ice,seaIce, +iicebome,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of Melt at Sea Ice Base,seaIce, +iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce, +iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thickness,seaIce, +iiceconc,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce, +iicedive,divice,Strain Rate Divergence of Sea Ice,divergence_of_sea_ice_velocity,seaIce, +iicedypr,iicedypr,daily_dynamic_ice_production,Daily dynamic ice production,seaIce, +iiceheco,hcice,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea Ice Heat Content,seaIce, +iicelapr,iicelapr,daily_lateral_thermo_ice_production,Daily lateral thermo ice prod.,seaIce, +iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce, +iicesali,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce, +iicesflx,iicesflx,solar_flux_ice_ocean_surface,Solar flux at ice/ocean surface,seaIce, +iiceshea,iiceshea,shear,Shear,seaIce, +iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce, +iicestre,streng,compressive_strength_of_sea_ice,Compressive Sea Ice Strength,seaIce, +iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of Melt at Upper Surface of Sea Ice,seaIce, +iicesurt,tsice,surface_temperature,Surface Temperature of Sea Ice,seaIce, +iicetemp,iicetemp,ice_temperature,Mean ice temperature,seaIce, +iicethic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce, +iicevelo,iicevelo,ice_velocity,Ice velocity,seaIce, +iicevelu,iicevelu,ice_velocity_u,Ice velocity u,seaIce, +iicevelv,iicevelv,ice_velocity_v,Ice velocity v,seaIce, +iicfsbri,iicfsbri,brine_salt_flux,Fsbri - brine salt flux,seaIce, +iicfseqv,iicfseqv,equivalent_FW_salt_flux,Fseqv - equivalent FW salt flux,seaIce, +ioceflxb,ioceflxb,oceanic_flux_ar_ice_base,Oceanic flux at the ice base,seaIce, +iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release,seaIce, +iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce, +iocestru,iocestru,wind_stress_u,Wind stress u,seaIce, +iocestrv,iocestrv,wind_stress_v,Wind stress v,seaIce, +iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce, +iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce, +isnoheco,isnoheco,snow_heat_content,Snow total heat content,seaIce, +isnowpre,prsn,snowfall_flux,Surface Snowfall Rate into the Sea Ice Portion of the Grid Cell,seaIce, +isnowthi,snd,surface_snow_thickness,Snow Depth,seaIce, +isssalin,isssalin,sea_surface_salinity,Sea surface salinity,seaIce, +isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce, +msftmyz,zomsfglo,msftmyz,Meridional Mass Streamfunction,ocean, +msftmyza,zomsfatl,msftmyza,Meridional Mass Streamfunction in the Atlantic,ocean, +msftmyzba,zomsfeiv,ocean_meridional_overturning_mass_streamfunction_due_to_bolus_advection,Meridional Mass Streamfunction Due to Bolus Advection,ocean, +sltnortha,sltnortha,northward_ocean_salt_transport,Atlantic Northward Ocean Salt Transport,ocean, +so20chgt,t20d,depth_of_isosurface_of_sea_water_potential_temperature,,ocean, +sohefldo,hfds,surface_downward_heat_flux_in_sea_water,Downward Heat Flux at Sea Water Surface,ocean, +sohtatl,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,Atl +sohtind,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,Ind +sohtipc,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,IndPac +sohtpac,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,Pac +soicealb,ialb,sea_ice_albedo,Sea Ice Albedo,seaIce, +somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (Turbocline),ocean, +somxl010,mlotst,ocean_mixed_layer_thickness_defined_by_sigma_t,Ocean Mixed Layer Thickness Defined by Sigma T ,ocean, +sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward Ocean Heat Transport due to Advection ,ocean, +sophteiv,hfbasinba,northward_ocean_heat_transport_due_to_bolus_advection,Northward Ocean Heat Transport due to Bolus Advection ,ocean, +sophtldf,fhbasindif,northward_ocean_heat_transport_due_to_diffusion,Northward Ocean Heat Transport due to Diffusion,ocean, +sophtove,htovovrt,northward_ocean_heat_transport_due_to_overturning,Northward Ocean Heat Transport due to Overturning ,ocean, +sopstadv,sltbasinadv,northward_ocean_salt_transport_due_to_advection,Northward Ocean Salt Transport due to Advection ,ocean, +sopsteiv,sltbasinba,northward_ocean_salt_transport_due_to_bolus_advection,Northward Ocean Salt Transport due to Bolus Advection ,ocean, +sopstldf,sltbasindif,northward_ocean_salt_transport_due_to_diffusion,Northward Ocean Salt Transport due to Diffusion,ocean, +sopstove,sltovovrt,northward_ocean_salt_transport_due_to_overturning,Northward Ocean Salt Transport due to Overturning ,ocean, +sosaline,sos,sea_surface_salinity,Sea Surface Salinity ,ocean, +soshfldo,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net Downward Shortwave Radiation at Sea Water Surface ,ocean, +sossheigh,zos,sea_surface_height_above_geoid,Sea Surface Height Above Geoid ,ocean, +sosstsst,tos,sea_surface_temperature,Sea Surface Temperature ,ocean, +sostatl,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Atl +sostind,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Ind +sostipc,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,IndPac +sostpac,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Pac +sothedep,sothedep,thermocline_depth,Thermocline Depth (max dT/dz),ocean, +sozotaux,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,atmosphere, +sozotauy,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,atmosphere, +tos,sosstsst,sea_surface_temperature,Sea Surface Temperature,ocean, +vomecrty,vo,sea_water_y_velocity,Sea Water Y Velocity,ocean, +vosaline,so,sea_water_salinity,Sea Water Salinity,ocean, +votemper,thetao,sea_water_potential_temperature,Sea Water Potential Temperature,ocean, +vozocrtx,uo,sea_water_x_velocity,Sea Water X Velocity,ocean, +zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,Glob +zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction,Ocean Meridional Overturning Volume Streamfunction due to Bolus Advection ,ocean, +zomsfglo,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,Atl +zomsfind,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,Ind +zomsfipc,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,IndPac +zomsfpac,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,Pac +zosalatl,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,Atl +zosalglo,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,Glob +zosalind,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,Ind +zosalipc,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,IndPac +zosalpac,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,Pac +zosrfatl,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,Atl +zosrfglo,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,Glob +zosrfind,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,Ind +zosrfipc,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,IndPac +zosrfpac,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,Pac +zotematl,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Atl +zotemglo,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Glob +zotemind,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Ind +zotemipc,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,IndPac +zotempac,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Pac diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 5bca21d..05dace5 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,18 +1,25 @@ +# coding: latin-1 +import Queue import glob import shutil import threading import os import numpy as np +import netCDF4 from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day +from basins import Basins from earthdiagnostics.utils import Utils, TempFile +from datetime import datetime +import uuid +import csv class DataManager(object): def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name, num_chunks, - calendar='standard'): + scratch_dir, nfrp, calendar='standard'): """ :param institution: @@ -36,9 +43,11 @@ class DataManager(object): self.add_name = True self.num_chunks = num_chunks self.calendar = calendar + self.scratch_dir = scratch_dir + self.nfrp = nfrp # noinspection PyPep8Naming - def prepare_CMOR_files(self, startdates, members): + def prepare_CMOR_files(self, startdates, members, force_rebuild): """ Prepares the data to be used by the diagnostic. @@ -47,6 +56,8 @@ class DataManager(object): If CMOR data is available but packed, the procedure will unpack it. + :param force_rebuild: if True, forces the creation of the CMOR files + :type force_rebuild: bool :param startdates: list of startdates that will be used by the diagnostics :type startdates: list[str] :param members: lists of members that will be used by the diagnostics @@ -54,13 +65,31 @@ class DataManager(object): :return: """ # Check if cmorized and convert if not - if not os.path.exists(os.path.join(self.data_dir, self.expid)): - raise Exception('The experiment {0} is not CMORized. ' - 'Please, CMORize it and launch again.'.format(self.expid)) + if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles')): + list_jobs = Queue.Queue() + for startdate in startdates: + for member in members: + Log.info('Untaring member S{0} fc{1}', startdate, member) + for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, + 'fc{0}'.format(member), + 'outputs', 'MMO*')): + list_jobs.put((member, startdate, tarfile)) + # It's quicker to use just one for I/O reasons, at least at the moment + # numthreads = Utils.available_cpu_count() + numthreads = 1 + threads = list() + for numthread in range(0, numthreads): + t = threading.Thread(target=self._cmorize, args=(list_jobs, numthread)) + threads.append(t) + t.start() + + list_jobs.join() + return for startdate in startdates: for member in members: - member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc{0}'.format(member), 'outputs') + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, 'fc{0}'.format(member), + 'outputs') Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) filepaths = glob.glob(os.path.join(member_path, '*.gz')) @@ -68,53 +97,186 @@ class DataManager(object): if len(filepaths) == 0: continue - threads = list() - numthreads = Utils.available_cpu_count() - - for numthread in range(0, numthreads): - t = threading.Thread(target=DataManager._unzip, - args=([filepaths[numthread::numthreads]])) - threads.append(t) - t.start() - - for t in threads: - t.join() - - filepaths = glob.glob(os.path.join(member_path, '*.tar')) - for numthread in range(0, numthreads): - t = threading.Thread(target=DataManager._untar, - args=(filepaths[numthread::numthreads], member_path)) - threads.append(t) - t.start() - - for t in threads: - t.join() - - if self.experiment_name != self.model: - bad_path = os.path.join(member_path, 'output', self.institution, self.model, self.model) - for (dirpath, dirnames, filenames) in os.walk(bad_path, False): - for filename in filenames: - filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_output_'.format(self.model), - '_{0}_{1}_'.format(self.model, self.experiment_name)) - - good = good.replace('/{0}/{0}'.format(self.model), - '/{0}/{1}'.format(self.model, - self.experiment_name)) - - Utils.move_file(filepath, good) - os.rmdir(dirpath) - - good_dir = os.path.join(member_path, 'output', self.institution, self.model, self.experiment_name) - for sdate in os.listdir(good_dir): - for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): - for filename in filenames: - filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name, sdate), - '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) - if good != filepath: - Log.info('Moving {0} to {1}'.format(filename, good)) - Utils.move_file(filepath, good) + self._unpack_cmorfiles(filepaths, member_path) + + def _unpack_cmorfiles(self, filepaths, member_path): + threads = list() + numthreads = Utils.available_cpu_count() + for numthread in range(0, numthreads): + t = threading.Thread(target=DataManager._unzip, + args=([filepaths[numthread::numthreads]])) + threads.append(t) + t.start() + for t in threads: + t.join() + filepaths = glob.glob(os.path.join(member_path, '*.tar')) + for numthread in range(0, numthreads): + t = threading.Thread(target=DataManager._untar, + args=(filepaths[numthread::numthreads], member_path)) + threads.append(t) + t.start() + for t in threads: + t.join() + if self.experiment_name != self.model: + bad_path = os.path.join(member_path, 'output', self.institution, self.model, self.model) + for (dirpath, dirnames, filenames) in os.walk(bad_path, False): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_output_'.format(self.model), + '_{0}_{1}_'.format(self.model, self.experiment_name)) + + good = good.replace('/{0}/{0}'.format(self.model), + '/{0}/{1}'.format(self.model, + self.experiment_name)) + + Utils.move_file(filepath, good) + os.rmdir(dirpath) + good_dir = os.path.join(member_path, 'output', self.institution, self.model, self.experiment_name) + for sdate in os.listdir(good_dir): + for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name, sdate), + '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) + if good != filepath: + Log.info('Moving {0} to {1}'.format(filename, good)) + Utils.move_file(filepath, good) + + def _cmorize(self, queue, numthread): + scratch_dir = os.path.join(self.scratch_dir, str(numthread)) + if not os.path.exists(scratch_dir): + os.mkdir(scratch_dir) + while not queue.empty(): + try: + member, startdate, tarfile = queue.get(timeout=1) + self._unpack_tar(member, startdate, tarfile, numthread) + except Queue.Empty: + continue + os.rmdir(scratch_dir) + return + + def _unpack_tar(self, member, startdate, tarfile, numthread): + Log.info('Unpacking {0}', tarfile) + + scratch_dir = os.path.join(self.scratch_dir, str(numthread)) + self._untar((tarfile,), scratch_dir) + self._unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) + for filename in glob.glob(os.path.join(scratch_dir, '{0}*.nc'.format(self.expid))): + Log.info('Processing file {0}', filename) + file_parts = os.path.basename(filename).split('_') + frequency = file_parts[1][1] + + variables = dict() + variables['time_counter'] = 'time' + variables['time_counter_bnds'] = 'time_bnds' + variables['nav_lat'] = 'lat' + variables['nav_lon'] = 'lon' + variables['x'] = 'i' + variables['y'] = 'j' + Utils.rename_variables(filename, variables, False, True) + + handler = Utils.openCdf(filename) + + self._add_common_attributes(frequency, handler, member, startdate) + self._update_time_variables(handler, startdate) + + temp = TempFile.get() + Log.info('Splitting file {0}', filename) + for variable in handler.variables.keys(): + if variable in ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', + 'deptht', 'depthu', 'depthw', 'depthv'): + continue + self.extract_variable(file_parts, filename, frequency, handler, member, startdate, temp, + variable) + Log.result('File {0} cmorized!', filename) + handler.close() + os.remove(filename) + + def extract_variable(self, file_parts, filename, frequency, handler, member, startdate, temp, variable): + var_cmor = Variable.get_variable(variable) + Utils.nco.ncks(input=filename, output=temp, options='-v {0}'.format(variable)) + Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev'}, False, True) + handler_cmor = Utils.openCdf(temp) + Utils.copy_variable(handler, handler_cmor, 'lon', False) + Utils.copy_variable(handler, handler_cmor, 'lat', False) + if 'time' in handler_cmor.dimensions.keys(): + Utils.copy_variable(handler, handler_cmor, 'leadtime', False) + handler_cmor.modeling_realm = var_cmor.domain + handler_cmor.table_id = 'SPECS_' + self.domain_abbreviation(var_cmor.domain, frequency) + var_handler = handler_cmor.variables[variable] + var_handler.short_name = var_cmor.short_name + var_handler.standard_name = var_cmor.standard_name + var_handler.long_name = var_cmor.long_name + handler_cmor.close() + if frequency == 'd': + frequency = 'day' + elif frequency == 'm': + frequency = 'mon' + else: + raise Exception('Frequency {0} not supported'.format(frequency)) + + if var_cmor.basin is None: + region = None + else: + region = var_cmor.basin.fullname + + self.send_file(temp, var_cmor.domain, var_cmor.short_name, startdate, member, + frequency=frequency, rename_var=variable, + date_str='{0}-{1}'.format(file_parts[2][0:6], file_parts[3][0:6]), + region=region) + + @staticmethod + def _update_time_variables(handler, startdate): + time_var = handler.variables['time'] + times = netCDF4.num2date(time_var[:], time_var.units, time_var.calendar) + time_var[:] = netCDF4.date2num(times, 'days since 1850-01-01', 'standard') + time_bounds_var = handler.variables['time_bnds'] + time_bounds = netCDF4.num2date(time_bounds_var[:], time_var.units, time_var.calendar) + time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') + time_var.units = 'days since 1850-01-01' + time_var.calendar = 'standard' + time_var.bounds = "time_bnds" + time_var.long_name = "Verification time of the forecast" + time_var.standard_name = "time" + time_var.axis = "T" + if 'leadtime' in handler.variables: + var = handler.variables['leadtime'] + else: + var = handler.createVariable('leadtime', float, 'time') + var.units = "days" + var.long_name = "Time elapsed since the start of the forecast" + var.standard_name = "forecast_period" + leadtime = (netCDF4.num2date(time_var[:], time_var.units, time_var.calendar) - parse_date(startdate)) + for lt in range(0, leadtime.shape[0]): + var[lt] = leadtime[lt].days + + def _add_common_attributes(self, frequency, handler, member, startdate): + handler.associated_experiment = 'to be filled' + handler.batch = '{0}{1}'.format(self.institution, datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')) + handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ + 'Javier Vegas-Regidor, javier.vegas@bsc.es ' + handler.conventions = 'CF-1.6' + handler.creation_date = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ') + handler.experiment_id = self.experiment_name + handler.forecast_reference_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ') + if frequency == 'd': + handler.frequency = 'daily' + elif frequency == 'm': + handler.frequency = 'monthly' + handler.institute_id = self.institution + handler.institution = self.institution + handler.initialization_method = 'to be filled' + handler.initialization_description = 'to be filled' + handler.physics_version = 'to be filled' + handler.physics_description = 'to be filled' + handler.model_id = self.model + handler.associated_model = 'to be filled' + handler.project_id = 'SPECS' + handler.realization = member + handler.source = 'to be filled' + handler.startdate = 'S{0}'.format(startdate) + handler.tracking_id = str(uuid.uuid1()) + handler.title = "{0} model output prepared for SPECS {1}".format(self.model, self.experiment_name) @staticmethod def _unzip(files): @@ -127,7 +289,7 @@ class DataManager(object): for filepath in files: Log.debug('Unpacking {0}', filepath) Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) - os.remove(filepath) + # os.remove(filepath) def get_files(self, startdate, member, chunk, domain, variables, grid=None): """ @@ -150,16 +312,13 @@ class DataManager(object): file_names = list() - if domain == 'seaIce': - domain_abreviattion = 'OI' - else: - domain_abreviattion = domain[0].upper() + domain_abreviattion = self.domain_abbreviation(domain, self.frequency) start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', - self.institution, self.model, self.experiment_name, 'S' + startdate, self.frequency, - domain) + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, 'fc' + str(member), 'outputs', + 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, + self.frequency, domain) chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') @@ -173,7 +332,7 @@ class DataManager(object): var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) var_file.append(os.path.join(var_path, - '{0}_{1}{2}_{3}_{4}_S{5}_r{6}i1p1_' + '{0}_{1}_{3}_{4}_S{5}_r{6}i1p1_' '{7}-{8}.nc'.format(var, domain_abreviattion, self.frequency, self.model, self.experiment_name, startdate, member_plus, @@ -208,19 +367,17 @@ class DataManager(object): :return: path to the copy created on the scratch folder :rtype: str """ - if domain == 'seaIce': - domain_abreviattion = 'OI' - else: - domain_abreviattion = domain[0].upper() if not frequency: frequency = self.frequency + domain_abbreviation = self.domain_abbreviation(domain, frequency) + start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', - self.institution, self.model, self.experiment_name, 'S' + startdate, frequency, - domain) + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, 'fc' + str(member), 'outputs', + 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, + frequency, domain) chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') @@ -234,8 +391,8 @@ class DataManager(object): else: var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) - filepath = os.path.join(var_path, '{0}_{1}{2}_{3}_{4}_S{5}_r{6}i1p1_' - '{7}-{8}.nc'.format(var, domain_abreviattion, frequency, self.model, + filepath = os.path.join(var_path, '{0}_{1}_{3}_{4}_S{5}_r{6}i1p1_' + '{7}-{8}.nc'.format(var, domain_abbreviation, frequency, self.model, self.experiment_name, startdate, member_plus, "{0:04}{1:02}".format(chunk_start.year, chunk_start.month), @@ -247,11 +404,12 @@ class DataManager(object): return temp_path def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, - rename_var=None, frequency=None, year=None): + rename_var=None, frequency=None, year=None, date_str=None): """ Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge with already existing ones as needed + :param date_str: :param year: if frequency is yearly, this parameter is used to give the corresponding year :type year: int :param rename_var: if exists, the given variable will be renamed to the one given by var @@ -283,11 +441,6 @@ class DataManager(object): Utils.convert2netcdf4(filetosend) - if domain == 'seaIce': - domain_abreviattion = 'OI' - else: - domain_abreviattion = domain[0].upper() - if box: var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() @@ -296,12 +449,13 @@ class DataManager(object): if not frequency: frequency = self.frequency + domain_abreviattion = self.domain_abbreviation(domain, frequency) start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, startdate, 'fc' + str(member), 'outputs', 'output', - self.institution, self.model, self.experiment_name, 'S' + startdate, frequency, - domain) + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, 'fc' + str(member), 'outputs', + 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, + frequency, domain) if chunk is not None: chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') @@ -315,7 +469,8 @@ class DataManager(object): if frequency is not 'yr': raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') time_bound = str(year) - + elif date_str is not None: + time_bound = date_str else: raise ValueError('Chunk and year can not be None at the same time') @@ -324,8 +479,8 @@ class DataManager(object): else: var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) - filepath = os.path.join(var_path, '{0}_{1}{2}_{3}_{4}_S{5}_r{6}i1p1_' - '{7}.nc'.format(var, domain_abreviattion, frequency, self.model, + filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' + '{6}.nc'.format(var, domain_abreviattion, self.model, self.experiment_name, startdate, member_plus, time_bound)) if region: @@ -368,9 +523,34 @@ class DataManager(object): handler_send.close() Utils.move_file(temp, filetosend) Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') - Utils.move_file(filetosend, filepath) + if frequency in ('d', 'daily', 'day'): + freq_str = 'daily_mean' + else: + freq_str = 'monthly_mean' + + if domain in ['ocean', 'seaIce']: + link_path = os.path.join(self.data_dir, self.expid, freq_str, '{0}_f6h'.format(var)) + else: + link_path = os.path.join(self.data_dir, self.expid, freq_str, '{0}_f{1}h'.format(var, self.nfrp)) + + if not os.path.exists(os.path.dirname(link_path)): + os.makedirs(os.path.dirname(link_path)) + if not os.path.exists(link_path): + os.symlink(var_path, link_path) + + @staticmethod + def domain_abbreviation(domain, frequency): + if frequency == 'mon': + if domain == 'seaIce': + domain_abreviattion = 'OImon' + else: + domain_abreviattion = domain[0].upper() + 'mon' + else: + domain_abreviattion = 'day' + return domain_abreviattion + def get_year(self, domain, var, startdate, member, year, grid=None, box=None): """ Gets all the data corresponfing to a given year from the CMOR repository to the scratch folder as one file and @@ -468,3 +648,33 @@ class DataManager(object): years.append(first_year) first_year += 1 return years + + +class Variable(object): + def __init__(self, line): + self.short_name = line[1] + self.standard_name = line[2] + self.long_name = line[3] + self.domain = line[4] + self.basin = Basins.parse(line[5]) + + @classmethod + def get_variable(cls, original_name): + try: + return Variable._dict_variables[original_name] + + except AttributeError: + Variable._dict_variables = dict() + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'cmor_table.csv'), 'rb') as csvfile: + reader = csv.reader(csvfile, dialect='excel') + for line in reader: + if line[0] == 'variable': + continue + var = Variable(line) + Variable._dict_variables[line[0]] = var + return Variable.get_variable(original_name) + + except KeyError: + Log.error('Variable {0} is not defined'.format(original_name)) + return None + diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 6f67491..d570a56 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ # Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/jvegas # Root path for the cmorized data to use -DATA_DIR = /esnas/exp/ecearth/cmorfiles +DATA_DIR = /esnas/exp/ecearth/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run @@ -29,7 +29,7 @@ EXPID = a034 STARTDATES = 19500201 MEMBERS = 0 CHUNK_SIZE = 3 -CHUNKS = 1 +CHUNKS = 256 # Model version NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 18187b0..c0a7cd8 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -32,6 +32,7 @@ class Diags: self._read_config(config_file) self.data_manager = DataManager(self.institute, self.model, self.expid, self.data_dir, self.frequency, self.chunk_size, self.experiment_name, self.chunks, + self.scratch_dir, self.nfrp, self.calendar) self.data_manager.add_startdate = self.add_startdate self.data_manager.add_name = self.add_name @@ -80,7 +81,7 @@ class Diags: parse_date('20000101') - self.data_manager.prepare_CMOR_files(self.startdates, self.members) + self.data_manager.prepare_CMOR_files(self.startdates, self.members, self.force_CMOR) # Run diagnostics Log.info('Running diagnostics') @@ -262,6 +263,7 @@ class Diags: self.frequency = self.parser.get_option('DIAGNOSTICS', 'FREQUENCY') self.cdftools_path = self.parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') self.max_cores = self.parser.get_int_option('DIAGNOSTICS', 'MAX_CORES', 100000) + self.force_CMOR = self.parser.get_bool_option('DIAGNOSTICS', 'FORCE_CMOR', False) # Read experiment config self.institute = self.parser.get_option('EXPERIMENT', 'INSTITUTE') @@ -277,6 +279,7 @@ class Diags: self.chunks = self.parser.get_int_option('EXPERIMENT', 'CHUNKS') self.calendar = self.parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') self.model = self.parser.get_option('EXPERIMENT', 'MODEL') + self.nfrp = self.parser.get_int_option('EXPERIMENT', 'NFRP') self.nemo_version = self.parser.get_option('EXPERIMENT', 'NEMO_VERSION') self.add_name = self.parser.get_bool_option('CMOR', 'ADD_NAME') diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 407755b..487d9dc 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -81,7 +81,7 @@ class Siasiesiv(Diagnostic): sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) sit_handler = Utils.openCdf(sit_file) sic_handler = Utils.openCdf(sic_file) - results = list() + results = np.zeros() for t in range(0, sit_handler.dimensions['time'].size): try: sit = sit_handler.variables['sit'][t, :] @@ -93,38 +93,36 @@ class Siasiesiv(Diagnostic): sit_handler.close() sic_handler.close() - self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'SVolume', 'sivols', + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'sivols', "10^3 km3"), 'seaIce', 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'SArea', 'siareas', + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'siareas', "10^6 km2"), 'seaIce', 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'SExnsidc', 'siextents', + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'siextents', "10^6 km2"), 'seaIce', 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'NVolume', 'sivoln', + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'sivoln', "10^3 km3"), 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'NArea', 'siarean', "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'siarean', "10^6 km2"), 'seaIce', 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(temp, sit_file, 'NExnsidc', 'siextentn', + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'siextentn', "10^6 km2"), 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) os.remove(temp) - def _extract_variable_and_rename(self, input_file, reference_file, variable, cmor_name, output_units): + def _extract_variable_and_rename(self, reference_file, values, cmor_name, output_units): temp = TempFile.get() - input_handler = Utils.openCdf(input_file) reference_handler = Utils.openCdf(reference_file) - os.remove(temp) handler = netCDF4.Dataset(temp, 'w') @@ -138,22 +136,9 @@ class Siasiesiv(Diagnostic): Utils.copy_variable(reference_handler, handler, 'time_bnds') Utils.copy_variable(reference_handler, handler, 'leadtime') reference_handler.close() - # time_var = input_handler.variables['time'] - # new_time = handler.createVariable('time', time_var.datatype, time_var.dimensions) - # new_time.setncatts({k: time_var.getncattr(k) for k in time_var.ncattrs()}) - # new_time[:] = time_var[:] - # - # original_bnds = input_handler.variables['time_bnds'] - # new_bnds = handler.createVariable('time_bnds', original_bnds.datatype, original_bnds.dimensions) - # new_bnds.setncatts({k: original_bnds.getncattr(k) for k in original_bnds.ncattrs()}) - # new_bnds[:] = original_bnds[:] - - original_variable = input_handler.variables[variable] - values = original_variable[:, 0, 0] - - new_var = handler.createVariable(cmor_name, original_variable.datatype, 'time', fill_value=0.0) - new_var.setncatts({k: original_variable.getncattr(k) for k in original_variable.ncattrs()}) - factor = self._get_conversion_factor(original_variable.units, output_units) + + new_var = handler.createVariable(cmor_name, float, 'time', fill_value=0.0) + factor = self._get_conversion_factor('10^9 m3', output_units) values *= factor new_var[:] = values new_var.units = output_units diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 9764934..8358ca7 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -192,7 +192,11 @@ class Utils(object): return netCDF4.num2date(nctime, units=units, calendar=cal_temps) @staticmethod - def copy_variable(source, destiny, variable): + def copy_variable(source, destiny, variable, must_exist=True): + if not must_exist and variable not in source.variables.keys(): + return + if variable in destiny.variables.keys(): + return original_var = source.variables[variable] new_var = destiny.createVariable(variable, original_var.datatype, original_var.dimensions) new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) -- GitLab From 140479a5b18f27ebc72b828521988d22e6421277 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 22 Jun 2016 16:26:18 +0200 Subject: [PATCH 098/268] Finished migration of siasiesiv to f2py --- earthdiagnostics/ocean/siasiesiv.py | 94 ++++++++++++++++------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 487d9dc..d7fcf22 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -1,6 +1,5 @@ import netCDF4 import os -from earthdiagnostics import cdftools from earthdiagnostics.basins import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile @@ -22,7 +21,11 @@ class Siasiesiv(Diagnostic): :last modified: June 2016 """ - def __init__(self, data_manager, basin, startdate, member, chunk): + e1t = None + e2t = None + gphit = None + + def __init__(self, data_manager, basin, startdate, member, chunk, mask): Diagnostic.__init__(self, data_manager) self.basin = basin if basin == Basins.Global: @@ -32,6 +35,7 @@ class Siasiesiv(Diagnostic): self.startdate = startdate self.member = member self.chunk = chunk + self.mask = mask self.required_vars = ['sit', 'sic'] self.generated_vars = ['siextents', 'sivols', 'siareas', 'siextentn', 'sivoln', 'siarean'] @@ -53,74 +57,78 @@ class Siasiesiv(Diagnostic): if len(options) != 2: raise Exception('You must specify the basin for the siasiesiv diagnostic (and nothing else)') basin = Basins.parse(options[1]) + + if basin != Basins.Global: + mask_handler = Utils.openCdf('mask_regions.nc') + mask = mask_handler.variables[basin.fullname][:, 0, :] + mask_handler.close() + else: + mask_handler = Utils.openCdf('mask.nc') + mask = np.asfortranarray(mask_handler.variables['tmask'][0, 0, :]) + mask_handler.close() + job_list = list() for startdate in diags.startdates: for member in diags.members: for chunk in range(1, diags.chunks + 1): - job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk)) + job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk, mask)) + mesh_handler = Utils.openCdf('mesh_hgr.nc') + Siasiesiv.e1t = np.asfortranarray(mesh_handler.variables['e1t'][0, :]) + Siasiesiv.e2t = np.asfortranarray(mesh_handler.variables['e2t'][0, :]) + Siasiesiv.gphit = np.asfortranarray(mesh_handler.variables['gphit'][0, :]) + mesh_handler.close() + return job_list def compute(self): - nco = Utils.nco - - mesh_handler = Utils.openCdf('mesh_hgr.nc') - e1t = mesh_handler.variables['e1t'][0, :] - e2t = mesh_handler.variables['e2t'][0, :] - gphit = mesh_handler.variables['gphit'][0, :] - mesh_handler.close() - if self.basin != Basins.Global: - mask_handler = Utils.openCdf('mask_regions.nc') - mask = mask_handler.variables[self.basin.fullname][:, 0, :] - mask_handler.close() - else: - mask_handler = Utils.openCdf('mask.nc') - mask = mask_handler.variables['tmask'][0, 0, :] - mask_handler.close() sit_file = self.data_manager.get_file('seaIce', 'sit', self.startdate, self.member, self.chunk) - sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) sit_handler = Utils.openCdf(sit_file) + sit = np.asfortranarray(sit_handler.variables['sit'][:]) + timesteps = sit_handler.dimensions['time'].size + sit_handler.close() + + sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) sic_handler = Utils.openCdf(sic_file) - results = np.zeros() - for t in range(0, sit_handler.dimensions['time'].size): + sic = np.asfortranarray(sic_handler.variables['sic'][:]) + sic_handler.close() + + result = np.empty((8, timesteps)) + for t in range(0, timesteps): try: - sit = sit_handler.variables['sit'][t, :] - sic = sic_handler.variables['sic'][t, :] - results.append(cdftoolspython.icediag.icediags(e1t, e2t, mask, gphit, sit, sic)) + + result[:, t] = cdftoolspython.icediag.icediags(Siasiesiv.e1t, Siasiesiv.e2t, self.mask, + Siasiesiv.gphit, sit[t, :], sic[t, :]) except Exception as ex: print ex - sit_handler.close() - sic_handler.close() - - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'sivols', - "10^3 km3"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[4, :], 'sivols', + "10^3 km3", "10^9 m3"), 'seaIce', 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'siareas', - "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[5, :], 'siareas', + "10^6 km2", "10^9 m2"), 'seaIce', 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'siextents', - "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[7, :], 'siextents', + "10^6 km2", "10^9 m2"), 'seaIce', 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'sivoln', - "10^3 km3"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[0, :], 'sivoln', + "10^3 km3", "10^9 m3"), 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'siarean', "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[1, :], 'siarean', + "10^6 km2", "10^9 m2"), 'seaIce', 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, results[0], 'siextentn', - "10^6 km2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[3, :], 'siextentn', + "10^6 km2", "10^9 m2"), 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) - os.remove(temp) - - def _extract_variable_and_rename(self, reference_file, values, cmor_name, output_units): + def _extract_variable_and_rename(self, reference_file, values, cmor_name, output_units, target_units): temp = TempFile.get() reference_handler = Utils.openCdf(reference_file) os.remove(temp) @@ -138,7 +146,7 @@ class Siasiesiv(Diagnostic): reference_handler.close() new_var = handler.createVariable(cmor_name, float, 'time', fill_value=0.0) - factor = self._get_conversion_factor('10^9 m3', output_units) + factor = self._get_conversion_factor(target_units, output_units) values *= factor new_var[:] = values new_var.units = output_units @@ -180,7 +188,7 @@ class Siasiesiv(Diagnostic): invert = True if factor is None: - raise Exception("Conversion from {0} to {1} not supported".format(units, output_units)) + raise Exception("Conversion from {0} to {1} not supported".format(input_units, output_units)) if invert: factor = scale_unit / float(scale_new_unit * factor) -- GitLab From 84257c7733ea2ad629f8e8dbf4de41f8c09fd58e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 22 Jun 2016 16:50:49 +0200 Subject: [PATCH 099/268] Fixed bug on ocean cmorization --- earthdiagnostics/datamanager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 05dace5..e81adfc 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -169,6 +169,7 @@ class DataManager(object): variables = dict() variables['time_counter'] = 'time' variables['time_counter_bnds'] = 'time_bnds' + variables['tbnds'] = 'bnds' variables['nav_lat'] = 'lat' variables['nav_lon'] = 'lon' variables['x'] = 'i' -- GitLab From fab216b53492046f2ecd7e9284153a37f32793e2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 27 Jun 2016 14:29:11 +0200 Subject: [PATCH 100/268] Completing CMORization to be able to handle more experiments --- earthdiagnostics/cmor_table.csv | 127 +++++++++++++++++++++++++++----- earthdiagnostics/datamanager.py | 109 ++++++++++++++++++++------- earthdiagnostics/diags.conf | 27 +++++-- earthdiagnostics/diags.py | 27 +++++-- earthdiagnostics/models.py | 2 + earthdiagnostics/utils.py | 5 +- 6 files changed, 234 insertions(+), 63 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index da6928b..f224c16 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -2,40 +2,36 @@ Variable,Shortname,Name,Long name,Domain,Basin hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic Northward Ocean Heat Transport,ocean, ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce, iice_etd,iice_etd,brine_volume_distribution,Brine volume distribution,seaIce, -iice_hid,iice_hid,ice_thicknesss_in_categories,Ice thickness in categories,seaIce, -iice_hsd,iice_hsd,snow_depth_in_categories,Snow depth in in categories,seaIce, -iice_itd,iice_itd,ice_area_in_categories,Ice area in categories,seaIce, -iice_otd,ageice,age_of_sea_ice,Age of Sea Ice,seaIce, -iice_std,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce, -iiceages,ageice,age_of_sea_ice,Age of Sea Ice,seaIce, +iice_hid:sithic_cat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce, +iice_hsd,sndcat,snow_depth_in_categories,Snow depth in in categories,seaIce, +iice_itd:siconc_cat,siccat,ice_area_in_categories,Ice area in categories,seaIce, +iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of Sea Ice,seaIce, iicebome,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of Melt at Sea Ice Base,seaIce, iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce, iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thickness,seaIce, -iiceconc,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce, -iicedive,divice,Strain Rate Divergence of Sea Ice,divergence_of_sea_ice_velocity,seaIce, +Iiceconc:siconc:soicecov:ileadfra,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce, +iicedive:sidive,divice,Strain Rate Divergence of Sea Ice,divergence_of_sea_ice_velocity,seaIce, iicedypr,iicedypr,daily_dynamic_ice_production,Daily dynamic ice production,seaIce, iiceheco,hcice,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea Ice Heat Content,seaIce, iicelapr,iicelapr,daily_lateral_thermo_ice_production,Daily lateral thermo ice prod.,seaIce, iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce, -iicesali,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce, +iicesali:iice_std,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce, iicesflx,iicesflx,solar_flux_ice_ocean_surface,Solar flux at ice/ocean surface,seaIce, iiceshea,iiceshea,shear,Shear,seaIce, iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce, iicestre,streng,compressive_strength_of_sea_ice,Compressive Sea Ice Strength,seaIce, iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of Melt at Upper Surface of Sea Ice,seaIce, -iicesurt,tsice,surface_temperature,Surface Temperature of Sea Ice,seaIce, -iicetemp,iicetemp,ice_temperature,Mean ice temperature,seaIce, +iicesurt:soicetem,tsice,surface_temperature,Surface Temperature of Sea Ice,seaIce, +iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce, iicethic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce, -iicevelo,iicevelo,ice_velocity,Ice velocity,seaIce, -iicevelu,iicevelu,ice_velocity_u,Ice velocity u,seaIce, -iicevelv,iicevelv,ice_velocity_v,Ice velocity v,seaIce, +iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce, +iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce, +iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce, iicfsbri,iicfsbri,brine_salt_flux,Fsbri - brine salt flux,seaIce, iicfseqv,iicfseqv,equivalent_FW_salt_flux,Fseqv - equivalent FW salt flux,seaIce, ioceflxb,ioceflxb,oceanic_flux_ar_ice_base,Oceanic flux at the ice base,seaIce, iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release,seaIce, iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce, -iocestru,iocestru,wind_stress_u,Wind stress u,seaIce, -iocestrv,iocestrv,wind_stress_v,Wind stress v,seaIce, iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce, iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce, isnoheco,isnoheco,snow_heat_content,Snow total heat content,seaIce, @@ -55,7 +51,7 @@ sohtipc,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,oc sohtpac,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,Pac soicealb,ialb,sea_ice_albedo,Sea Ice Albedo,seaIce, somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (Turbocline),ocean, -somxl010,mlotst,ocean_mixed_layer_thickness_defined_by_sigma_t,Ocean Mixed Layer Thickness Defined by Sigma T ,ocean, +somxl010:mldr10_1,mlotst,ocean_mixed_layer_thickness_defined_by_sigma_t,Ocean Mixed Layer Thickness Defined by Sigma T ,ocean, sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward Ocean Heat Transport due to Advection ,ocean, sophteiv,hfbasinba,northward_ocean_heat_transport_due_to_bolus_advection,Northward Ocean Heat Transport due to Bolus Advection ,ocean, sophtldf,fhbasindif,northward_ocean_heat_transport_due_to_diffusion,Northward Ocean Heat Transport due to Diffusion,ocean, @@ -66,15 +62,15 @@ sopstldf,sltbasindif,northward_ocean_salt_transport_due_to_diffusion,Northward O sopstove,sltovovrt,northward_ocean_salt_transport_due_to_overturning,Northward Ocean Salt Transport due to Overturning ,ocean, sosaline,sos,sea_surface_salinity,Sea Surface Salinity ,ocean, soshfldo,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net Downward Shortwave Radiation at Sea Water Surface ,ocean, -sossheigh,zos,sea_surface_height_above_geoid,Sea Surface Height Above Geoid ,ocean, +sossheigh:sossheig,zos,sea_surface_height_above_geoid,Sea Surface Height Above Geoid ,ocean, sosstsst,tos,sea_surface_temperature,Sea Surface Temperature ,ocean, sostatl,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Atl sostind,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Ind sostipc,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,IndPac sostpac,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Pac sothedep,sothedep,thermocline_depth,Thermocline Depth (max dT/dz),ocean, -sozotaux,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,atmosphere, -sozotauy,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,atmosphere, +sozotaux,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,ocean, +sozotauy:sometauy,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,ocean, tos,sosstsst,sea_surface_temperature,Sea Surface Temperature,ocean, vomecrty,vo,sea_water_y_velocity,Sea Water Y Velocity,ocean, vosaline,so,sea_water_salinity,Sea Water Salinity,ocean, @@ -101,3 +97,94 @@ zotemglo,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Glob zotemind,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Ind zotemipc,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,IndPac zotempac,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Pac +tossq,tossq,square_of_sea_surface_temperature,Square of Sea Surface Temperature ,ocean, +zossq,zossq,square_of_sea_surface_height_above_geoid,Square of Sea Surface Height Above Geoid ,ocean, +mldkz5,mldkz5,ocean_mixed_layer_thickness_defined_by_vertical_tracer_diffusivity,Turbocline depth (Kz = 5e-4),ocean, +heatc,heatc,integral_of_sea_water_potential_temperature_wrt_depth_expressed_as_heat_content,Heat content vertically integrated,ocean, +saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrated,ocean, +qt_oce,hfds,surface_downward_heat_flux_in_sea_water,Downward Heat Flux at Sea Water Surface,ocean, +sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea Ice Volume per gridcell area unit,seaIce, +snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow Volume per gridcell area unit,seaIce, +utau_ice:iocestru,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,seaIce, +vtau_ice:iocestrv,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,seaIce, +scvoltot,volo,sea_water_volume,Sea Water Volume ,ocean, +scsshtot,zosga,global_average_sea_level_change,Global Average Sea Level Change ,ocean, +scsshste,zossga,global_average_steric_sea_level_change,Global Average Steric Sea Level Change ,ocean, +scsshtst,zostoga,global_average_thermosteric_sea_level_change,Global Average Thermosteric Sea Level Change ,ocean, +scmastot,masso,sea_water_mass,Sea Water Mass ,ocean, +sctemtot,thetaoga,sea_water_potential_temperature,Global Average Sea Water Potential Temperature ,ocean, +scsaltot,soga,sea_water_salinity,Global Mean Sea Water Salinity ,ocean, +bgtemper,bgtemper,change_over_time_in_sea_water_potential_temperature,Change Over Time in Sea Water Potential Temperature,ocean, +bgsaline,bgsaline,change_over_time_in_sea_water_practical_salinity,Change Over Time in Sea Water Salinity,ocean, +bgheatco,bgheatco,change_over_time_in_heat_content,Change Over Time in Sea Water Heat Content,ocean, +bgsaltco,bgsaltco,change_over_time_in_salt_content,Change Over Time in Sea Water Salt Content,ocean, +bgvolssh,bgvolssh,change_over_time_in_sea_surface_height,Change Over Time in Sea Surface Height,ocean, +bgvole3t,bgvole3t,change_over_time_in_volume_variation,Change Over Time in Volume Variation (e3t),ocean, +bgfrcvol,bgfrcvol,change_over_time_in_volume_from_forcing,Change Over Time In Volume From Forcing,ocean, +bgfrctem,bgfrctem,change_over_time_in_heat_content_from_forcing,Change Over Time In Heat Content from forcing,ocean, +bgfrcsal,bgfrcsal,change_over_time_in_heat_content_from_forcing,Change Over Time In Salt Content from forcing,ocean, +ibgvoltot,sivolga,sea_ice_volume,Global Mean Sea Ice Volume,seaIce, +sbgvoltot,snvolga,snow_volume,Global Mean Snow Volume,seaIce, +ibgarea,sicga,sea_ice_content,Global Mean Sea Ice Content,seaIce, +ibgsaline,ssiga,sea_ice_salinity,Global Mean Sea Ice Salinity ,seaIce, +ibgtemper,sitempga,sea_ice_temperature,Global Mean Sea Ice Temperature,seaIce, +ibgheatco,hcicega,global mean ice heat content,global mean ice heat content,seaIce, +sbgheatco,hcsnga,global mean snow heat content,global mean snow heat content,seaIce, +ibgsaltco,sisaltcga,global mean ice salt content,global mean ice salt content,seaIce, +ibgvfx,ibgvfxga,volume_flux_emp,global mean volume flux (emp),seaIce, +ibgvfxbog,ibgvfxbogga,volume_flux_bottom_growth,global mean volume flux (bottom growth),seaIce, +ibgvfxopw,ibgvfxopwga,volume_flux_open_water_growth,global mean volume flux (open water growth),seaIce, +ibgvfxsni,ibgvfxsniga,volume_flux_snow_ice_growth,global mean volume flux (snow-ice growth),seaIce, +ibgvfxdyn,ibgvfxdynga,volume_flux_dynamic_growth,global mean volume flux (dynamic growth),seaIce, +ibgvfxbom,ibgvfxbomga,volume_flux_bottom_melt,global mean volume flux (bottom melt),seaIce, +ibgvfxsum,ibgvfxsumga,volume_flux_surface_melt,global mean volume flux (surface melt),seaIce, +ibgvfxres,ibgvfxresga,volume_flux_resultant,global mean volume flux (resultant),seaIce, +ibgvfxspr,ibgvfxsprga,volume_flux_snow_precip,global mean volume flux (snow precip),seaIce, +ibgvfxsnw,ibgvfxsnwga,volume_flux_snow_melt,global mean volume flux (snow melt),seaIce, +ibgvfxsub,ibgvfxsubga,volume_flux_snow_sublimation,global mean volume flux (snow sublimation),seaIce, +ibgsfx,ibgsfxga,salt_flux,global mean salt flux (total),seaIce, +ibgsfxbri,ibgsfxbriga,salt_flux_brines,global mean salt flux (brines),seaIce, +ibgsfxdyn,ibgsfxdynga,salt_flux_dynamic,global mean salt flux (dynamic),seaIce, +ibgsfxres,ibgsfxresga,salt_flux_resultant,global mean salt flux (resultant),seaIce, +ibgsfxbog,ibgsfxbogga,salt_flux_thermo,global mean salt flux (thermo),seaIce, +ibgsfxopw,ibgsfxopwga,salt_flux_open_waters,global mean salt flux (open water),seaIce, +ibgsfxsni,ibgsfxsniga,salt_flux_snow_ice_growth,global mean salt flux (snow-ice growth),seaIce, +ibgsfxbom,ibgsfxbomga,salt_flux_bottom_melt,global mean salt flux (bottom melt),seaIce, +ibgsfxsum,ibgsfxsumga,salt_flux_surface_melt,global mean salt flux (surface melt),seaIce, +ibghfxdhc,ibghfxdhc,Heat_content_variation_in_snow_and_ice,Heat content variation in snow and ice,seaIce, +ibghfxspr,ibghfxspr,Heat_content_of_snow_precip,Heat content of snow precip,seaIce, +ibghfxres,ibghfxres,heat_fluxes_from_ice-ocean_exchange_during_resultant,heat fluxes from ice-ocean exchange during resultant,seaIce, +ibghfxsub,ibghfxsub,heat_fluxes_from_sublimation,heat fluxes from sublimation,seaIce, +ibghfxdyn,ibghfxdyn,heat_fluxes_from_ice-ocean_exchange_during_dynamic,heat fluxes from ice-ocean exchange during dynamic,seaIce, +ibghfxthd,ibghfxthd,heat_fluxes_from_ice-ocean_exchange_during_thermo,heat fluxes from ice-ocean exchange during thermo,seaIce, +ibghfxsum,ibghfxsum,heat_fluxes_causing_surface_ice_melt,heat fluxes causing surface ice melt,seaIce, +ibghfxbom,ibghfxbom,heat_fluxes_causing_bottom_ice_melt,heat fluxes causing bottom ice melt,seaIce, +ibghfxbog,ibghfxbog,heat_fluxes_causing_bottom_ice_growth,heat fluxes causing bottom ice growth,seaIce, +ibghfxdif,ibghfxdif,heat_fluxes_causing_ice temperature_change,heat fluxes causing ice temperature change,seaIce, +ibghfxopw,ibghfxopw,heat_fluxes_causing_open_water_ice_formation,heat fluxes causing open water ice formation,seaIce, +ibghfxout,ibghfxout,non_solar_heat_fluxes_received_by_the_ocean,non solar heat fluxes received by the ocean,seaIce, +ibghfxin,ibghfxin,total_heat_fluxes_at_the_ice_surface,total heat fluxes at the ice surface,seaIce, +ibghfxsnw,ibghfxsnw,heat_fluxes_from_snow-ocean_exchange,heat fluxes from snow-ocean exchange,seaIce, +ibgfrcvol,ibgfrcvol,globa_mean_forcing_volume,global mean forcing volume (emp),seaIce, +ibgfrcsfx,ibgfrcsfx,global_mean_forcing_salt,global mean forcing salt (sfx),seaIce, +ibgvolgrm,ibgvolgrm,global_mean_ice_growth+melt_volume,global mean ice growth+melt volume,seaIce, +vozoeivu,voeivu,sea_water_x_EIV_current,Zonal EIV Current,ocean, +vomeeivv,voeivv,sea_water_y_EIV_current,Meridional EIV Current,ocean, +iowaflup,ficeocean,ice_ocean_water_flux,Ice=>ocean net freshwater,ocean, +sowaflep,fatmosocean,atmosphere_ocean_water_flux,atmos=>ocean net freshwater,ocean, +sowaflup,fupward,upward_water_flux,Net Upward Water Flux,ocean, +sorunoff,friver,water_flux_into_sea_water_from_rivers,Water Flux into Sea Water From Rivers ,ocean, +sowaflcd,fdilution,dilution_water_flux,concentration/dilution water flux,ocean, +sosalflx,sfs,salt_flux_surface,Surface Salt Flux,ocean, +sobowlin,bowlin,bowl_index,Bowl Index,ocean, +iiceprod,sigr,ice_production,Ice Production,seaIce, +iocesafl,iocesafl,salt_flux_ocean_surface,Salt Flux at Ocean Surface,seaIce, +vovecrtz,zo,sea_water_z_velocity,Sea Water Z Velocity,ocean, +voveeivw,voeivz,sea_water_z_EIV_current,Vertical EIV Current,ocean, +votkeavt,votkeavt,vertical_eddy_diffusivity,Vertical Eddy Diffusivity,ocean, +votkeevd,votkeevd,enhanced_vertical_diffusivity,Enhanced Vertical Diffusivity,ocean, +votkeavm,votkeavm,vertical_eddy_viscosity,Vertical Eddy Viscosity,ocean, +votkeevm,votkeevm,enhanced_vertical_viscosity,Enhanced Vertical Viscosity,ocean, +voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt Vertical Eddy Diffusivity,ocean, +soleahtw,soleahtw,lateral_eddy_diffusivity,lateral eddy diffusivity,ocean, +soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,eddy induced vel. coeff. at w-point,ocean, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index e81adfc..0b493dd 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -2,12 +2,12 @@ import Queue import glob import shutil -import threading import os import numpy as np import netCDF4 +import threading from autosubmit.config.log import Log -from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day +from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day, date2str from basins import Basins from earthdiagnostics.utils import Utils, TempFile @@ -19,7 +19,7 @@ import csv class DataManager(object): def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name, num_chunks, - scratch_dir, nfrp, calendar='standard'): + scratch_dir, nfrp, member_digits, calendar='standard'): """ :param institution: @@ -32,6 +32,13 @@ class DataManager(object): :param num_chunks: :param calendar: """ + self.initialization_method = 'to be filled' + self.initialization_description = 'to be filled' + self.physics_version = 'to be filled' + self.physics_description = 'to be filled' + self.associated_model = 'to be filled' + self.source = 'to be filled' + self.associated_experiment = 'to be filled' self.institution = institution self.model = model self.expid = expid @@ -45,6 +52,7 @@ class DataManager(object): self.calendar = calendar self.scratch_dir = scratch_dir self.nfrp = nfrp + self.member_digits = member_digits # noinspection PyPep8Naming def prepare_CMOR_files(self, startdates, members, force_rebuild): @@ -67,11 +75,12 @@ class DataManager(object): # Check if cmorized and convert if not if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles')): list_jobs = Queue.Queue() + for startdate in startdates: for member in members: - Log.info('Untaring member S{0} fc{1}', startdate, member) + Log.info('Untaring member S{0} {1}', startdate, self.get_member_str(member)) for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, - 'fc{0}'.format(member), + self.get_member_str(member), 'outputs', 'MMO*')): list_jobs.put((member, startdate, tarfile)) # It's quicker to use just one for I/O reasons, at least at the moment @@ -88,7 +97,7 @@ class DataManager(object): for startdate in startdates: for member in members: - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, 'fc{0}'.format(member), + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), 'outputs') Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) @@ -161,15 +170,17 @@ class DataManager(object): scratch_dir = os.path.join(self.scratch_dir, str(numthread)) self._untar((tarfile,), scratch_dir) self._unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) - for filename in glob.glob(os.path.join(scratch_dir, '{0}*.nc'.format(self.expid))): + for filename in glob.glob(os.path.join(scratch_dir, '*.nc'.format(self.expid))): Log.info('Processing file {0}', filename) file_parts = os.path.basename(filename).split('_') - frequency = file_parts[1][1] + frequency = file_parts[1][1].lower() variables = dict() variables['time_counter'] = 'time' variables['time_counter_bnds'] = 'time_bnds' + # variables['time_counter_bounds'] = 'time_bnds' variables['tbnds'] = 'bnds' + # variables['axis_nbounds'] = 'bnds' variables['nav_lat'] = 'lat' variables['nav_lon'] = 'lon' variables['x'] = 'i' @@ -180,12 +191,15 @@ class DataManager(object): self._add_common_attributes(frequency, handler, member, startdate) self._update_time_variables(handler, startdate) + handler.sync() temp = TempFile.get() Log.info('Splitting file {0}', filename) for variable in handler.variables.keys(): if variable in ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', - 'deptht', 'depthu', 'depthw', 'depthv'): + 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', + 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', + 'time_counter_bounds', 'ncatice'): continue self.extract_variable(file_parts, filename, frequency, handler, member, startdate, temp, variable) @@ -195,6 +209,8 @@ class DataManager(object): def extract_variable(self, file_parts, filename, frequency, handler, member, startdate, temp, variable): var_cmor = Variable.get_variable(variable) + if var_cmor is None: + return Utils.nco.ncks(input=filename, output=temp, options='-v {0}'.format(variable)) Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev'}, False, True) handler_cmor = Utils.openCdf(temp) @@ -230,13 +246,29 @@ class DataManager(object): def _update_time_variables(handler, startdate): time_var = handler.variables['time'] times = netCDF4.num2date(time_var[:], time_var.units, time_var.calendar) + if type(times[0]) is not datetime: + for x in range(0, times.shape[0]): + times[x] = times[x]._to_real_datetime() time_var[:] = netCDF4.date2num(times, 'days since 1850-01-01', 'standard') - time_bounds_var = handler.variables['time_bnds'] - time_bounds = netCDF4.num2date(time_bounds_var[:], time_var.units, time_var.calendar) - time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') + if 'axis_nbounds' in handler.dimensions: + handler.renameDimension('axis_nbounds', 'nbnds') + + if 'time_counter_bounds' in handler.variables: + handler.renameVariable('time_counter_bounds', 'time_bnds') + handler.sync() + if 'time_bnds' in handler.variables: + time_bounds_var = handler.variables['time_bnds'] + time_var.bounds = "time_bnds" + + time_bounds = netCDF4.num2date(time_bounds_var[:], time_var.units, time_var.calendar) + if type(time_bounds[0,0]) is not datetime: + for x in range(0, time_bounds.shape[0]): + for y in range(0, time_bounds.shape[1]): + time_bounds[x, y] = time_bounds[x, y]._to_real_datetime() + time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') time_var.units = 'days since 1850-01-01' + time_var.time_origin = "1850-01-01" time_var.calendar = 'standard' - time_var.bounds = "time_bnds" time_var.long_name = "Verification time of the forecast" time_var.standard_name = "time" time_var.axis = "T" @@ -252,7 +284,7 @@ class DataManager(object): var[lt] = leadtime[lt].days def _add_common_attributes(self, frequency, handler, member, startdate): - handler.associated_experiment = 'to be filled' + handler.associated_experiment = self.associated_experiment handler.batch = '{0}{1}'.format(self.institution, datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')) handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ 'Javier Vegas-Regidor, javier.vegas@bsc.es ' @@ -266,15 +298,15 @@ class DataManager(object): handler.frequency = 'monthly' handler.institute_id = self.institution handler.institution = self.institution - handler.initialization_method = 'to be filled' - handler.initialization_description = 'to be filled' - handler.physics_version = 'to be filled' - handler.physics_description = 'to be filled' + handler.initialization_method = self.initialization_method + handler.initialization_description = self.initialization_description + handler.physics_version = self.physics_version + handler.physics_description = self.physics_description handler.model_id = self.model - handler.associated_model = 'to be filled' + handler.associated_model = self.associated_model handler.project_id = 'SPECS' handler.realization = member - handler.source = 'to be filled' + handler.source = self.source handler.startdate = 'S{0}'.format(startdate) handler.tracking_id = str(uuid.uuid1()) handler.title = "{0} model output prepared for SPECS {1}".format(self.model, self.experiment_name) @@ -317,7 +349,7 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, 'fc' + str(member), 'outputs', + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), 'outputs', 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, self.frequency, domain) @@ -376,7 +408,7 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, 'fc' + str(member), 'outputs', + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), 'outputs', 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, frequency, domain) @@ -454,7 +486,7 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, 'fc' + str(member), 'outputs', + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), 'outputs', 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, frequency, domain) @@ -538,8 +570,9 @@ class DataManager(object): if not os.path.exists(os.path.dirname(link_path)): os.makedirs(os.path.dirname(link_path)) - if not os.path.exists(link_path): - os.symlink(var_path, link_path) + if os.path.lexists(link_path): + os.remove(link_path) + os.symlink(var_path, link_path) @staticmethod def domain_abbreviation(domain, frequency): @@ -650,6 +683,9 @@ class DataManager(object): first_year += 1 return years + def get_member_str(self, member): + return 'fc{0}'.format(str(member).zfill(self.member_digits)) + class Variable(object): def __init__(self, line): @@ -671,11 +707,32 @@ class Variable(object): for line in reader: if line[0] == 'variable': continue + var = Variable(line) - Variable._dict_variables[line[0]] = var + for old_name in line[0].split(':'): + Variable._dict_variables[old_name] = var + Variable._dict_variables[var.short_name] = var return Variable.get_variable(original_name) except KeyError: Log.error('Variable {0} is not defined'.format(original_name)) return None + +# os.chdir('/esnas/exp/ecearth/a034/original_files/19500201/fc0/outputs') +# mma = glob.glob('MMA*') +# mmo = glob.glob('MMO*') +# +# mma.sort() +# start = parse_date('19500201') +# count = 0 +# chunks = list() +# for chunk in range(1, 257): +# chunk_start = chunk_start_date(start, chunk, 3, 'month', 'standard') +# chunk_end = chunk_end_date(chunk_start, 3, 'month', 'standard') +# chunk_end = previous_day(chunk_end, 'standard') +# if len(glob.glob('MMO*{0}-{1}.tar'.format(date2str(chunk_start), date2str(chunk_end)))) == 0: +# chunks.append(str(chunk)) +# count += 1 +# print ' '.join(chunks) +# print 'Total chunks missing: {0}'.format(count) \ No newline at end of file diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index d570a56..71eab9c 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -12,11 +12,21 @@ FREQUENCY = mon # Path to CDFTOOLS binaries CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin +[CMOR] +FORCE = true +ASSOCIATED_EXPERIMENT = +INITIALIZATION_METHOD = 1 +INITIALIZATION_DESCRIPTION = ocean: ECMWF system4, ice: DFS4.3 , atmosphere: +PHYSICS_VERSION = 1 +PHYSICS_DESCRIPTION = +ASSOCIATED_MODEL = +SOURCE = 'EC-Earthv2.3.0, ocean: Nemo3.1, ifs31r1, lim2 + [EXPERIMENT] # Experiments parameters as defined in CMOR standard -INSTITUTE = IC3 -MODEL = EC-EARTH3 -NAME = historical +INSTITUTE = BSC +MODEL = EC-EARTH +NAME = decadal # For those who use Autosubmit, this no need documentation # For those who not, EXPID is the unique identifier of the experiment. @@ -25,11 +35,12 @@ NAME = historical # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks to process -EXPID = a034 -STARTDATES = 19500201 -MEMBERS = 0 -CHUNK_SIZE = 3 -CHUNKS = 256 +EXPID = i00k +STARTDATES = 19601101 +MEMBERS = 0 1 2 3 4 +MEMBER_DIGITS = 1 +CHUNK_SIZE = 4 +CHUNKS = 312 # Model version NEMO_VERSION = Ec3.0_O1L46 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index c0a7cd8..c6d62d1 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -30,12 +30,7 @@ class Diags: def __init__(self, config_file): Log.debug('Initialising Diags') self._read_config(config_file) - self.data_manager = DataManager(self.institute, self.model, self.expid, self.data_dir, - self.frequency, self.chunk_size, self.experiment_name, self.chunks, - self.scratch_dir, self.nfrp, - self.calendar) - self.data_manager.add_startdate = self.add_startdate - self.data_manager.add_name = self.add_name + TempFile.scratch_folder = self.scratch_dir cdftools.path = self.cdftools_path self._create_dic_variables() @@ -263,17 +258,17 @@ class Diags: self.frequency = self.parser.get_option('DIAGNOSTICS', 'FREQUENCY') self.cdftools_path = self.parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') self.max_cores = self.parser.get_int_option('DIAGNOSTICS', 'MAX_CORES', 100000) - self.force_CMOR = self.parser.get_bool_option('DIAGNOSTICS', 'FORCE_CMOR', False) # Read experiment config self.institute = self.parser.get_option('EXPERIMENT', 'INSTITUTE') self.expid = self.parser.get_option('EXPERIMENT', 'EXPID') - self.experiment_name = self.parser.get_option('EXPERIMENT', 'NAME') + self.experiment_name = self.parser.get_option('EXPERIMENT', 'NAME', self.expid) self.members = list() for member in self.parser.get_option('EXPERIMENT', 'MEMBERS').split(): self.members.append(int(member)) + self.member_digits = self.parser.get_int_option('EXPERIMENT', 'MEMBER_DIGITS', 1) self.startdates = self.parser.get_option('EXPERIMENT', 'STARTDATES').split() self.chunk_size = self.parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') self.chunks = self.parser.get_int_option('EXPERIMENT', 'CHUNKS') @@ -296,6 +291,22 @@ class Diags: os.makedirs(self.scratch_dir) os.chdir(self.scratch_dir) + self.data_manager = DataManager(self.institute, self.model, self.expid, self.data_dir, + self.frequency, self.chunk_size, self.experiment_name, self.chunks, + self.scratch_dir, self.nfrp, self.member_digits, + self.calendar) + + self.data_manager.add_startdate = self.add_startdate + self.data_manager.add_name = self.add_name + + self.force_CMOR = self.parser.get_bool_option('CMOR', 'FORCE', False) + self.data_manager.associated_experiment = self.parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', False) + self.data_manager.associated_model = self.parser.get_option('CMOR', 'ASSOCIATED_MODEL', False) + self.data_manager.initialization_description = self.parser.get_option('CMOR', 'INITIALIZATION_DESCRIPTION', False) + self.data_manager.initialization_method = self.parser.get_option('CMOR', 'INITIALIZATION_METHOD', False) + self.data_manager.physics_description = self.parser.get_option('CMOR', 'PHYSICS_DESCRIPTION', False) + self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', False) + self.data_manager.source = self.parser.get_option('CMOR', 'SOURCE', False) def main(): parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') diff --git a/earthdiagnostics/models.py b/earthdiagnostics/models.py index 0723b1a..89661e0 100644 --- a/earthdiagnostics/models.py +++ b/earthdiagnostics/models.py @@ -17,6 +17,8 @@ class Models(object): """ NEMO 3.2 ORCA1 L42 """ NEMO_3_3_O1L46 = 'N3.3_O1L46' """ NEMO 3.3 ORCA1 L46 """ + NEMO_3_6_O1L46 = 'N3.6_O1L75' + """ NEMO 3.6 ORCA1 L75 """ NEMOVAR_O1L42 = 'nemovar_O1L42' """ NEMOVAR ORCA1 L42 """ diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 8358ca7..5d32599 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -89,7 +89,10 @@ class Utils(object): if old_name in handler.dimensions: handler.renameDimension(old_name, new_name) elif must_exist: - raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) + raise Exception("Dimension {0} does not exist in file {1}".format(old_name, filepath)) + handler.sync() + + handler.close() -- GitLab From d83ad6f87ac5f503c8d844a89bcd913223e75ed0 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 27 Jun 2016 18:28:56 +0200 Subject: [PATCH 101/268] More exceptions for CMORization. Automatic deflation and shuffling when sending netCDF files to the storage --- earthdiagnostics/cmor_table.csv | 28 ++++++++++++++++------------ earthdiagnostics/datamanager.py | 12 ++++++++---- earthdiagnostics/diags.conf | 33 ++++++++++++++++----------------- earthdiagnostics/diags.py | 16 +++++++++------- earthdiagnostics/utils.py | 2 +- 5 files changed, 50 insertions(+), 41 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index f224c16..e5f23b3 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -2,9 +2,9 @@ Variable,Shortname,Name,Long name,Domain,Basin hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic Northward Ocean Heat Transport,ocean, ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce, iice_etd,iice_etd,brine_volume_distribution,Brine volume distribution,seaIce, -iice_hid:sithic_cat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce, -iice_hsd,sndcat,snow_depth_in_categories,Snow depth in in categories,seaIce, -iice_itd:siconc_cat,siccat,ice_area_in_categories,Ice area in categories,seaIce, +iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce, +iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce, +iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce, iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of Sea Ice,seaIce, iicebome,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of Melt at Sea Ice Base,seaIce, iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce, @@ -12,7 +12,7 @@ iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thicknes Iiceconc:siconc:soicecov:ileadfra,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce, iicedive:sidive,divice,Strain Rate Divergence of Sea Ice,divergence_of_sea_ice_velocity,seaIce, iicedypr,iicedypr,daily_dynamic_ice_production,Daily dynamic ice production,seaIce, -iiceheco,hcice,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea Ice Heat Content,seaIce, +iiceheco,siheco,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea Ice Heat Content,seaIce, iicelapr,iicelapr,daily_lateral_thermo_ice_production,Daily lateral thermo ice prod.,seaIce, iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce, iicesali:iice_std,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce, @@ -21,9 +21,9 @@ iiceshea,iiceshea,shear,Shear,seaIce, iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce, iicestre,streng,compressive_strength_of_sea_ice,Compressive Sea Ice Strength,seaIce, iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of Melt at Upper Surface of Sea Ice,seaIce, -iicesurt:soicetem,tsice,surface_temperature,Surface Temperature of Sea Ice,seaIce, +iicesurt:soicetem:sistem,tsice,surface_temperature,Surface Temperature of Sea Ice,seaIce, iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce, -iicethic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce, +iicethic:sithic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce, iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce, iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce, iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce, @@ -34,9 +34,9 @@ iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release, iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce, iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce, iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce, -isnoheco,isnoheco,snow_heat_content,Snow total heat content,seaIce, +isnoheco,snheco,snow_heat_content,Snow total heat content,seaIce, isnowpre,prsn,snowfall_flux,Surface Snowfall Rate into the Sea Ice Portion of the Grid Cell,seaIce, -isnowthi,snd,surface_snow_thickness,Snow Depth,seaIce, +isnowthi,snthic,surface_snow_thickness,Surface Snow Thickness,seaIce, isssalin,isssalin,sea_surface_salinity,Sea surface salinity,seaIce, isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce, msftmyz,zomsfglo,msftmyz,Meridional Mass Streamfunction,ocean, @@ -69,8 +69,8 @@ sostind,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,o sostipc,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,IndPac sostpac,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Pac sothedep,sothedep,thermocline_depth,Thermocline Depth (max dT/dz),ocean, -sozotaux,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,ocean, -sozotauy:sometauy,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,ocean, +sozotaux,tauuo,surface_downward_x_stress,Surface Downward X Stress ,ocean, +sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface Downward Y Stress ,ocean, tos,sosstsst,sea_surface_temperature,Sea Surface Temperature,ocean, vomecrty,vo,sea_water_y_velocity,Sea Water Y Velocity,ocean, vosaline,so,sea_water_salinity,Sea Water Salinity,ocean, @@ -110,7 +110,7 @@ vtau_ice:iocestrv,tauv,surface_downward_northward_stress,Surface Downward Northw scvoltot,volo,sea_water_volume,Sea Water Volume ,ocean, scsshtot,zosga,global_average_sea_level_change,Global Average Sea Level Change ,ocean, scsshste,zossga,global_average_steric_sea_level_change,Global Average Steric Sea Level Change ,ocean, -scsshtst,zostoga,global_average_thermosteric_sea_level_change,Global Average Thermosteric Sea Level Change ,ocean, +scsshtst,zostoga,snthic,Global Average Thermosteric Sea Level Change ,ocean, scmastot,masso,sea_water_mass,Sea Water Mass ,ocean, sctemtot,thetaoga,sea_water_potential_temperature,Global Average Sea Water Potential Temperature ,ocean, scsaltot,soga,sea_water_salinity,Global Mean Sea Water Salinity ,ocean, @@ -139,7 +139,7 @@ ibgvfxdyn,ibgvfxdynga,volume_flux_dynamic_growth,global mean volume flux (dynami ibgvfxbom,ibgvfxbomga,volume_flux_bottom_melt,global mean volume flux (bottom melt),seaIce, ibgvfxsum,ibgvfxsumga,volume_flux_surface_melt,global mean volume flux (surface melt),seaIce, ibgvfxres,ibgvfxresga,volume_flux_resultant,global mean volume flux (resultant),seaIce, -ibgvfxspr,ibgvfxsprga,volume_flux_snow_precip,global mean volume flux (snow precip),seaIce, +ibgvfxspr,ibgvfxsprga,snheco,global mean volume flux (snow precip),seaIce, ibgvfxsnw,ibgvfxsnwga,volume_flux_snow_melt,global mean volume flux (snow melt),seaIce, ibgvfxsub,ibgvfxsubga,volume_flux_snow_sublimation,global mean volume flux (snow sublimation),seaIce, ibgsfx,ibgsfxga,salt_flux,global mean salt flux (total),seaIce, @@ -188,3 +188,7 @@ votkeevm,votkeevm,enhanced_vertical_viscosity,Enhanced Vertical Viscosity,ocean, voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt Vertical Eddy Diffusivity,ocean, soleahtw,soleahtw,lateral_eddy_diffusivity,lateral eddy diffusivity,ocean, soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,eddy induced vel. coeff. at w-point,ocean, +salincat,ssicat,sea_ice_salinity_in_categories,Sea-Ice Bulk salinity for categories,seaIce, +sibricat,ibrinvolcat,brine_volume_in_categories,Brine volume for categories,seaIce, +qt_ice,qtice,surface_downward_heat_flux_in_air,Surface Downward Heat Flux in Air,seaIce, +qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,non-solar heat flux at ice surface: sum over categories,seaIce, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 0b493dd..d914e55 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -199,7 +199,9 @@ class DataManager(object): if variable in ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', - 'time_counter_bounds', 'ncatice'): + 'time_counter_bounds', 'ncatice', + 'nav_lat_grid_V', 'nav_lat_grid_U', 'nav_lat_grid_T', + 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T',): continue self.extract_variable(file_parts, filename, frequency, handler, member, startdate, temp, variable) @@ -471,9 +473,6 @@ class DataManager(object): :return: path to the copy created on the scratch folder :rtype: str """ - - Utils.convert2netcdf4(filetosend) - if box: var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() @@ -556,6 +555,11 @@ class DataManager(object): handler_send.close() Utils.move_file(temp, filetosend) Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') + + temp = TempFile.get() + Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) + shutil.move(temp, filetosend) + Utils.move_file(filetosend, filepath) if frequency in ('d', 'daily', 'day'): diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 71eab9c..35761a0 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ # Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/jvegas # Root path for the cmorized data to use -DATA_DIR = /esnas/exp/ecearth/ +DATA_DIR = /esnas/exp/nemo/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run @@ -14,19 +14,18 @@ CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin [CMOR] FORCE = true -ASSOCIATED_EXPERIMENT = -INITIALIZATION_METHOD = 1 -INITIALIZATION_DESCRIPTION = ocean: ECMWF system4, ice: DFS4.3 , atmosphere: -PHYSICS_VERSION = 1 -PHYSICS_DESCRIPTION = -ASSOCIATED_MODEL = -SOURCE = 'EC-Earthv2.3.0, ocean: Nemo3.1, ifs31r1, lim2 +# ASSOCIATED_EXPERIMENT = +# INITIALIZATION_METHOD = 1 +# INITIALIZATION_DESCRIPTION = ocean: ECMWF system4, ice: DFS4.3 , atmosphere: +# PHYSICS_VERSION = 1 +# PHYSICS_DESCRIPTION = +# ASSOCIATED_MODEL = +# SOURCE = 'EC-Earthv2.3.0, ocean: Nemo3.1, ifs31r1, lim2 [EXPERIMENT] # Experiments parameters as defined in CMOR standard INSTITUTE = BSC -MODEL = EC-EARTH -NAME = decadal +MODEL = NEMO # For those who use Autosubmit, this no need documentation # For those who not, EXPID is the unique identifier of the experiment. @@ -35,15 +34,15 @@ NAME = decadal # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks to process -EXPID = i00k -STARTDATES = 19601101 -MEMBERS = 0 1 2 3 4 -MEMBER_DIGITS = 1 -CHUNK_SIZE = 4 -CHUNKS = 312 +EXPID = a05p +STARTDATES = 19580101 +MEMBERS = 0 +MEMBER_DIGITS = 2 +CHUNK_SIZE = 12 +CHUNKS = 58 # Model version -NEMO_VERSION = Ec3.0_O1L46 +NEMO_VERSION = N3.6_O1L75 # [EXPERIMENT] # INSTITUTE = IC3 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index c6d62d1..d4c6ea5 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -300,13 +300,15 @@ class Diags: self.data_manager.add_name = self.add_name self.force_CMOR = self.parser.get_bool_option('CMOR', 'FORCE', False) - self.data_manager.associated_experiment = self.parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', False) - self.data_manager.associated_model = self.parser.get_option('CMOR', 'ASSOCIATED_MODEL', False) - self.data_manager.initialization_description = self.parser.get_option('CMOR', 'INITIALIZATION_DESCRIPTION', False) - self.data_manager.initialization_method = self.parser.get_option('CMOR', 'INITIALIZATION_METHOD', False) - self.data_manager.physics_description = self.parser.get_option('CMOR', 'PHYSICS_DESCRIPTION', False) - self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', False) - self.data_manager.source = self.parser.get_option('CMOR', 'SOURCE', False) + self.data_manager.associated_experiment = self.parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', 'to be filled') + self.data_manager.associated_model = self.parser.get_option('CMOR', 'ASSOCIATED_MODEL', 'to be filled') + self.data_manager.initialization_description = self.parser.get_option('CMOR', 'INITIALIZATION_DESCRIPTION', + 'to be filled') + self.data_manager.initialization_method = self.parser.get_option('CMOR', 'INITIALIZATION_METHOD', + 'to be filled') + self.data_manager.physics_description = self.parser.get_option('CMOR', 'PHYSICS_DESCRIPTION', 'to be filled') + self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', 'to be filled') + self.data_manager.source = self.parser.get_option('CMOR', 'SOURCE', 'to be filled') def main(): parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 5d32599..fa4baf9 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -175,7 +175,7 @@ class Utils(object): return handler.close() Log.debug('Reformatting to netCDF-4') - Utils.execute_shell_command(["nccopy", "-4", filetoconvert, temp]) + Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetoconvert, temp]) shutil.move(temp, filetoconvert) # noinspection PyPep8Naming -- GitLab From 941196c2fac7fc36317ecad759989650f604bf75 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 29 Jun 2016 10:09:52 +0200 Subject: [PATCH 102/268] Last diagnostics moved to the new way. Some minor corrections on CMOR --- earthdiagnostics/cmor_table.csv | 2 +- earthdiagnostics/datamanager.py | 64 ++--- earthdiagnostics/diagnostic.py | 2 +- earthdiagnostics/diags.conf | 6 +- earthdiagnostics/diags.py | 75 ++--- earthdiagnostics/ocean/__init__.py | 5 +- earthdiagnostics/ocean/heat.py | 257 ------------------ earthdiagnostics/ocean/heatcontent.py | 142 ++++++++++ earthdiagnostics/ocean/heatcontentlayer.py | 138 ++++++++++ .../ocean/mixedlayerheatcontent.py | 83 ++++++ .../ocean/mixedlayersaltcontent.py | 8 +- earthdiagnostics/utils.py | 5 +- testing_diags_moore.job | 4 +- 13 files changed, 426 insertions(+), 365 deletions(-) delete mode 100644 earthdiagnostics/ocean/heat.py create mode 100644 earthdiagnostics/ocean/heatcontent.py create mode 100644 earthdiagnostics/ocean/heatcontentlayer.py create mode 100644 earthdiagnostics/ocean/mixedlayerheatcontent.py diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index e5f23b3..7b352d9 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -1,7 +1,7 @@ Variable,Shortname,Name,Long name,Domain,Basin hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic Northward Ocean Heat Transport,ocean, ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce, -iice_etd,iice_etd,brine_volume_distribution,Brine volume distribution,seaIce, +iice_etd,iiceetd,brine_volume_distribution,Brine volume distribution,seaIce, iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce, iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce, iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index d914e55..20a54dd 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -7,7 +7,7 @@ import numpy as np import netCDF4 import threading from autosubmit.config.log import Log -from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day, date2str +from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day from basins import Basins from earthdiagnostics.utils import Utils, TempFile @@ -97,8 +97,8 @@ class DataManager(object): for startdate in startdates: for member in members: - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), - 'outputs') + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, + self.get_member_str(member), 'outputs') Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) filepaths = glob.glob(os.path.join(member_path, '*.gz')) @@ -160,7 +160,8 @@ class DataManager(object): member, startdate, tarfile = queue.get(timeout=1) self._unpack_tar(member, startdate, tarfile, numthread) except Queue.Empty: - continue + pass + queue.task_done() os.rmdir(scratch_dir) return @@ -250,10 +251,11 @@ class DataManager(object): times = netCDF4.num2date(time_var[:], time_var.units, time_var.calendar) if type(times[0]) is not datetime: for x in range(0, times.shape[0]): + # noinspection PyProtectedMember times[x] = times[x]._to_real_datetime() time_var[:] = netCDF4.date2num(times, 'days since 1850-01-01', 'standard') if 'axis_nbounds' in handler.dimensions: - handler.renameDimension('axis_nbounds', 'nbnds') + handler.renameDimension('axis_nbounds', 'bnds') if 'time_counter_bounds' in handler.variables: handler.renameVariable('time_counter_bounds', 'time_bnds') @@ -263,9 +265,10 @@ class DataManager(object): time_var.bounds = "time_bnds" time_bounds = netCDF4.num2date(time_bounds_var[:], time_var.units, time_var.calendar) - if type(time_bounds[0,0]) is not datetime: + if type(time_bounds[0, 0]) is not datetime: for x in range(0, time_bounds.shape[0]): for y in range(0, time_bounds.shape[1]): + # noinspection PyProtectedMember time_bounds[x, y] = time_bounds[x, y]._to_real_datetime() time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') time_var.units = 'days since 1850-01-01' @@ -351,9 +354,9 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), 'outputs', - 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, - self.frequency, domain) + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), + 'outputs', 'output', self.institution, self.model, self.experiment_name, + 'S' + startdate, self.frequency, domain) chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') @@ -410,9 +413,9 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), 'outputs', - 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, - frequency, domain) + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), + 'outputs', 'output', self.institution, self.model, self.experiment_name, + 'S' + startdate, frequency, domain) chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') @@ -485,8 +488,9 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), 'outputs', - 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), + 'outputs', 'output', self.institution, self.model, self.experiment_name, + 'S' + startdate, frequency, domain) if chunk is not None: @@ -572,11 +576,18 @@ class DataManager(object): else: link_path = os.path.join(self.data_dir, self.expid, freq_str, '{0}_f{1}h'.format(var, self.nfrp)) - if not os.path.exists(os.path.dirname(link_path)): - os.makedirs(os.path.dirname(link_path)) + if not os.path.exists(link_path): + # This can be a race condition + # noinspection PyBroadException + try: + os.makedirs(link_path) + except Exception: + pass + + link_path = os.path.join(link_path, os.path.basename(filepath)) if os.path.lexists(link_path): os.remove(link_path) - os.symlink(var_path, link_path) + os.symlink(filepath, link_path) @staticmethod def domain_abbreviation(domain, frequency): @@ -721,22 +732,3 @@ class Variable(object): except KeyError: Log.error('Variable {0} is not defined'.format(original_name)) return None - - -# os.chdir('/esnas/exp/ecearth/a034/original_files/19500201/fc0/outputs') -# mma = glob.glob('MMA*') -# mmo = glob.glob('MMO*') -# -# mma.sort() -# start = parse_date('19500201') -# count = 0 -# chunks = list() -# for chunk in range(1, 257): -# chunk_start = chunk_start_date(start, chunk, 3, 'month', 'standard') -# chunk_end = chunk_end_date(chunk_start, 3, 'month', 'standard') -# chunk_end = previous_day(chunk_end, 'standard') -# if len(glob.glob('MMO*{0}-{1}.tar'.format(date2str(chunk_start), date2str(chunk_end)))) == 0: -# chunks.append(str(chunk)) -# count += 1 -# print ' '.join(chunks) -# print 'Total chunks missing: {0}'.format(count) \ No newline at end of file diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 1aa3110..afc1115 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -1,6 +1,6 @@ class Diagnostic(object): """ - Base classs for the diagnostics. Provides a common interface for them and also + Base class for the diagnostics. Provides a common interface for them and also has a mechanism that allows diagnostic retrieval by name. """ diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 35761a0..d7339b6 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -6,14 +6,14 @@ DATA_DIR = /esnas/exp/nemo/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run -DIAGS = siasiesiv +DIAGS = ohc # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin [CMOR] -FORCE = true +FORCE = False # ASSOCIATED_EXPERIMENT = # INITIALIZATION_METHOD = 1 # INITIALIZATION_DESCRIPTION = ocean: ECMWF system4, ice: DFS4.3 , atmosphere: @@ -39,7 +39,7 @@ STARTDATES = 19580101 MEMBERS = 0 MEMBER_DIGITS = 2 CHUNK_SIZE = 12 -CHUNKS = 58 +CHUNKS = 1 # Model version NEMO_VERSION = N3.6_O1L75 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index d4c6ea5..08e13ce 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -20,7 +20,7 @@ from parser import Parser from utils import Utils -class Diags: +class Diags(object): """ Launcher class for the diagnostics @@ -73,6 +73,9 @@ class Diags: Diagnostic.register(ConvectionSites, 'convection') Diagnostic.register(CutSection, 'cutsection') Diagnostic.register(AverageSection, 'avgsection') + Diagnostic.register(MixedLayerHeatContent, 'mlotsthc') + Diagnostic.register(HeatContentLayer, 'ohclayer') + Diagnostic.register(HeatContent, 'ohc') parse_date('20000101') @@ -91,12 +94,7 @@ class Diags: list_jobs.put(job) continue else: - for startdate in self.startdates: - for member in self.members: - for chunk in range(1, self.chunks+1): - self._execute_diagnostic(diag_options, startdate, member, chunk) - - Log.result('Finished {0}', fulldiag) + Log.error('{0} is not an available diagnostic', diag_options[0]) numthreads = min(Utils.available_cpu_count(), self.max_cores) threads = list() @@ -149,58 +147,20 @@ class Diags: Log.error('Job {0} could not be run', job) return - def _execute_diagnostic(self, diag_options, startdate, member, chunk): - diag = diag_options[0] - if diag == 'ohc': - basin = diag_options[1] - mixed_layer = int(diag_options[2]) - depth_min = int(diag_options[3]) - depth_max = int(diag_options[4]) - - if mixed_layer == 1: - mxl = 'mlotst' - depth = '' - elif mixed_layer == 0: - mxl = '' - depth = '{0}-{1}'.format(depth_min, depth_max) - else: - mxl = 'nomlotst' - depth = '' - variables = ('thetao', 'mlotst', 'ohcsum{0}{1}', 'ohcvmean{0}{1}'.format(mxl, depth)) - for [input_file, mlotst_file, ohcsum_file, ohcvmean_file] in self.data_manager.get_files(startdate, member, - chunk, 'ocean', - variables): - Heat.total(input_file, mlotst_file, ohcsum_file, ohcvmean_file, basin, mixed_layer, - depth_min, depth_max) - elif diag == 'ohclayer': - depth_min = int(diag_options[1]) - depth_max = int(diag_options[2]) - - depth = '{0}-{1}'.format(depth_min, depth_max) - variables = ('thetao', 'ohc{0}'.format(depth)) - for [input_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', variables): - Heat.layer(input_file, output_file, depth_min, depth_max) - elif diag == 'mlotsthc': - variables = ('thetao', 'mlotst', 'ohcvertsummlotst') - for [input_file, mlotst_file, output_file] in self.data_manager.get_files(startdate, member, chunk, 'ocean', - variables): - Heat.mixed_layer_content(input_file, mlotst_file, output_file) - else: - Log.warning('Diagnostic {0} not available', diag) - return - def _get_commands(self): Log.debug('Preparing command list') commands = self.diags.split() - - for alias, added_commands in self._aliases.items(): - if alias in commands: - Log.info('Changing alias {0} for {1}', alias, ' '.join(added_commands)) - commands.remove(alias) + real_commands = list() + for command in commands: + if command in self._aliases: + added_commands = self._aliases[command] + Log.info('Changing alias {0} for {1}', command, ' '.join(added_commands)) for add_command in added_commands: - commands.append(add_command) + real_commands.append(add_command) + else: + real_commands.append(command) Log.debug('Command list ready ') - return commands + return real_commands def _prepare_mesh_files(self): Log.info('Copying mesh files') @@ -300,7 +260,8 @@ class Diags: self.data_manager.add_name = self.add_name self.force_CMOR = self.parser.get_bool_option('CMOR', 'FORCE', False) - self.data_manager.associated_experiment = self.parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', 'to be filled') + self.data_manager.associated_experiment = self.parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', + 'to be filled') self.data_manager.associated_model = self.parser.get_option('CMOR', 'ASSOCIATED_MODEL', 'to be filled') self.data_manager.initialization_description = self.parser.get_option('CMOR', 'INITIALIZATION_DESCRIPTION', 'to be filled') @@ -310,7 +271,11 @@ class Diags: self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', 'to be filled') self.data_manager.source = self.parser.get_option('CMOR', 'SOURCE', 'to be filled') + def main(): + """ Entry point for the Earth Diagnostics. For more detailed documentation, use -h option + + """ parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') parser.add_argument('-v', '--version', action='version', version='0.1', help="returns Earth Diagnostics's version number and exit") diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index 8dbb420..b88abc8 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,5 +1,4 @@ -# from earthdiagnostics.diagnostic import Diagnostic -from earthdiagnostics.ocean.heat import Heat +from earthdiagnostics.ocean.heatcontent import HeatContent from earthdiagnostics.ocean.moc import Moc from earthdiagnostics.ocean.areamoc import AreaMoc from earthdiagnostics.ocean.maxmoc import MaxMoc @@ -13,3 +12,5 @@ from earthdiagnostics.ocean.verticalmeanmeters import VerticalMeanMeters from earthdiagnostics.ocean.verticalmean import VerticalMean from earthdiagnostics.ocean.mixedlayersaltcontent import MixedLayerSaltContent from earthdiagnostics.ocean.siasiesiv import Siasiesiv +from earthdiagnostics.ocean.heatcontentlayer import HeatContentLayer +from earthdiagnostics.ocean.mixedlayerheatcontent import MixedLayerHeatContent diff --git a/earthdiagnostics/ocean/heat.py b/earthdiagnostics/ocean/heat.py deleted file mode 100644 index 101f4d0..0000000 --- a/earthdiagnostics/ocean/heat.py +++ /dev/null @@ -1,257 +0,0 @@ -from earthdiagnostics import cdftools, cdo -from earthdiagnostics.utils import Utils, TempFile -from earthdiagnostics.basins import Basins -from autosubmit.config.log import Log -import os -import shutil -import traceback -import numpy as np -from nco import NCOException - - -class Heat(object): - """ - Diagnsotics for the ocean heat content - """ - - @staticmethod - def mixed_layer_content(input_file, mltost_file, output_file): - """ - Compute mixed layer heat and salt content - - Created in February 2012 Author : vguemas@ic3.cat - - :param mltost_file: imput mltost file - :param input_file: input grid_T file name - :param output_file: output file name (=> 2D x-y ) - :return: - """ - - nco = Utils.nco - - input_scratch = TempFile.get() - shutil.copy(input_file, input_scratch) - nco.ncks(input=mltost_file, output=input_scratch, options='-A -v mlotst') - - ntime = int(cdo.ntime(input=input_scratch)[0]) - files = list() - - for time in range(ntime): - Log.info('Running time {0}', time) - temp = TempFile.get() - nco.ncks(input=input_scratch, output=temp, options='-O -d time,{0}'.format(time)) - Log.info('Computing heat content') - cdftools.run('cdfmxlheatc', input=temp) - Utils.move_file('mxlheatc.nc', temp) - files.append(temp) - - temp = TempFile.get() - nco.ncrcat(input=' '.join(files), output=temp,) - nco.ncks(input=input_scratch, output=temp, options='-A -v time') - - for temp_file in files: - os.remove(temp_file) - os.remove(input_scratch) - - Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlheatc': 'ohcsummlotst'}, False, True) - Utils.setminmax(temp, 'ohcsummlotst') - Utils.move_file(temp, output_file) - - @staticmethod - def layer(input_file, output_file, min_depth, max_depth): - """ - Pointwise Ocean Heat Content in a specified ocean thickness (J/m-2) - - Created in June 2012 Author : isabel.andreu-burillo@ic3.cat - May 2014 - Virginie Guemas - Way around the bc that does not work on moore - - :param input_file: input grid_T file nam - :param output_file: output file name (=> 2D x-y ) - :param min_depth: upper depth of the layer (in meters) - :param max_depth: lower depth of the layer (in meters) - :return: - """ - - nco = Utils.nco - - temp = TempFile.get() - heatc_sl_out = TempFile.get() - heatc_sl_top = TempFile.get() - level_above = TempFile.get() - level_below = TempFile.get() - heatc_sl_bottom = TempFile.get() - heatc_sl_top_invert = TempFile.get() - e3tfile = TempFile.get() - results = TempFile.get() - - nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*e3t"'), - - shutil.copy(input_file, temp) - - Utils.rename_variable(temp, 'thetao', 'heatc_sl') - - nco.ncks(input=temp, output=temp, options='-O -v heatc_sl') - cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) - - # extract the data between the two given depths --> heatc_sl_top.nc - nco.ncks(input=heatc_sl_out, output=heatc_sl_top, - options='-O -d lev,{0}.0,{1}.0'.format(min_depth, max_depth)) - - # now extract a few levels below, to compute the residual ohc - # addition with float returned: - nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, - options='-O -d lev,{0}.0,{1}.0'.format(max_depth, max_depth+200)) - - # obtain the weight for the extra level containing the 300 m - # deptht in the gridT files is positive - # weight = (300.0 - depth_top)/(depth_bottom - depth_top) - # and add the thickness down to 300 m in the next layer - nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) - nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') - nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') - - handler = Utils.openCdf(level_above) - lev_above = handler.variables['lev'][:] - handler.close() - - handler = Utils.openCdf(level_below) - layerthcknss = handler.variables['lev'][:] - lev_above - heatc_sl_below = handler.variables['heatc_sl'][:] - handler.close() - - factor = (max_depth - lev_above) / layerthcknss - - heatc_sl_below = heatc_sl_below * factor - handler = Utils.openCdf(heatc_sl_top) - heatc_sl = handler.variables['heatc_sl'][:] - handler.close() - - heatc_sl = np.sum(heatc_sl, 1) - heatc_sl = heatc_sl[:] + heatc_sl_below[:, 0, :] - heatc_sl = heatc_sl[:] * 1020 * 4000 - - nco.ncks(input=heatc_sl_top_invert, output=results, options='-O -v lon,lat,time') - handler_results = Utils.openCdf(results) - handler_results.createVariable('ohc', float, ('time', 'y', 'x')) - handler_results.close() - - handler_results = Utils.openCdf(results) - handler_results.variables['ohc'][:] = heatc_sl - handler_results.close() - - Utils.setminmax(results, 'ohc') - Utils.move_file(results, output_file) - - @staticmethod - def total(input_file, mlotst_file, ohcsum_file, ohcvmean_file, basin=Basins.Global.shortname, mixed_layer=0, - upper=None, lower=None): - """ - Compute the total ocean heat extent - - Created in May 2012 Author : vguemas@ic3.cat - - :param ohcvmean_file: - :param ohcsum_file: - :param mlotst_file: - :param input_file: input temperature file name - :param basin: basin name (default: global) - :param mixed_layer: mixed layer (1=only, 0=included, -1=without) - :param upper: upper level of the layer (optional) Default : top - :param lower: lower level of the layer (optional) Default : bottom - """ - - nco = Utils.nco - temp = TempFile.get() - - shutil.copy(input_file, temp) - nco.ncks(input=mlotst_file, output=temp, options='-A -v mlotst') - - basin = Basins.parse(basin) - - handler = Utils.openCdf('mask_regions.3d.nc') - if basin.fullname not in handler.variables: - raise Exception('Basin {0} is not defined on mask_regions.nc'.format(basin.fullname)) - - handler.close() - if basin != Basins.Global: - shutil.move('mask.nc', 'original_mask.nc') - shutil.move('mask_regions.3d.nc', 'mask.nc') - Utils.rename_variable('mask.nc', basin.fullname, 'tmask') - error = None - - try: - para = list() - para.append(str(basin.box.min_lon)) - para.append(str(basin.box.max_lon)) - para.append(str(basin.box.min_lat)) - para.append(str(basin.box.max_lat)) - para.append(upper) - para.append(lower) - para.append(str(mixed_layer)) - shell_output = cdftools.run('cdfheatc', options=para, input=temp) - except Exception as ex: - error = ex.message - finally: - if basin != Basins.Global: - Utils.rename_variable('mask.nc', 'tmask', basin.fullname) - shutil.move('mask.nc', 'mask_regions.3d.nc') - shutil.move('original_mask.nc', 'mask.nc') - if error: - raise Exception(error) - - ohcsum_temp = TempFile.get() - ohcvmean_temp = TempFile.get() - nco.ncks(input=temp, output=ohcsum_temp, options='-O -v time') - shutil.copy(ohcsum_temp, ohcvmean_temp) - - ohcsum_handler = Utils.openCdf(ohcsum_temp) - thc = ohcsum_handler.createVariable('ohcsum', float, 'time') - thc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" - thc.long_name = "Total heat content" - thc.units = "Joules" - - ohcvmean_handler = Utils.openCdf(ohcvmean_temp) - uhc = ohcvmean_handler.createVariable('ohcvmean', float, 'time') - uhc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" - uhc.long_name = "Heat content per unit volume" - uhc.units = "Joules/m3" - - time = 0 - # noinspection PyUnboundLocalVariable - for lines in shell_output: - if not lines: - continue - - for line in lines.split('\n'): - line = line.lstrip() - if line.startswith("Heat Content at level"): - Log.info(line) - elif line.startswith("Total Heat content/volume"): - Log.user_warning(line) - uhc[time] = line[line.index(':')+1: line.index('Joules')] - time += 1 - if line.startswith("Total Heat content "): - Log.result(line) - thc[time] = line[line.index(':')+1: line.index('Joules')] - elif line.startswith('TIME : '): - Log.info(line) - - ohcsum_handler.close() - ohcvmean_handler.close() - - Utils.setminmax(ohcsum_temp, 'ohcsum') - Utils.move_file(ohcsum_temp, ohcsum_file) - Utils.setminmax(ohcvmean_temp, 'ohcvmean') - Utils.move_file(ohcvmean_temp, ohcvmean_file) - - -def main(): - try: - Heat.layer("ORCA1_MM_19601101_19610228_grid_T.nc", "out.nc", 300, 2000) - except NCOException as ex: - Log.error('Exception {0}: stderr: {1}, stdout: {2}', ex.msg, ex.stderr, ex.stdout) - Log.error(traceback.format_exc()) - - -if __name__ == "__main__": - main() diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py new file mode 100644 index 0000000..b9bf883 --- /dev/null +++ b/earthdiagnostics/ocean/heatcontent.py @@ -0,0 +1,142 @@ +import shutil + +from autosubmit.config.log import Log + +from earthdiagnostics import cdftools +from earthdiagnostics.basins import Basins +from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.box import Box + + +class HeatContent(Diagnostic): + """ + Compute the total ocean heat extent + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: May 2012 + :last modified: June 2016 + + """ + + def __init__(self, data_manager, startdate, member, chunk, basin, mixed_layer, box): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.basin = basin + self.mxloption = mixed_layer + self.box = box + self.required_vars = ['so', 'mlotst'] + self.generated_vars = ['scvertsum'] + + def __str__(self): + return 'Heat content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, + self.chunk) + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: None + :type options: list[str] + :return: + """ + num_options = len(options) - 1 + if num_options < 4: + raise Exception('You must specify the basin, mixed layer option and minimum and maximum depth to use') + if num_options > 4: + raise Exception('You must specify 4 parameters for the heat content diagnostic') + basin = Basins.parse(options[1]) + mixed_layer = int(options[2]) + box = Box(True) + box.min_depth = int(options[3]) + box.max_depth = int(options[4]) + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(HeatContent(diags.data_manager, startdate, member, chunk, basin, mixed_layer, box)) + return job_list + + def compute(self): + nco = Utils.nco + temperature_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) + if self.mxloption != 0: + mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) + nco.ncks(input=mlotst_file, output=temperature_file, options='-A -v mlotst') + + para = list() + para.append('0') + para.append('0') + para.append('0') + para.append('0') + para.append(self.box.min_depth) + para.append(self.box.max_depth) + if self.mxloption != 0: + para.append('-mxloption') + para.append(str(self.mxloption)) + if self.basin != Basins.Global: + handler = Utils.openCdf('mask_regions.3d.nc') + if self.basin.fullname not in handler.variables: + raise Exception('Basin {0} is not defined on mask_regions.nc'.format(self.basin.fullname)) + + handler.close() + para.append('-maskfile') + para.append('mask_regions.3d.nc') + para.append('-mask') + para.append(self.basin.fullname) + + shell_output = cdftools.run('cdfheatc', options=para, input=temperature_file) + + ohcsum_temp = TempFile.get() + ohcvmean_temp = TempFile.get() + nco.ncks(input=temperature_file, output=ohcsum_temp, options='-O -v time') + shutil.copy(ohcsum_temp, ohcvmean_temp) + + ohcsum_handler = Utils.openCdf(ohcsum_temp) + thc = ohcsum_handler.createVariable('ohcsum', float, 'time') + thc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" + thc.long_name = "Total heat content" + thc.units = "Joules" + + ohcvmean_handler = Utils.openCdf(ohcvmean_temp) + uhc = ohcvmean_handler.createVariable('ohcvmean', float, 'time') + uhc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" + uhc.long_name = "Heat content per unit volume" + uhc.units = "Joules/m3" + + time = 0 + # noinspection PyUnboundLocalVariable + for lines in shell_output: + if not lines: + continue + + for line in lines.split('\n'): + line = line.lstrip() + if line.startswith("Heat Content at level"): + Log.info(line) + elif line.startswith("Total Heat content/volume"): + Log.user_warning(line) + uhc[time] = line[line.index(':') + 1: line.index('Joules')] + time += 1 + if line.startswith("Total Heat content "): + Log.result(line) + thc[time] = line[line.index(':') + 1: line.index('Joules')] + elif line.startswith('TIME : '): + Log.info(line) + + ohcsum_handler.close() + ohcvmean_handler.close() + + Utils.setminmax(ohcsum_temp, 'ohcsum') + self.data_manager.send_file(ohcsum_temp, 'ocean', 'ohcsum', self.startdate, self.member, self.chunk, + box=self.box, region=self.basin.fullname, rename_var='ohcsum') + Utils.setminmax(ohcvmean_temp, 'ohcvmean') + self.data_manager.send_file(ohcvmean_temp, 'ocean', 'ohcvmean', self.startdate, self.member, self.chunk, + box=self.box, region=self.basin.fullname, rename_var='ohcvmean') diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py new file mode 100644 index 0000000..2ce9d07 --- /dev/null +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -0,0 +1,138 @@ +import numpy as np + +from box import Box +from diagnostic import Diagnostic +from earthdiagnostics import cdo +from utils import Utils, TempFile + + +class HeatContentLayer(Diagnostic): + """ + Point-wise Ocean Heat Content in a specified ocean thickness (J/m-2) + + :original author: Isabel Andreu Burillo + :contributor: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: June 2012 + :last modified: June 2016 + + """ + + def __init__(self, data_manager, startdate, member, chunk, box): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.box = box + self.required_vars = ['so', 'mlotst'] + self.generated_vars = ['scvertsum'] + + def __str__(self): + return 'Heat content layer Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, + self.chunk) + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: None + :type options: list[str] + :return: + """ + num_options = len(options) - 1 + if num_options < 2: + raise Exception('You must specify the minimum and maximum depth to use') + if num_options > 2: + raise Exception('You must specify 2 for the heat content layer diagnostic') + box = Box(True) + box.min_depth = int(options[1]) + box.max_depth = int(options[2]) + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box)) + return job_list + + def compute(self): + nco = Utils.nco + temp = TempFile.get() + heatc_sl_out = TempFile.get() + heatc_sl_top = TempFile.get() + level_above = TempFile.get() + level_below = TempFile.get() + heatc_sl_bottom = TempFile.get() + heatc_sl_top_invert = TempFile.get() + e3tfile = TempFile.get() + results = TempFile.get() + + handler = Utils.openCdf('mesh_zgr.nc') + if 'e3t' in handler.variables: + e3t_name = 'e3t' + elif 'e3t_0' in handler.variables: + e3t_name = 'e3t_0' + else: + raise Exception('e3t variable can not be found') + handler.close() + + nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*{0}"'.format(e3t_name)), + + thetao_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) + + nco.ncks(input=thetao_file, output=temp, options='-O -v thetao') + Utils.rename_variable(temp, 'thetao', 'heatc_sl') + cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) + + # extract the data between the two given depths --> heatc_sl_top.nc + nco.ncks(input=heatc_sl_out, output=heatc_sl_top, + options='-O -d lev,{0}.0,{1}.0'.format(self.box.min_depth, self.box.max_depth)) + + # now extract a few levels below, to compute the residual ohc + # addition with float returned: + nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, + options='-O -d lev,{0}.0,{1}.0'.format(self.box.max_depth, self.box.max_depth + 200)) + + # obtain the weight for the extra level containing the 300 m + # deptht in the gridT files is positive + # weight = (300.0 - depth_top)/(depth_bottom - depth_top) + # and add the thickness down to 300 m in the next layer + nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) + nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') + nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') + + handler = Utils.openCdf(level_above) + lev_above = handler.variables['lev'][:] + handler.close() + + handler = Utils.openCdf(level_below) + layerthcknss = handler.variables['lev'][:] - lev_above + heatc_sl_below = handler.variables['heatc_sl'][:] + handler.close() + + factor = (self.box.max_depth - lev_above) / layerthcknss + + heatc_sl_below = heatc_sl_below * factor + handler = Utils.openCdf(heatc_sl_top) + heatc_sl = handler.variables['heatc_sl'][:] + handler.close() + + heatc_sl = np.sum(heatc_sl, 1) + heatc_sl = heatc_sl[:] + heatc_sl_below[:, 0, :] + heatc_sl = heatc_sl[:] * 1020 * 4000 + + nco.ncks(input=thetao_file, output=results, options='-O -v lon,lat,time') + Utils.rename_variables(results, {'x': 'i', 'y': 'j'}, False, True) + handler_results = Utils.openCdf(results) + handler_results.createVariable('ohc', float, ('time', 'j', 'i')) + handler_results.close() + + handler_results = Utils.openCdf(results) + handler_results.variables['ohc'][:] = heatc_sl + handler_results.close() + + Utils.setminmax(results, 'ohc') + self.data_manager.send_file(results, 'ocean', 'ohc', self.startdate, self.member, self.chunk, box=self.box) diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py new file mode 100644 index 0000000..ef88246 --- /dev/null +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -0,0 +1,83 @@ +import os +from autosubmit.config.log import Log + +from diagnostic import Diagnostic +from earthdiagnostics import cdftools +from utils import Utils, TempFile + + +class MixedLayerHeatContent(Diagnostic): + """ + Compute mixed layer heat content + + :original author: Virginie Guemas + :contributor: Javier Vegas-Regidor + + :created: February 2012 + :last modified: June 2016 + + """ + + def __init__(self, data_manager, startdate, member, chunk): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.required_vars = ['so', 'mlotst'] + self.generated_vars = ['scvertsum'] + + def __str__(self): + return 'Mixed layer heat content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, + self.chunk) + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: None + :type options: list[str] + :return: + """ + if len(options) > 1: + raise Exception('The mixed layer ocean heat content diagnostic has no options') + job_list = list() + for startdate in diags.startdates: + for member in diags.members: + for chunk in range(1, diags.chunks + 1): + job_list.append(MixedLayerHeatContent(diags.data_manager, startdate, member, chunk)) + return job_list + + def compute(self): + nco = Utils.nco + cdo = Utils.cdo + temperature_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) + mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) + + Utils.nco.ncks(input=mlotst_file, output=temperature_file, options='-A -v mlotst') + + ntime = int(cdo.ntime(input=temperature_file)[0]) + files = list() + + for time in range(ntime): + Log.debug('Running time {0}', time) + temp = TempFile.get() + temp2 = TempFile.get() + nco.ncks(input=temperature_file, output=temp, options='-O -d time,{0}'.format(time)) + cdftools.run('cdfmxlheatc', input=temp, output=temp2) + os.remove(temp) + files.append(temp2) + + temp = TempFile.get() + cdo.cat(input=' '.join(files), output=temp,) + nco.ncks(input=temperature_file, output=temp, options='-A -v time') + + for temp_file in files: + os.remove(temp_file) + os.remove(temperature_file) + + Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlheatc': 'ohcvsumlotst'}, False, True) + Utils.setminmax(temp, 'ohcvsumlotst') + self.data_manager.send_file(temp, 'ocean', 'ohcvsumlotst', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index ed849f3..2160f4b 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -46,7 +46,7 @@ class MixedLayerSaltContent(Diagnostic): for startdate in diags.startdates: for member in diags.members: for chunk in range(1, diags.chunks + 1): - job_list.append(MixedLayerSaltContent(diags.datamanager, startdate, member, chunk)) + job_list.append(MixedLayerSaltContent(diags.data_manager, startdate, member, chunk)) return job_list def compute(self): @@ -78,6 +78,6 @@ class MixedLayerSaltContent(Diagnostic): os.remove(temp_file) os.remove(salinity_file) - Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'scvertsum'}, False, True) - Utils.setminmax(temp, 'scvsum') - self.data_manager.send_file(temp, 'ocean', 'scvsum', self.startdate, self.member, self.chunk) + Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'scvsummlotst'}, False, True) + Utils.setminmax(temp, 'scvsummlotst') + self.data_manager.send_file(temp, 'ocean', 'scvsummlotst', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index fa4baf9..d3b5d50 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -8,7 +8,6 @@ from cdo import Cdo from nco import Nco import tempfile import os -import pwd import shutil @@ -92,8 +91,6 @@ class Utils(object): raise Exception("Dimension {0} does not exist in file {1}".format(old_name, filepath)) handler.sync() - - handler.close() @staticmethod @@ -219,7 +216,7 @@ class TempFile(object): """ List of files to clean automatically """ - scratch_folder = os.path.join('/scratch', pwd.getpwuid(os.getuid())[0]) + scratch_folder = '' """ Scratch folder to create temporary files on it """ diff --git a/testing_diags_moore.job b/testing_diags_moore.job index 96333e4..e51487d 100755 --- a/testing_diags_moore.job +++ b/testing_diags_moore.job @@ -4,7 +4,7 @@ #SBATCH --error=/home/Earth/jvegas/job.%J.err #SBATCH --output=/home/Earth/jvegas/job.%J.out -set -xve +set -xv module load NCO/4.5.4-foss-2015a module load CDO @@ -15,4 +15,4 @@ source /home/Earth/jvegas/virtualenvs/diags/bin/activate export PYTHONPATH=/home/Earth/jvegas/pyCharm/ocean_diagnostics/:$PYTHONPATH cd /home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/ -./diags.py -lc DEBUG \ No newline at end of file +./diags.py -lc DEBUG -- GitLab From 0e088d3fc77ded92b0e62761b326f616d09d8006 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 1 Jul 2016 11:01:14 +0200 Subject: [PATCH 103/268] Atmosphere cmorization ready --- earthdiagnostics/cmor_table.csv | 56 +++++ earthdiagnostics/datamanager.py | 411 +++++++++++++++++++++++++++----- earthdiagnostics/diags.conf | 16 +- earthdiagnostics/diags.py | 13 +- testing_diags_moore.job | 2 +- 5 files changed, 420 insertions(+), 78 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 7b352d9..2292cd6 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -192,3 +192,59 @@ salincat,ssicat,sea_ice_salinity_in_categories,Sea-Ice Bulk salinity for categor sibricat,ibrinvolcat,brine_volume_in_categories,Brine volume for categories,seaIce, qt_ice,qtice,surface_downward_heat_flux_in_air,Surface Downward Heat Flux in Air,seaIce, qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,non-solar heat flux at ice surface: sum over categories,seaIce, +al,al,surface_albedo,Albedo,atmos, +asn,snal,snow_albedo,Snow Albedo,landIce, +ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,atmos, +cp,prc,convective_precipitation_flux,Convective Precipitation,atmos, +d2m,tdps,dew_point_temperature,2m Dewpoint Temperature,atmos, +e,evspsbl,water_evaporation_flux,Evaporation,atmos, +ewss,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,atmos, +fal,fal,forecast_albedo,Forecast albedo,atmos, +hcc,clh,high_cloud_area_fraction,High Cloud Fraction,atmos, +istl1,tsice,surface_temperature,Surface Temperature of Ice,landICe, +lcc,clh,low_cloud_area_fraction,Low Cloud Fraction,atmos, +lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos, +mcc,clh,medium_cloud_area_fraction,Medium Cloud Fraction,atmos, +mn2t,tasmin,air_temperature,Daily Minimum Near-Surface Air Temperature,atmos, +msl,psl,air_pressure_at_sea_level,Sea Level Pressure,atmos, +mx2t,tasmax,air_temperature,Daily Maximum Near-Surface Air Temperature,atmos, +nsss,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,atmos, +q,hus,specific_humidity,Specific humidity,atmos, +ro,mrro,runoff_flux,Total Runoff,atmos, +sd,snld,lwe_thickness_of_surface_snow_amount,Snow Depth,atmos, +sf,prsn,snowfall_flux,Snowfall Flux,atmos, +si,si,solar_insolation,Solar insolation,atmos, +skt,ts,surface_temperature,Surface Temperature,atmos, +slhf,hfls,surface_upward_latent_heat_flux,Surface Upward Latent Heat Flux,atmos, +sshf,hfss,surface_upward_sensible_heat_flux,Surface Upward Sensible Heat Flux,atmos, +ssr,rss,surface_shortwave_flux_in_air,Surface Shortwave Radiation,atmos, +ssrc,rsscs,surface_shortwave_flux_in_air_assuming_clear_sky,Surface Clear-Sky Shortwave Radiation,atmos, +ssrd,rsds,surface_downwelling_shortwave_flux_in_air,Surface Downwelling Shortwave Radiation,atmos, +sstk,tos,sea_surface_temperature,Sea Surface Temperature ,atmos, +stl1,tsl1,soil_temperature_level_1,Temperature of Soil Level 1,land, +stl2,tsl2,soil_temperature_level_2,Temperature of Soil Level 2,land, +stl3,tsl3,soil_temperature_level_3,Temperature of Soil Level 3,land, +stl4,tsl4,soil_temperature_level_4,Temperature of Soil Level 4,land, +str,rls,surface_net_downward_longwave_flux,Net Longwave Surface Radiation,atmos, +strc,rls,surface_longwave_flux_in_air,Surface Longwave Radiation,atmos, +strd,rlds,surface_downwelling_longwave_flux_in_air,Surface Downwelling Longwave Radiation,atmos, +swvl1,mrlsl1,moisture_content_of_soil_layer_1, Water Content of Soil Layer 1,land, +swvl2,mrlsl2,moisture_content_of_soil_layer_2, Water Content of Soil Layer 2,land, +swvl3,mrlsl3,moisture_content_of_soil_layer_3, Water Content of Soil Layer 3,land, +swvl4,mrlsl4,moisture_content_of_soil_layer_4, Water Content of Soil Layer 4,land, +t2m,tas,air_temperature,Near-Surface Air Temperature,atmos, +tcc,clt,cloud_area_fraction,Total Cloud Fraction,atmos, +tcw,clwvi,atmosphere_cloud_condensed_water_content,Condensed Water Path,atmos, +tcwv,prw,atmosphere_water_vapor_content,Water Vapor Path,atmos, +tsn,tsn,temperature_in_surface_snow,Snow Internal Temperature,landIce, +tsr,rsdt,toa_incoming_shortwave_flux,TOA Incident Shortwave Radiation,atmos, +tsrc,rsut,toa_outgoing_shortwave_flux,TOA Outgoing Shortwave Radiation,atmos, +ttr,rlut,toa_outgoing_longwave_flux,TOA Outgoing Longwave Radiation,atmos, +ttrc,rlutcs,toa_outgoing_longwave_flux_assuming_clear_sky,"Top net thermal radiation, clear sky",atmos, +u10m,uas,eastward_wind,Eastward Near-Surface Wind,atmos, +v10m,vas,northward_wind,Northward Near-Surface Wind,atmos, +t,ta,air_temperature,Air Temperature,atmos, +u,ua,eastward_wind,U velocity,atmos, +v,va,northward_wind,V velocity,atmos, +z,zg,geopotential_height,Geopotential Height,atmos, +tp,pr,precipitation_flux,Precipitation,atmos, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 20a54dd..7bb7e3a 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,23 +1,24 @@ # coding: latin-1 import Queue +import csv import glob import shutil -import os -import numpy as np -import netCDF4 import threading +import uuid +from datetime import datetime + +import netCDF4 +import numpy as np +import os from autosubmit.config.log import Log -from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day +from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day, add_months, \ + date2str from basins import Basins from earthdiagnostics.utils import Utils, TempFile -from datetime import datetime -import uuid -import csv class DataManager(object): - def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name, num_chunks, scratch_dir, nfrp, member_digits, calendar='standard'): """ @@ -83,17 +84,266 @@ class DataManager(object): self.get_member_str(member), 'outputs', 'MMO*')): list_jobs.put((member, startdate, tarfile)) - # It's quicker to use just one for I/O reasons, at least at the moment - # numthreads = Utils.available_cpu_count() - numthreads = 1 - threads = list() - for numthread in range(0, numthreads): - t = threading.Thread(target=self._cmorize, args=(list_jobs, numthread)) - threads.append(t) - t.start() - - list_jobs.join() - return + grb_path = os.path.join(self.data_dir, self.expid, 'original_files', startdate, + self.get_member_str(member), 'outputs', '*.grb') + gribfiles = glob.glob(grb_path) + if len(gribfiles) == 0: + for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, + self.get_member_str(member), + 'outputs', 'MMA*')): + list_jobs.put((member, startdate, tarfile)) + else: + gribfiles.sort() + copied_gribfiles = list() + for gribfile in gribfiles: + shutil.copy(gribfile, os.path.join(self.scratch_dir, os.path.basename(gribfile))) + copied_gribfiles.append(os.path.join(self.scratch_dir, os.path.basename(gribfile))) + + for gribfile in copied_gribfiles: + cdo = Utils.cdo + start = parse_date(gribfile[-10:-4]) + month = '{0:02}'.format(start.month) + times = cdo.showtimestamp(input=gribfile) + times = times[0].split()[0:2] + time_diff = datetime.strptime(times[1], '%Y-%m-%dT%H:%M:%S') - datetime.strptime(times[0], + '%Y-%m-%dT%H:%M:%S') + NFRP = (time_diff.seconds // 3600) + + param_6hr = (151, 167, 168, 164, 165, 166, 129,) + param_day = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) + param_mon = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, + 177, 175, 212, 141, 180, 181, 179, 168, 243, 129, 130, 131, 132, 133) + + grid = os.path.basename(gribfile)[3:5] + + if os.path.exists('ICM{0}{1}+{2.year}{2.month:02}.grb'.format(grid, self.expid, + add_months(start, -1, + 'standard'))): + fd = open('rules_files', 'w') + fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(start)) + fd.close() + # get first timestep for each month from previous file (if possible) + if os.path.exists('ICM'): + os.remove('ICM') + Utils.execute_shell_command('grib_filter -o ICM rules_files ' + 'ICM{0}{1}+{2.year}{2.month:02}.grb ' + '{3}'.format(grid, self.expid, + add_months(start, -1, 'standard'), + gribfile)) + os.remove('rules_files') + + else: + shutil.copy(gribfile, 'ICM') + + # remap on regular Gauss grid + if grid == 'SH': + Utils.cdo.splitparam(input='-sp2gpl ICM', output=gribfile + '_') + else: + Utils.cdo.splitparam(input='ICM', output=gribfile + '_', options='-R') + # total precipitation (remove negative values) + Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' + '{0}_{{142,143}}.128.grb'.format(gribfile), + output='{0}_228.128.grb'.format(gribfile)) + os.remove('ICM') + + cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') + + # daily variables + for param in param_day: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param in (169, 177, 179): + # radiation + new_units = "W m-2" + cdo_operator = "-divc,{0} -daymean -selmon,{2} " \ + "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) + elif param == 228: + # precipitation + new_units = "kg m-2 -s" + cdo_operator = "-mulc,1000 -divc,{0} -daymean -selmon,{2} " \ + "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) + elif param == 201: + # maximum + cdo_operator = "-daymax -selmon,{1} -shifttime,-{0}hours".format(NFRP, month) + elif param == 202: + # minmimum + cdo_operator = "-daymin -selmon,{1} -shifttime,-{0}hours".format(NFRP, month) + elif param == 130: + # 850 hPa + cdo_operator = "-daymean -sellevel,85000 -selmon,{0}".format(month) + else: + # default, plain daily mean + cdo_operator = "-daymean -selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_day.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + + if new_units: + handler = Utils.openCdf('{0}_{1}_day.nc'.format(gribfile, param)) + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + handler.close() + # concat all vars in one file for day + Utils.nco.ncks(input='{0}_{1}_day.nc'.format(gribfile, param), + output='{0}_day.nc'.format(gribfile), options='-A') + os.remove('{0}_{1}_day.nc'.format(gribfile, param)) + + # monthly variables + for param in param_mon: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param in (146, 147, 176, 169, 177, 175, 179, 212): + # radiation/heat + new_units = "W m-2" + cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) + elif param in (180, 181): + # momentum flux + new_units = "N m-2" + cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) + elif param in (144, 228, 205, 182): + # precipitation/evaporation/runoff + new_units = "kg m-2 s-1" + cdo_operator = "-mulc,1000 -divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) + elif param == 201: + # mean daily maximum + cdo_operator = "-monmean -daymax -selmon,{1} " \ + "-shifttime,-{0}hours".format(NFRP, month) + elif param == 202: + # mean daily minmimum + cdo_operator = "-monmean -daymin -selmon,{1} " \ + "-shifttime,-{0}hours".format(NFRP, month) + elif param in (130, 131, 132, 133): + # upper-air + cdo_operator = "-monmean -sellevel,5000,20000,50000,85000 " \ + "-selmon,{0}".format(month) + elif param == 129: + # upper-air geopotential + new_units = "m" + cdo_operator = "-divc,9.81 -timmean -sellevel,5000,20000,50000,85000 " \ + "-selmon,{0}".format(month) + else: + # default, plain monthly mean + cdo_operator = "-monmean -selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_mon.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + handler = Utils.openCdf('{0}_{1}_mon.nc'.format(gribfile, param)) + if new_units: + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + var_name = None + for key in handler.variables.keys(): + if key + '_2' in handler.variables and key not in handler.dimensions: + var_name = key + + handler.close() + if var_name is not None: + Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), + output='{0}_{1}_mon.nc'.format(gribfile, param), + options='-O -v {0}'.format(var_name)) + + # concat all vars in one file for mon + Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), + output='{0}_mon.nc'.format(gribfile), options='-A') + os.remove('{0}_{1}_mon.nc'.format(gribfile, param)) + + # 6-hourly variables + for param in param_6hr: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param == 129: + # geopotential + new_units = "m" + cdo_operator = "-divc,9.81 -sellevel,50000 -selmon,{0}".format(month) + else: + # default, plain monthly mean + cdo_operator = "-selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + if new_units: + handler = Utils.openCdf('{0}_{1}_6hr.nc'.format(gribfile, param)) + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + handler.close() + # concat all vars in one file for 6hr + Utils.nco.ncks(input='{0}_{1}_6hr.nc'.format(gribfile, param), + output='{0}_6hr.nc'.format(gribfile), options='-A') + os.remove('{0}_{1}_6hr.nc'.format(gribfile, param)) + + for splited_file in glob.glob('{0}_???.128.grb'.format(gribfile)): + os.remove(splited_file) + + chunk_start = parse_date(startdate) + while os.path.exists(os.path.join(self.scratch_dir, + 'ICMGG{0}+{1}.grb'.format(self.expid, + date2str(chunk_start)[:-2]))): + chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + chunk_files_gg_mon = list() + chunk_files_gg_day = list() + chunk_files_gg_6h = list() + + chunk_files_sh_mon = list() + chunk_files_sh_day = list() + chunk_files_sh_6h = list() + + for month in range(0, self.chunk_size): + chunk_file = 'ICMGG{0}+{1}.grb'.format(self.expid, + date2str(add_months(chunk_start, month, + 'standard'))[:-2]) + os.remove(chunk_file) + os.remove('ICMSH' + chunk_file[5:]) + chunk_files_gg_mon.append(chunk_file + '_mon.nc') + chunk_files_gg_day.append(chunk_file + '_day.nc') + chunk_files_gg_6h.append(chunk_file + '_6hr.nc') + chunk_files_sh_mon.append('ICMSH' + chunk_file[5:] + '_mon.nc') + chunk_files_sh_day.append('ICMSH' + chunk_file[5:] + '_day.nc') + chunk_files_sh_6h.append('ICMSH' + chunk_file[5:] + '_6hr.nc') + + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_mon, + 'SH', '1m') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_day, + 'SH', '1d') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_6h, + 'SH', '6hr') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_mon, + 'GG', '1m') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_day, + 'GG', '1d') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_6h, + 'GG', '6hr') + chunk_start = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + + # It's quicker to use just one for I/O reasons, at least at the moment + # numthreads = Utils.available_cpu_count() + numthreads = 1 + threads = list() + for numthread in range(0, numthreads): + t = threading.Thread(target=self._cmorize, args=(list_jobs, numthread)) + threads.append(t) + t.start() + + list_jobs.join() + return for startdate in startdates: for member in members: @@ -108,6 +358,15 @@ class DataManager(object): self._unpack_cmorfiles(filepaths, member_path) + def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, chunk_files, grid, frequency): + merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) + for x in range(0, len(chunk_files)): + chunk_files[x] = os.path.join(self.scratch_dir, chunk_files[x]) + Utils.cdo.mergetime(input=' '.join(chunk_files), output=merged_file, options='-O') + for filepath in chunk_files: + os.remove(filepath) + self._cmorize_nc_file(merged_file, member, startdate) + def _unpack_cmorfiles(self, filepaths, member_path): threads = list() numthreads = Utils.available_cpu_count() @@ -171,44 +430,67 @@ class DataManager(object): scratch_dir = os.path.join(self.scratch_dir, str(numthread)) self._untar((tarfile,), scratch_dir) self._unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) - for filename in glob.glob(os.path.join(scratch_dir, '*.nc'.format(self.expid))): - Log.info('Processing file {0}', filename) - file_parts = os.path.basename(filename).split('_') - frequency = file_parts[1][1].lower() - - variables = dict() - variables['time_counter'] = 'time' - variables['time_counter_bnds'] = 'time_bnds' - # variables['time_counter_bounds'] = 'time_bnds' - variables['tbnds'] = 'bnds' - # variables['axis_nbounds'] = 'bnds' - variables['nav_lat'] = 'lat' - variables['nav_lon'] = 'lon' - variables['x'] = 'i' - variables['y'] = 'j' - Utils.rename_variables(filename, variables, False, True) - - handler = Utils.openCdf(filename) - - self._add_common_attributes(frequency, handler, member, startdate) - self._update_time_variables(handler, startdate) - handler.sync() + if os.path.basename(tarfile).startswith('MMA'): temp = TempFile.get() - Log.info('Splitting file {0}', filename) - for variable in handler.variables.keys(): - if variable in ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', - 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', - 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', - 'time_counter_bounds', 'ncatice', - 'nav_lat_grid_V', 'nav_lat_grid_U', 'nav_lat_grid_T', - 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T',): - continue - self.extract_variable(file_parts, filename, frequency, handler, member, startdate, temp, - variable) - Log.result('File {0} cmorized!', filename) - handler.close() - os.remove(filename) + for filename in glob.glob(os.path.join(scratch_dir, 'MMA_*_SH_*.nc')): + Utils.cdo.sp2gpl(options='-O', input=filename, output=temp) + shutil.move(temp, filename) + + sh_files = glob.glob(os.path.join(scratch_dir, 'MMA_*_SH_*.nc')) + Utils.cdo.mergetime(input=sh_files, output=os.path.join(scratch_dir, 'sh.nc')) + + gg_files = glob.glob(os.path.join(scratch_dir, 'MMA_*_GG_*.nc')) + Utils.cdo.mergetime(input=gg_files, output=os.path.join(scratch_dir, 'gg.nc')) + + for filename in sh_files + gg_files: + os.remove(filename) + + Utils.nco.ncks(input=os.path.join(scratch_dir, 'sh.nc'), + output=os.path.join(scratch_dir, 'gg.nc'), options='-A') + os.remove(os.path.join(scratch_dir, 'sh.nc')) + + tar_startdate = tarfile[0:-4].split('_')[5].split('-') + new_name = 'MMA_1m_{0[0]}_{0[1]}.nc'.format(tar_startdate) + shutil.move(os.path.join(scratch_dir, 'gg.nc'), os.path.join(scratch_dir, new_name)) + + for filename in glob.glob(os.path.join(scratch_dir, '*.nc')): + self._cmorize_nc_file(filename, member, startdate) + + def _cmorize_nc_file(self, filename, member, startdate): + Log.info('Processing file {0}', filename) + file_parts = os.path.basename(filename).split('_') + frequency = file_parts[1][1].lower() + variables = dict() + variables['time_counter'] = 'time' + variables['time_counter_bnds'] = 'time_bnds' + # variables['time_counter_bounds'] = 'time_bnds' + variables['tbnds'] = 'bnds' + # variables['axis_nbounds'] = 'bnds' + variables['nav_lat'] = 'lat' + variables['nav_lon'] = 'lon' + variables['x'] = 'i' + variables['y'] = 'j' + Utils.rename_variables(filename, variables, False, True) + handler = Utils.openCdf(filename) + self._add_common_attributes(frequency, handler, member, startdate) + self._update_time_variables(handler, startdate) + handler.sync() + temp = TempFile.get() + Log.info('Splitting file {0}', filename) + for variable in handler.variables.keys(): + if variable in ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', + 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', + 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', + 'time_counter_bounds', 'ncatice', + 'nav_lat_grid_V', 'nav_lat_grid_U', 'nav_lat_grid_T', + 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T',): + continue + self.extract_variable(file_parts, filename, frequency, handler, member, startdate, temp, + variable) + Log.result('File {0} cmorized!', filename) + handler.close() + os.remove(filename) def extract_variable(self, file_parts, filename, frequency, handler, member, startdate, temp, variable): var_cmor = Variable.get_variable(variable) @@ -232,6 +514,8 @@ class DataManager(object): frequency = 'day' elif frequency == 'm': frequency = 'mon' + elif frequency == 'h': + frequency = '6hr' else: raise Exception('Frequency {0} not supported'.format(frequency)) @@ -316,6 +600,7 @@ class DataManager(object): handler.tracking_id = str(uuid.uuid1()) handler.title = "{0} model output prepared for SPECS {1}".format(self.model, self.experiment_name) + @staticmethod def _unzip(files): for filepath in files: @@ -342,7 +627,7 @@ class DataManager(object): :param domain: variable's CMOR domain :type domain:str :param variables: variables list - :type variables: list[str] | tuple[str] + :type variables: list[str], tuple[str] :param grid: specifies if the variable must be in a interpolated grid :type grid: str :return: @@ -382,7 +667,7 @@ class DataManager(object): return file_names - def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): + def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy @@ -516,7 +801,7 @@ class DataManager(object): var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' - '{6}.nc'.format(var, domain_abreviattion, self.model, + '{6}.nc'.format(var, domain_abreviattion, self.model, self.experiment_name, startdate, member_plus, time_bound)) if region: @@ -596,13 +881,15 @@ class DataManager(object): domain_abreviattion = 'OImon' else: domain_abreviattion = domain[0].upper() + 'mon' + elif frequency == '6hr': + domain_abreviattion = '6hrPlev' else: domain_abreviattion = 'day' return domain_abreviattion def get_year(self, domain, var, startdate, member, year, grid=None, box=None): """ - Gets all the data corresponfing to a given year from the CMOR repository to the scratch folder as one file and + Gets all the data corresponding to a given year from the CMOR repository to the scratch folder as one file and returns the path to the scratch's copy. :param year: year to retrieve @@ -663,7 +950,7 @@ class DataManager(object): """ date = parse_date(startdate) chunks = list() - for chunk in range(1, self.num_chunks+1): + for chunk in range(1, self.num_chunks + 1): chunk_start = chunk_start_date(date, chunk, self.chunk_size, 'month', self.calendar) if chunk_start.year > year: break @@ -713,7 +1000,7 @@ class Variable(object): @classmethod def get_variable(cls, original_name): try: - return Variable._dict_variables[original_name] + return Variable._dict_variables[original_name.lower()] except AttributeError: Variable._dict_variables = dict() @@ -724,6 +1011,8 @@ class Variable(object): continue var = Variable(line) + if not var.short_name: + continue for old_name in line[0].split(':'): Variable._dict_variables[old_name] = var Variable._dict_variables[var.short_name] = var diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index d7339b6..f1bfb99 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ # Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/jvegas # Root path for the cmorized data to use -DATA_DIR = /esnas/exp/nemo/ +DATA_DIR = /esnas/exp/ecearth/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run @@ -13,7 +13,7 @@ FREQUENCY = mon CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin [CMOR] -FORCE = False +FORCE = True # ASSOCIATED_EXPERIMENT = # INITIALIZATION_METHOD = 1 # INITIALIZATION_DESCRIPTION = ocean: ECMWF system4, ice: DFS4.3 , atmosphere: @@ -25,7 +25,7 @@ FORCE = False [EXPERIMENT] # Experiments parameters as defined in CMOR standard INSTITUTE = BSC -MODEL = NEMO +MODEL = EC-EARTH # For those who use Autosubmit, this no need documentation # For those who not, EXPID is the unique identifier of the experiment. @@ -34,15 +34,15 @@ MODEL = NEMO # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks to process -EXPID = a05p -STARTDATES = 19580101 +EXPID = m02j +STARTDATES = 20001101 MEMBERS = 0 -MEMBER_DIGITS = 2 -CHUNK_SIZE = 12 +MEMBER_DIGITS = 1 +CHUNK_SIZE = 4 CHUNKS = 1 # Model version -NEMO_VERSION = N3.6_O1L75 +NEMO_VERSION = Ec3.0_O1L46 # [EXPERIMENT] # INSTITUTE = IC3 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 08e13ce..4406fb6 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -194,13 +194,10 @@ class Diags(object): def _link_file(self, source, destiny): if not os.path.exists(source): Log.user_warning('File {0} is not available for {1}', destiny, self.nemo_version) + return - if os.path.exists(destiny): - if os.stat(source).st_size == os.stat(destiny).st_size: - Log.info('File {0} already exists', destiny) - return - else: - os.remove(destiny) + if os.path.lexists(destiny): + os.remove(destiny) os.symlink(source, destiny) Log.info('File {0} ready', destiny) @@ -273,8 +270,8 @@ class Diags(object): def main(): - """ Entry point for the Earth Diagnostics. For more detailed documentation, use -h option - + """ + Entry point for the Earth Diagnostics. For more detailed documentation, use -h option """ parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') parser.add_argument('-v', '--version', action='version', version='0.1', diff --git a/testing_diags_moore.job b/testing_diags_moore.job index e51487d..05df067 100755 --- a/testing_diags_moore.job +++ b/testing_diags_moore.job @@ -15,4 +15,4 @@ source /home/Earth/jvegas/virtualenvs/diags/bin/activate export PYTHONPATH=/home/Earth/jvegas/pyCharm/ocean_diagnostics/:$PYTHONPATH cd /home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/ -./diags.py -lc DEBUG +./diags.py -lc DEBUG -f /home/Earth/jvegas/diags_i00k.conf -- GitLab From 2c79b3320688b963a186870a9b6503e78e05ed09 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 1 Jul 2016 11:26:28 +0200 Subject: [PATCH 104/268] Removed threading for cmorization (does not improve performance) --- .idea/dictionaries/jvegas.xml | 10 ++++++++++ earthdiagnostics/datamanager.py | 35 +++++---------------------------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/.idea/dictionaries/jvegas.xml b/.idea/dictionaries/jvegas.xml index 9ff66da..1563054 100644 --- a/.idea/dictionaries/jvegas.xml +++ b/.idea/dictionaries/jvegas.xml @@ -1,10 +1,20 @@ + cdftools cmor + cmorized + ecearth + eleftheria + esnas + exarchou + guemas + jvegas leadtime nemo orca + regidor + startdate \ No newline at end of file diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 7bb7e3a..c7ac3bc 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -75,7 +75,6 @@ class DataManager(object): """ # Check if cmorized and convert if not if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles')): - list_jobs = Queue.Queue() for startdate in startdates: for member in members: @@ -83,7 +82,7 @@ class DataManager(object): for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, self.get_member_str(member), 'outputs', 'MMO*')): - list_jobs.put((member, startdate, tarfile)) + self._unpack_tar(member, startdate, tarfile) grb_path = os.path.join(self.data_dir, self.expid, 'original_files', startdate, self.get_member_str(member), 'outputs', '*.grb') gribfiles = glob.glob(grb_path) @@ -91,7 +90,7 @@ class DataManager(object): for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, self.get_member_str(member), 'outputs', 'MMA*')): - list_jobs.put((member, startdate, tarfile)) + self._unpack_tar(member, startdate, tarfile) else: gribfiles.sort() copied_gribfiles = list() @@ -332,17 +331,6 @@ class DataManager(object): self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_6h, 'GG', '6hr') chunk_start = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') - - # It's quicker to use just one for I/O reasons, at least at the moment - # numthreads = Utils.available_cpu_count() - numthreads = 1 - threads = list() - for numthread in range(0, numthreads): - t = threading.Thread(target=self._cmorize, args=(list_jobs, numthread)) - threads.append(t) - t.start() - - list_jobs.join() return for startdate in startdates: @@ -410,24 +398,11 @@ class DataManager(object): Log.info('Moving {0} to {1}'.format(filename, good)) Utils.move_file(filepath, good) - def _cmorize(self, queue, numthread): - scratch_dir = os.path.join(self.scratch_dir, str(numthread)) - if not os.path.exists(scratch_dir): - os.mkdir(scratch_dir) - while not queue.empty(): - try: - member, startdate, tarfile = queue.get(timeout=1) - self._unpack_tar(member, startdate, tarfile, numthread) - except Queue.Empty: - pass - queue.task_done() - os.rmdir(scratch_dir) - return - - def _unpack_tar(self, member, startdate, tarfile, numthread): + def _unpack_tar(self, member, startdate, tarfile): Log.info('Unpacking {0}', tarfile) - scratch_dir = os.path.join(self.scratch_dir, str(numthread)) + scratch_dir = os.path.join(self.scratch_dir, 'CMOR') + os.makedirs(scratch_dir) self._untar((tarfile,), scratch_dir) self._unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) -- GitLab From e7af30a8e50e1e1cda737561e16ae3ab7319b41e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 1 Jul 2016 13:09:58 +0200 Subject: [PATCH 105/268] Updated CMOR for i00k --- earthdiagnostics/cmor_table.csv | 374 ++++++++++++++++---------------- earthdiagnostics/datamanager.py | 18 +- 2 files changed, 208 insertions(+), 184 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 2292cd6..9c3271f 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -1,55 +1,156 @@ Variable,Shortname,Name,Long name,Domain,Basin +al,al,surface_albedo,Albedo,atmos, +asn,snal,snow_albedo,Snow Albedo,landIce, +bgfrcsal,bgfrcsal,change_over_time_in_heat_content_from_forcing,Change Over Time In Salt Content from forcing,ocean, +bgfrctem,bgfrctem,change_over_time_in_heat_content_from_forcing,Change Over Time In Heat Content from forcing,ocean, +bgfrcvol,bgfrcvol,change_over_time_in_volume_from_forcing,Change Over Time In Volume From Forcing,ocean, +bgheatco,bgheatco,change_over_time_in_heat_content,Change Over Time in Sea Water Heat Content,ocean, +bgsaline,bgsaline,change_over_time_in_sea_water_practical_salinity,Change Over Time in Sea Water Salinity,ocean, +bgsaltco,bgsaltco,change_over_time_in_salt_content,Change Over Time in Sea Water Salt Content,ocean, +bgtemper,bgtemper,change_over_time_in_sea_water_potential_temperature,Change Over Time in Sea Water Potential Temperature,ocean, +bgvole3t,bgvole3t,change_over_time_in_volume_variation,Change Over Time in Volume Variation (e3t),ocean, +bgvolssh,bgvolssh,change_over_time_in_sea_surface_height,Change Over Time in Sea Surface Height,ocean, +ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,atmos, +cp,prc,convective_precipitation_flux,Convective Precipitation,atmos, +d2m,tdps,dew_point_temperature,2m Dewpoint Temperature,atmos, +e,evspsbl,water_evaporation_flux,Evaporation,atmos, +ewss,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,atmos, +fal,fal,forecast_albedo,Forecast albedo,atmos, +hcc,clh,high_cloud_area_fraction,High Cloud Fraction,atmos, +heatc,heatc,integral_of_sea_water_potential_temperature_wrt_depth_expressed_as_heat_content,Heat content vertically integrated,ocean, hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic Northward Ocean Heat Transport,ocean, +ibgarea,sicga,sea_ice_content,Global Mean Sea Ice Content,seaIce, +ibgfrcsfx,ibgfrcsfx,global_mean_forcing_salt,global mean forcing salt (sfx),seaIce, +ibgfrcvol,ibgfrcvol,globa_mean_forcing_volume,global mean forcing volume (emp),seaIce, +ibgheatco,hcicega,global mean ice heat content,global mean ice heat content,seaIce, +ibghfxbog,ibghfxbog,heat_fluxes_causing_bottom_ice_growth,heat fluxes causing bottom ice growth,seaIce, +ibghfxbom,ibghfxbom,heat_fluxes_causing_bottom_ice_melt,heat fluxes causing bottom ice melt,seaIce, +ibghfxdhc,ibghfxdhc,Heat_content_variation_in_snow_and_ice,Heat content variation in snow and ice,seaIce, +ibghfxdif,ibghfxdif,heat_fluxes_causing_ice temperature_change,heat fluxes causing ice temperature change,seaIce, +ibghfxdyn,ibghfxdyn,heat_fluxes_from_ice-ocean_exchange_during_dynamic,heat fluxes from ice-ocean exchange during dynamic,seaIce, +ibghfxin,ibghfxin,total_heat_fluxes_at_the_ice_surface,total heat fluxes at the ice surface,seaIce, +ibghfxopw,ibghfxopw,heat_fluxes_causing_open_water_ice_formation,heat fluxes causing open water ice formation,seaIce, +ibghfxout,ibghfxout,non_solar_heat_fluxes_received_by_the_ocean,non solar heat fluxes received by the ocean,seaIce, +ibghfxres,ibghfxres,heat_fluxes_from_ice-ocean_exchange_during_resultant,heat fluxes from ice-ocean exchange during resultant,seaIce, +ibghfxsnw,ibghfxsnw,heat_fluxes_from_snow-ocean_exchange,heat fluxes from snow-ocean exchange,seaIce, +ibghfxspr,ibghfxspr,Heat_content_of_snow_precip,Heat content of snow precip,seaIce, +ibghfxsub,ibghfxsub,heat_fluxes_from_sublimation,heat fluxes from sublimation,seaIce, +ibghfxsum,ibghfxsum,heat_fluxes_causing_surface_ice_melt,heat fluxes causing surface ice melt,seaIce, +ibghfxthd,ibghfxthd,heat_fluxes_from_ice-ocean_exchange_during_thermo,heat fluxes from ice-ocean exchange during thermo,seaIce, +ibgsaline,ssiga,sea_ice_salinity,Global Mean Sea Ice Salinity ,seaIce, +ibgsaltco,sisaltcga,global mean ice salt content,global mean ice salt content,seaIce, +ibgsfx,ibgsfxga,salt_flux,global mean salt flux (total),seaIce, +ibgsfxbog,ibgsfxbogga,salt_flux_thermo,global mean salt flux (thermo),seaIce, +ibgsfxbom,ibgsfxbomga,salt_flux_bottom_melt,global mean salt flux (bottom melt),seaIce, +ibgsfxbri,ibgsfxbriga,salt_flux_brines,global mean salt flux (brines),seaIce, +ibgsfxdyn,ibgsfxdynga,salt_flux_dynamic,global mean salt flux (dynamic),seaIce, +ibgsfxopw,ibgsfxopwga,salt_flux_open_waters,global mean salt flux (open water),seaIce, +ibgsfxres,ibgsfxresga,salt_flux_resultant,global mean salt flux (resultant),seaIce,Atl +ibgsfxsni,ibgsfxsniga,salt_flux_snow_ice_growth,global mean salt flux (snow-ice growth),seaIce,Ind +ibgsfxsum,ibgsfxsumga,salt_flux_surface_melt,global mean salt flux (surface melt),seaIce,IndPac +ibgtemper,sitempga,sea_ice_temperature,Global Mean Sea Ice Temperature,seaIce,Pac +ibgvfx,ibgvfxga,volume_flux_emp,global mean volume flux (emp),seaIce, +ibgvfxbog,ibgvfxbogga,volume_flux_bottom_growth,global mean volume flux (bottom growth),seaIce, +ibgvfxbom,ibgvfxbomga,volume_flux_bottom_melt,global mean volume flux (bottom melt),seaIce, +ibgvfxdyn,ibgvfxdynga,volume_flux_dynamic_growth,global mean volume flux (dynamic growth),seaIce, +ibgvfxopw,ibgvfxopwga,volume_flux_open_water_growth,global mean volume flux (open water growth),seaIce, +ibgvfxres,ibgvfxresga,volume_flux_resultant,global mean volume flux (resultant),seaIce, +ibgvfxsni,ibgvfxsniga,volume_flux_snow_ice_growth,global mean volume flux (snow-ice growth),seaIce, +ibgvfxsnw,ibgvfxsnwga,volume_flux_snow_melt,global mean volume flux (snow melt),seaIce, +ibgvfxspr,ibgvfxsprga,snheco,global mean volume flux (snow precip),seaIce, +ibgvfxsub,ibgvfxsubga,volume_flux_snow_sublimation,global mean volume flux (snow sublimation),seaIce, +ibgvfxsum,ibgvfxsumga,volume_flux_surface_melt,global mean volume flux (surface melt),seaIce, +ibgvolgrm,ibgvolgrm,global_mean_ice_growth+melt_volume,global mean ice growth+melt volume,seaIce, +ibgvoltot,sivolga,sea_ice_volume,Global Mean Sea Ice Volume,seaIce, ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce, iice_etd,iiceetd,brine_volume_distribution,Brine volume distribution,seaIce, -iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce, -iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce, -iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce, -iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of Sea Ice,seaIce, +iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce,Atl +iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce,Ind +iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,IndPac +iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of Sea Ice,seaIce,Pac iicebome,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of Melt at Sea Ice Base,seaIce, iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce, iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thickness,seaIce, -Iiceconc:siconc:soicecov:ileadfra,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce, +iiceconc:siconc:soicecov:ileadfra,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce, iicedive:sidive,divice,Strain Rate Divergence of Sea Ice,divergence_of_sea_ice_velocity,seaIce, iicedypr,iicedypr,daily_dynamic_ice_production,Daily dynamic ice production,seaIce, iiceheco,siheco,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea Ice Heat Content,seaIce, iicelapr,iicelapr,daily_lateral_thermo_ice_production,Daily lateral thermo ice prod.,seaIce, -iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce, -iicesali:iice_std,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce, -iicesflx,iicesflx,solar_flux_ice_ocean_surface,Solar flux at ice/ocean surface,seaIce, -iiceshea,iiceshea,shear,Shear,seaIce, -iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce, -iicestre,streng,compressive_strength_of_sea_ice,Compressive Sea Ice Strength,seaIce, -iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of Melt at Upper Surface of Sea Ice,seaIce, -iicesurt:soicetem:sistem,tsice,surface_temperature,Surface Temperature of Sea Ice,seaIce, -iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce, -iicethic:sithic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce, -iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce, -iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce, -iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce, -iicfsbri,iicfsbri,brine_salt_flux,Fsbri - brine salt flux,seaIce, -iicfseqv,iicfseqv,equivalent_FW_salt_flux,Fseqv - equivalent FW salt flux,seaIce, -ioceflxb,ioceflxb,oceanic_flux_ar_ice_base,Oceanic flux at the ice base,seaIce, -iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release,seaIce, -iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce, -iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce, +iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce,Glob +iiceprod,sigr,ice_production,Ice Production,seaIce, +iicesali:iice_std,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce,Atl +iicesflx,iicesflx,solar_flux_ice_ocean_surface,Solar flux at ice/ocean surface,seaIce,Ind +iiceshea,iiceshea,shear,Shear,seaIce,IndPac +iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce,Pac +iicestre,streng,compressive_strength_of_sea_ice,Compressive Sea Ice Strength,seaIce,Atl +iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of Melt at Upper Surface of Sea Ice,seaIce,Glob +iicesurt:soicetem:sistem,tsice,surface_temperature,Surface Temperature of Sea Ice,seaIce,Ind +iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce,IndPac +iicethic:sithic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce,Pac +iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce,Atl +iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce,Glob +iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce,Ind +iicfsbri,iicfsbri,brine_salt_flux,Fsbri - brine salt flux,seaIce,IndPac +iicfseqv,iicfseqv,equivalent_FW_salt_flux,Fseqv - equivalent FW salt flux,seaIce,Pac +ioceflxb,ioceflxb,oceanic_flux_ar_ice_base,Oceanic flux at the ice base,seaIce,Atl +iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release,seaIce,Glob +iocesafl,iocesafl,salt_flux_ocean_surface,Salt Flux at Ocean Surface,seaIce,Ind +iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce,IndPac +iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce,Pac iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce, +iowaflup,ficeocean,ice_ocean_water_flux,Ice=>ocean net freshwater,ocean, isnoheco,snheco,snow_heat_content,Snow total heat content,seaIce, isnowpre,prsn,snowfall_flux,Surface Snowfall Rate into the Sea Ice Portion of the Grid Cell,seaIce, isnowthi,snthic,surface_snow_thickness,Surface Snow Thickness,seaIce, isssalin,isssalin,sea_surface_salinity,Sea surface salinity,seaIce, isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce, +istl1,tsice,surface_temperature,Surface Temperature of Ice,landICe, +lcc,clh,low_cloud_area_fraction,Low Cloud Fraction,atmos, +lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos, +mcc,clh,medium_cloud_area_fraction,Medium Cloud Fraction,atmos, +mldkz5,mldkz5,ocean_mixed_layer_thickness_defined_by_vertical_tracer_diffusivity,Turbocline depth (Kz = 5e-4),ocean, +mn2t,tasmin,air_temperature,Daily Minimum Near-Surface Air Temperature,atmos, msftmyz,zomsfglo,msftmyz,Meridional Mass Streamfunction,ocean, msftmyza,zomsfatl,msftmyza,Meridional Mass Streamfunction in the Atlantic,ocean, msftmyzba,zomsfeiv,ocean_meridional_overturning_mass_streamfunction_due_to_bolus_advection,Meridional Mass Streamfunction Due to Bolus Advection,ocean, +msl,psl,air_pressure_at_sea_level,Sea Level Pressure,atmos, +mx2t,tasmax,air_temperature,Daily Maximum Near-Surface Air Temperature,atmos, +nsss,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,atmos, +q,hus,specific_humidity,Specific humidity,atmos, +qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,non-solar heat flux at ice surface: sum over categories,seaIce, +qt_ice,qtice,surface_downward_heat_flux_in_air,Surface Downward Heat Flux in Air,seaIce, +qt_oce,hfds,surface_downward_heat_flux_in_sea_water,Downward Heat Flux at Sea Water Surface,ocean, +ro,mrro,runoff_flux,Total Runoff,atmos, +salincat,ssicat,sea_ice_salinity_in_categories,Sea-Ice Bulk salinity for categories,seaIce, +saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrated,ocean, +sbgheatco,hcsnga,global mean snow heat content,global mean snow heat content,seaIce, +sbgvoltot,snvolga,snow_volume,Global Mean Snow Volume,seaIce, +scmastot,masso,sea_water_mass,Sea Water Mass ,ocean, +scsaltot,soga,sea_water_salinity,Global Mean Sea Water Salinity ,ocean, +scsshste,zossga,global_average_steric_sea_level_change,Global Average Steric Sea Level Change ,ocean, +scsshtot,zosga,global_average_sea_level_change,Global Average Sea Level Change ,ocean, +scsshtst,zostoga,snthic,Global Average Thermosteric Sea Level Change ,ocean, +sctemtot,thetaoga,sea_water_potential_temperature,Global Average Sea Water Potential Temperature ,ocean, +scvoltot,volo,sea_water_volume,Sea Water Volume ,ocean, +sd,snld,lwe_thickness_of_surface_snow_amount,Snow Depth,atmos, +sf,prsn,snowfall_flux,Snowfall Flux,atmos, +si,si,solar_insolation,Solar insolation,atmos, +sibricat,ibrinvolcat,brine_volume_in_categories,Brine volume for categories,seaIce, +sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea Ice Volume per gridcell area unit,seaIce, +skt,ts,surface_temperature,Surface Temperature,atmos, +slhf,hfls,surface_upward_latent_heat_flux,Surface Upward Latent Heat Flux,atmos, sltnortha,sltnortha,northward_ocean_salt_transport,Atlantic Northward Ocean Salt Transport,ocean, +snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow Volume per gridcell area unit,seaIce, so20chgt,t20d,depth_of_isosurface_of_sea_water_potential_temperature,,ocean, +sobowlin,bowlin,bowl_index,Bowl Index,ocean, sohefldo,hfds,surface_downward_heat_flux_in_sea_water,Downward Heat Flux at Sea Water Surface,ocean, -sohtatl,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,Atl -sohtind,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,Ind -sohtipc,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,IndPac -sohtpac,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean,Pac +sohtatl,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, +sohtind,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, +sohtipc,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, +sohtpac,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, soicealb,ialb,sea_ice_albedo,Sea Ice Albedo,seaIce, +soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,eddy induced vel. coeff. at w-point,ocean, +soleahtw,soleahtw,lateral_eddy_diffusivity,lateral eddy diffusivity,ocean, somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (Turbocline),ocean, somxl010:mldr10_1,mlotst,ocean_mixed_layer_thickness_defined_by_sigma_t,Ocean Mixed Layer Thickness Defined by Sigma T ,ocean, sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward Ocean Heat Transport due to Advection ,ocean, @@ -60,162 +161,22 @@ sopstadv,sltbasinadv,northward_ocean_salt_transport_due_to_advection,Northward O sopsteiv,sltbasinba,northward_ocean_salt_transport_due_to_bolus_advection,Northward Ocean Salt Transport due to Bolus Advection ,ocean, sopstldf,sltbasindif,northward_ocean_salt_transport_due_to_diffusion,Northward Ocean Salt Transport due to Diffusion,ocean, sopstove,sltovovrt,northward_ocean_salt_transport_due_to_overturning,Northward Ocean Salt Transport due to Overturning ,ocean, +sorunoff,friver,water_flux_into_sea_water_from_rivers,Water Flux into Sea Water From Rivers ,ocean, +sosalflx,sfs,salt_flux_surface,Surface Salt Flux,ocean, sosaline,sos,sea_surface_salinity,Sea Surface Salinity ,ocean, soshfldo,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net Downward Shortwave Radiation at Sea Water Surface ,ocean, sossheigh:sossheig,zos,sea_surface_height_above_geoid,Sea Surface Height Above Geoid ,ocean, sosstsst,tos,sea_surface_temperature,Sea Surface Temperature ,ocean, -sostatl,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Atl -sostind,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Ind -sostipc,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,IndPac -sostpac,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean,Pac +sostatl,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean, +sostind,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean, +sostipc,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean, +sostpac,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean, sothedep,sothedep,thermocline_depth,Thermocline Depth (max dT/dz),ocean, -sozotaux,tauuo,surface_downward_x_stress,Surface Downward X Stress ,ocean, -sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface Downward Y Stress ,ocean, -tos,sosstsst,sea_surface_temperature,Sea Surface Temperature,ocean, -vomecrty,vo,sea_water_y_velocity,Sea Water Y Velocity,ocean, -vosaline,so,sea_water_salinity,Sea Water Salinity,ocean, -votemper,thetao,sea_water_potential_temperature,Sea Water Potential Temperature,ocean, -vozocrtx,uo,sea_water_x_velocity,Sea Water X Velocity,ocean, -zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,Glob -zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction,Ocean Meridional Overturning Volume Streamfunction due to Bolus Advection ,ocean, -zomsfglo,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,Atl -zomsfind,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,Ind -zomsfipc,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,IndPac -zomsfpac,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean,Pac -zosalatl,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,Atl -zosalglo,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,Glob -zosalind,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,Ind -zosalipc,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,IndPac -zosalpac,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean,Pac -zosrfatl,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,Atl -zosrfglo,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,Glob -zosrfind,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,Ind -zosrfipc,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,IndPac -zosrfpac,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean,Pac -zotematl,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Atl -zotemglo,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Glob -zotemind,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Ind -zotemipc,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,IndPac -zotempac,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean,Pac -tossq,tossq,square_of_sea_surface_temperature,Square of Sea Surface Temperature ,ocean, -zossq,zossq,square_of_sea_surface_height_above_geoid,Square of Sea Surface Height Above Geoid ,ocean, -mldkz5,mldkz5,ocean_mixed_layer_thickness_defined_by_vertical_tracer_diffusivity,Turbocline depth (Kz = 5e-4),ocean, -heatc,heatc,integral_of_sea_water_potential_temperature_wrt_depth_expressed_as_heat_content,Heat content vertically integrated,ocean, -saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrated,ocean, -qt_oce,hfds,surface_downward_heat_flux_in_sea_water,Downward Heat Flux at Sea Water Surface,ocean, -sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea Ice Volume per gridcell area unit,seaIce, -snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow Volume per gridcell area unit,seaIce, -utau_ice:iocestru,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,seaIce, -vtau_ice:iocestrv,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,seaIce, -scvoltot,volo,sea_water_volume,Sea Water Volume ,ocean, -scsshtot,zosga,global_average_sea_level_change,Global Average Sea Level Change ,ocean, -scsshste,zossga,global_average_steric_sea_level_change,Global Average Steric Sea Level Change ,ocean, -scsshtst,zostoga,snthic,Global Average Thermosteric Sea Level Change ,ocean, -scmastot,masso,sea_water_mass,Sea Water Mass ,ocean, -sctemtot,thetaoga,sea_water_potential_temperature,Global Average Sea Water Potential Temperature ,ocean, -scsaltot,soga,sea_water_salinity,Global Mean Sea Water Salinity ,ocean, -bgtemper,bgtemper,change_over_time_in_sea_water_potential_temperature,Change Over Time in Sea Water Potential Temperature,ocean, -bgsaline,bgsaline,change_over_time_in_sea_water_practical_salinity,Change Over Time in Sea Water Salinity,ocean, -bgheatco,bgheatco,change_over_time_in_heat_content,Change Over Time in Sea Water Heat Content,ocean, -bgsaltco,bgsaltco,change_over_time_in_salt_content,Change Over Time in Sea Water Salt Content,ocean, -bgvolssh,bgvolssh,change_over_time_in_sea_surface_height,Change Over Time in Sea Surface Height,ocean, -bgvole3t,bgvole3t,change_over_time_in_volume_variation,Change Over Time in Volume Variation (e3t),ocean, -bgfrcvol,bgfrcvol,change_over_time_in_volume_from_forcing,Change Over Time In Volume From Forcing,ocean, -bgfrctem,bgfrctem,change_over_time_in_heat_content_from_forcing,Change Over Time In Heat Content from forcing,ocean, -bgfrcsal,bgfrcsal,change_over_time_in_heat_content_from_forcing,Change Over Time In Salt Content from forcing,ocean, -ibgvoltot,sivolga,sea_ice_volume,Global Mean Sea Ice Volume,seaIce, -sbgvoltot,snvolga,snow_volume,Global Mean Snow Volume,seaIce, -ibgarea,sicga,sea_ice_content,Global Mean Sea Ice Content,seaIce, -ibgsaline,ssiga,sea_ice_salinity,Global Mean Sea Ice Salinity ,seaIce, -ibgtemper,sitempga,sea_ice_temperature,Global Mean Sea Ice Temperature,seaIce, -ibgheatco,hcicega,global mean ice heat content,global mean ice heat content,seaIce, -sbgheatco,hcsnga,global mean snow heat content,global mean snow heat content,seaIce, -ibgsaltco,sisaltcga,global mean ice salt content,global mean ice salt content,seaIce, -ibgvfx,ibgvfxga,volume_flux_emp,global mean volume flux (emp),seaIce, -ibgvfxbog,ibgvfxbogga,volume_flux_bottom_growth,global mean volume flux (bottom growth),seaIce, -ibgvfxopw,ibgvfxopwga,volume_flux_open_water_growth,global mean volume flux (open water growth),seaIce, -ibgvfxsni,ibgvfxsniga,volume_flux_snow_ice_growth,global mean volume flux (snow-ice growth),seaIce, -ibgvfxdyn,ibgvfxdynga,volume_flux_dynamic_growth,global mean volume flux (dynamic growth),seaIce, -ibgvfxbom,ibgvfxbomga,volume_flux_bottom_melt,global mean volume flux (bottom melt),seaIce, -ibgvfxsum,ibgvfxsumga,volume_flux_surface_melt,global mean volume flux (surface melt),seaIce, -ibgvfxres,ibgvfxresga,volume_flux_resultant,global mean volume flux (resultant),seaIce, -ibgvfxspr,ibgvfxsprga,snheco,global mean volume flux (snow precip),seaIce, -ibgvfxsnw,ibgvfxsnwga,volume_flux_snow_melt,global mean volume flux (snow melt),seaIce, -ibgvfxsub,ibgvfxsubga,volume_flux_snow_sublimation,global mean volume flux (snow sublimation),seaIce, -ibgsfx,ibgsfxga,salt_flux,global mean salt flux (total),seaIce, -ibgsfxbri,ibgsfxbriga,salt_flux_brines,global mean salt flux (brines),seaIce, -ibgsfxdyn,ibgsfxdynga,salt_flux_dynamic,global mean salt flux (dynamic),seaIce, -ibgsfxres,ibgsfxresga,salt_flux_resultant,global mean salt flux (resultant),seaIce, -ibgsfxbog,ibgsfxbogga,salt_flux_thermo,global mean salt flux (thermo),seaIce, -ibgsfxopw,ibgsfxopwga,salt_flux_open_waters,global mean salt flux (open water),seaIce, -ibgsfxsni,ibgsfxsniga,salt_flux_snow_ice_growth,global mean salt flux (snow-ice growth),seaIce, -ibgsfxbom,ibgsfxbomga,salt_flux_bottom_melt,global mean salt flux (bottom melt),seaIce, -ibgsfxsum,ibgsfxsumga,salt_flux_surface_melt,global mean salt flux (surface melt),seaIce, -ibghfxdhc,ibghfxdhc,Heat_content_variation_in_snow_and_ice,Heat content variation in snow and ice,seaIce, -ibghfxspr,ibghfxspr,Heat_content_of_snow_precip,Heat content of snow precip,seaIce, -ibghfxres,ibghfxres,heat_fluxes_from_ice-ocean_exchange_during_resultant,heat fluxes from ice-ocean exchange during resultant,seaIce, -ibghfxsub,ibghfxsub,heat_fluxes_from_sublimation,heat fluxes from sublimation,seaIce, -ibghfxdyn,ibghfxdyn,heat_fluxes_from_ice-ocean_exchange_during_dynamic,heat fluxes from ice-ocean exchange during dynamic,seaIce, -ibghfxthd,ibghfxthd,heat_fluxes_from_ice-ocean_exchange_during_thermo,heat fluxes from ice-ocean exchange during thermo,seaIce, -ibghfxsum,ibghfxsum,heat_fluxes_causing_surface_ice_melt,heat fluxes causing surface ice melt,seaIce, -ibghfxbom,ibghfxbom,heat_fluxes_causing_bottom_ice_melt,heat fluxes causing bottom ice melt,seaIce, -ibghfxbog,ibghfxbog,heat_fluxes_causing_bottom_ice_growth,heat fluxes causing bottom ice growth,seaIce, -ibghfxdif,ibghfxdif,heat_fluxes_causing_ice temperature_change,heat fluxes causing ice temperature change,seaIce, -ibghfxopw,ibghfxopw,heat_fluxes_causing_open_water_ice_formation,heat fluxes causing open water ice formation,seaIce, -ibghfxout,ibghfxout,non_solar_heat_fluxes_received_by_the_ocean,non solar heat fluxes received by the ocean,seaIce, -ibghfxin,ibghfxin,total_heat_fluxes_at_the_ice_surface,total heat fluxes at the ice surface,seaIce, -ibghfxsnw,ibghfxsnw,heat_fluxes_from_snow-ocean_exchange,heat fluxes from snow-ocean exchange,seaIce, -ibgfrcvol,ibgfrcvol,globa_mean_forcing_volume,global mean forcing volume (emp),seaIce, -ibgfrcsfx,ibgfrcsfx,global_mean_forcing_salt,global mean forcing salt (sfx),seaIce, -ibgvolgrm,ibgvolgrm,global_mean_ice_growth+melt_volume,global mean ice growth+melt volume,seaIce, -vozoeivu,voeivu,sea_water_x_EIV_current,Zonal EIV Current,ocean, -vomeeivv,voeivv,sea_water_y_EIV_current,Meridional EIV Current,ocean, -iowaflup,ficeocean,ice_ocean_water_flux,Ice=>ocean net freshwater,ocean, +sowaflcd,fdilution,dilution_water_flux,concentration/dilution water flux,ocean, sowaflep,fatmosocean,atmosphere_ocean_water_flux,atmos=>ocean net freshwater,ocean, sowaflup,fupward,upward_water_flux,Net Upward Water Flux,ocean, -sorunoff,friver,water_flux_into_sea_water_from_rivers,Water Flux into Sea Water From Rivers ,ocean, -sowaflcd,fdilution,dilution_water_flux,concentration/dilution water flux,ocean, -sosalflx,sfs,salt_flux_surface,Surface Salt Flux,ocean, -sobowlin,bowlin,bowl_index,Bowl Index,ocean, -iiceprod,sigr,ice_production,Ice Production,seaIce, -iocesafl,iocesafl,salt_flux_ocean_surface,Salt Flux at Ocean Surface,seaIce, -vovecrtz,zo,sea_water_z_velocity,Sea Water Z Velocity,ocean, -voveeivw,voeivz,sea_water_z_EIV_current,Vertical EIV Current,ocean, -votkeavt,votkeavt,vertical_eddy_diffusivity,Vertical Eddy Diffusivity,ocean, -votkeevd,votkeevd,enhanced_vertical_diffusivity,Enhanced Vertical Diffusivity,ocean, -votkeavm,votkeavm,vertical_eddy_viscosity,Vertical Eddy Viscosity,ocean, -votkeevm,votkeevm,enhanced_vertical_viscosity,Enhanced Vertical Viscosity,ocean, -voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt Vertical Eddy Diffusivity,ocean, -soleahtw,soleahtw,lateral_eddy_diffusivity,lateral eddy diffusivity,ocean, -soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,eddy induced vel. coeff. at w-point,ocean, -salincat,ssicat,sea_ice_salinity_in_categories,Sea-Ice Bulk salinity for categories,seaIce, -sibricat,ibrinvolcat,brine_volume_in_categories,Brine volume for categories,seaIce, -qt_ice,qtice,surface_downward_heat_flux_in_air,Surface Downward Heat Flux in Air,seaIce, -qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,non-solar heat flux at ice surface: sum over categories,seaIce, -al,al,surface_albedo,Albedo,atmos, -asn,snal,snow_albedo,Snow Albedo,landIce, -ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,atmos, -cp,prc,convective_precipitation_flux,Convective Precipitation,atmos, -d2m,tdps,dew_point_temperature,2m Dewpoint Temperature,atmos, -e,evspsbl,water_evaporation_flux,Evaporation,atmos, -ewss,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,atmos, -fal,fal,forecast_albedo,Forecast albedo,atmos, -hcc,clh,high_cloud_area_fraction,High Cloud Fraction,atmos, -istl1,tsice,surface_temperature,Surface Temperature of Ice,landICe, -lcc,clh,low_cloud_area_fraction,Low Cloud Fraction,atmos, -lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos, -mcc,clh,medium_cloud_area_fraction,Medium Cloud Fraction,atmos, -mn2t,tasmin,air_temperature,Daily Minimum Near-Surface Air Temperature,atmos, -msl,psl,air_pressure_at_sea_level,Sea Level Pressure,atmos, -mx2t,tasmax,air_temperature,Daily Maximum Near-Surface Air Temperature,atmos, -nsss,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,atmos, -q,hus,specific_humidity,Specific humidity,atmos, -ro,mrro,runoff_flux,Total Runoff,atmos, -sd,snld,lwe_thickness_of_surface_snow_amount,Snow Depth,atmos, -sf,prsn,snowfall_flux,Snowfall Flux,atmos, -si,si,solar_insolation,Solar insolation,atmos, -skt,ts,surface_temperature,Surface Temperature,atmos, -slhf,hfls,surface_upward_latent_heat_flux,Surface Upward Latent Heat Flux,atmos, +sozotaux,tauuo,surface_downward_x_stress,Surface Downward X Stress ,ocean, +sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface Downward Y Stress ,ocean, sshf,hfss,surface_upward_sensible_heat_flux,Surface Upward Sensible Heat Flux,atmos, ssr,rss,surface_shortwave_flux_in_air,Surface Shortwave Radiation,atmos, ssrc,rsscs,surface_shortwave_flux_in_air_assuming_clear_sky,Surface Clear-Sky Shortwave Radiation,atmos, @@ -232,19 +193,70 @@ swvl1,mrlsl1,moisture_content_of_soil_layer_1, Water Content of Soil Layer 1,lan swvl2,mrlsl2,moisture_content_of_soil_layer_2, Water Content of Soil Layer 2,land, swvl3,mrlsl3,moisture_content_of_soil_layer_3, Water Content of Soil Layer 3,land, swvl4,mrlsl4,moisture_content_of_soil_layer_4, Water Content of Soil Layer 4,land, +t,ta,air_temperature,Air Temperature,atmos, t2m,tas,air_temperature,Near-Surface Air Temperature,atmos, tcc,clt,cloud_area_fraction,Total Cloud Fraction,atmos, tcw,clwvi,atmosphere_cloud_condensed_water_content,Condensed Water Path,atmos, tcwv,prw,atmosphere_water_vapor_content,Water Vapor Path,atmos, +tos,sosstsst,sea_surface_temperature,Sea Surface Temperature,ocean, +tossq,tossq,square_of_sea_surface_temperature,Square of Sea Surface Temperature ,ocean, +tp,pr,precipitation_flux,Precipitation,atmos, tsn,tsn,temperature_in_surface_snow,Snow Internal Temperature,landIce, tsr,rsdt,toa_incoming_shortwave_flux,TOA Incident Shortwave Radiation,atmos, tsrc,rsut,toa_outgoing_shortwave_flux,TOA Outgoing Shortwave Radiation,atmos, ttr,rlut,toa_outgoing_longwave_flux,TOA Outgoing Longwave Radiation,atmos, ttrc,rlutcs,toa_outgoing_longwave_flux_assuming_clear_sky,"Top net thermal radiation, clear sky",atmos, -u10m,uas,eastward_wind,Eastward Near-Surface Wind,atmos, -v10m,vas,northward_wind,Northward Near-Surface Wind,atmos, -t,ta,air_temperature,Air Temperature,atmos, u,ua,eastward_wind,U velocity,atmos, +u10m,uas,eastward_wind,Eastward Near-Surface Wind,atmos, +utau_ice:iocestru,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,seaIce, v,va,northward_wind,V velocity,atmos, +v10m,vas,northward_wind,Northward Near-Surface Wind,atmos, +voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt Vertical Eddy Diffusivity,ocean, +vomecrty,vo,sea_water_y_velocity,Sea Water Y Velocity,ocean, +vomeeivv,voeivv,sea_water_y_EIV_current,Meridional EIV Current,ocean, +vosaline,so,sea_water_salinity,Sea Water Salinity,ocean, +votemper,thetao,sea_water_potential_temperature,Sea Water Potential Temperature,ocean, +votkeavm,votkeavm,vertical_eddy_viscosity,Vertical Eddy Viscosity,ocean, +votkeavt,votkeavt,vertical_eddy_diffusivity,Vertical Eddy Diffusivity,ocean, +votkeevd,votkeevd,enhanced_vertical_diffusivity,Enhanced Vertical Diffusivity,ocean, +votkeevm,votkeevm,enhanced_vertical_viscosity,Enhanced Vertical Viscosity,ocean, +vovecrtz,zo,sea_water_z_velocity,Sea Water Z Velocity,ocean, +voveeivw,voeivz,sea_water_z_EIV_current,Vertical EIV Current,ocean, +vozocrtx,uo,sea_water_x_velocity,Sea Water X Velocity,ocean, +vozoeivu,voeivu,sea_water_x_EIV_current,Zonal EIV Current,ocean, +vtau_ice:iocestrv,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,seaIce, z,zg,geopotential_height,Geopotential Height,atmos, -tp,pr,precipitation_flux,Precipitation,atmos, +zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, +zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction,Ocean Meridional Overturning Volume Streamfunction due to Bolus Advection ,ocean, +zomsfglo,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, +zomsfind,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, +zomsfipc,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, +zomsfpac,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, +zosalatl,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, +zosalglo,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, +zosalind,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, +zosalipc,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, +zosalpac,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, +zosrfatl,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, +zosrfglo,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, +zosrfind,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, +zosrfipc,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, +zosrfpac,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, +zossq,zossq,square_of_sea_surface_height_above_geoid,Square of Sea Surface Height Above Geoid ,ocean, +zotematl,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, +zotemglo,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, +zotemind,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, +zotemipc,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, +zotempac,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, +bld,bld,boundary_layer_dissipation,Boundary layer dissipation,atmos, +cc,cl,cloud_area_fraction_in_atmosphere_layer,Cloud Area Fraction,atmos, +ciwc,cli,mass_fraction_of_cloud_ice_in_air,Mass Fraction of Cloud Ice,atmos, +clwc,clw,mass_fraction_of_cloud_liquid_water_in_air,Mass Fraction of Cloud Liquid Water,atmos, +es,sbl,surface_snow_and_ice_sublimation_flux,Surface Snow and Ice Sublimation Flux,landIce, +gwd,gwd,gravity_wave_dissipation,Gravity wave dissipation,atmos, +rsn,srho,snow_density,Snow Density,landIce, +smlt,snm,surface_snow_melt_flux,Surface Snow Melt,landIce, +src,src,skin_reservoir_content,Skin reservoir content,land, +w,wa,vertical_velocity,Vertical velocity,atmos, +var78,,,,, +var79,,,,, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index c7ac3bc..c80d707 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -78,7 +78,6 @@ class DataManager(object): for startdate in startdates: for member in members: - Log.info('Untaring member S{0} {1}', startdate, self.get_member_str(member)) for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, self.get_member_str(member), 'outputs', 'MMO*')): @@ -402,6 +401,9 @@ class DataManager(object): Log.info('Unpacking {0}', tarfile) scratch_dir = os.path.join(self.scratch_dir, 'CMOR') + + if os.path.exists(scratch_dir): + shutil.rmtree(scratch_dir) os.makedirs(scratch_dir) self._untar((tarfile,), scratch_dir) self._unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) @@ -459,7 +461,9 @@ class DataManager(object): 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', 'time_counter_bounds', 'ncatice', 'nav_lat_grid_V', 'nav_lat_grid_U', 'nav_lat_grid_T', - 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T',): + 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T', + 'depth', 'depth_2', 'depth_3', 'depth_4', + 'mlev', 'hyai', 'hybi', 'hyam', 'hybm'): continue self.extract_variable(file_parts, filename, frequency, handler, member, startdate, temp, variable) @@ -472,7 +476,15 @@ class DataManager(object): if var_cmor is None: return Utils.nco.ncks(input=filename, output=temp, options='-v {0}'.format(variable)) - Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev'}, False, True) + if var_cmor.domain == 'ocean': + Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev', + 'depth': 'lev'}, False, True) + elif var_cmor.domain in ('land', 'landIce'): + Utils.rename_variables(temp, {'depth': 'sdepth', 'depth_2': 'sdepth', 'depth_3': 'sdepth', + 'depth_4': 'sdepth'}, False, True) + elif var_cmor.domain in ('atmos'): + Utils.rename_variables(temp, {'depth': 'plev'}, False, True) + handler_cmor = Utils.openCdf(temp) Utils.copy_variable(handler, handler_cmor, 'lon', False) Utils.copy_variable(handler, handler_cmor, 'lat', False) -- GitLab From 5dc4e596f15b6189c360c811a8280be73177a724 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 1 Jul 2016 13:16:39 +0200 Subject: [PATCH 106/268] Fixed bug in CMOR for variables with region --- earthdiagnostics/datamanager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index c80d707..e00e3f1 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -792,6 +792,7 @@ class DataManager(object): self.experiment_name, startdate, member_plus, time_bound)) if region: + Utils.convert2netcdf4(filetosend) if not os.path.exists(filepath): handler = Utils.openCdf(filetosend) -- GitLab From 020a60a744f9e59dccf6b235ba908179ac6f8ac4 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 1 Jul 2016 16:12:30 +0200 Subject: [PATCH 107/268] Added option to deactivate CMORization for ocean or atmosphere --- .gitignore | 3 + .idea/dictionaries/jvegas.xml | 3 + earthdiagnostics/cmor_table.csv | 9 +- earthdiagnostics/datamanager.py | 502 ++++++++++++++++---------------- earthdiagnostics/diags.conf | 12 +- earthdiagnostics/diags.py | 7 +- 6 files changed, 277 insertions(+), 259 deletions(-) diff --git a/.gitignore b/.gitignore index 3ed3e8b..a3f647b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ .*.sw* .*.log* +.*.pyc* +.idea/* +doc/build/ diff --git a/.idea/dictionaries/jvegas.xml b/.idea/dictionaries/jvegas.xml index 1563054..23425c0 100644 --- a/.idea/dictionaries/jvegas.xml +++ b/.idea/dictionaries/jvegas.xml @@ -3,7 +3,9 @@ cdftools cmor + cmorization cmorized + diags ecearth eleftheria esnas @@ -15,6 +17,7 @@ orca regidor startdate + startdates \ No newline at end of file diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 9c3271f..960f4b0 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -68,7 +68,7 @@ iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness i iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce,Ind iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,IndPac iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of Sea Ice,seaIce,Pac -iicebome,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of Melt at Sea Ice Base,seaIce, +iicebome:iocewflx,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of Melt at Sea Ice Base,seaIce, iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce, iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thickness,seaIce, iiceconc:siconc:soicecov:ileadfra,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce, @@ -208,7 +208,7 @@ ttr,rlut,toa_outgoing_longwave_flux,TOA Outgoing Longwave Radiation,atmos, ttrc,rlutcs,toa_outgoing_longwave_flux_assuming_clear_sky,"Top net thermal radiation, clear sky",atmos, u,ua,eastward_wind,U velocity,atmos, u10m,uas,eastward_wind,Eastward Near-Surface Wind,atmos, -utau_ice:iocestru,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,seaIce, +utau_ice:iocestru:iicestru,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,seaIce, v,va,northward_wind,V velocity,atmos, v10m,vas,northward_wind,Northward Near-Surface Wind,atmos, voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt Vertical Eddy Diffusivity,ocean, @@ -224,7 +224,7 @@ vovecrtz,zo,sea_water_z_velocity,Sea Water Z Velocity,ocean, voveeivw,voeivz,sea_water_z_EIV_current,Vertical EIV Current,ocean, vozocrtx,uo,sea_water_x_velocity,Sea Water X Velocity,ocean, vozoeivu,voeivu,sea_water_x_EIV_current,Zonal EIV Current,ocean, -vtau_ice:iocestrv,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,seaIce, +vtau_ice:iocestrv:iicestrv,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,seaIce, z,zg,geopotential_height,Geopotential Height,atmos, zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction,Ocean Meridional Overturning Volume Streamfunction due to Bolus Advection ,ocean, @@ -258,5 +258,4 @@ rsn,srho,snow_density,Snow Density,landIce, smlt,snm,surface_snow_melt_flux,Surface Snow Melt,landIce, src,src,skin_reservoir_content,Skin reservoir content,land, w,wa,vertical_velocity,Vertical velocity,atmos, -var78,,,,, -var79,,,,, +iocewflx,,,,seaIce, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index e00e3f1..e30c8b7 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,5 +1,4 @@ # coding: latin-1 -import Queue import csv import glob import shutil @@ -56,7 +55,7 @@ class DataManager(object): self.member_digits = member_digits # noinspection PyPep8Naming - def prepare_CMOR_files(self, startdates, members, force_rebuild): + def prepare_CMOR_files(self, startdates, members, force_rebuild, ocean, atmosphere): """ Prepares the data to be used by the diagnostic. @@ -65,6 +64,10 @@ class DataManager(object): If CMOR data is available but packed, the procedure will unpack it. + :param atmosphere: activates atmosphere files cmorization + :type atmosphere: bool + :param ocean: activates ocean files cmorization + :type ocean: bool :param force_rebuild: if True, forces the creation of the CMOR files :type force_rebuild: bool :param startdates: list of startdates that will be used by the diagnostics @@ -78,10 +81,15 @@ class DataManager(object): for startdate in startdates: for member in members: - for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, - self.get_member_str(member), - 'outputs', 'MMO*')): - self._unpack_tar(member, startdate, tarfile) + + if ocean: + path_MMO = os.path.join(self.data_dir, self.expid, 'original_files', startdate, + self.get_member_str(member), 'outputs', 'MMO*') + for tarfile in glob.glob(path_MMO): + self._unpack_tar(member, startdate, tarfile) + + if not atmosphere: + continue grb_path = os.path.join(self.data_dir, self.expid, 'original_files', startdate, self.get_member_str(member), 'outputs', '*.grb') gribfiles = glob.glob(grb_path) @@ -91,245 +99,7 @@ class DataManager(object): 'outputs', 'MMA*')): self._unpack_tar(member, startdate, tarfile) else: - gribfiles.sort() - copied_gribfiles = list() - for gribfile in gribfiles: - shutil.copy(gribfile, os.path.join(self.scratch_dir, os.path.basename(gribfile))) - copied_gribfiles.append(os.path.join(self.scratch_dir, os.path.basename(gribfile))) - - for gribfile in copied_gribfiles: - cdo = Utils.cdo - start = parse_date(gribfile[-10:-4]) - month = '{0:02}'.format(start.month) - times = cdo.showtimestamp(input=gribfile) - times = times[0].split()[0:2] - time_diff = datetime.strptime(times[1], '%Y-%m-%dT%H:%M:%S') - datetime.strptime(times[0], - '%Y-%m-%dT%H:%M:%S') - NFRP = (time_diff.seconds // 3600) - - param_6hr = (151, 167, 168, 164, 165, 166, 129,) - param_day = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) - param_mon = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, - 177, 175, 212, 141, 180, 181, 179, 168, 243, 129, 130, 131, 132, 133) - - grid = os.path.basename(gribfile)[3:5] - - if os.path.exists('ICM{0}{1}+{2.year}{2.month:02}.grb'.format(grid, self.expid, - add_months(start, -1, - 'standard'))): - fd = open('rules_files', 'w') - fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(start)) - fd.close() - # get first timestep for each month from previous file (if possible) - if os.path.exists('ICM'): - os.remove('ICM') - Utils.execute_shell_command('grib_filter -o ICM rules_files ' - 'ICM{0}{1}+{2.year}{2.month:02}.grb ' - '{3}'.format(grid, self.expid, - add_months(start, -1, 'standard'), - gribfile)) - os.remove('rules_files') - - else: - shutil.copy(gribfile, 'ICM') - - # remap on regular Gauss grid - if grid == 'SH': - Utils.cdo.splitparam(input='-sp2gpl ICM', output=gribfile + '_') - else: - Utils.cdo.splitparam(input='ICM', output=gribfile + '_', options='-R') - # total precipitation (remove negative values) - Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' - '{0}_{{142,143}}.128.grb'.format(gribfile), - output='{0}_228.128.grb'.format(gribfile)) - os.remove('ICM') - - cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') - - # daily variables - for param in param_day: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): - continue - new_units = None - if param in (169, 177, 179): - # radiation - new_units = "W m-2" - cdo_operator = "-divc,{0} -daymean -selmon,{2} " \ - "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) - elif param == 228: - # precipitation - new_units = "kg m-2 -s" - cdo_operator = "-mulc,1000 -divc,{0} -daymean -selmon,{2} " \ - "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) - elif param == 201: - # maximum - cdo_operator = "-daymax -selmon,{1} -shifttime,-{0}hours".format(NFRP, month) - elif param == 202: - # minmimum - cdo_operator = "-daymin -selmon,{1} -shifttime,-{0}hours".format(NFRP, month) - elif param == 130: - # 850 hPa - cdo_operator = "-daymean -sellevel,85000 -selmon,{0}".format(month) - else: - # default, plain daily mean - cdo_operator = "-daymean -selmon,{0}".format(month) - - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' - '{2}_{3}_day.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - - if new_units: - handler = Utils.openCdf('{0}_{1}_day.nc'.format(gribfile, param)) - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: - var.units = new_units - break - handler.close() - # concat all vars in one file for day - Utils.nco.ncks(input='{0}_{1}_day.nc'.format(gribfile, param), - output='{0}_day.nc'.format(gribfile), options='-A') - os.remove('{0}_{1}_day.nc'.format(gribfile, param)) - - # monthly variables - for param in param_mon: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): - continue - new_units = None - if param in (146, 147, 176, 169, 177, 175, 179, 212): - # radiation/heat - new_units = "W m-2" - cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) - elif param in (180, 181): - # momentum flux - new_units = "N m-2" - cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) - elif param in (144, 228, 205, 182): - # precipitation/evaporation/runoff - new_units = "kg m-2 s-1" - cdo_operator = "-mulc,1000 -divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(NFRP * 3600, NFRP, month) - elif param == 201: - # mean daily maximum - cdo_operator = "-monmean -daymax -selmon,{1} " \ - "-shifttime,-{0}hours".format(NFRP, month) - elif param == 202: - # mean daily minmimum - cdo_operator = "-monmean -daymin -selmon,{1} " \ - "-shifttime,-{0}hours".format(NFRP, month) - elif param in (130, 131, 132, 133): - # upper-air - cdo_operator = "-monmean -sellevel,5000,20000,50000,85000 " \ - "-selmon,{0}".format(month) - elif param == 129: - # upper-air geopotential - new_units = "m" - cdo_operator = "-divc,9.81 -timmean -sellevel,5000,20000,50000,85000 " \ - "-selmon,{0}".format(month) - else: - # default, plain monthly mean - cdo_operator = "-monmean -selmon,{0}".format(month) - - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' - '{2}_{3}_mon.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - handler = Utils.openCdf('{0}_{1}_mon.nc'.format(gribfile, param)) - if new_units: - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: - var.units = new_units - break - var_name = None - for key in handler.variables.keys(): - if key + '_2' in handler.variables and key not in handler.dimensions: - var_name = key - - handler.close() - if var_name is not None: - Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), - output='{0}_{1}_mon.nc'.format(gribfile, param), - options='-O -v {0}'.format(var_name)) - - # concat all vars in one file for mon - Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), - output='{0}_mon.nc'.format(gribfile), options='-A') - os.remove('{0}_{1}_mon.nc'.format(gribfile, param)) - - # 6-hourly variables - for param in param_6hr: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): - continue - new_units = None - if param == 129: - # geopotential - new_units = "m" - cdo_operator = "-divc,9.81 -sellevel,50000 -selmon,{0}".format(month) - else: - # default, plain monthly mean - cdo_operator = "-selmon,{0}".format(month) - - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' - '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - if new_units: - handler = Utils.openCdf('{0}_{1}_6hr.nc'.format(gribfile, param)) - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: - var.units = new_units - break - handler.close() - # concat all vars in one file for 6hr - Utils.nco.ncks(input='{0}_{1}_6hr.nc'.format(gribfile, param), - output='{0}_6hr.nc'.format(gribfile), options='-A') - os.remove('{0}_{1}_6hr.nc'.format(gribfile, param)) - - for splited_file in glob.glob('{0}_???.128.grb'.format(gribfile)): - os.remove(splited_file) - - chunk_start = parse_date(startdate) - while os.path.exists(os.path.join(self.scratch_dir, - 'ICMGG{0}+{1}.grb'.format(self.expid, - date2str(chunk_start)[:-2]))): - chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') - chunk_files_gg_mon = list() - chunk_files_gg_day = list() - chunk_files_gg_6h = list() - - chunk_files_sh_mon = list() - chunk_files_sh_day = list() - chunk_files_sh_6h = list() - - for month in range(0, self.chunk_size): - chunk_file = 'ICMGG{0}+{1}.grb'.format(self.expid, - date2str(add_months(chunk_start, month, - 'standard'))[:-2]) - os.remove(chunk_file) - os.remove('ICMSH' + chunk_file[5:]) - chunk_files_gg_mon.append(chunk_file + '_mon.nc') - chunk_files_gg_day.append(chunk_file + '_day.nc') - chunk_files_gg_6h.append(chunk_file + '_6hr.nc') - chunk_files_sh_mon.append('ICMSH' + chunk_file[5:] + '_mon.nc') - chunk_files_sh_day.append('ICMSH' + chunk_file[5:] + '_day.nc') - chunk_files_sh_6h.append('ICMSH' + chunk_file[5:] + '_6hr.nc') - - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_mon, - 'SH', '1m') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_day, - 'SH', '1d') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_6h, - 'SH', '6hr') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_mon, - 'GG', '1m') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_day, - 'GG', '1d') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_6h, - 'GG', '6hr') - chunk_start = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + self._cmorize_grib(startdate, member, gribfiles) return for startdate in startdates: @@ -345,6 +115,245 @@ class DataManager(object): self._unpack_cmorfiles(filepaths, member_path) + def _cmorize_grib(self, startdate, member, gribfiles): + gribfiles.sort() + copied_gribfiles = list() + for gribfile in gribfiles: + shutil.copy(gribfile, os.path.join(self.scratch_dir, os.path.basename(gribfile))) + copied_gribfiles.append(os.path.join(self.scratch_dir, os.path.basename(gribfile))) + for gribfile in copied_gribfiles: + cdo = Utils.cdo + start = parse_date(gribfile[-10:-4]) + month = '{0:02}'.format(start.month) + times = cdo.showtimestamp(input=gribfile) + times = times[0].split()[0:2] + time_diff = datetime.strptime(times[1], '%Y-%m-%dT%H:%M:%S') - datetime.strptime(times[0], + '%Y-%m-%dT%H:%M:%S') + nfrp = (time_diff.seconds // 3600) + + param_6hr = (151, 167, 168, 164, 165, 166, 129,) + param_day = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) + param_mon = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, + 177, 175, 212, 141, 180, 181, 179, 168, 243, 129, 130, 131, 132, 133) + + grid = os.path.basename(gribfile)[3:5] + + if os.path.exists('ICM{0}{1}+{2.year}{2.month:02}.grb'.format(grid, self.expid, + add_months(start, -1, + 'standard'))): + fd = open('rules_files', 'w') + fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(start)) + fd.close() + # get first timestep for each month from previous file (if possible) + if os.path.exists('ICM'): + os.remove('ICM') + Utils.execute_shell_command('grib_filter -o ICM rules_files ' + 'ICM{0}{1}+{2.year}{2.month:02}.grb ' + '{3}'.format(grid, self.expid, + add_months(start, -1, 'standard'), + gribfile)) + os.remove('rules_files') + + else: + shutil.copy(gribfile, 'ICM') + + # remap on regular Gauss grid + if grid == 'SH': + Utils.cdo.splitparam(input='-sp2gpl ICM', output=gribfile + '_') + else: + Utils.cdo.splitparam(input='ICM', output=gribfile + '_', options='-R') + # total precipitation (remove negative values) + Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' + '{0}_{{142,143}}.128.grb'.format(gribfile), + output='{0}_228.128.grb'.format(gribfile)) + os.remove('ICM') + + cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') + + # daily variables + for param in param_day: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param in (169, 177, 179): + # radiation + new_units = "W m-2" + cdo_operator = "-divc,{0} -daymean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + elif param == 228: + # precipitation + new_units = "kg m-2 -s" + cdo_operator = "-mulc,1000 -divc,{0} -daymean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + elif param == 201: + # maximum + cdo_operator = "-daymax -selmon,{1} -shifttime,-{0}hours".format(nfrp, month) + elif param == 202: + # minmimum + cdo_operator = "-daymin -selmon,{1} -shifttime,-{0}hours".format(nfrp, month) + elif param == 130: + # 850 hPa + cdo_operator = "-daymean -sellevel,85000 -selmon,{0}".format(month) + else: + # default, plain daily mean + cdo_operator = "-daymean -selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_day.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + + if new_units: + handler = Utils.openCdf('{0}_{1}_day.nc'.format(gribfile, param)) + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + handler.close() + # concat all vars in one file for day + Utils.nco.ncks(input='{0}_{1}_day.nc'.format(gribfile, param), + output='{0}_day.nc'.format(gribfile), options='-A') + os.remove('{0}_{1}_day.nc'.format(gribfile, param)) + + # monthly variables + for param in param_mon: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param in (146, 147, 176, 169, 177, 175, 179, 212): + # radiation/heat + new_units = "W m-2" + cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + elif param in (180, 181): + # momentum flux + new_units = "N m-2" + cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + elif param in (144, 228, 205, 182): + # precipitation/evaporation/runoff + new_units = "kg m-2 s-1" + cdo_operator = "-mulc,1000 -divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + elif param == 201: + # mean daily maximum + cdo_operator = "-monmean -daymax -selmon,{1} " \ + "-shifttime,-{0}hours".format(nfrp, month) + elif param == 202: + # mean daily minmimum + cdo_operator = "-monmean -daymin -selmon,{1} " \ + "-shifttime,-{0}hours".format(nfrp, month) + elif param in (130, 131, 132, 133): + # upper-air + cdo_operator = "-monmean -sellevel,5000,20000,50000,85000 " \ + "-selmon,{0}".format(month) + elif param == 129: + # upper-air geopotential + new_units = "m" + cdo_operator = "-divc,9.81 -timmean -sellevel,5000,20000,50000,85000 " \ + "-selmon,{0}".format(month) + else: + # default, plain monthly mean + cdo_operator = "-monmean -selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_mon.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + handler = Utils.openCdf('{0}_{1}_mon.nc'.format(gribfile, param)) + if new_units: + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + var_name = None + for key in handler.variables.keys(): + if key + '_2' in handler.variables and key not in handler.dimensions: + var_name = key + + handler.close() + if var_name is not None: + Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), + output='{0}_{1}_mon.nc'.format(gribfile, param), + options='-O -v {0}'.format(var_name)) + + # concat all vars in one file for mon + Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), + output='{0}_mon.nc'.format(gribfile), options='-A') + os.remove('{0}_{1}_mon.nc'.format(gribfile, param)) + + # 6-hourly variables + for param in param_6hr: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param == 129: + # geopotential + new_units = "m" + cdo_operator = "-divc,9.81 -sellevel,50000 -selmon,{0}".format(month) + else: + # default, plain monthly mean + cdo_operator = "-selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + if new_units: + handler = Utils.openCdf('{0}_{1}_6hr.nc'.format(gribfile, param)) + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + handler.close() + # concat all vars in one file for 6hr + Utils.nco.ncks(input='{0}_{1}_6hr.nc'.format(gribfile, param), + output='{0}_6hr.nc'.format(gribfile), options='-A') + os.remove('{0}_{1}_6hr.nc'.format(gribfile, param)) + + for splited_file in glob.glob('{0}_???.128.grb'.format(gribfile)): + os.remove(splited_file) + chunk_start = parse_date(startdate) + while os.path.exists(os.path.join(self.scratch_dir, + 'ICMGG{0}+{1}.grb'.format(self.expid, + date2str(chunk_start)[:-2]))): + chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + chunk_files_gg_mon = list() + chunk_files_gg_day = list() + chunk_files_gg_6h = list() + + chunk_files_sh_mon = list() + chunk_files_sh_day = list() + chunk_files_sh_6h = list() + + for month in range(0, self.chunk_size): + chunk_file = 'ICMGG{0}+{1}.grb'.format(self.expid, + date2str(add_months(chunk_start, month, + 'standard'))[:-2]) + os.remove(chunk_file) + os.remove('ICMSH' + chunk_file[5:]) + chunk_files_gg_mon.append(chunk_file + '_mon.nc') + chunk_files_gg_day.append(chunk_file + '_day.nc') + chunk_files_gg_6h.append(chunk_file + '_6hr.nc') + chunk_files_sh_mon.append('ICMSH' + chunk_file[5:] + '_mon.nc') + chunk_files_sh_day.append('ICMSH' + chunk_file[5:] + '_day.nc') + chunk_files_sh_6h.append('ICMSH' + chunk_file[5:] + '_6hr.nc') + + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_mon, + 'SH', '1m') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_day, + 'SH', '1d') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_6h, + 'SH', '6hr') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_mon, + 'GG', '1m') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_day, + 'GG', '1d') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_6h, + 'GG', '6hr') + chunk_start = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, chunk_files, grid, frequency): merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) for x in range(0, len(chunk_files)): @@ -482,7 +491,7 @@ class DataManager(object): elif var_cmor.domain in ('land', 'landIce'): Utils.rename_variables(temp, {'depth': 'sdepth', 'depth_2': 'sdepth', 'depth_3': 'sdepth', 'depth_4': 'sdepth'}, False, True) - elif var_cmor.domain in ('atmos'): + elif var_cmor.domain == 'atmos': Utils.rename_variables(temp, {'depth': 'plev'}, False, True) handler_cmor = Utils.openCdf(temp) @@ -587,7 +596,6 @@ class DataManager(object): handler.tracking_id = str(uuid.uuid1()) handler.title = "{0} model output prepared for SPECS {1}".format(self.model, self.experiment_name) - @staticmethod def _unzip(files): for filepath in files: diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index f1bfb99..100006a 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -6,7 +6,7 @@ DATA_DIR = /esnas/exp/ecearth/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run -DIAGS = ohc +DIAGS = ohc siasiesiv # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -14,6 +14,8 @@ CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin [CMOR] FORCE = True +OCEAN_FILES = True +ATMOSPHERE_FILES = True # ASSOCIATED_EXPERIMENT = # INITIALIZATION_METHOD = 1 # INITIALIZATION_DESCRIPTION = ocean: ECMWF system4, ice: DFS4.3 , atmosphere: @@ -34,15 +36,15 @@ MODEL = EC-EARTH # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks to process -EXPID = m02j -STARTDATES = 20001101 -MEMBERS = 0 +EXPID = a04e +STARTDATES = 19930501 19940501 +MEMBERS = 0 1 2 MEMBER_DIGITS = 1 CHUNK_SIZE = 4 CHUNKS = 1 # Model version -NEMO_VERSION = Ec3.0_O1L46 +NEMO_VERSION = Ec3.0_O25L75 # [EXPERIMENT] # INSTITUTE = IC3 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 4406fb6..d856b25 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -79,7 +79,8 @@ class Diags(object): parse_date('20000101') - self.data_manager.prepare_CMOR_files(self.startdates, self.members, self.force_CMOR) + self.data_manager.prepare_CMOR_files(self.startdates, self.members, self.CMOR_force, + self.CMOR_ocean, self.CMOR_atmosphere) # Run diagnostics Log.info('Running diagnostics') @@ -256,7 +257,9 @@ class Diags(object): self.data_manager.add_startdate = self.add_startdate self.data_manager.add_name = self.add_name - self.force_CMOR = self.parser.get_bool_option('CMOR', 'FORCE', False) + self.CMOR_force = self.parser.get_bool_option('CMOR', 'FORCE', False) + self.CMOR_ocean = self.parser.get_bool_option('CMOR', 'OCEAN_FILES', True) + self.CMOR_atmosphere = self.parser.get_bool_option('CMOR', 'ATMOSPHERE_FILES', True) self.data_manager.associated_experiment = self.parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', 'to be filled') self.data_manager.associated_model = self.parser.get_option('CMOR', 'ASSOCIATED_MODEL', 'to be filled') -- GitLab From c7b830d2e91743a2147eb9f78ed59404687f2ca0 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 1 Jul 2016 16:56:37 +0200 Subject: [PATCH 108/268] Added hash-check to move method --- earthdiagnostics/utils.py | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index d3b5d50..a373aab 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -1,3 +1,4 @@ +import hashlib import subprocess import netCDF4 @@ -110,7 +111,34 @@ class Utils(object): # This can be due to a race condition. If directory already exists, we don have to do nothing if not os.path.exists(os.path.dirname(destiny)): raise ex - shutil.move(source, destiny) + hash_destiny = None + hash_original = Utils.get_file_hash(source) + + retrials = 5 + while hash_original != hash_destiny: + if retrials == 0: + raise Exception('Can not move {0} to {1}'.format(source, destiny)) + shutil.copy(source, destiny) + hash_destiny = Utils.get_file_hash(destiny) + os.remove(source) + + @staticmethod + def get_file_hash(filepath): + """ + Returns the MD5 hash for the given filepath + :param filepath: path to the file to compute hash on + :type filepath:str + :return: file's MD5 hash + :rtype: str + """ + BLOCKSIZE = 65536 + hasher = hashlib.md5() + with open(filepath, 'rb') as afile: + buf = afile.read(BLOCKSIZE) + while len(buf) > 0: + hasher.update(buf) + buf = afile.read(BLOCKSIZE) + return hasher.hexdigest() @staticmethod def execute_shell_command(command, log_level=Log.DEBUG): @@ -262,3 +290,11 @@ class TempFile(object): if os.path.exists(temp_file): os.remove(temp_file) TempFile.files = list() + + +def main(): + print Utils.move_file('/esnas/exp/ecearth/a04e/original_files/19930501/fc0/outputs/ICMGGa04e+199305.grb', + '/scratch/Earth/jvegas/temp.nc') + +if __name__ == "__main__": + main() -- GitLab From cdf46932a4026d57a8afe360e935fbde92c85aa9 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 1 Jul 2016 18:02:59 +0200 Subject: [PATCH 109/268] Updated doc --- doc/source/errors.rst | 5 ++-- doc/source/tips.rst | 6 ++--- earthdiagnostics/__init__.py | 4 ++++ earthdiagnostics/basins.py | 1 + earthdiagnostics/box.py | 2 +- earthdiagnostics/cdftools.py | 1 + earthdiagnostics/datamanager.py | 23 +++++++++++++++++++ earthdiagnostics/diagnostic.py | 1 + earthdiagnostics/diags.py | 1 + earthdiagnostics/models.py | 2 +- earthdiagnostics/ocean/__init__.py | 4 ++++ earthdiagnostics/ocean/areamoc.py | 1 + earthdiagnostics/ocean/averagesection.py | 1 + earthdiagnostics/ocean/convectionsites.py | 1 + earthdiagnostics/ocean/cutsection.py | 1 + earthdiagnostics/ocean/gyres.py | 1 + earthdiagnostics/ocean/heatcontent.py | 1 + earthdiagnostics/ocean/heatcontentlayer.py | 1 + earthdiagnostics/ocean/interpolate.py | 1 + earthdiagnostics/ocean/maxmoc.py | 1 + .../ocean/mixedlayerheatcontent.py | 1 + .../ocean/mixedlayersaltcontent.py | 1 + earthdiagnostics/ocean/moc.py | 1 + earthdiagnostics/ocean/psi.py | 1 + earthdiagnostics/ocean/siasiesiv.py | 1 + earthdiagnostics/ocean/verticalmean.py | 1 + earthdiagnostics/ocean/verticalmeanmeters.py | 1 + earthdiagnostics/parser.py | 2 ++ earthdiagnostics/utils.py | 7 +++--- 29 files changed, 64 insertions(+), 11 deletions(-) diff --git a/doc/source/errors.rst b/doc/source/errors.rst index 3c68133..d7ba88a 100644 --- a/doc/source/errors.rst +++ b/doc/source/errors.rst @@ -14,8 +14,7 @@ Try this simple steps BEFORE reporting an issue * Clean scratch folder * Update to the latest compatible tag: maybe your issue is already solved in it -* If you get the error for the first chunk of a given diagnostic, change configuration so this will be the only one - that will run +* If you get the error for the first chunk of a given diagnostic, change the number of chunks to 1 * Call the diags with the -lc DEBUG -log log.txt options Now, you have two options: if everything is fine, the error was probably due to some corrupted files or some unstable @@ -29,5 +28,5 @@ happening to you. In any case, it will be very useful if you can attach your diags.conf and log.txt files. -After that, it's just a matter of waiting for the developers to do its work and answering the questions that they may +After that, it's just a matter of waiting for the developers to do their work and answering the questions that they may have. Please, be patient. diff --git a/doc/source/tips.rst b/doc/source/tips.rst index e4a5eaf..834d720 100644 --- a/doc/source/tips.rst +++ b/doc/source/tips.rst @@ -13,11 +13,11 @@ Configuring core usage By default, the Earth Diagnostics creates a thread for each available core for the execution. If you are using a queueing system, the diagnostics will always use the number of cores that you reserved. If you are running outside a queueing system, the diagnostics will try to use all the cores on the machine. To avoid this, add the MAX_CORES parameter to the -to the DIAGNOSTICS section inside the diags.conf file that you are using. +DIAGNOSTICS section inside the diags.conf file that you are using. NEMO files ---------- Unlike the bash version of the ocean diagnostics, this program keeps the NEMO files in the scratch folder so you can -launch different configurations with reduced start time. You will need to remove the experiment's folder in the scratch -directory at the end of the experiment to avoid wasting resources. +launch different configurations for the same experiment with reduced start time. You will need to remove the experiment's +folder in the scratch directory at the end of the experiment to avoid wasting resources. diff --git a/earthdiagnostics/__init__.py b/earthdiagnostics/__init__.py index 74efa4c..7524485 100644 --- a/earthdiagnostics/__init__.py +++ b/earthdiagnostics/__init__.py @@ -1,3 +1,7 @@ +# coding=utf-8 +""" +Module containing the Earth Diagnostics. +""" from cdo import Cdo from nco import Nco from earthdiagnostics.cdftools import CDFTools diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/basins.py index d5eb291..70bcc1a 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/basins.py @@ -1,3 +1,4 @@ +# coding=utf-8 from earthdiagnostics.box import Box diff --git a/earthdiagnostics/box.py b/earthdiagnostics/box.py index f097936..cc32dc2 100644 --- a/earthdiagnostics/box.py +++ b/earthdiagnostics/box.py @@ -1,4 +1,4 @@ - +# coding=utf-8 class Box(object): """ Represents a box in the 3D space. Also allows easy conversion from the coordinate values to significant string diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 08a2f81..82f7012 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -1,3 +1,4 @@ +# coding=utf-8 from earthdiagnostics.utils import Utils import os from autosubmit.config.log import Log diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index e30c8b7..3544914 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -872,9 +872,20 @@ class DataManager(object): @staticmethod def domain_abbreviation(domain, frequency): + """ + Returns the table name for a domain-frequency pair + :param domain: variable's domain + :type domain: str + :param frequency: variable's frequency + :type frequency: str + :return: variable's table name + :rtype: str + """ if frequency == 'mon': if domain == 'seaIce': domain_abreviattion = 'OImon' + elif domain == 'landIce': + domain_abreviattion = 'LImon' else: domain_abreviattion = domain[0].upper() + 'mon' elif frequency == '6hr': @@ -982,10 +993,22 @@ class DataManager(object): return years def get_member_str(self, member): + """ + Returns the member name for a given member number. + :param member: member's number + :type member: int + :return: member's name + :rtype: str + """ return 'fc{0}'.format(str(member).zfill(self.member_digits)) class Variable(object): + """ + Class to characterize a CMOR variable. It also contains the static method to make the match between thje original + name and the standard name. Requires cmor_table.csv to work. + """ + def __init__(self, line): self.short_name = line[1] self.standard_name = line[2] diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index afc1115..9e64233 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -1,3 +1,4 @@ +# coding=utf-8 class Diagnostic(object): """ Base class for the diagnostics. Provides a common interface for them and also diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index d856b25..618cd18 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# coding=utf-8 import Queue import argparse diff --git a/earthdiagnostics/models.py b/earthdiagnostics/models.py index 89661e0..2fcad83 100644 --- a/earthdiagnostics/models.py +++ b/earthdiagnostics/models.py @@ -1,4 +1,4 @@ - +# coding=utf-8 class Models(object): """ Predefined models diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index b88abc8..adc29cc 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -1,3 +1,7 @@ +# coding=utf-8 +""" +Module containing the diagnostics related to the ocean output +""" from earthdiagnostics.ocean.heatcontent import HeatContent from earthdiagnostics.ocean.moc import Moc from earthdiagnostics.ocean.areamoc import AreaMoc diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index d0d4cf8..70f3f68 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -1,3 +1,4 @@ +# coding=utf-8 import numpy as np from earthdiagnostics.basins import Basins from earthdiagnostics.diagnostic import Diagnostic diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 6601c85..4886562 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -1,3 +1,4 @@ +# coding=utf-8 import os from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index cb7c2d9..879f740 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -1,3 +1,4 @@ +# coding=utf-8 import numpy as np from autosubmit.config.log import Log from earthdiagnostics.diagnostic import Diagnostic diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index cfcf2a4..f6e7fd2 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -1,3 +1,4 @@ +# coding=utf-8 import numpy as np from autosubmit.config.log import Log diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 910f7dc..1244a44 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -1,3 +1,4 @@ +# coding=utf-8 import numpy as np from autosubmit.config.log import Log diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index b9bf883..bf9d02e 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -1,3 +1,4 @@ +# coding=utf-8 import shutil from autosubmit.config.log import Log diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 2ce9d07..00dd144 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -1,3 +1,4 @@ +# coding=utf-8 import numpy as np from box import Box diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 75fb5e4..1555767 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -1,3 +1,4 @@ +# coding=utf-8 import shutil import os diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 070d2a6..1b0aea4 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -1,3 +1,4 @@ +# coding=utf-8 import netCDF4 import numpy as np import os diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index ef88246..c0e7e80 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -1,3 +1,4 @@ +# coding=utf-8 import os from autosubmit.config.log import Log diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 2160f4b..7dd37bc 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -1,3 +1,4 @@ +# coding=utf-8 import os from autosubmit.config.log import Log from earthdiagnostics import cdftools diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index f5d6b5b..fa5f705 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -1,3 +1,4 @@ +# coding=utf-8 import numpy as np from autosubmit.config.log import Log diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 8523b2a..3bb1a8d 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -1,3 +1,4 @@ +# coding=utf-8 from earthdiagnostics import cdftools from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index d7fcf22..798745f 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -1,3 +1,4 @@ +# coding=utf-8 import netCDF4 import os from earthdiagnostics.basins import Basins diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 4cdaa46..26d4b6c 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -1,3 +1,4 @@ +# coding=utf-8 from earthdiagnostics import cdftools from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 7da1185..7397240 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -1,3 +1,4 @@ +# coding=utf-8 from earthdiagnostics import cdftools from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic diff --git a/earthdiagnostics/parser.py b/earthdiagnostics/parser.py index 790308d..af4bfbb 100644 --- a/earthdiagnostics/parser.py +++ b/earthdiagnostics/parser.py @@ -1,8 +1,10 @@ +# coding=utf-8 from ConfigParser import SafeConfigParser from autosubmit.config.log import Log import re +# noinspection PyClassicStyleClass class Parser(SafeConfigParser): def get_option(self, section, option, default=''): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index a373aab..80e6bfc 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -1,3 +1,4 @@ +# coding=utf-8 import hashlib import subprocess @@ -131,13 +132,13 @@ class Utils(object): :return: file's MD5 hash :rtype: str """ - BLOCKSIZE = 65536 + blocksize = 65536 hasher = hashlib.md5() with open(filepath, 'rb') as afile: - buf = afile.read(BLOCKSIZE) + buf = afile.read(blocksize) while len(buf) > 0: hasher.update(buf) - buf = afile.read(BLOCKSIZE) + buf = afile.read(blocksize) return hasher.hexdigest() @staticmethod -- GitLab From b3cf52d37b2e08a035d59cd62fb247267c3db2ce Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 4 Jul 2016 16:01:34 +0200 Subject: [PATCH 110/268] Added option to restore mesh files --- earthdiagnostics/cmor_table.csv | 2 +- earthdiagnostics/datamanager.py | 4 ++-- earthdiagnostics/diags.conf | 22 ++++++++++++---------- earthdiagnostics/diags.py | 21 ++++++++++++--------- testing_diags_moore.job | 4 ++-- 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 960f4b0..4359ca2 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -104,7 +104,7 @@ isnowpre,prsn,snowfall_flux,Surface Snowfall Rate into the Sea Ice Portion of th isnowthi,snthic,surface_snow_thickness,Surface Snow Thickness,seaIce, isssalin,isssalin,sea_surface_salinity,Sea surface salinity,seaIce, isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce, -istl1,tsice,surface_temperature,Surface Temperature of Ice,landICe, +istl1,tsice,surface_temperature,Surface Temperature of Ice,landIce, lcc,clh,low_cloud_area_fraction,Low Cloud Fraction,atmos, lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos, mcc,clh,medium_cloud_area_fraction,Medium Cloud Fraction,atmos, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 3544914..a600a85 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -81,7 +81,7 @@ class DataManager(object): for startdate in startdates: for member in members: - + Log.info('CMORizing startdate {0} member {1}', startdate, self.get_member_str(member)) if ocean: path_MMO = os.path.join(self.data_dir, self.expid, 'original_files', startdate, self.get_member_str(member), 'outputs', 'MMO*') @@ -590,7 +590,7 @@ class DataManager(object): handler.model_id = self.model handler.associated_model = self.associated_model handler.project_id = 'SPECS' - handler.realization = member + handler.realization = member + 1 handler.source = self.source handler.startdate = 'S{0}'.format(startdate) handler.tracking_id = str(uuid.uuid1()) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 100006a..c29864a 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,18 +2,19 @@ # Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/jvegas # Root path for the cmorized data to use -DATA_DIR = /esnas/exp/ecearth/ +DATA_DIR = /esnas/exp/nemo/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run -DIAGS = ohc siasiesiv +DIAGS = mlotsthc # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin +RESTORE_MESHES = False [CMOR] -FORCE = True +FORCE = False OCEAN_FILES = True ATMOSPHERE_FILES = True # ASSOCIATED_EXPERIMENT = @@ -27,7 +28,7 @@ ATMOSPHERE_FILES = True [EXPERIMENT] # Experiments parameters as defined in CMOR standard INSTITUTE = BSC -MODEL = EC-EARTH +MODEL = NEMO # For those who use Autosubmit, this no need documentation # For those who not, EXPID is the unique identifier of the experiment. @@ -36,15 +37,16 @@ MODEL = EC-EARTH # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks to process -EXPID = a04e -STARTDATES = 19930501 19940501 -MEMBERS = 0 1 2 -MEMBER_DIGITS = 1 -CHUNK_SIZE = 4 +EXPID = a05p +STARTDATES = 19580101 +MEMBERS = 0 +MEMBER_DIGITS = 2 +CHUNK_SIZE = 12 +# CHUNKS = 58 CHUNKS = 1 # Model version -NEMO_VERSION = Ec3.0_O25L75 +NEMO_VERSION = N3.6_O1L75 # [EXPERIMENT] # INSTITUTE = IC3 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 618cd18..804c407 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -53,8 +53,6 @@ class Diags(object): Run the diagnostics """ Log.debug('Using netCDF version {0}', netCDF4.getlibversion()) - time = datetime.datetime.now() - Log.info("Starting diagnostics at {0}", time) if not os.path.exists(self.scratch_dir): os.makedirs(self.scratch_dir) os.chdir(self.scratch_dir) @@ -87,7 +85,7 @@ class Diags(object): Log.info('Running diagnostics') list_jobs = Queue.Queue() for fulldiag in self._get_commands(): - Log.info("Running {0}", fulldiag) + Log.info("Adding {0} to diagnostic list", fulldiag) diag_options = fulldiag.split(',') diag_class = Diagnostic.get_diagnostic(diag_options[0]) @@ -98,6 +96,8 @@ class Diags(object): else: Log.error('{0} is not an available diagnostic', diag_options[0]) + time = datetime.datetime.now() + Log.info("Starting to compute at {0}", time) numthreads = min(Utils.available_cpu_count(), self.max_cores) threads = list() for numthread in range(0, numthreads): @@ -166,24 +166,26 @@ class Diags(object): def _prepare_mesh_files(self): Log.info('Copying mesh files') - self._copy_file(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc') + self._copy_file(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc', + self.restore_meshes) self._link_file('mesh_hgr.nc', 'mesh_zgr.nc') self._link_file('mesh_hgr.nc', 'mask.nc') - self._copy_file(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc') + self._copy_file(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc', + self.restore_meshes) self._copy_file(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), - 'mask_regions.nc') + 'mask_regions.nc', self.restore_meshes) self._copy_file(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.nemo_version)), - 'mask_regions.3d.nc') + 'mask_regions.3d.nc', self.restore_meshes) Log.result('Mesh files ready!') - def _copy_file(self, source, destiny): + def _copy_file(self, source, destiny, force): if not os.path.exists(source): Log.user_warning('File {0} is not available for {1}', destiny, self.nemo_version) return - if os.path.exists(destiny): + if not force and os.path.exists(destiny): if os.stat(source).st_size == os.stat(destiny).st_size: Log.info('File {0} already exists', destiny) return @@ -217,6 +219,7 @@ class Diags(object): self.frequency = self.parser.get_option('DIAGNOSTICS', 'FREQUENCY') self.cdftools_path = self.parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') self.max_cores = self.parser.get_int_option('DIAGNOSTICS', 'MAX_CORES', 100000) + self.restore_meshes = self.parser.get_bool_option('DIAGNOSTICS', 'RESTORE_MESHES', False) # Read experiment config self.institute = self.parser.get_option('EXPERIMENT', 'INSTITUTE') diff --git a/testing_diags_moore.job b/testing_diags_moore.job index 05df067..b4b222d 100755 --- a/testing_diags_moore.job +++ b/testing_diags_moore.job @@ -1,6 +1,6 @@ #!/bin/bash #SBATCH --time=24:00:00 -#SBATCH -n 15 +#SBATCH -n 8 #SBATCH --error=/home/Earth/jvegas/job.%J.err #SBATCH --output=/home/Earth/jvegas/job.%J.out @@ -15,4 +15,4 @@ source /home/Earth/jvegas/virtualenvs/diags/bin/activate export PYTHONPATH=/home/Earth/jvegas/pyCharm/ocean_diagnostics/:$PYTHONPATH cd /home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/ -./diags.py -lc DEBUG -f /home/Earth/jvegas/diags_i00k.conf +./diags.py -lc DEBUG -- GitLab From 821a7c6e5c3c6620cef376f48bcba6a01cfdb0c2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 4 Jul 2016 16:56:54 +0200 Subject: [PATCH 111/268] Modified mixed layer salt and heat content to avoid splitting chunk files in once for each timestep --- earthdiagnostics/diags.conf | 2 +- .../ocean/mixedlayerheatcontent.py | 19 +---------------- .../ocean/mixedlayersaltcontent.py | 21 +------------------ 3 files changed, 3 insertions(+), 39 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index c29864a..203da0a 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -6,7 +6,7 @@ DATA_DIR = /esnas/exp/nemo/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run -DIAGS = mlotsthc +DIAGS = mlotstsc # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index c0e7e80..b6cbff6 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -52,31 +52,14 @@ class MixedLayerHeatContent(Diagnostic): return job_list def compute(self): - nco = Utils.nco - cdo = Utils.cdo temperature_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) Utils.nco.ncks(input=mlotst_file, output=temperature_file, options='-A -v mlotst') - ntime = int(cdo.ntime(input=temperature_file)[0]) - files = list() - - for time in range(ntime): - Log.debug('Running time {0}', time) - temp = TempFile.get() - temp2 = TempFile.get() - nco.ncks(input=temperature_file, output=temp, options='-O -d time,{0}'.format(time)) - cdftools.run('cdfmxlheatc', input=temp, output=temp2) - os.remove(temp) - files.append(temp2) - temp = TempFile.get() - cdo.cat(input=' '.join(files), output=temp,) - nco.ncks(input=temperature_file, output=temp, options='-A -v time') + cdftools.run('cdfmxlheatc', input=temperature_file, output=temp) - for temp_file in files: - os.remove(temp_file) os.remove(temperature_file) Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlheatc': 'ohcvsumlotst'}, False, True) diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 7dd37bc..26aa990 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -51,32 +51,13 @@ class MixedLayerSaltContent(Diagnostic): return job_list def compute(self): - nco = Utils.nco - cdo = Utils.cdo salinity_file = self.data_manager.get_file('ocean', 'so', self.startdate, self.member, self.chunk) mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) Utils.nco.ncks(input=mlotst_file, output=salinity_file, options='-A -v mlotst') - ntime = int(cdo.ntime(input=salinity_file)[0]) - files = list() - - for time in range(ntime): - Log.info('Running time {0}', time) - temp = TempFile.get() - temp2 = TempFile.get() - nco.ncks(input=salinity_file, output=temp, options='-O -d time,{0}'.format(time)) - Log.info('Computing salt content') - cdftools.run('cdfmxlsaltc', input=temp, output=temp2) - os.remove(temp) - files.append(temp2) - temp = TempFile.get() - cdo.cat(input=' '.join(files), output=temp,) - nco.ncks(input=salinity_file, output=temp, options='-A -v time') - - for temp_file in files: - os.remove(temp_file) + cdftools.run('cdfmxlsaltc', input=salinity_file, output=temp) os.remove(salinity_file) Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'scvsummlotst'}, False, True) -- GitLab From 3c6bf3f640fd16b5be68bb69f78f632adae95a01 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 5 Jul 2016 09:19:56 +0200 Subject: [PATCH 112/268] Created method on diags to return the list of chunks to be run --- earthdiagnostics/datamanager.py | 8 +++++--- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 14 ++++++++++++++ earthdiagnostics/ocean/areamoc.py | 6 ++---- earthdiagnostics/ocean/averagesection.py | 7 ++----- earthdiagnostics/ocean/convectionsites.py | 6 ++---- earthdiagnostics/ocean/cutsection.py | 7 ++----- earthdiagnostics/ocean/gyres.py | 6 ++---- earthdiagnostics/ocean/heatcontent.py | 6 ++---- earthdiagnostics/ocean/heatcontentlayer.py | 6 ++---- earthdiagnostics/ocean/interpolate.py | 8 +++----- earthdiagnostics/ocean/mixedlayerheatcontent.py | 6 ++---- earthdiagnostics/ocean/mixedlayersaltcontent.py | 6 ++---- earthdiagnostics/ocean/moc.py | 6 ++---- earthdiagnostics/ocean/psi.py | 6 ++---- earthdiagnostics/ocean/siasiesiv.py | 6 ++---- earthdiagnostics/ocean/verticalmean.py | 8 +++----- earthdiagnostics/ocean/verticalmeanmeters.py | 7 ++----- 18 files changed, 52 insertions(+), 69 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index a600a85..076bebe 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -77,10 +77,11 @@ class DataManager(object): :return: """ # Check if cmorized and convert if not - if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles')): - for startdate in startdates: - for member in members: + for startdate in startdates: + for member in members: + if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles', + startdate, self.get_member_str(member))): Log.info('CMORizing startdate {0} member {1}', startdate, self.get_member_str(member)) if ocean: path_MMO = os.path.join(self.data_dir, self.expid, 'original_files', startdate, @@ -1040,3 +1041,4 @@ class Variable(object): except KeyError: Log.error('Variable {0} is not defined'.format(original_name)) return None + diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 203da0a..557f710 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -43,7 +43,7 @@ MEMBERS = 0 MEMBER_DIGITS = 2 CHUNK_SIZE = 12 # CHUNKS = 58 -CHUNKS = 1 +CHUNKS = 58 # Model version NEMO_VERSION = N3.6_O1L75 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 804c407..36458fd 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -118,6 +118,7 @@ class Diags(object): def _run_job(current_job, retrials=1): while retrials > 0: try: + Log.info('Starting {0}', current_job) current_job.compute() Log.result('Finished {0}', current_job) return True @@ -275,6 +276,19 @@ class Diags(object): self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', 'to be filled') self.data_manager.source = self.parser.get_option('CMOR', 'SOURCE', 'to be filled') + def get_chunk_list(self): + """ + Return a list with all the chunks + :return: List contanining tuples of startdtae, member and chunk + :rtype: tuple[str, int, int] + """ + chunk_list = list() + for startdate in self.startdates: + for member in self.members: + for chunk in range(1, self.chunks + 1): + chunk_list.append((startdate, member, chunk)) + return chunk_list + def main(): """ diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 70f3f68..34039aa 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -62,10 +62,8 @@ class AreaMoc(Diagnostic): basin = Basins.Global job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(AreaMoc(diags.data_manager, startdate, member, chunk, basin, box)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(AreaMoc(diags.data_manager, startdate, member, chunk, basin, box)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 4886562..12e2730 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -58,11 +58,8 @@ class AverageSection(Diagnostic): domain = 'ocean' job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, - variable, domain, box)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, variable, domain, box)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 879f740..9a6e458 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -44,10 +44,8 @@ class ConvectionSites(Diagnostic): if len(options) > 1: raise Exception('The convection sites diagnostic has no options') job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.nemo_version)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.nemo_version)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index f6e7fd2..6867b77 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -59,11 +59,8 @@ class CutSection(Diagnostic): domain = 'ocean' job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(CutSection(diags.data_manager, startdate, member, chunk, - variable, domain, zonal, value)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(CutSection(diags.data_manager, startdate, member, chunk, variable, domain, zonal, value)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 1244a44..0e6ee31 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -45,10 +45,8 @@ class Gyres(Diagnostic): if len(options) > 1: raise Exception('The gyres diagnostic has no options') job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.nemo_version)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.nemo_version)) return job_list # noinspection PyPep8Naming diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index bf9d02e..a5f7fe2 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -59,10 +59,8 @@ class HeatContent(Diagnostic): box.min_depth = int(options[3]) box.max_depth = int(options[4]) job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(HeatContent(diags.data_manager, startdate, member, chunk, basin, mixed_layer, box)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(HeatContent(diags.data_manager, startdate, member, chunk, basin, mixed_layer, box)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 00dd144..19e04c3 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -53,10 +53,8 @@ class HeatContentLayer(Diagnostic): box.min_depth = int(options[1]) box.max_depth = int(options[2]) job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 1555767..bcfc905 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -58,11 +58,9 @@ class Interpolate(Diagnostic): domain = 'ocean' job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Interpolate(diags.data_manager, startdate, member, chunk, - variable, domain, diags.nemo_version)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(Interpolate(diags.data_manager, startdate, member, chunk, + variable, domain, diags.nemo_version)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index b6cbff6..b19e5b9 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -45,10 +45,8 @@ class MixedLayerHeatContent(Diagnostic): if len(options) > 1: raise Exception('The mixed layer ocean heat content diagnostic has no options') job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(MixedLayerHeatContent(diags.data_manager, startdate, member, chunk)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(MixedLayerHeatContent(diags.data_manager, startdate, member, chunk)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 26aa990..e62765e 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -44,10 +44,8 @@ class MixedLayerSaltContent(Diagnostic): if len(options) > 1: raise Exception('The mixed layer salt content diagnostic has no options') job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(MixedLayerSaltContent(diags.data_manager, startdate, member, chunk)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(MixedLayerSaltContent(diags.data_manager, startdate, member, chunk)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index fa5f705..3588f7c 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -45,10 +45,8 @@ class Moc(Diagnostic): if len(options) > 1: raise Exception('The MOC diagnostic has no options') job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Moc(diags.data_manager, startdate, member, chunk)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(Moc(diags.data_manager, startdate, member, chunk)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 3bb1a8d..8c7b372 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -40,10 +40,8 @@ class Psi(Diagnostic): if len(options) > 1: raise Exception('The PSI diagnostic has no options') job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Psi(diags.data_manager, startdate, member, chunk)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(Psi(diags.data_manager, startdate, member, chunk)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 798745f..caedf87 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -69,10 +69,8 @@ class Siasiesiv(Diagnostic): mask_handler.close() job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk, mask)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk, mask)) mesh_handler = Utils.openCdf('mesh_hgr.nc') Siasiesiv.e1t = np.asfortranarray(mesh_handler.variables['e1t'][0, :]) Siasiesiv.e2t = np.asfortranarray(mesh_handler.variables['e2t'][0, :]) diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 26d4b6c..d3b4d19 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -58,11 +58,9 @@ class VerticalMean(Diagnostic): box.max_depth = float(options[3]) job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(VerticalMean(diags.data_manager, startdate, member, chunk, - variable, box)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(VerticalMean(diags.data_manager, startdate, member, chunk, + variable, box)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 7397240..b656eb2 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -55,11 +55,8 @@ class VerticalMeanMeters(Diagnostic): box.max_depth = float(options[3]) job_list = list() - for startdate in diags.startdates: - for member in diags.members: - for chunk in range(1, diags.chunks + 1): - job_list.append(VerticalMeanMeters(diags.data_manager, startdate, member, chunk, - variable, box)) + for startdate, member, chunk in diags.get_chunk_list(): + job_list.append(VerticalMeanMeters(diags.data_manager, startdate, member, chunk, variable, box)) return job_list def compute(self): -- GitLab From 97d62554f59b757124a37c86b966968634621f7f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 5 Jul 2016 11:05:46 +0200 Subject: [PATCH 113/268] Updated doc and minor refactors --- doc/source/codedoc/earthdiagnostics.rst | 19 +-- earthdiagnostics/{basins.py => constants.py} | 30 +++++ earthdiagnostics/datamanager.py | 112 ++++++------------ earthdiagnostics/models.py | 26 ---- earthdiagnostics/ocean/areamoc.py | 5 +- earthdiagnostics/ocean/averagesection.py | 3 + earthdiagnostics/ocean/convectionsites.py | 5 +- earthdiagnostics/ocean/cutsection.py | 3 + earthdiagnostics/ocean/gyres.py | 5 +- earthdiagnostics/ocean/heatcontent.py | 5 +- earthdiagnostics/ocean/heatcontentlayer.py | 9 +- earthdiagnostics/ocean/interpolate.py | 3 + earthdiagnostics/ocean/maxmoc.py | 5 +- .../ocean/mixedlayerheatcontent.py | 8 +- .../ocean/mixedlayersaltcontent.py | 4 +- earthdiagnostics/ocean/moc.py | 5 +- earthdiagnostics/ocean/psi.py | 3 + earthdiagnostics/ocean/siasiesiv.py | 6 +- earthdiagnostics/ocean/verticalmean.py | 3 + earthdiagnostics/ocean/verticalmeanmeters.py | 3 + earthdiagnostics/parser.py | 4 + earthdiagnostics/utils.py | 59 ++++++--- 22 files changed, 183 insertions(+), 142 deletions(-) rename earthdiagnostics/{basins.py => constants.py} (90%) delete mode 100644 earthdiagnostics/models.py diff --git a/doc/source/codedoc/earthdiagnostics.rst b/doc/source/codedoc/earthdiagnostics.rst index b516ff9..363fc6c 100644 --- a/doc/source/codedoc/earthdiagnostics.rst +++ b/doc/source/codedoc/earthdiagnostics.rst @@ -1,16 +1,16 @@ earthdiagnostics ================ -earthdiagnostics.ocean.basins ------------------------------ -.. automodule:: earthdiagnostics.basins +earthdiagnostics.ocean.box +-------------------------- +.. automodule:: earthdiagnostics.box :show-inheritance: :inherited-members: :members: -earthdiagnostics.ocean.box --------------------------- -.. automodule:: earthdiagnostics.box +earthdiagnostics.ocean.constants +-------------------------------- +.. automodule:: earthdiagnostics.constants :show-inheritance: :inherited-members: :members: @@ -44,13 +44,6 @@ earthdiagnostics.ocean.diags :inherited-members: :members: -earthdiagnostics.ocean.models ------------------------------ -.. automodule:: earthdiagnostics.models - :show-inheritance: - :inherited-members: - :members: - earthdiagnostics.ocean.utils ---------------------------- .. automodule:: earthdiagnostics.utils diff --git a/earthdiagnostics/basins.py b/earthdiagnostics/constants.py similarity index 90% rename from earthdiagnostics/basins.py rename to earthdiagnostics/constants.py index 70bcc1a..018b1fe 100644 --- a/earthdiagnostics/basins.py +++ b/earthdiagnostics/constants.py @@ -1,4 +1,7 @@ # coding=utf-8 +""" +Contains the enumeration-like classes used by the diagnostics +""" from earthdiagnostics.box import Box @@ -211,3 +214,30 @@ class Basins(object): if basin.lower() in [value.shortname.lower(), value.fullname.lower()]: return value return None + + +class Models(object): + """ + Predefined models + """ + + ECEARTH_2_3_O1L42 = 'Ec2.3_O1L42' + """ EC-Earth 2.3 ORCA1 L42""" + ECEARTH_3_0_O1L46 = 'Ec3.0_O1L46' + """ EC-Earth 3 ORCA1 L46 """ + ECEARTH_3_0_O25L46 = 'Ec3.0_O25L46' + """ EC-Earth 3 ORCA0.25 L46 """ + ECEARTH_3_0_O25L75 = 'Ec3.0_O25L75' + """ EC-Earth 3 ORCA0.25 L75 """ + + NEMO_3_2_O1L42 = 'N3.2_O1L42' + """ NEMO 3.2 ORCA1 L42 """ + NEMO_3_3_O1L46 = 'N3.3_O1L46' + """ NEMO 3.3 ORCA1 L46 """ + NEMO_3_6_O1L46 = 'N3.6_O1L75' + """ NEMO 3.6 ORCA1 L75 """ + + NEMOVAR_O1L42 = 'nemovar_O1L42' + """ NEMOVAR ORCA1 L42 """ + GLORYS2_V1_O25L75 = 'glorys2v1_O25L75' + """ GLORYS2v1 ORCA0.25 L75 """ diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 076bebe..5289879 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -13,25 +13,16 @@ from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day, add_months, \ date2str -from basins import Basins +from earthdiagnostics.constants import Basins from earthdiagnostics.utils import Utils, TempFile class DataManager(object): + """ + Class to manage the data repositories + """ def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name, num_chunks, scratch_dir, nfrp, member_digits, calendar='standard'): - """ - - :param institution: - :param model: - :param expid: - :param datafolder: - :param frequency: - :param chunk_size: - :param experiment_name: - :param num_chunks: - :param calendar: - """ self.initialization_method = 'to be filled' self.initialization_description = 'to be filled' self.physics_version = 'to be filled' @@ -77,11 +68,12 @@ class DataManager(object): :return: """ # Check if cmorized and convert if not - + created = False for startdate in startdates: for member in members: if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member))): + created = True Log.info('CMORizing startdate {0} member {1}', startdate, self.get_member_str(member)) if ocean: path_MMO = os.path.join(self.data_dir, self.expid, 'original_files', startdate, @@ -101,8 +93,9 @@ class DataManager(object): self._unpack_tar(member, startdate, tarfile) else: self._cmorize_grib(startdate, member, gribfiles) - return - + Log.result('CMORized startdate {0} member {1}!\n\n', startdate, self.get_member_str(member)) + if created: + return for startdate in startdates: for member in members: member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, @@ -475,17 +468,35 @@ class DataManager(object): 'depth', 'depth_2', 'depth_3', 'depth_4', 'mlev', 'hyai', 'hybi', 'hyam', 'hybm'): continue - self.extract_variable(file_parts, filename, frequency, handler, member, startdate, temp, - variable) + self.extract_variable(filename, handler, frequency, member, startdate, temp, variable) Log.result('File {0} cmorized!', filename) handler.close() os.remove(filename) - def extract_variable(self, file_parts, filename, frequency, handler, member, startdate, temp, variable): + def extract_variable(self, file_path, handler, frequency, member, startdate, temp, variable): + """ + Extracts a variable from a file and creates the CMOR file + + :param file_path: path to the file + :type file_path: str + :param handler: netCDF4 handler for the file + :type handler: netCDF$.Dataset + :param frequency: variable's frequency + :type frequency: str + :param member: member + :type member: int + :param startdate: startdate + :type startdate: str + :param temp: temporal file to use + :type temp: str + :param variable: variable's name + :type variable: str + """ + file_parts = os.path.basename(file_path).split('_') var_cmor = Variable.get_variable(variable) if var_cmor is None: return - Utils.nco.ncks(input=filename, output=temp, options='-v {0}'.format(variable)) + Utils.nco.ncks(input=file_path, output=temp, options='-v {0}'.format(variable)) if var_cmor.domain == 'ocean': Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev', 'depth': 'lev'}, False, True) @@ -608,60 +619,6 @@ class DataManager(object): for filepath in files: Log.debug('Unpacking {0}', filepath) Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) - # os.remove(filepath) - - def get_files(self, startdate, member, chunk, domain, variables, grid=None): - """ - Returns a list of filenames for different variables - - :param startdate: startdate to retrieve - :type startdate: str - :param member: member to retrieve - :type member: int - :param chunk: chunk to retrieve - :type chunk: int - :param domain: variable's CMOR domain - :type domain:str - :param variables: variables list - :type variables: list[str], tuple[str] - :param grid: specifies if the variable must be in a interpolated grid - :type grid: str - :return: - """ - - file_names = list() - - domain_abreviattion = self.domain_abbreviation(domain, self.frequency) - - start = parse_date(startdate) - member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), - 'outputs', 'output', self.institution, self.model, self.experiment_name, - 'S' + startdate, self.frequency, domain) - - chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') - - var_file = list() - for var in variables: - if grid: - var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) - else: - var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) - - var_file.append(os.path.join(var_path, - '{0}_{1}_{3}_{4}_S{5}_r{6}i1p1_' - '{7}-{8}.nc'.format(var, domain_abreviattion, - self.frequency, self.model, self.experiment_name, - startdate, member_plus, - "{0:04}{1:02}".format(chunk_start.year, - chunk_start.month), - "{0:04}{1:02}".format(chunk_end.year, - chunk_end.month)))) - file_names.append(var_file) - - return file_names def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ @@ -1019,6 +976,13 @@ class Variable(object): @classmethod def get_variable(cls, original_name): + """ + Returns the cmor variable instance given a varuiable name + :param original_name: original variable's name + :type original_name: str + :return: CMOR variable + :rtype: Variable + """ try: return Variable._dict_variables[original_name.lower()] diff --git a/earthdiagnostics/models.py b/earthdiagnostics/models.py deleted file mode 100644 index 2fcad83..0000000 --- a/earthdiagnostics/models.py +++ /dev/null @@ -1,26 +0,0 @@ -# coding=utf-8 -class Models(object): - """ - Predefined models - """ - - ECEARTH_2_3_O1L42 = 'Ec2.3_O1L42' - """ EC-Earth 2.3 ORCA1 L42""" - ECEARTH_3_0_O1L46 = 'Ec3.0_O1L46' - """ EC-Earth 3 ORCA1 L46 """ - ECEARTH_3_0_O25L46 = 'Ec3.0_O25L46' - """ EC-Earth 3 ORCA0.25 L46 """ - ECEARTH_3_0_O25L75 = 'Ec3.0_O25L75' - """ EC-Earth 3 ORCA0.25 L75 """ - - NEMO_3_2_O1L42 = 'N3.2_O1L42' - """ NEMO 3.2 ORCA1 L42 """ - NEMO_3_3_O1L46 = 'N3.3_O1L46' - """ NEMO 3.3 ORCA1 L46 """ - NEMO_3_6_O1L46 = 'N3.6_O1L75' - """ NEMO 3.6 ORCA1 L75 """ - - NEMOVAR_O1L42 = 'nemovar_O1L42' - """ NEMOVAR ORCA1 L42 """ - GLORYS2_V1_O25L75 = 'glorys2v1_O25L75' - """ GLORYS2v1 ORCA0.25 L75 """ diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 34039aa..5c5b1a4 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -1,6 +1,6 @@ # coding=utf-8 import numpy as np -from earthdiagnostics.basins import Basins +from earthdiagnostics.constants import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.box import Box from earthdiagnostics.utils import Utils, TempFile @@ -67,6 +67,9 @@ class AreaMoc(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ nco = Utils.nco cdo = Utils.cdo temp2 = TempFile.get() diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 12e2730..1370206 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -63,6 +63,9 @@ class AverageSection(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ temp = TempFile.get() variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk, grid='regular') diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 9a6e458..11e2c98 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -3,7 +3,7 @@ import numpy as np from autosubmit.config.log import Log from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile -from earthdiagnostics.models import Models +from earthdiagnostics.constants import Models class ConvectionSites(Diagnostic): @@ -49,6 +49,9 @@ class ConvectionSites(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, Models.NEMOVAR_O1L42]: diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index 6867b77..8bc5725 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -64,6 +64,9 @@ class CutSection(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ nco = Utils.nco handler = Utils.openCdf('mesh_hgr.nc') diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 0e6ee31..bdfc97b 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -2,7 +2,7 @@ import numpy as np from autosubmit.config.log import Log -from earthdiagnostics.models import Models +from earthdiagnostics.constants import Models from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile @@ -51,6 +51,9 @@ class Gyres(Diagnostic): # noinspection PyPep8Naming def compute(self): + """ + Runs the diagnostic + """ if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, Models.NEMOVAR_O1L42]: diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index a5f7fe2..6ab84f0 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -4,7 +4,7 @@ import shutil from autosubmit.config.log import Log from earthdiagnostics import cdftools -from earthdiagnostics.basins import Basins +from earthdiagnostics.constants import Basins from earthdiagnostics.utils import Utils, TempFile from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.box import Box @@ -64,6 +64,9 @@ class HeatContent(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ nco = Utils.nco temperature_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) if self.mxloption != 0: diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 19e04c3..cda8135 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -1,10 +1,10 @@ # coding=utf-8 import numpy as np -from box import Box -from diagnostic import Diagnostic +from earthdiagnostics.box import Box +from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics import cdo -from utils import Utils, TempFile +from earthdiagnostics.utils import Utils, TempFile class HeatContentLayer(Diagnostic): @@ -58,6 +58,9 @@ class HeatContentLayer(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ nco = Utils.nco temp = TempFile.get() heatc_sl_out = TempFile.get() diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index bcfc905..1aa7dda 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -64,6 +64,9 @@ class Interpolate(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) cdo = Utils.cdo nco = Utils.nco diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 1b0aea4..93ff457 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -3,7 +3,7 @@ import netCDF4 import numpy as np import os from autosubmit.config.log import Log -from earthdiagnostics.basins import Basins +from earthdiagnostics.constants import Basins from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils @@ -74,6 +74,9 @@ class MaxMoc(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ nco = Utils.nco temp = self.data_manager.get_year('ocean', 'vsftmyz', self.startdate, self.member, self.year) diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index b19e5b9..acd1abb 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -1,10 +1,9 @@ # coding=utf-8 import os -from autosubmit.config.log import Log -from diagnostic import Diagnostic +from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics import cdftools -from utils import Utils, TempFile +from earthdiagnostics.utils import Utils, TempFile class MixedLayerHeatContent(Diagnostic): @@ -50,6 +49,9 @@ class MixedLayerHeatContent(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ temperature_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index e62765e..8eb38b6 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -1,6 +1,5 @@ # coding=utf-8 import os -from autosubmit.config.log import Log from earthdiagnostics import cdftools from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile @@ -49,6 +48,9 @@ class MixedLayerSaltContent(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ salinity_file = self.data_manager.get_file('ocean', 'so', self.startdate, self.member, self.chunk) mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index 3588f7c..0310719 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -3,7 +3,7 @@ import numpy as np from autosubmit.config.log import Log from earthdiagnostics import cdftools -from earthdiagnostics.basins import Basins +from earthdiagnostics.constants import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile @@ -50,6 +50,9 @@ class Moc(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ temp = TempFile.get() input_file = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 8c7b372..78ebcb6 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -45,6 +45,9 @@ class Psi(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ temp = TempFile.get() input_file_u = self.data_manager.get_file('ocean', 'uo', self.startdate, self.member, self.chunk) input_file_v = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index caedf87..a016149 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -1,7 +1,7 @@ # coding=utf-8 import netCDF4 import os -from earthdiagnostics.basins import Basins +from earthdiagnostics.constants import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile import cdftoolspython @@ -80,7 +80,9 @@ class Siasiesiv(Diagnostic): return job_list def compute(self): - + """ + Runs the diagnostic + """ sit_file = self.data_manager.get_file('seaIce', 'sit', self.startdate, self.member, self.chunk) sit_handler = Utils.openCdf(sit_file) sit = np.asfortranarray(sit_handler.variables['sit'][:]) diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index d3b4d19..053486d 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -64,6 +64,9 @@ class VerticalMean(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ temp = TempFile.get() variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index b656eb2..17b2adc 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -60,6 +60,9 @@ class VerticalMeanMeters(Diagnostic): return job_list def compute(self): + """ + Runs the diagnostic + """ temp = TempFile.get() variable_file = self.data_manager.get_file('ocean', self.variable, self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/parser.py b/earthdiagnostics/parser.py index af4bfbb..2567821 100644 --- a/earthdiagnostics/parser.py +++ b/earthdiagnostics/parser.py @@ -6,6 +6,10 @@ import re # noinspection PyClassicStyleClass class Parser(SafeConfigParser): + """ + Class to manage the config file. It add options to manage default values and to convert strings to the + desired types (int, bool, list ...) + """ def get_option(self, section, option, default=''): """ diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 80e6bfc..a2cdcf4 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -1,16 +1,16 @@ # coding=utf-8 import hashlib +import shutil import subprocess import netCDF4 import numpy as np +import os import re +import tempfile from autosubmit.config.log import Log from cdo import Cdo from nco import Nco -import tempfile -import os -import shutil class Utils(object): @@ -171,9 +171,9 @@ class Utils(object): @staticmethod def available_cpu_count(): - """ Number of available virtual or physical CPUs on this system, i.e. - user/real as output by time(1) when called with an optimally scaling - userspace-only program""" + """ + Number of available virtual or physical CPUs on this systemx + """ if Utils._cpu_count is None: try: m = re.search(r'(?m)^Cpus_allowed:\s*(.*)$', @@ -194,6 +194,12 @@ class Utils(object): @staticmethod def convert2netcdf4(filetoconvert): + """ + Checks if a file is in netCDF4 format and converts to netCDF4 if not + + :param filetoconvert: file to convert + :type filetoconvert: str + """ temp = TempFile.get() handler = Utils.openCdf(filetoconvert) if handler.file_format == 'NETCDF4': @@ -207,10 +213,30 @@ class Utils(object): # noinspection PyPep8Naming @staticmethod def openCdf(filepath, mode='a'): + """ + Opens a netCDF file and returns a handler to it + + :param filepath: path to the file + :type filepath: str + :param mode: mode to open the file. By default, a (append) + :type mode: str + :return: handler to the file + :rtype: netCDF4.Dataset + """ return netCDF4.Dataset(filepath, mode) @staticmethod def get_datetime_from_netcdf(handler, time_variable='time'): + """ + Gets a datetime array from a netCDF file + + :param handler: file to read + :type handler: netCDF4.Dataset + :param time_variable: variable to read, by default 'time' + :type time_variable: str + :return: Datetime numpy array created from the values stored at the netCDF file + :rtype: np.array + """ nctime = handler.variables[time_variable][:] # get values units = handler.variables[time_variable].units # get unit "days since 1950-01-01T00:00:00Z" @@ -222,6 +248,19 @@ class Utils(object): @staticmethod def copy_variable(source, destiny, variable, must_exist=True): + """ + Copies the given variable from source to destiny + + :param source: origin file + :type source: netCDF4.Dataset + :param destiny: destiny file + :type destiny: netCDF4.Dataset + :param variable: variable to copy + :type variable: str + :param must_exist: if false, does not raise an error uf variable does not exist + :type must_exist: booº + :return: + """ if not must_exist and variable not in source.variables.keys(): return if variable in destiny.variables.keys(): @@ -291,11 +330,3 @@ class TempFile(object): if os.path.exists(temp_file): os.remove(temp_file) TempFile.files = list() - - -def main(): - print Utils.move_file('/esnas/exp/ecearth/a04e/original_files/19930501/fc0/outputs/ICMGGa04e+199305.grb', - '/scratch/Earth/jvegas/temp.nc') - -if __name__ == "__main__": - main() -- GitLab From f99a166b285ad0beb44d0083047632913d430dcc Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 5 Jul 2016 16:01:19 +0200 Subject: [PATCH 114/268] Minor changes to make the diagnostics more user-friendly. Removed old diagnostics. Added measurement of time consumed by each diagnostic class --- CHANGES | 3 +- EarthDiagnostics.pdf | Bin 0 -> 181999 bytes README | 106 +-- VERSION | 2 +- common_ocean_post.txt | 1362 ----------------------------------- config_file-ocean_pp.bash | 45 -- doc/source/developers.rst | 58 +- doc/source/errors.rst | 8 +- doc/source/tips.rst | 3 +- doc/source/tutorial.rst | 12 +- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 41 +- earthdiagnostics/utils.py | 3 +- ocean_pp.bash | 678 ----------------- setup_development.bash | 41 -- testing_ocean_pp_moore.job | 26 - 16 files changed, 119 insertions(+), 2271 deletions(-) create mode 100644 EarthDiagnostics.pdf delete mode 100644 common_ocean_post.txt delete mode 100644 config_file-ocean_pp.bash delete mode 100755 ocean_pp.bash delete mode 100755 setup_development.bash delete mode 100755 testing_ocean_pp_moore.job diff --git a/CHANGES b/CHANGES index bfcabf5..11b4c2e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,5 @@ 3.0.0 - Migration to Python + Complete rewrite in Python Update CDFTools from version 2.1 to 3.0 Adoption of CMOR standard + diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf new file mode 100644 index 0000000000000000000000000000000000000000..85d3422960dfecbafb188f50ea99ea2af64fdd54 GIT binary patch literal 181999 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

xgqPdzW!c0W4h+w#aw%h04I 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 D> +Check the Earth Diagnostics documentation in PDF format in EarthDiagnostics.pdf available also in this folder. -# +CONTACT +======= -####################### DIAGNOSTICS LIST ####################################### -'siasiesiv' : sea ice area + sea ice extent + sea ice volume -'moc' : Atlantic + Pacific + Indian + Indo-Pacific + Global - meridional overturning streamfunction -'max_moc' : Yearly maximum of the Atlantic meridional overturning - streamfunction between 38N-50N and 500-3000m and - at 40N. - Beware that the max_moc diagnostics can not be computed - if you don't process complete years, as it is a diagnostic - computed from complete years. -'area_moc' : Averaged Atlantic meridional overturning streamfunction - between 40N-55N and 1km-2km and between 30N-40N and 1km-2km -'convection' : indices of convective activity in the Labrador, extended Irminger, - GIN and Wedell seas computed as the maximum in mixed layer depth - based on the potential density criteria -'stc' : Subtropical cell strength, computed as the averaged Atlantic - and Pacific overturning streamfunction in 0-25N/S, 0-200m -'ext_raw_ice' : raw ice varibales to be extracted from input files - (called "ice" before february 2013 update)) -'ext_raw_oce' : raw ocean varibales to be extracted from input files - (called "sstsssmld" before february 2013 update)) -'heat_sal_mxl' : mixed layer heat and salt content (potential density criteria) -'psi' : barotropic streamfunction -'gyres' : indices of the barotropic gyres computed as the maximum absolute - barotropic streamfunction in the North Atlantic and North Pacific - subpolar and subtropical gyres and in the South Atlantic, South - Pacific and Indian subtropical gyres and indice of the Antarctic - Circumpolar Current strength -'usalc' : upper layer salt content 0-300m -'temp_lev' : temperature, vertical mean between dif levels (2D) -'sal_lev' : salinity, vertical mean between dif levels (2D) -'lmsalc' : middle + lower layer salt content 300m-bottom -'ohc' : global total ocean heat content -'ohc_specified_layer' : Pointwise ocean heat content in a specified ocean thickness (at present 0-300 m) -'uohc' : global upper (0-350m) ocean heat content -'mohc' : global middle (350-800m) ocean heat content -'lohc' : global lower (800m-bottom) ocean heat content -'xohc' : global mixed layer ocean heat content -'TSec_ave190-220E' : meridional temperature section averaged between 190E and 220E -'SSec_ave190-220E' : meridional salinity section averaged between 190E and 220E (added in february 2013 update) -'vert_Tsections' : zonal temperature sections along 45S, 0N, 45N, and - meridional temperature sections along 30W, 80E, 180E -'vert_Ssections' : zonal salinity sections along 45S, 0N, 45N, and - meridional salinity sections along 30W, 80E, 180E (added in february 2013 update) -'3dtemp' : 3-dimensional temperature interpolated horizontally onto the - atmospheric grid -'3dsal' : 3-dimensional salinity interpolated horizontally onto the - atmospheric grid (added in february 2013 update) -'NAtlohc' : North Atlantic (10-65N) total ocean heat content -'xNAtlohc' : North Atlantic (10-65N) mixed layer ocean heat content -'uNAtlohc' : North Atlantic (10-65N) upper (0-350m) ocean heat content -'mNAtlohc' : North Atlantic (10-65N) middle (350-800m) ocean heat content -'lNAtlohc' : North Atlantic (10-65N) lower (800m-bottom) ocean heat content -'NPacohc' : North Pacific (10-70N) ocean heat content -'xNPacohc' : North Pacific (10-70N) mixed layer ocean heat content -'uNPacohc' : North Pacific (10-70N) upper (0-350m) ocean heat content -'mNPacohc' : North Pacific (10-70N) middle (350-800m) ocean heat content -'lNPacohc' : North Pacific (10-70N) lower (800m-bottom) ocean heat content -'TAtlohc' : Tropical Atlantic (30S-30N) ocean heat content -'xTAtlohc' : Tropical Atlantic (30S-30N) mixed layer ocean heat content -'uTAtlohc' : Tropical Atlantic (30S-30N) upper (0-350m) ocean heat content -'mTAtlohc' : Tropical Atlantic (30S-30N) middle (350-800m) ocean heat - content -'lTAtlohc' : Tropical Atlantic (30S-30N) lower (800m-bottom) ocean heat - content -'TPacohc' : Tropical Pacific (30S-30N) ocean heat content -'xTPacohc' : Tropical Pacific (30S-30N) mixed layer ocean heat content -'uTPacohc' : Tropical Pacific (30S-30N) upper (0-350m) ocean heat content -'mTPacohc' : Tropical Pacific (30S-30N) middle (350-800m) ocean heat content -'lTPacohc' : Tropical Pacific (30S-30N) lower (800m-bottom) ocean heat - content -'TIndohc' : Tropical Indian (30S-30N) ocean heat content -'xTIndohc' : Tropical Indian (30S-30N) mixed layer ocean heat content -'uTIndohc' : Tropical Indian (30S-30N) upper (0-350m) ocean heat content -'mTIndohc' : Tropical Indian (30S-30N) middle (350-800m) ocean heat content -'lTIndohc' : Tropical Indian (30S-30N) lower (800m-bottom) ocean heat - content -'Antaohc' : Antarctic (90-60S) ocean heat content -'xAntaohc' : Antarctic (90-60S) mixed layer ocean heat content -'uAntaohc' : Antarctic (90-60S) upper (0-350m) ocean heat content -'mAntaohc' : Antarctic (90-60S) middle (350-800m) ocean heat content -'lAntaohc' : Antarctic (90-60S) lower (800m-bottom) ocean heat content -'Arctohc' : Arctic (65-90N) ocean heat content -'xArctohc' : Arctic (65-90N) mixed layer ocean heat content -'uArctohc' : Arctic (65-90N) upper (0-350m) ocean heat content -'mArctohc' : Arctic (65-90N) middle (350-800m) ocean heat content -'lArctohc' : Arctic (65-90N) lower (800m-bottom) ocean heat content -'temp_lev' : vertical mean of ocean temp (weighted) between level1 and level2 (in numbers, not in meters), specified in the config file -'sal_lev' : vertical mean of ocean sal (weighted) between level1 and level2 (in numbers, not in meters), specified in the config file -'ohc_Articreg1' : ocean heat content in the specified Arctic region (0-657m) +For any doubts or suggestions, contact javier.vegas@bsc.es \ No newline at end of file diff --git a/VERSION b/VERSION index 4a36342..2daa89b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0 +3.0.0b1 diff --git a/common_ocean_post.txt b/common_ocean_post.txt deleted file mode 100644 index 72665f8..0000000 --- a/common_ocean_post.txt +++ /dev/null @@ -1,1362 +0,0 @@ -############################################################################### -# This file gathers a set of bash functions that rely on cdftools to # -# # -# reduce_mmo # -# get_diagsMMO # -# get_nemovar # -# get_glorys # -# clean_diagsMMO # -# vertmeansal # -# heat_sal_mxl # -# ohc_specified_layer # -# moc # -# convection # -# psi # -# gyres # -# area_moc # -# max_moc # -# siasiesiv # -# ohc # -# cutsection # -# interp3d # -# setminmax # -# concat # -# gather_memb # -# vertmeanvar # -# # -# Those functions would never have seen the day without Hui Du, # -# usually referred to as Super-Hui. # -# # -# He made a crucial work to develop what ended up below in the functions # -# that computes the sea ice extent, sea ice area, ocean heat content and # -# meridional overturning streamfunction. # -# Especially, he developped new options from the cdftools sources to be # -# able to compute the heat content in different basins. # -# # -#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -# You want to make available a new diagnostic ? @ -# @ -# 1) Get an MMO tar files from any experiment on esnas @ -# 2) Write a bash function that works on a grid_T or grid_U or grid_V or @ -# grid_W file or a combination from this MMO file @ -# --> You can test your function by defining the CON_FILES and NEMOVERSION @ -# variables and by sourcing the current file, the meshmasks will be @ -# available after sourcing, remember to source again after any @ -# modification of your function @ -# --> Your function should work on input files of any resolution @ -# ORCA1/ORCA025/ORCA2 @ -# --> Your function should work on input files of any time length @ -# --> The output file should contain a proper time axis that you can copy @ -# from your input file @ -# --> The output file should be at most a 3d field including the time @ -# dimension @ -# 3) Write a short description of your function, and add its name to the @ -# list above @ -# 4) Go the the ocean_pp.sh script to add a call to your function @ -# @ -# Any doubt ---> vguemas@ic3.cat @ -#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -# Link constant file for co # -############################################################################### - -cp -f ${CON_FILES}/mesh_mask_nemo.${NEMOVERSION}.nc mesh_hgr.nc -cp -f ${CON_FILES}/mesh_mask_nemo.${NEMOVERSION}.nc mesh_zgr.nc -cp -f ${CON_FILES}/mesh_mask_nemo.${NEMOVERSION}.nc mask.nc -cp -f ${CON_FILES}/new_maskglo.${NEMOVERSION}.nc new_maskglo.nc - -if [ -e ${CON_FILES}/mask.regions.${NEMOVERSION}.nc ] ; then -cp ${CON_FILES}/mask.regions.${NEMOVERSION}.nc mask_regions.nc -fi - -if [ -e ${CON_FILES}/mask.regions.3d.${NEMOVERSION}.nc ] ; then -cp ${CON_FILES}/mask.regions.3d.${NEMOVERSION}.nc mask_regions.3d.nc -fi - -if [[ ! -f mask.nc ]] ; then - echo "No configuration files for cdftools" - exit -fi - -############################################################################### -# Reduced number of variables in diag files to save disk space # -# # -# $1 : input grid_T file name # -# $2 : input icemod file name # -# $3 : suffix of output files with nc extension # -# # -# Created in February 2012 Author : vguemas@ic3.cat # -# May 2014 : Compatibility with PA changes to oce output - Virginie # -############################################################################### - -function reduce_mmo { -ncks -O -v sosstsst,sosaline,somixhgt,somxl010,sossheig $1 oce_${3} -typeset var lstvars=`cdo showvar $2` -if [[ ${lstvars/ileadfra} != ${lstvars} ]] ; then - ncks -O -v isnowthi,iicethic,ileadfra,iicetemp $2 ice_${3} -else - ncks -O -v isnowthi,iicethic,iiceconc,iicetemp $2 ice_${3} -fi -ncks -O -v votemper $1 t3d_${3} -} -############################################################################### -# Copy diags or MMO files from esnas # -# # -# $1 : starting date # -# $2 : expid # -# $3 : member # -# $4 : starting leadtime # -# $5 : end leadtime # -# $6 : chunk length in month # -# $7 : nemo/ecearth # -# $8 : diags/MMO # -# $9 : storage frequency (daily/monthly) # -# $10 : list of files extracted from the original tarballs -# # -# Created in May 2012 Author : vguemas@ic3.cat # -# Option 10: June 2013 isabel.andreu-burillo@ic3.cat -############################################################################### - -function get_diagsMMO { -typeset var yyyy0=`echo $1|cut -c1-4` -typeset var mm0=`echo $1|cut -c5-6` -if [ -z "${10}" ] ; then - typeset var lstypes="grid_T grid_U grid_V grid_W icemod" -else - typeset var lstypes=${10} -fi - -typeset var jt -typeset var year1 -typeset var year2 -typeset var mon1 -typeset var mon2 -for jt in $(seq $4 $6 $5) ; do - year1=$(($yyyy0+(10#$mm0+$jt-2)/12)) - mon1=$(((10#$mm0+$jt-2)%12+1)) - year2=$(($yyyy0+(10#$mm0+$jt+$6-3)/12)) - mon2=$(((10#$mm0+$jt+$6-3)%12+1)) - cp /esnas/exp/$7/$2/$1/fc$3/outputs/$8_$2_$1_fc$3_${year1}$(printf "%02d" $mon1)01-${year2}$(printf "%02d" $mon2)*.tar . - if [[ "$8" == "MMO" ]]; then - for filetype in $lstypes; do - tar --wildcards -xvf $8_$2_$1_fc$3_${year1}$(printf "%02d" $mon1)01-${year2}$(printf "%02d" $mon2)*.tar "*${freqkeep}*${filetype}*" - done - else - tar --wildcards -xvf $8_$2_$1_fc$3_${year1}$(printf "%02d" $mon1)01-${year2}$(printf "%02d" $mon2)*.tar - fi - rm -f $8_$2_$1_fc$3_${year1}$(printf "%02d" $mon1)01-${year2}$(printf "%02d" $mon2)*.tar - if [[ `ls *.gz` != '' ]] ; then gunzip -f *.gz ; fi -done - -typeset var listroots -case $8 in - 'diags' ) - listroots="t3d heat_sal_mxl ice moc psi sal_0-300m sal_300-5400m" - if [[ `ls sstsimld*` != '' ]] ; then - listroots=$listroots" sstsimld" - elif [[ `ls sstsssmld*` != '' ]] ; then - listroots=$listroots" sstsssmld" - else - listroots=$listroots" oce" - fi - ;; - 'MMO' ) listroots=$lstypes ;; -esac -case $9 in - 'daily') freqexcl1='1m' ; freqexcl2='MM' ;; - 'monthly' ) freqexcl1='1d' ; freqexcl2='DD' ;; - *) freqexcl1='1d' ; freqexcl2='DD' ;; -esac - -function concat_startdate { - typeset var root - typeset var lstfiles - for root in ${listroots[@]} ; do - if [[ `ls *${root}*` != '' ]] && [[ `ls *${root}*` != ${root}_1m.nc ]] && [[ `ls *${root}* | grep -v "${freqexcl1}" | grep -v "${freqexcl2}"` != '' ]] ; then - if [[ "$8" == "MMO" ]] ; then - lstfiles=`ls *${root}* | grep -v "${root}_$2_$1_fc" | grep -v "${freqexcl1}" | grep -v "${freqexcl2}" | grep -v "km" ` - else - lstfiles=`ls ${root}* | grep -v "${root}_$2_$1_fc" | grep -v "${freqexcl1}" | grep -v "${freqexcl2}" | grep -v "km" ` - fi - if [[ ! -z ${lstfiles} ]] ; then - file1=`echo "${lstfiles}" | tail -n 1` - cdo_version=`cdo -V &> ff ; grep Climate ff | cut -d \ -f 5` - rm ff - #test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values out of that range to be replaced by NaN - if [[ "$cdo_version" = "`echo -e "$cdo_version\n1.5.6" | sort -V | head -n1`" ]] ; then - if [[ $root == 'grid_T' || $root == 't3d' ]] ; then - for file in $lstfiles ; do - ncatted -O -a valid_max,votemper,d,, $file $file - ncatted -O -a valid_min,votemper,d,, $file $file - done - fi - if [[ $root == 'heat_sal_mxl' ]] ; then - for file in $lstfiles ; do - ncatted -O -a valid_max,somxlheatc,d,, $file $file - ncatted -O -a valid_min,somxlheatc,d,, $file $file - done - fi - fi - - - outfile=${root}_$2_$1_fc$3_$(($yyyy0+(10#$mm0+$4-2)/12))$(printf "%02d" $(((10#$mm0+$4-2)%12+1)))_${year2}$(printf "%02d" $mon2).nc - typeset var lstvars=`cdo showvar $file1` - if [[ ${lstvars/iicenflx} != ${lstvars} ]] ; then for file in $lstfiles ; do ncks -O -x -v iicenflx $file $file ; done ; fi - cdo mergetime $lstfiles ${outfile} - timevar=`ncdump -h ${outfile} | grep UNLIMITED | awk '{print $1}'` - if [[ $timevar == 'time_counter' ]] ; then ncrename -v time_counter,time -d time_counter,time ${outfile} ; fi - if [[ $root == 'moc' ]] ; then - lstdims=`ncdump -h ${outfile} | awk /dimensions:/,/variables:/ | grep -v dimensions: | grep -v variables: | awk '{print $1}'` - if [[ ${lstdims/gsize} != ${lstdims} ]] ; then - ncrename -d gsize,y ${outfile} - fi - lenx=`ncdump -h ${outfile} | grep 'x =' | head -n 1 | awk '{print $3}'` - if [[ $lenx > 1 ]] ; then - if [[ ${lstvars/nav_lon} != ${lstvars} ]] ; then - ncks -O -x -v nav_lon,nav_lat ${outfile} ${outfile} - fi - ncrename -d x,y ${outfile} - fi - ncks -A -v nav_lon,nav_lat `echo $lstfiles | awk '{print $1}' ` ${outfile} - fi - rm -f $lstfiles - if [[ $root == 'sstsimld' || $root == 'sstsssmld' ]] ; then mv ${outfile} oce_$2_$1_fc$3_$(($yyyy0+(10#$mm0+$4-2)/12))$(printf "%02d" $(((10#$mm0+$4-2)%12+1)))_${year2}$(printf "%02d" $mon2).nc ; fi - fi - fi - done -} - -concat_startdate $1 $2 $3 $4 $5 $6 $7 $8 - -# These lines aim at concatenating the daily means as well and computing the monthly means from these daily means -if [[ $9 == 'monthly' ]] ; then - freqexcl1='1m' ; freqexcl2='MM' - for root in ${listroots[@]} ; do - outfile=${root}_$2_$1_fc$3_$(($yyyy0+(10#$mm0+$4-2)/12))$(printf "%02d" $(((10#$mm0+$4-2)%12+1)))_${year2}$(printf "%02d" $mon2).nc - if [[ -e $outfile ]] ; then - mv $outfile ${root}_1m.nc - fi - done - concat_startdate $1 $2 $3 $4 $5 $6 $7 $8 - for root in ${listroots[@]} ; do - outfile=${root}_$2_$1_fc$3_$(($yyyy0+(10#$mm0+$4-2)/12))$(printf "%02d" $(((10#$mm0+$4-2)%12+1)))_${year2}$(printf "%02d" $mon2).nc - if [[ -e $outfile ]] ; then - cdo monmean $outfile ${root}_daily2monthly.nc - rm -f $outfile - if [[ -e ${root}_1m.nc ]] ; then - mv ${root}_1m.nc $outfile - ncks -A ${root}_daily2monthly.nc $outfile - rm -f ${root}_daily2monthly.nc - else - mv ${root}_daily2monthly.nc $outfile - fi - else - if [[ -e ${root}_1m.nc ]] ; then - mv ${root}_1m.nc $outfile - fi - fi - done -fi - -rm -f *${freqexcl1}* *${freqexcl2}* - -} -############################################################################### -# Copy NEMOVAR files from esnas # -# # -# $1 : expid # -# $2 : member # -# $3 : start year # -# $4 : end year # -# $5 : start month # -# $6 : end month # -# $7 : list of files extracted from the original tarballs -# # -# Created in May 2012 Author : vguemas@ic3.cat # -# Modified: June 2013 isabel.andreu-burillo@ic3.cat # -############################################################################### - -function get_nemovar { - -if [ -z "$5" ] ; then - typeset var moni=9 -else - typeset var moni=$5 -fi - -if [ -z "$5" ] ; then - typeset var monf=8 -else - typeset var monf=$6 -fi - -typeset var path -typeset var yearf -case $1 in - 'nemovar_s4') path=/esnas/exp/ECMWF/NEMOVAR_S4/outputs/fc$2/s4 ;; - 'nemovar_combine') path=/esnas/exp/ECMWF/NEMOVAR_COMBINE/outputs/opa0/fa9p_1m ;; -esac -typeset var year -typeset var mon -for year in $(seq $3 $4) ; do - case $year in - $3) mona=${moni} ;; - *) mona=1 ;; - esac - case $year in - $4) monb=${monf} ;; - *) monb=12 ;; - esac - for mon in $(seq $mona $monb); do - cp ${path}_fc$2_${year}$(printf "%02d" $mon)*.gz . - done -done -gunzip -f *.gz - -typeset var listroots=${7} -typeset var root -typeset var lstfiles -typeset var ntimes -typeset var jt -for root in ${listroots[@]} ; do - lstfiles=`ls *fc${2}*${root}* | grep -v "${root}_$1_195709_fc$2_${3}09_${4}$(printf "%02d" $monb).nc"` - ncrcat -O -x -v vorbiasp $lstfiles tmp_${root}.nc - cdo settaxis,${3}-$(printf "%02d" $moni)-15,12:00,1mon tmp_${root}.nc ${root}_$1_19570901_fc$2_${3}$(printf "%02d" $moni)_${4}$(printf "%02d" $monf).nc - rm -f $lstfiles tmp_${root}.nc -done -} -############################################################################### -# Copy GLORYS files from esnas # -# # -# $1 : start year # -# $2 : end year # -# $3 : start month # -# $4 : end month # -# # -# Created in June 2013 Author : vguemas@ic3.cat # -############################################################################### - -function get_glorys { -typeset var path=/esnas/exp/MERCATOR/GLORYS2V1/outputs/ORCA1L46 #ORCA025L75_glorys -typeset var lstfiles="" -for year in $(seq $1 $2) ; do - cp ${path}/vosaline_${year}.nc . - cp ${path}/votemper_${year}.nc . - ncks -A vosaline_${year}.nc votemper_${year}.nc - rm -f vosaline_${year}.nc - lstfiles=${lstfiles}" "votemper_${year}.nc -done -cdo cat ${lstfiles} tmp.nc -cdo settaxis,${1}-01-15,12:00,1mon tmp.nc tmp2.nc -cdo seldate,${1}-$(printf "%02d" $3)-00,${2}-$(printf "%02d" $4)-31 tmp2.nc grid_T_glorys2v1_19930101_fc0_${1}$(printf "%02d" $3)_${2}$(printf "%02d" $4).nc -rm -f ${lstfiles} tmp.nc tmp2.nc -ncks -O -x -v nav_lon,nav_lat,x_2,y_2 grid_T_glorys2v1_19930101_fc0_${1}$(printf "%02d" $3)_${2}$(printf "%02d" $4).nc grid_T_glorys2v1_19930101_fc0_${1}$(printf "%02d" $3)_${2}$(printf "%02d" $4).nc -ncks -A -v nav_lon,nav_lat mesh_hgr.nc grid_T_glorys2v1_19930101_fc0_${1}$(printf "%02d" $3)_${2}$(printf "%02d" $4).nc -} -############################################################################### -# Clean diags or MMO files after postprocessing # -# # -# $1 : starting date # -# $2 : expid # -# $3 : member # -# $4 : starting leadtime # -# $5 : end leadtime # -# $6 : diags/MMO # -# $7 : list of files extracted from the original tarballs -# # -# Created in May 2012 Author : vguemas@ic3.cat # -# Modified: June 2013 isabel.andreu-burillo@ic3.cat # -############################################################################### - -function clean_diagsMMO { -typeset var yyyy0=`echo $1|cut -c1-4` -typeset var mm0=`echo $1|cut -c5-6` -typeset var year1=$(($yyyy0+(10#$mm0+$4-2)/12)) -typeset var year2=$(($yyyy0+(10#$mm0+$5-2)/12)) -typeset var mon1=$(((10#$mm0+$4-2)%12+1)) -typeset var mon2=$(((10#$mm0+$5-2)%12+1)) - -typeset var listroots - case $6 in - 'diags' ) listroots="t3d" ;; - 'MMO' ) - if [ -z "${7}" ] ; then - listroots="grid_T grid_U grid_V grid_W icemod" - else - listroots=${7} - fi - ;; - esac -typeset var root -typeset var lstfiles -for root in ${listroots[@]} ; do - rm -f ${root}_$2_$1_fc$3_${year1}$(printf "%02d" $mon1)_${year2}$(printf "%02d" $mon2).nc -done -} -############################################################################### -# Vertically averaged salt content # -# # -# $1 : input grid_T file name # -# $2 : upper depth of the layer (in meters) # -# $3 : lower depth of the layer (in meters) # -# $4 : output file name (=> 2D) # -# # -# Created in February 2012 Author : vguemas@ic3.cat # -############################################################################### - -function vertmeansal { -cdo_version=`cdo -V &> ff ; grep Climate ff | cut -d \ -f 5` -rm ff -typeset var ntime=`cdo ntime $1` -typeset var list="" -typeset var jt -for jt in $(seq 1 $ntime); do - ncks -O -d time,$((jt-1)) $1 intvertmeansal.nc - - #test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values out of that range to be replaced by NaN - if [[ "$cdo_version" > "`echo -e "$cdo_version\n1.5.6" | sort -V | head -n1`" ]] ; then - ncatted -O -a valid_max,deptht,d,, intvertmeansal.nc - ncatted -O -a valid_min,deptht,d,, intvertmeansal.nc - fi - cdfvertmean intvertmeansal.nc vosaline T $2 $3 - ncrename -O -v sovertmean,vertmeansal -d time_counter,time -v time_counter,time vertmean.nc - mv vertmean.nc outputvertmeansal_$jt.nc - list=$list" "outputvertmeansal_$jt.nc - rm -f intvertmeansal.nc -# #test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values out of that range to be replaced by NaN -# if [[ "$cdo_version" = "`echo -e "$cdo_version\n1.5.6" | sort -V | head -n1`" ]] ; then -# ncatted -O -a valid_max,vertmeansal,d,, outputvertmeansal_$jt.nc outputvertmeansal_$jt.nc -# ncatted -O -a valid_min,vertmeansal,d,, outputvertmeansal_$jt.nc outputvertmeansal_$jt.nc -# fi -done -cdo cat $list $4 -ncks -A -v time $1 $4 -rm -f $list -setminmax $4 vertmeansal -} -############################################################################### -# Compute mixed layer heat and salt content # -# # -# $1 : input grid_T file name # -# $2 : output file name (=> 2D x-y ) # -# # -# Created in February 2012 Author : vguemas@ic3.cat # -################################################################################ - -function heat_sal_mxl { -typeset var ntime=`cdo ntime $1` -typeset var list="" -typeset var jt -typeset var lstvars=`cdo showvar $1` -for jt in $(seq 1 $ntime); do - ncks -O -d time,$((jt-1)) $1 intheat_sal_mxl.nc - if [[ ${lstvars/somxl010} == ${lstvars} ]] ; then - cdfmxl intheat_sal_mxl.nc mxl.nc - ncrename -d time_counter,time mxl.nc - ncks -A mxl.nc intheat_sal_mxl.nc - rm -f mxl.nc - fi - cdfmxlheatc intheat_sal_mxl.nc - if [[ $lstvars != ${lstvars/vosaline} ]] ; then - cdfmxlsaltc intheat_sal_mxl.nc - ncks -A mxlsaltc.nc mxlheatc.nc - rm -f mxlsaltc.nc - fi - mv mxlheatc.nc outputintheat_sal_mxl_$jt.nc - timevar=`ncdump -h outputintheat_sal_mxl_$jt.nc | grep UNLIMITED | awk '{print $1}'` - if [[ $timevar == 'time_counter' ]] ; then ncrename -v time_counter,time -d time_counter,time outputintheat_sal_mxl_$jt.nc ; fi - list=$list" "outputintheat_sal_mxl_$jt.nc - rm -f intheat_sal_mxl.nc -done -cdo cat $list $2 -ncks -A -v time $1 $2 -rm -f $list -setminmax $2 somxlheatc -if [[ $lstvars != ${lstvars/vosaline} ]] ; then setminmax $2 somxlsaltc ; fi -} -############################################################################### -# Pointwise Ocean Heat Content in a specified ocean thickness # -# (J/m-2) -# # -# $1 : input grid_T file name # -# $2 : upper depth of the layer (in meters) # -# $3 : lower depth of the layer (in meters) # -# $4 : output file name (=> 2D x-y ) # -# # -# Created in June 2012 Author : isabel.andreu-burillo@ic3.cat # -# May 2014 - Virginie Guemas - Way around the bc that does not work on moore # -############################################################################### - -function ohc_specified_layer { -typeset var ntime=`cdo ntime $1` -typeset var list="" -typeset var jt -ncap2 -v -O -s "heatc_sl=tmask*e3t" mesh_zgr.nc e3t_file.nc -ncrename -d t,time -d z,deptht e3t_file.nc -for jt in $(seq 1 $ntime); do - cdo seltimestep,$jt $1 intohc_slayer.nc - ncks -O -v votemper intohc_slayer.nc intmeantem.nc - ncrename -v votemper,heatc_sl intmeantem.nc #to be commented - cdo mul intmeantem.nc e3t_file.nc heatc_sl_out.nc -#? ncks -A -m -v nav_lon,nav_lat $1 heatc_sl_out.nc - # extract the data between the two given depths --> heatc_sl_top.nc - ncks -O -d deptht,$2,$3 heatc_sl_out.nc heatc_sl_top.nc - #perform the integration of ohc down to that level (main contribution) - ncap2 -O -s 'heatc_sl=heatc_sl.total($deptht)' heatc_sl_top.nc heatc_sl_top.nc - # now extract a few levels below, to compute the residual ohc - # lower_bnd=`echo "$3 + 200.0" | bc` -> does not work on new moore - # strip out the .* from $3: - stripped=`echo ${3/.*}` - # addition with float returned: - lower_bnd=`echo $(printf "%f" $(( $stripped + 200)))` - ncks -O -d deptht,$3,$lower_bnd heatc_sl_out.nc heatc_sl_bottom.nc - # obtain the weight for the extra level containing the 300 m - # deptht in the gridT files is positive - # weight = (300.0 - depth_top)/(depth_bottom - depth_top) - # and add the thickness down to 300 m in the next layer - ncpdq -a '-deptht' heatc_sl_top.nc heatc_sl_top_invert.nc - ncks -O -d deptht,0,0,1 heatc_sl_top_invert.nc level_above.nc - ncks -O -d deptht,0,0,1 heatc_sl_bottom.nc level_below.nc - ## Here, add the residual contribution, before adding it to the main contribution - ncrename -v deptht,layerthcknss level_below.nc - ncrename -v deptht,layerthcknss level_above.nc - ncbo -A --op_typ=sub -v layerthcknss level_below.nc level_above.nc depth_diff_lay.nc - ncrename -v layerthcknss,heatc_sl depth_diff_lay.nc - ncap2 -s "heatc_sl=($3 - layerthcknss)" level_above.nc depth_diff_sublay.nc - ncbo --op_typ=/ -v heatc_sl depth_diff_sublay.nc depth_diff_lay.nc factor.nc - ncrename -v heatc_sl,factor factor.nc #to be commented - ncks -A -v factor factor.nc level_below.nc - rm -f depth_diff_sublay.nc depth_diff_lay.nc - ncap2 -O -s "heatc_sl=(factor * heatc_sl)" level_below.nc level_below.nc - ncwa -O -a deptht level_below.nc level_below.nc - ncbo --op_typ=+ -v heatc_sl heatc_sl_top.nc level_below.nc total_heatc_sl.nc - ncap2 -s "heatc_sl=1020.0*4000*heatc_sl" total_heatc_sl.nc heatc_sl_$jt.nc - list=$list" "heatc_sl_$jt.nc - rm -f depth_diff_lay.nc depth_diff_sublay.nc - rm -f heatc_sl_out.nc heatc_sl_top.nc heatc_sl_top_invert.nc heatc_sl_bottom.nc - rm -f level_above.nc level_below.nc - rm -f intohc_slayer.nc intmeantem.nc vertmean.nc total_heatc_sl.nc - rm -f factor.nc -done -cdo cat $list $4 -ncks -A -v time $1 $4 -rm -f $list -rm -f e3t_file.nc -setminmax $4 heatc_sl -} -############################################################################### -# Compute the MOC for oceanic basins # -# # -# $1 : input grid_V file name # -# $2 : output file name (=> 2D, depth-y) # -# # -# Created in March 2012 Author : vguemas@ic3.cat # -############################################################################### - -function moc { -typeset var ntime=`cdo ntime $1` -typeset var list="" -typeset var jt -for jt in $(seq 1 $ntime); do - cdo seltimestep,$jt $1 intmoc.nc - cdfmoc intmoc.nc - ncwa -O -a x moc.nc outmoc_$jt.nc - ncks -O -x -v nav_lon,nav_lat outmoc_$jt.nc outmoc_$jt.nc - timevar=`ncdump -h outmoc_$jt.nc | grep UNLIMITED | awk '{print $1}'` - if [[ $timevar == 'time_counter' ]] ; then ncrename -v time_counter,time -d time_counter,time outmoc_$jt.nc ; fi - list=$list" "outmoc_$jt.nc - rm -f intmoc.nc moc.nc -done -cdo cat $list $2 -lstdims=`ncdump -h $2 | awk /dimensions:/,/variables:/ | grep -v dimensions: | grep -v variables: | awk '{print $1}'` -if [[ ${lstdims/gsize} != ${lstdims} ]] ; then - ncrename -d gsize,y $2 -fi -ncks -A -v nav_lon,nav_lat $1 $2 -ncks -A -v time $1 $2 -rm -f $list -} -############################################################################### -# # -# Compute the intensity of convection in the four main convection sites # -# # -# $1 : input oce file name containing somxl010 # -# $2 : input grid # -# $3 : output file name (=> index) # -# # -# Created in October 2013 Author : vguemas@ic3.cat # -############################################################################### - -function convection { -case $2 in - 'Ec2.3_O1L42'|'Ec3.0_O1L46'|'N3.2_O1L42'|'N3.3_O1L46'|'nemovar_O1L42') - A1=225;A2=245;A3=215;A4=255; - B1=245;B2=290;B3=215;B4=245; - C1=260;C2=310;C3=245;C4=291; - D1=225;D2=280;D3=1;D4=50;; - - 'Ec3.0_O25L46'|'Ec3.0_O25L75'|'glorys2v1_O25L75') - stop"Option convection not available yet for this configuration" - ;; -esac - -cdo fldmax -selindexbox,${A1},${A2},${A3},${A4} $1 Labrador.nc -ncrename -v somxl010,Labrador Labrador.nc -ncks -O -v Labrador Labrador.nc convection.nc -rm -f Labrador.nc - -cdo fldmax -selindexbox,${B1},${B2},${B3},${B4} $1 Irminger.nc -ncrename -v somxl010,Irminger Irminger.nc -ncks -A -v Irminger Irminger.nc convection.nc -rm -f Irminger.nc - -cdo fldmax -selindexbox,${C1},${C2},${C3},${C4} $1 GIN.nc -ncrename -v somxl010,GIN GIN.nc -ncks -A -v GIN GIN.nc convection.nc -rm -f GIN.nc - -cdo fldmax -selindexbox,${D1},${D2},${D3},${D4} $1 Wedell.nc -ncrename -v somxl010,Wedell Wedell.nc -ncks -A -v Wedell Wedell.nc convection.nc -rm -f Wedell.nc - -mv convection.nc $3 -} -############################################################################### -# # -# Compute the barotropic stream function # -# # -# $1 : input grid_U file name # -# $2 : input grid_V file name # -# $3 : output file name without nc extension (=> 2D x-y) # -# # -# Created in March 2012 Author : vguemas@ic3.cat # -############################################################################### - -function psi { -typeset var ntime=`cdo ntime $1` -typeset var list="" -typeset var jt -ncrename -d .time,time_counter -v .time,time_counter $1 -for jt in $(seq 1 $ntime); do - cdo seltimestep,$jt $1 intU.nc - cdo seltimestep,$jt $2 intV.nc - cdfpsi intU.nc intV.nc - mv psi.nc psi_U.nc - cdfpsi intU.nc intV.nc V - mv psi.nc psi_V.nc - ncea psi_U.nc psi_V.nc psi_${jt}.nc - timevar=`ncdump -h psi_$jt.nc | grep UNLIMITED | awk '{print $1}'` - if [[ $timevar == 'time_counter' ]] ; then ncrename -v time_counter,time -d time_counter,time psi_$jt.nc ; fi - list=$list" "psi_$jt.nc - # rm -f intU.nc intV.nc psi_U.nc psi_V.nc -done -cdo cat $list ${3} -ncks -A -v time_counter $1 ${3} -ncrename -d .time_counter,time -v .time_counter,time $3 -rm -f $list -} -############################################################################### -# # -# Compute the intensity of the subtropical and subpolar gyres # -# # -# $1 : input psi file name # -# $2 : input grid # -# $3 : output file name ( => index ) # -# # -# Created in October 2013 Author : vguemas@ic3.cat # -############################################################################### - -function gyres { -case $2 in - 'Ec2.3_O1L42'|'Ec3.0_O1L46'|'N3.2_O1L42'|'N3.3_O1L46'|'nemovar_O1L42') - A1=230;A2=275;A3=215;A4=245; - B1=70;B2=145;B3=195;B4=235; - C1=45;C2=175;C3=165;C4=220; - D1=195;D2=275;D3=175;D4=225; - E1=70;E2=205;E3=120;E4=145; - F1=235;F2=300;F3=120;F4=145; - G1=320;G2=30;G3=110;G4=180; - H1=1;H2=361;H3=1;H4=65;; - - 'Ec3.0_O25L46'|'Ec3.0_O25L75'|'glorys2v1_O25L75') - stop"Option gyres not available yet for this configuration" - ;; -esac - -cdo fldmin -selindexbox,${A1},${A2},${A3},${A4} $1 subpolar_NAtl.nc -ncrename -v sobarstf,subpolNAtl subpolar_NAtl.nc -cdo mulc,-1 subpolar_NAtl.nc gyres.nc -rm -f subpolar_NAtl.nc - -cdo fldmin -selindexbox,${B1},${B2},${B3},${B4} $1 subpolar_NPac.nc -ncrename -v sobarstf,subpolNPac subpolar_NPac.nc -cdo mulc,-1 subpolar_NPac.nc tmp.nc -ncks -A tmp.nc gyres.nc -rm -f subpolar_NPac.nc tmp.nc - -cdo fldmax -selindexbox,${C1},${C2},${C3},${C4} $1 subtrop_NPac.nc -ncrename -v sobarstf,subtropNPac subtrop_NPac.nc -ncks -A subtrop_NPac.nc gyres.nc -rm -f subtrop_NPac.nc - -cdo fldmax -selindexbox,${E1},${E2},${E3},${E4} $1 subtrop_SPac.nc -ncrename -v sobarstf,subtropSPac subtrop_SPac.nc -ncks -A subtrop_SPac.nc gyres.nc -rm -f subtrop_SPac.nc - -cdo fldmax -selindexbox,${D1},${D2},${D3},${D4} $1 subtrop_NAtl.nc -ncrename -v sobarstf,subtropNAtl subtrop_NAtl.nc -ncks -A subtrop_NAtl.nc gyres.nc -rm -f subtrop_NAtl.nc - -cdo fldmax -selindexbox,${F1},${F2},${F3},${F4} $1 subtrop_SAtl.nc -ncrename -v sobarstf,subtropSAtl subtrop_SAtl.nc -ncks -A subtrop_SAtl.nc gyres.nc -rm -f subtrop_SAtl.nc - -cdo fldmax -selindexbox,${G1},${G2},${G3},${G4} $1 subtrop_Ind.nc -ncrename -v sobarstf,subtropInd subtrop_Ind.nc -ncks -A subtrop_Ind.nc gyres.nc -rm -f subtrop_Ind.nc - -cdo fldmax -selindexbox,${H1},${H2},${H3},${H4} $1 ACC.nc -ncrename -v sobarstf,ACC ACC.nc -ncks -A ACC.nc gyres.nc -rm -f ACC.nc - -mv gyres.nc $3 - -} -############################################################################### -# # -# Compute an Atlantic MOC index by averaging the meridional overturning # -# in a latitude band between 1km and 2km # -# or any other index averaging the meridional overturning in # -# a given basin and a given domain # -# # -# $1 : input moc file name # -# $2 : latitude min # -# $3 : latitude max # -# $4 : output file name ( => index ) # -# $5 : depth min (default : 1km) # -# $6 : depth max (default : 2km) # -# $7 : basin (default : zomsfatl) # -# # -# Created in March 2012 Author : vguemas@ic3.cat # -############################################################################### - -function area_moc { -if [ -z "$5" ] ; then - typeset var depmin=-1000.0 -else - typeset var depmin=-$5 -fi -if [ -z "$6" ] ; then - typeset var depmax=-2000.0 -else - typeset var depmax=-$6 -fi -if [ -z "$7" ] ; then - typeset var basin=zomsfatl -else - typeset var basin=$7 -fi -lstdims=`ncdump -h $1 | awk /dimensions:/,/variables:/ | grep -v dimensions: | grep -v variables: | awk '{print $1}'` -if [[ ${lstdims/x} != ${lstdims} ]] ; then - ncwa -O -a x $1 tmpmoc.nc -else - cp $1 tmpmoc.nc -fi -ncrename -O -d y,lat -v nav_lat,lat tmpmoc.nc tmpmoc.nc -ncks -O -v $basin,time,depthw,lat tmpmoc.nc tmpmoc.nc -ncks -O -d lat,$2,$3 -d depthw,${depmax},${depmin} tmpmoc.nc area_moc.nc -cdo vertmean area_moc.nc area_ave_moc.nc -ncap -O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)" area_ave_moc.nc area_ave_moc2.nc -ncwa -w coslat -a lat area_ave_moc2.nc area_ave_moc3.nc -ncks -O -v $basin,time area_ave_moc3.nc $4 -# rm -f tmpmoc.nc area_moc.nc area_ave_moc2.nc area_ave_moc3.nc -#if [[ $4 != area_ave_moc.nc ]] ; then -# rm -f area_ave_moc.nc -#fi -exit -} -############################################################################### -# # -# Compute an Atlantic MOC index by finding the maximum of the annual # -# mean meridional overturning in a latitude / depth region # -# # -# $1 : input moc file name # -# $2 : latitude min # -# $3 : latitude max # -# $4 : depth mean # -# $5 : depth max # -# $6 : output file name ( => index ) # -# # -# Created in March 2012 Author : vguemas@ic3.cat # -############################################################################### - -function max_moc { -if [ ! -f $6 ] ; then - ncecat -h $1 tmpmoc1.nc - lstdims=`ncdump -h tmpmoc1.nc | awk /dimensions:/,/variables:/ | grep -v dimensions: | grep -v variables: | awk '{print $1}'` - if [[ ${lstdims/x} != ${lstdims} ]] ; then - ncwa -O -a x tmpmoc1.nc tmpmoc1.nc - fi - ncrename -d record,x tmpmoc1.nc - ncpdq -O -h -a time,x tmpmoc1.nc tmpmoc1.nc - ncpdq -O -h -a depthw,x tmpmoc1.nc tmpmoc1.nc - ncpdq -O -h -a y,x tmpmoc1.nc tmpmoc1.nc - cdo yearmean tmpmoc1.nc tmpmoc.nc - typeset var ntime=`cdo ntime tmpmoc.nc` - typeset var list="" - for jt in $(seq 1 $ntime) ; do - cdo seltimestep,$jt tmpmoc.nc tmpmoc2.nc - cdfmaxmoc tmpmoc2.nc atl $2 $3 $4 $5 - mv maxmoc.nc maxmoc_$jt.nc - timevar=`ncdump -h maxmoc_$jt.nc | grep UNLIMITED | awk '{print $1}'` - if [[ $timevar == 'time_counter' ]] ; then ncrename -v time_counter,time -d time_counter,time maxmoc_$jt.nc ; fi - list=${list}" "maxmoc_$jt.nc - rm -f tmpmoc2.nc - done - cdo cat $list $6 - ncks -A -v time tmpmoc.nc $6 - rm -f $list tmpmoc.nc tmpmoc1.nc -fi -} -############################################################################### -# # -# Compute the sea ice extent (1000km2), area (1000km2), volume (km3) # -# and mean thickness (m) in both hemispheres or a specified region. # -# # -# $1 : input ice file name # -# $2 : output file name ( => index ) # -# $3 : region of interest (if empty default is global) # -# # -# Created in April 2012 Author : vguemas@ic3.cat # -# Modified in June 2014 Author : neven.fuckar@ic3.cat # -# # -# Computation of the properties in various selected regions according to # -# mask.regions.${NEMOVERSION}.nc (mask_regions.nc) is based on modification # -# of mask.regions.ORCA1.noverticalinfo.Matt.nc from Matthieu Chevallier. # -# # -############################################################################### - -function siasiesiv { -cp ${CON_FILES}/ice_template.nc toto_N.nc -cp ${CON_FILES}/ice_template.nc toto_S.nc -case ${NEMOVERSION} in - 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'Ec3.0_O25L75') for var in `cdo showvar $1 | head -n 1` -do -[[ $var = "ice_pres" || $var = "iiceconc" ]] && ncrename -v $var,ileadfra $1 -done;; -#'Ec3.0_O1L46'|'Ec3.0_O25L46') ncrename -v ice_pres,ileadfra $1 ;; -#'Ec3.0_O1L46'|'Ec3.0_O25L46') ncrename -v iiceconc,ileadfra $1 ;; -esac - -typeset var ntime=`cdo ntime $1` -typeset var list1="" -typeset var list2="" -typeset var jt - -if [ ! -z "$3" ] ; then - mv mask.nc mask_tmp.nc - mv mask_regions.nc mask.nc - ncrename -h -v $3,tmask mask.nc -fi - -for jt in $(seq 1 $ntime) ; do - cdo seltimestep,$jt $1 tmpice.nc - cdficediags tmpice.nc>ice.txt - for d in N S;do - ncdump toto_${d}.nc > ice_template.cdl - sia=`grep ${d}Area ice.txt |awk '{print $4}'` - sie=`grep ${d}Exnsidc ice.txt|awk '{print $4}'` - siv=`grep ${d}Volume ice.txt|awk '{print $4}'` - sed -e "s/sia =.*/sia = $sia ;/" ice_template.cdl > ice_template2.cdl - sed -e "s/sie =.*/sie = $sie ;/" ice_template2.cdl > ice_template3.cdl - sed -e "s/siv =.*/siv = $siv ;/" ice_template3.cdl > ice_template.cdl - ncgen -o ice_${d}_${jt}.nc ice_template.cdl - rm -f ice_template.cdl ice_template2.cdl ice_template3.cdl - done - list1=$list1" "ice_N_${jt}.nc - list2=$list2" "ice_S_${jt}.nc - rm -f ice.txt tmpice.nc icediags.nc -done -cdo cat $list1 ice_N_${2} -cdo cat $list2 ice_S_${2} -ncks -A -v time $1 ice_N_${2} -ncks -A -v time $1 ice_S_${2} -rm -f $list1 $list2 toto_N.nc toto_S.nc - -for d in N S;do - ncatted -O -a units,sia,m,c,1000km2 ice_${d}_${2} - ncatted -O -a units,sie,m,c,1000km2 ice_${d}_${2} - - ncks -O -v siv ice_${d}_${2} siv_${d}_${2}1 - ncks -O -v sia ice_${d}_${2} sia_${d}_${2}1 - ncrename -h -v sia,siv sia_${d}_${2}1 - ncbo -O --op_typ=dvd siv_${d}_${2}1 sia_${d}_${2}1 sit_${d}_${2} - ncatted -O -a standard_name,siv,m,c,Mean_sea_ice_thickness sit_${d}_${2} - ncatted -O -a long_name,siv,m,c,"Mean sea ice thickness" sit_${d}_${2} - ncatted -O -a units,siv,m,c,m sit_${d}_${2} - cdo ltc,100 sit_${d}_${2} sit_${d}_${2}1 - cdo ifthenelse sit_${d}_${2}1 sit_${d}_${2} sit_${d}_${2}1 sit_${d}_${2}2 - ncrename -h -v siv,sit sit_${d}_${2}2 - ncks -A sit_${d}_${2}2 ice_${d}_${2} - - rm siv_${d}_${2}1 sia_${d}_${2}1 sit_${d}_${2} sit_${d}_${2}1 sit_${d}_${2}2 -done - -setminmax ice_N_${2} sia sie siv sit -setminmax ice_S_${2} sia sie siv sit - -if [ ! -z "$3" ] ; then - ncrename -h -v tmask,$3 mask.nc - mv mask.nc mask_regions.nc - mv mask_tmp.nc mask.nc -fi - -} -############################################################################### -# # -# Compute the total ocean heat extent # -# # -# $1 : input temperature file name # -# $2 : output file name ( => 2D x-y ) # -# $3 : basin (NAtl, NPac, TAtl, TPac, TInd, Anta, Arct, Glob, or any basin # -# that is defined in ${CON_FILES}/mask.regions.3d.${NEMOVERSION}.nc) # -# Default : Glob) # -# $4 : mixed layer (1=only, 0=included, -1=without) Default : 0 # -# $5 : upper level of the layer (optional) Default : top # -# $6 : lower level of the layer (optional) Default : bottom # -# # -# Created in May 2012 Author : vguemas@ic3.cat # -# Modified in March 2016 Author : ruben.cruzgarcia@bsc.es # -# Modifications for computing the ohc # -# in the Arctic regions # -############################################################################### -function ohc { -cp ${CON_FILES}/depth.${NEMOVERSION}.txt depth.txt -# -# Input arguments -# -case $3 in -'') typeset var basin="Glob" ;; -'NAtl' | 'NPac' | 'TAtl' | 'TPac' | 'TInd' | 'Anta' | 'Arct' | 'Glob') typeset var basin=$3 ;; -*) mv mask.nc mask_tmp.nc ; mv mask_regions.3d.nc mask.nc ; typeset var lstvars=`cdo showvar mask.nc` ; if [[ ${lstvars/$3} != ${lstvars} ]] ; then ncrename -h -v $3,tmask mask.nc ; else echo 'This region does not exist, please choose another region' ; exit; fi ;; -esac -if [ -z "$4" ] ; then - typeset var mxl=0 -else - typeset var mxl=$4 -fi -if [ -z "$5" ] ; then - typeset var up=1 -else - typeset var up=$5 -fi -if [ -z "$6" ] ; then - typeset var down=`cat depth.txt | wc -l` -else - typeset var down=$6 -fi - -if [[ ${up} -eq 1 ]] ; then - typeset var depmin=0 -else - typeset var depmin=`cat depth.txt |head -n ${up} |tail -n 1 | awk '{print $2}' | awk '{printf "%.0f",$1}'` -fi -typeset var depmax=`cat depth.txt |head -n ${down} |tail -n 1 | awk '{print $2}' | awk '{printf "%.0f",$1}'` - -cp ${CON_FILES}/heatc_template.nc template_heatc.nc -ncdump template_heatc.nc > template_heatc.cdl -# -# Define some parameters -# -typeset var para -typeset var output -typeset var nlev=`cat depth.txt | wc -l` -if [[ ! -z "$depmin" && ! -z "$depmax" ]] ; then - if [[ $depmin != 0 || ${down} != ${nlev} && ${down} != 0 ]] ; then - output=${depmin}-${depmax}'_' - fi -fi - -case $basin in - 'NAtl') para="atl $mxl 0 0 10 65"; output='NAtl_10N65N_'${output} ;; - 'TAtl') para="atl $mxl 0 0 -30 30" ; output='TAtl_30S30N_'${output} ;; - 'NPac') para="pac $mxl 0 0 10 70" ; output='NPac_10N70N_'${output} ;; - 'TPac') para="pac $mxl 0 0 -30 30" ; output='TPac_30S30N_'${output} ;; - 'Arct') para="atl $mxl 0 0 65 90" ; output='Arc_65N90N_'${output} ;; - 'Anta') para="all $mxl 0 0 -90 -60" ; output='Ant_90S60S_'${output} ;; - 'TInd') para="ind $mxl 0 0 -30 30" ; output='TInd_30S30N_'${output} ;; - 'Glob') para="all $mxl 0 0 0 0" ;; - *) para="all $mxl 0 0 0 0" ; output=$3'_'${output} ;; -esac - -case $mxl in - 1) output='mxl_'${output} ;; - -1) output='nonmxl_'${output} ;; -esac -# -# Compute ohc -# -typeset var lstvars=`cdo showvar $1` -typeset var ntime=`cdo ntime $1` -typeset var list="" -typeset var jt -for jt in $(seq 1 $ntime) ; do - cdo seltimestep,$jt $1 tmpohc.nc - lstdims=`ncdump -h tmpohc.nc | awk /dimensions:/,/variables:/ | grep -v dimensions: | grep -v variables: | awk '{print $1}'` - if [[ ${lstdims/x_2} != ${lstdims} ]] ; then - if [[ ${lstdims/x} != ${lstdims} ]] ; then - ncwa -O -a x tmpohc.nc tmpohc.nc - fi - ncrename -d x_2,x tmpohc.nc - fi - if [[ ${lstvars/somxl010} != ${lstvars} ]] ; then - ncks -O -v somxl010 tmpohc.nc mxl.nc - else - cdfmxl tmpohc.nc mxl.nc - fi - cdfheatc-cfu tmpohc.nc $para $up $down > tmp.log -echo $para -echo $up -echo $down - cat tmp.log - thc=`cat tmp.log | grep "Total Heat content :" | awk '{print $5}'`; - uhc=`cat tmp.log | grep "Total Heat content/volume" | awk '{print $5}'`; - sed -e "s/thc =.*/thc = $thc ;/" template_heatc.cdl > template_heatc2.cdl - sed -e "s/uhc =.*/uhc = $uhc ;/" template_heatc2.cdl > template_heatc.cdl - ncgen -o heatc_${jt}.nc template_heatc.cdl - rm -f template_heatc2.cdl tmpohc.nc mxl.nc tmp.log - list=$list" "heatc_${jt}.nc -done -cdo cat $list ${output}$2 -ncks -h -A -v time $1 ${output}$2 -rm -f $list template_heatc.nc template_heatc.cdl depth.txt -setminmax ${output}$2 thc uhc - -if [[ ! -z "$3" ]] && [[ "$3" != NAtl ]] && [[ $3 != NPac ]] && [[ $3 != TAtl ]] && [[ $3 != TPac ]] && [[ $3 != TInd ]] && [[ $3 != Anta ]] && [[ $3 != Arct ]] && [[ $3 != Glob ]] ; then - ncrename -h -v tmask,$3 mask.nc - mv mask.nc mask_regions.3d.nc - mv mask_tmp.nc mask.nc -fi -} -############################################################################### -# # -# Cut a meridional or zonal section # -# # -# # -# $1 : input file # -# $2 : input var # -# $3 : Z/M (zonal / meridional section) # -# $4 : lat/lon # -# $5 : output file ( => 2D ) # -# # -# Created in September 2012 Author : vguemas@ic3.cat # -# # -############################################################################### - -function cutsection { - typeset var ntime=`cdo ntime $1` - typeset var nx=`ncdump -h $1|grep 'x = '|head -n 1|cut -f3 -d" "` - typeset var ny=`ncdump -h $1|grep 'y = '|head -n 1|cut -f3 -d" "` - typeset var nz=`ncdump -h $1|grep 'depth'|head -n 1|cut -f3 -d" "` -cat>section.R<max(lon)) {exactpos=exactpos-360} - } - # Collect the indexes defining the section - listi=array(dim=switch('$3','Z'=$nx-2,'M'=$ny-1)) - listj=array(dim=switch('$3','Z'=$nx-2,'M'=$ny-1)) - for (jpt in 1:length(listi)) { - vect=switch('$3','Z'=lat[jpt,],'M'=lon[,jpt+1]) - if (min(abs(vect-exactpos))<(2*360./$nx)) { - pos=sort(abs(vect-exactpos),index.return=T)\$ix[1] - listi[jpt]=switch('$3','Z'=jpt+1,'M'=pos) - listj[jpt]=switch('$3','Z'=pos,'M'=jpt) - } - } - listi=listi[is.na(listi)==F] - listj=listj[is.na(listj)==F] - print(listi) - print(listj) - # Select variable at those indexes - fnc1=open.ncdf('$1') - varout=array(dim=c(length(listi),$nz,$ntime)) - for (jt in 1:$ntime) { - varin=get.var.ncdf(fnc1,'$2',start=c(1,1,1,jt),count=c($nx,$ny,$nz,1)) - varin[which(mask<0.5)]=1e20 - for (jpt in 1:length(listi)) { - varout[jpt,,jt]=varin[listi[jpt],listj[jpt],] - } - } - close.ncdf(fnc1) - # Write the output - wtime=dim.def.ncdf("time","",seq(1,$ntime),unlim=TRUE) - dimout=array(dim=length(listi)) - for (jpt in 1:length(listi)) { - dimout[jpt]=switch('$3','Z'=lon[listi[jpt],listj[jpt]],'M'=lat[listi[jpt],listj[jpt]]) - } - wsec=switch('$3','Z'=dim.def.ncdf("lon","",dimout),'M'=dim.def.ncdf("lat","",dimout)) - wdep=dim.def.ncdf("deptht","",depth) - wvar=var.def.ncdf("$2","",list(wsec,wdep,wtime),1e20) - fnc2=create.ncdf('$5',wvar) - put.var.ncdf(fnc2,wvar,varout) - close.ncdf(fnc2) -EOF1 -R CMD BATCH section.R -ncks -h -A -v time $1 $5 -} -############################################################################### -# # -# 3-dimensional conservative interpolation to the regular atmospheric grid # -# # -# $1 : input file # -# $2 : input var # -# $3 : output file ( => 3D ) # -# # -# Created in November 2012 Author : vguemas@ic3.cat # -# # -############################################################################### - -function interp3d { - typeset var nz=`ncdump -h $1|grep 'deptht'|head -n 1|cut -f3 -d" "` - [[ ! -f scrip_use ]] && ln -sf /shared/earth/software/scripts/interpolation/scrip_use scrip_use - for lev in $(seq 1 $nz) ; do - ncks -O -d deptht,$((lev-1)) -v $2 $1 tmp_${lev}.nc - ncwa -O -h -a deptht tmp_${lev}.nc tmp_${lev}.nc - [[ ! -f rmp_${NEMOVERSION}_to_regular_lev${lev}.nc ]] && ln -sf /esnas/autosubmit/con_files/weigths/${NEMOVERSION}/rmp_${NEMOVERSION}_to_*_lev${lev}.nc rmp_${NEMOVERSION}_to_regular_lev${lev}.nc - cat > scrip_use_in < 2D field ) # -# # -# Created in February 2012 Author : vguemas@ic3.cat # -# Modified (more generic, -# i.e. for any input var) in December 2014 # -# Author : eleftheria.exarchou@ic3.cat # -############################################################################### - -function vertmeanvar { - typeset var ntime=`cdo ntime $1` - typeset var list="" - typeset var jt -for jt in $(seq 1 $ntime); do - ncks -O -d time,$((jt-1)) $1 a1 - # The oras4 data do not have gdepth data in their mask, but only gdept_0, so: - if grep -q nemovar_s4 $1 ; then - l1=$(( $3 % 6 )) - l2=$(( $4 % 6 )) - ll1=$(( $3 / 6 + 1 )) - ll2=$(( $4 / 6 + 1 )) - lev1=`echo $(cdo output -selvar,gdept_0 mesh_zgr.nc | sed -n ${ll1}p | awk '{ print $'$l1' }')` - lev2=`echo $(cdo output -selvar,gdept_0 mesh_zgr.nc | sed -n ${ll2}p | awk '{ print $'$l2' }')` - else - l1=$(($3+1)) - l2=$(($4+1)) - lev1=`echo $(cdo info -seltimestep,1 -selvar,gdept mesh_zgr.nc | sed -n ${l1}p | awk '{ print $10 }')` - lev2=`echo $(cdo info -seltimestep,1 -selvar,gdept mesh_zgr.nc | sed -n ${l2}p | awk '{ print $10 }')` - fi - cdfvertmean a1 $2 T $lev1 $lev2 - rm -f a1 - ncrename -O -v sovertmean,vertmean -d time_counter,time -v time_counter,time vertmean.nc - mv vertmean.nc outputvertmean_$jt.nc - list=$list" "outputvertmean_$jt.nc - rm -f intvertmean.nc a? -# #test on cdo version: if >1.5.6, remove valid_min/max attributes to avoid values out of that range to be replaced by NaN - ncatted -O -a valid_max,vertmean,d,, outputvertmean_$jt.nc outputvertmean_$jt.nc - ncatted -O -a valid_min,vertmean,d,, outputvertmean_$jt.nc outputvertmean_$jt.nc - ncatted -O -a standard_name,time,a,c,time outputvertmean_$jt.nc outputvertmean_$jt.nc - ncatted -O -a units,time,o,c,'seconds since 1993-05-01 00:00:00' outputvertmean_$jt.nc outputvertmean_$jt.nc - ncatted -O -a long_name,time,a,c,'Time axis' outputvertmean_$jt.nc outputvertmean_$jt.nc -done -cdo cat $list $5 -ncks -A -v time $1 $5 -rm -f $list -setminmax $5 vertmean -ncrename -v vertmean,$2 $5 -#typeset var level=`echo $(cdo info -selvar,$2 -setctomiss,0 $5 | sed -n 2p | awk '{ print $7 }')` -#typeset var lev=`echo $(cdo info -seltimestep,1 -selvar,$2 -setctomiss,0 $1 | grep $level | awk '{ print $1 }')` -lev=$3 -echo $lev -cp $5 tmp_${lev}.nc -## Here we interpolate horizontally onto a regular grid - [[ ! -f rmp_${NEMOVERSION}_to_regular_lev${lev}.nc ]] && ln -sf /esnas/autosubmit/con_files/weigths/${NEMOVERSION}/rmp_${NEMOVERSION}_to_*_lev${lev}.nc rmp_${NEMOVERSION}_to_regular_lev${lev}.nc - [[ ! -f scrip_use ]] && ln -sf /shared/earth/software/scripts/interpolation/scrip_use scrip_use - cat > scrip_use_in < 0: + while retrials >= 0: try: Log.info('Starting {0}', current_job) + time = datetime.datetime.now() current_job.compute() + time = datetime.datetime.now() - time + if type(current_job) in self.time[numthread]: + self.time[numthread][type(current_job)] += time + else: + self.time[numthread][type(current_job)] = time Log.result('Finished {0}', current_job) return True except Exception as ex: retrials -= 1 Log.error('Job {0} failed: {1}', job, ex) return False - count = 0 failed_jobs = list() @@ -295,8 +314,10 @@ def main(): Entry point for the Earth Diagnostics. For more detailed documentation, use -h option """ parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') - parser.add_argument('-v', '--version', action='version', version='0.1', + parser.add_argument('-v', '--version', action='version', version='3.0.0b1', help="returns Earth Diagnostics's version number and exit") + parser.add_argument('--doc', action='store_true', + help="opens documentation and exits") parser.add_argument('-lf', '--logfile', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), default='DEBUG', type=str, @@ -311,6 +332,12 @@ def main(): parser.add_argument('-f', '--configfile', default='diags.conf', type=str) args = parser.parse_args() + if args.doc: + Log.info('Opening documentation...') + Utils.execute_shell_command(('xdg-open', os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', + 'EarthDiagnostics.pdf'))) + Log.result('Documentation opened!') + return Log.set_console_level(args.logconsole) Log.set_file_level(args.logfile) if args.logfilepath: diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index a2cdcf4..a4c47c3 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -146,7 +146,8 @@ class Utils(object): """ Executes a sheel command :param command: command to execute - :type command: str|list + + Log.info('Detailed time for diagnostic class') :param log_level: log level to use for command output :type log_level: int :return: command output diff --git a/ocean_pp.bash b/ocean_pp.bash deleted file mode 100755 index d8e4a14..0000000 --- a/ocean_pp.bash +++ /dev/null @@ -1,678 +0,0 @@ -#!/bin/bash -set -evx - -module load CDFTOOLS/2.1-foss-2015a CDO NCO R - -function delete { -at now +7 days << EOF -rm -rf $WORKDIR -EOF -} - - -msg='Your experiment crashed! Your workdir \($WORKDIR\) will be kept for one week from now and then deleted' -trap "echo $msg ; delete ; exit" SIGINT SIGHUP SIGTERM SIGSEGV SIGKILL EXIT - -################################# -#### User Defined Funtions #### -################################# - - - - -# check if args are ok and read options in config_file - - if [ $# -ne 1 ] ; then - echo - echo "USAGE: config_file " - echo "For example: ./ocean_pp.new.bash /home/Earth/$user/es_git/ocean_diagnostics/config_file " - echo - exit 1 - fi - -config_file=$1 -. ${config_file} - -list_files='grid_T' -if [[ ${listpost[@]} =~ "psi" ]] || [[ ${listpost[@]} =~ "gyres" ]]; then - echo "The list of diags require grid_U" - list_files=$(echo ${list_files} grid_U) -fi - -if [[ ${listpost[@]} =~ "moc" ]] || [[ ${listpost[@]} =~ "psi" ]] || [[ ${listpost[@]} =~ "gyres" ]]; then - echo "The list of diags require grid_V" - list_files=$(echo ${list_files} grid_V) -fi -if [[ ${listpost[@]} =~ "ice" ]] || [[ ${listpost[@]} =~ "siasiesiv" ]]; then - echo "The list of diags contains ice" - list_files=$(echo ${list_files} icemod) -fi - -############################################################################### -# -# moc needs to be computed before max_moc and area_moc -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -if [[ ${listpost[@]##*moc*} != ${listpost[@]} ]] || [[ ${listpost[@]##*stc*} != ${listpost[@]} ]] ; then - if [[ ${listpost[@]#moc} != ${listpost[@]:1} ]] ; then - listpost=( 'moc' "${listpost[@]#moc}" ) - fi -fi -# -# psi needs to be computed before gyres -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -if [[ ${listpost[@]##*gyres*} != ${listpost[@]} ]] ; then - if [[ ${listpost[@]#psi} != ${listpost[@]:1} ]] ; then - listpost=( 'psi' "${listpost[@]#psi}" ) - fi -fi -# -# oce raw outputs need to be extracted before convection option -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -if [[ ${listpost[@]##*convection*} != ${listpost[@]} ]] ; then - if [[ ${listpost[@]#ext_raw_oce} != ${listpost[@]:1} ]] ; then - listpost=( 'ext_raw_oce' "${listpost[@]#ext_raw_oce}" ) - fi -fi -# -# 3d interpolation required before average T sections over longitudes -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -if [[ ${listpost[@]##TSec_ave*} != ${listpost[@]} ]] ; then - if [[ ${listpost[@]#3dtemp} != ${listpost[@]:1} ]] ; then - listpost=( '3dtemp' "${listpost[@]#3dtemp}" ) - warning_T=.true. - fi -fi -if [[ ${listpost[@]##SSec_ave*} != ${listpost[@]} ]] ; then - if [[ ${listpost[@]#3dsal} != ${listpost[@]:1} ]] ; then - listpost=( '3dsal' "${listpost[@]#3dsal}" ) - warning_S=.true. - fi -fi -# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -# You have created a function ? If your new diagnostic relies on an already -# existing diagnotics, you might need similar lignes to the above ones -# Any doubt ---> vguemas@ic3.cat -# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -# -# Preparing WORKDIR and set of available functions -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -export WORKDIR=/scratch/Earth/${USER}/tmp/post_ocean/$$ -mkdir -p $WORKDIR -cd $WORKDIR -source $PATHCOMMONOCEANDIAG/common_ocean_post.txt -# -# Interval of lead months be post-processed -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -case $expid in - 'nemovar_s4'|'nemovar_combine') moni=09 ; syeari=1957 ; syearf=1957 ; insdate=1 ; typeoutput='MMO' ; NEMOVERSION='nemovar_O1L42' ;; - 'glorys2v1') moni=01 ; syeari=1993 ; syearf=1993 ; insdate=1 ; typeoutput='MMO' ;; -esac -case $expid in - 'nemovar_s4') rootout='/esnas/exp/ECMWF/NEMOVAR_S4/monthly_mean' ;; - 'nemovar_combine') rootout='/esnas/exp/ECMWF/NEMOVAR_COMBINE/monthly_mean' ;; - 'glorys2v1') rootout='/esnas/exp/MERCATOR/GLORYS2V1/monthly_mean';; -esac -if [[ ${listpost[@]##max_moc} != ${listpost[@]} ]] || [[ -z "$ltimef" ]] || [[ -z "$ltime0" ]] ; then - if [[ ! -z "$year0" ]] && [[ ! -z "$yearf" ]] ; then - ltime0=$(((${year0}-${syeari})*12+1)) - ltimef=$(((${yearf}-${syeari}+1-(10#$moni+10)/12)*12)) - fi -fi -mon0=$(( (10#$moni+$ltime0-2)%12+1 )) -monf=$(( (10#$moni+$ltimef-2)%12+1 )) -# -# Check on the consistency between the chunk length and the leadtimes -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -if [[ $((($ltimef-$ltime0+1)%$chunklen)) != 0 || $((($ltime0-1)%$chunklen)) != 0 ]] ; then - echo "This a safety stop because we think you might have made a mistake in your configuration file" - echo "Unless you have run your experiment with a variable chunk length, you should have" - echo "a number of leadtimes to post-process that is a multiple of the chunken and the first" - echo "leadtime should be right after the end of a chunk" - echo "If you have run your experiment with a variable chunk length, please remove l.85-93 of ocean_pp.bash" - exit 1 -fi -# -# Loop on start dates -# ~~~~~~~~~~~~~~~~~~~~~ -if [[ $intsdate -eq 0 ]] ; then intsdate=1 ; fi # if only one start date, user might set -# intsdates to 0 which leads to an infinite loop below -for ((yeari=$syeari;yeari<=$syearf;yeari=$(($yeari+intsdate)))) ; do - # - # Interval of years to be post-processed - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - year0=$(($yeari+(10#$moni+$ltime0-2)/12)) - yearf=$(($yeari+(10#$moni+$ltimef-2)/12)) - - for memb in ${listmemb[@]} ; do - # - # Fetching the files on esnas - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - case $expid in - 'nemovar_s4'|'nemovar_combine') get_nemovar ${expid} ${memb} ${year0} ${yearf} ${mon0} ${monf} "${list_files}" - ;; - 'glorys2v1') get_glorys ${year0} ${yearf} ${mon0} ${monf} ;; - *) freqout=${rootout:${#rootout}-12} ; freqout=${freqout/_mean} ; freqout=${freqout/*\/} - get_diagsMMO ${yeari}${moni}01 ${expid} ${memb} $ltime0 $ltimef $chunklen $mod $typeoutput $freqout "${list_files}" - esac - # - # Ready for the post-processing - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - for post in ${listpost[@]} ; do - - case $post in -# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -# You have created a function ? Enter its call right here under the flag chosen -# Remember to consider both 'MMO' and 'diags' cases -# Any doubt ---> vguemas@ic3.cat -# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - 'ext_raw_oce') - if [[ $typeoutput == 'MMO' ]] ; then - lstvars=`cdo showvar grid_T_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc` - if [[ $raw_vars_ocean == '' ]] ; then - lstext=`echo $lstvars | sed s/\ /,/g` - else - if [[ $raw_vars_ocean == 'default' ]] ; then - lstextvar=( 'sosstsst' 'sosaline' 'somixhgt' 'somxl010' ) - lstext='' - for varex in ${lstextvar[@]} ; do - if [[ ${lstvars/${varex}/} != ${lstvars} ]] ; then - lstext=`echo ${lstext} ${varex}|sed s/\ /,/g` - fi - done - else - lstext=`echo ${raw_vars_ocean[@]} |sed s/\ /,/g` - fi - fi - if [ -z "$lstext" ] ; then - echo "The list of variables you wish to extract is not in your outputs" - exit 1 - else - ncks -O -v ${lstext} grid_T_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc oce_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc -# ncks -O -v ${lstext[@]} grid_T_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc oce_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - 'ext_raw_ice') - if [[ $typeoutput == 'MMO' ]] ; then - lstvars=`cdo showvar icemod_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc` - if [[ $raw_vars_ice == '' ]] ; then - lstext=`echo $lstvars | sed s/\ /,/g` - else - if [[ $raw_vars_ice == 'default' ]] ; then - lstextvar=( 'isnowthi' 'iicethic' 'ileadfra' 'iicetemp' 'ice_pres' ) - lstext='' - for varex in ${lstextvar[@]} ; do - if [[ ${lstvars/${varex}/} != ${lstvars} ]] ; then - lstext=`echo ${lstext} ${varex}|sed s/\ /,/g` - fi - done - else - lstext=`echo $raw_vars_ice |sed s/\ /,/g` - fi - fi - if [ -z "$lstext" ] ; then - echo "The list of variables you wish to extract is not in your outputs" - exit 1 - else - ncks -O -v ${lstext} icemod_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ice_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - 'heat_sal_mxl') - if [[ $typeoutput == 'MMO' ]] ; then - if [ ! -f heat_sal_mxl_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] ; then - heat_sal_mxl grid_T_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc heat_sal_mxl_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - 'psi') - if [[ $typeoutput == 'MMO' ]] ; then - if [ ! -f psi_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] ; then - psi grid_U_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc grid_V_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc psi_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - 'gyres') - gyres psi_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $NEMOVERSION gyres_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ;; - - 'lmsalc') - if [[ $typeoutput == 'MMO' ]] ; then - if [ ! -f sal_300-5400m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] ; then - vertmeansal grid_T_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 300 5400 sal_300-5400m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - 'usalc') - if [[ $typeoutput == 'MMO' ]] ; then - if [ ! -f sal_0-300m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] ; then - vertmeansal grid_T_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 0 300 sal_0-300m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - - 'temp_lev') - if [[ $typeoutput == 'MMO' ]] ; then - if [ ! -f temp_lev${level1}-${level2}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] ; then - vertmeanvar grid_T_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc votemper $level1 $level2 temp_lev${level1}-${level2}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - - 'sal_lev') - if [[ $typeoutput == 'MMO' ]] ; then - if [ ! -f sal_lev${level1}-${level2}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] ; then - vertmeanvar grid_T_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc vosaline $level1 $level2 sal_lev${level1}-${level2}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - 'ohc_specified_layer') - if [ ! -f ohc_2d_avg_0-300m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ];then - case $typeoutput in - 'MMO' ) pref='grid_T' ;; - 'diags') pref='t3d' ;; - esac - ohc_specified_layer ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 0.0 300.0 ohc_2d_avg_0-300m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ohc_specified_layer ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 300.0 800.0 ohc_2d_avg_300-800m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - ;; - - 'vert_Tsections') - case $typeoutput in - 'MMO' ) pref='grid_T' ;; - 'diags') pref='t3d' ;; - esac - for coord in 0 45 -45 -30 180 80 - do - if [[ $coord == '0' ]] || [[ $coord == '45' ]] || [[ $coord == '-45' ]] ; then - [[ ` echo $coord | cut -b 1 ` == '-' ]] && direction=S || direction=N - z_m=Z - else - [[ ` echo $coord | cut -b 1 ` == '-' ]] && direction=W || direction=E - z_m=M - fi - coord=`echo $coord | sed -e s/-//g` - [ ! -f temp_${coord}${direction}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] && cutsection ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc votemper $z_m $coord temp_${coord}${direction}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - done - - ;; - - 'vert_Ssections') - if [[ $typeoutput == 'MMO' ]] ; then - pref='grid_T' - for coord in 0 45 -45 -30 180 80 - do - if [[ $coord == '0' ]] || [[ $coord == '45' ]] || [[ $coord == '-45' ]] ; then - [[ ` echo $coord | cut -b 1 ` == '-' ]] && direction=S || direction=N - z_m=Z - else - [[ ` echo $coord | cut -b 1 ` == '-' ]] && direction=W || direction=E - z_m=M - fi - coord=`echo $coord | sed -e s/-//g` - [ ! -f sal_${coord}${direction}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] && cutsection ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc vosaline $z_m $coord sal_${coord}${direction}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - done - fi - ;; - '3dtemp') - case $typeoutput in - 'MMO' ) pref='grid_T' ;; - 'diags') pref='t3d' ;; - esac - if [ ! -f regular3dT_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ]; then - echo " Warning: you are about to perform a 3d interpolation " - [ $warning_T ] && echo "(because you asked for cross sections calculations)" - echo "this might take time to complete (~days), be sure you really need/want to do this..." - interp3d ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc votemper regular3dT_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - ;; - '3dsal') - if [[ $typeoutput == 'MMO' ]] ; then - pref='grid_T' - if [ ! -f regular3dS_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ]; then - echo " Warning: you are about to perform a 3d interpolation " - [ $warning_S ] && echo "(because you asked for cross sections calculations)" - echo "this might take time to complete (~days), be sure you really need/want to do this..." - interp3d ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc vosaline regular3dS_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - 'TSec_ave190-220E') - [ ! -f TSec_ave190-220E_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] && cdo zonmean -sellonlatbox,190,220,-90,90 regular3dT_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc TSec_ave190-220E_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ;; - 'SSec_ave190-220E') - if [[ $typeoutput == 'MMO' ]] ; then - [ ! -f SSec_ave190-220E_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] && cdo zonmean -sellonlatbox,190,220,-90,90 regular3dS_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc SSec_ave190-220E_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - ;; - - 'moc') - if [[ $typeoutput == 'MMO' ]] ; then - if [ ! -f moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] ; then - moc grid_V_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - fi - ;; - - 'max_moc') - max_moc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 38 50 500 2000 max_moc_38N50N_500m-2km_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - max_moc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 40 40 0 10000 max_moc_40N_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ;; - - 'stc') - area_moc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 0.0 25.0 NPac_stc_0N25N_0-200m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 0.0 200.0 zomsfpac - area_moc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc -25.0 0.0 SPac_stc_25S0S_0-200m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 0.0 200.0 zomsfpac - area_moc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 0.0 25.0 NAtl_stc_0N25N_0-200m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 0.0 200.0 - area_moc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc -25.0 0.0 SAtl_stc_25S0S_0-200m_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 0.0 200.0 - ;; - - 'area_moc') - if [ ! -f moc_40N55N_1-2km_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ];then - area_moc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 40.0 55.0 moc_40N55N_1-2km_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - if [ ! -f moc_30N40N_1-2km_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ];then - area_moc moc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc 30.0 40.0 moc_30N40N_1-2km_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - ;; - - 'convection') - convection oce_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $NEMOVERSION convection_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ;; - - 'siasiesiv' ) - - if [ ! -f siasiesiv_N_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ]||[ ! -f siasiesiv_S_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ];then #check if ? instead of N or S works - case $typeoutput in - 'MMO' ) pref='icemod' ;; - 'diags') pref='ice' ;; - esac - siasiesiv ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc tmp.nc - mv ice_N_tmp.nc siasiesiv_N_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - mv ice_S_tmp.nc siasiesiv_S_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - fi - ;; - - 'siasiesivsit_Arcticreg1') - - case $typeoutput in - 'MMO' ) pref='icemod' ;; - 'diags') pref='ice' ;; - esac - - if [[ $raw_regions_ice == '' ]] ; then - lstseas=$( cdo showvar mask_regions.nc ) - else - if [[ $raw_regions_ice == 'default' ]] ; then - lstseas="Baffin_Bay Baltic_Sea Barents_Sea Beaufort_Sea Bering CanArch Chukchi_Sea CntArctic CntArcticRing1 CntArcticRing2 CntArcticRing3 CntArcticRing4 CntArcticRing5 CntArcticRing6 CntArcticRing7_Lincoln_Sea CntArcticRing8 CntArcticPrf1 CntArcticPrf2r CntArcticPrf3 CntArcticPrf4 East_Siberian_Sea1 Greenland_Sea Hudson Icelandic_Sea Irminger Japan1 Kara_Sea Laptev_Sea Labrador_Sea1 Norwegian_Sea Okhotsk StLawr" - else - lstseas=$( echo ${raw_regions_ice[@]} ) - fi - fi - - for sea in $lstseas ; do - - siasiesiv ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc tmp.nc $sea - - ncks -O -v sia ice_N_tmp.nc sia_N_tmp.nc - ncks -O -v sie ice_N_tmp.nc sie_N_tmp.nc - ncks -O -v siv ice_N_tmp.nc siv_N_tmp.nc - ncks -O -v sit ice_N_tmp.nc sit_N_tmp.nc - - ncrename -h -v sia,sia_$sea sia_N_tmp.nc - ncrename -h -v sie,sie_$sea sie_N_tmp.nc - ncrename -h -v siv,siv_$sea siv_N_tmp.nc - ncrename -h -v sit,sit_$sea sit_N_tmp.nc - - if [ -e sia_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc ] ; then - ncks -A sia_N_tmp.nc sia_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ncks -A sie_N_tmp.nc sie_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ncks -A siv_N_tmp.nc siv_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ncks -A sit_N_tmp.nc sit_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - rm -f sia_N_tmp.nc sie_N_tmp.nc siv_N_tmp.nc sit_N_tmp.nc ice_N_tmp.nc ice_S_tmp.nc - else - mv sia_N_tmp.nc sia_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - mv sie_N_tmp.nc sie_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - mv siv_N_tmp.nc siv_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - mv sit_N_tmp.nc sit_Arcticreg1_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - rm -f ice_N_tmp.nc ice_S_tmp.nc - fi - - done - ;; - - 'ohc_Arcticreg1') - - case $typeoutput in - 'MMO' ) pref='grid_T' ;; - 'diags') pref='t3d' ;; - esac - - if [[ $raw_regions_ice == '' ]] ; then - lstseas=$( cdo showvar mask_regions.nc ) - else - if [[ $raw_regions_ice == 'default' ]] ; then - lstseas="Baffin_Bay Barents_Sea Beaufort_Sea Bering CanArch Chukchi_Sea East_Siberian_Sea Greenland_Sea Hudson Icelandic_Sea Kara_Sea Laptev_Sea Labrador_Sea Norwegian_Sea Okhotsk Central_Arctic" - else - lstseas=$( echo ${raw_regions_ice[@]} ) - fi - fi - - for sea in $lstseas ; do - - ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $sea 0 1 46 - - - done - ;; - - - esac - - case `echo $post|cut -c$((${#post}-2))-${#post}` in - 'ohc') - case `echo $post | cut -c1` in - 'x') kmin=0 ; kmax=0 ; start=2 ; mxl=1 ;; - 'l') start=2 ; mxl=0 - case $NEMOVERSION in - 'Ec2.3_O1L42'|'N3.2_O1L42'|'nemovar_O1L42') kmin=25 ; kmax=42 ;; - 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'N3.3_O1L46') kmin=23 ; kmax=46 ;; - 'Ec3.0_O1L75'|'Ec3.0_O25L75'|'glorys2v1_O25L75') kmin=45; kmax=75;; - esac - ;; - 'm') start=2 ; mxl=0 - case $NEMOVERSION in - 'Ec2.3_O1L42'|'N3.2_O1L42'|'nemovar_O1L42') kmin=21 ; kmax=24 ;; - 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'N3.3_O1L46') kmin=18 ; kmax=22 ;; - 'Ec3.0_O1L75'|'Ec3.0_O25L75'|'glorys2v1_O25L75') kmin=35; kmax=44;; - esac - ;; - 'u') kmin=1 ; start=2 ; mxl=0 - case $NEMOVERSION in - 'Ec2.3_O1L42'|'N3.2_O1L42'|'nemovar_O1L42') kmax=20 ;; - 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'N3.3_O1L46') kmax=17 ;; - 'Ec3.0_O1L75'|'Ec3.0_O25L75'|'glorys2v1_O25L75') kmax=34;; - esac - ;; - *) kmin="" ; kmax="" ; start=1 ; mxl=0 ;; - esac - case `echo $post | cut -c${start}-$((start+3))` in - 'ohc') basin='Glob' ;; - *) basin=`echo $post | cut -c${start}-$((start+3))` - esac - case $typeoutput in - 'MMO' ) pref='grid_T' ;; - 'diags') - pref='t3d' - ncks -A -v somxl010,somixhgt oce_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc t3d_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - ;; - esac - ohc ${pref}_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc heatc_${expid}_${yeari}${moni}01_fc${memb}_${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc $basin $mxl $kmin $kmax - ;; - esac - - done - - # Removing the raw output from this start dates and this member - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - clean_diagsMMO ${yeari}${moni}01 ${expid} ${memb} $ltime0 $ltimef $typeoutput "${list_files}" - done - - # Prepare storage : choose output directory and file name - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - for post in ${listpost[@]} ; do - case $post in -# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -# You have created a function ? Enter the output directory and the prefix -# or your(s) output files under the flag chosen -# Any doubt ---> vguemas@ic3.cat -# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - 'area_moc') dirout='moc'; files=('moc_40N55N_1-2km' 'moc_30N40N_1-2km') ;; - 'stc') dirout='moc' ; files=( 'NPac_stc_0N25N_0-200m' 'SPac_stc_25S0S_0-200m' 'NAtl_stc_0N25N_0-200m' 'SAtl_stc_25S0S_0-200m' ) ;; - 'max_moc') dirout='moc' ; files=('max_moc_38N50N_500m-2km' 'max_moc_40N' ) ;; - 'siasiesiv' ) dirout='ice' ; files=('siasiesiv_N' 'siasiesiv_S') ;; - 'siasiesivsit_Arcticreg1' ) dirout='ice' ; files=('sia_Arcticreg1' 'sie_Arcticreg1' 'siv_Arcticreg1' 'sit_Arcticreg1') ;; - 'moc') dirout='moc' ; files=('moc') ;; - 'convection') dirout='moc' ; files=('convection') ;; -# 'ext_raw_ice') dirout='ice' ; files=('ice_raw') ;; -# 'ext_raw_oce') dirout='oce_raw' ; files=('oce_raw') ;; - 'ext_raw_ice') dirout='ice' ; files=('ice') ;; - 'ext_raw_oce') dirout='oce' ; files=('oce') ;; - 'heat_sal_mxl') dirout='heatc' ; files=('heat_sal_mxl') ;; - 'psi') dirout='psi' ; files=('psi') ;; - 'gyres') dirout='psi' ; files=('gyres') ;; - 'usalc') dirout='saltc' ; files=('sal_0-300m') ;; - 'temp_lev') dirout='temp_lev'${level1}-${level2} ; files=('temp_lev'${level1}-${level2}) ;; - 'sal_lev') dirout='sal_lev'${level1}-${level2} ; files=('sal_lev'${level1}-${level2}) ;; - 'lmsalc') dirout='saltc' ; files=('sal_300-5400m') ;; - 'ohc_specified_layer') dirout='heatc' ; files=('ohc_2d_avg_0-300m' 'ohc_2d_avg_300-800m') ;; - 'vert_Tsections') dirout='sections' ; files=('temp_0N' 'temp_45N' 'temp_45S' 'temp_30W' 'temp_80E' 'temp_180E') ;; - 'vert_Ssections') dirout='sections' ; files=('sal_0N' 'sal_45N' 'sal_45S' 'sal_30W' 'sal_80E' 'sal_180E') ;; - '3dtemp') dirout='InterpT' ; files=('regular3dT') ;; - '3dsal') dirout='InterpS' ; files=('regular3dS') ;; - 'TSec_ave190-220E') dirout='sections' ; files=('TSec_ave190-220E') ;; - 'SSec_ave190-220E') dirout='sections' ; files=('SSec_ave190-220E') ;; - 'ohc_Arcticreg1') dirout='heatc' ; - files=('') - for sea in ${lstseas[@]} ; do - file=${sea}_0-657_heatc - files=$( echo ${files[@]} $file) - done ;; - esac - case `echo $post|cut -c$((${#post}-2))-${#post}` in - 'ohc') - dirout='heatc' - file='heatc' - case `echo $post | cut -c1` in - 'x') mxl=1 ; start=2 ;; - 'l') start=2 ; mxl=0 - case $NEMOVERSION in - 'Ec2.3_O1L42'|'N3.2_O1L42'|'nemovar_O1L42') file='800-5350_'${file} ;; - 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'N3.3_O1L46') file='855-5875_'${file} ;; - 'Ec3.0_O1L75'|'Ec3.0_O25L75'|'glorys2v1_O25L75') file='857-5902_'${file};; - esac - ;; - 'm') start=2 ; mxl=0 - case $NEMOVERSION in - 'Ec2.3_O1L42'|'N3.2_O1L42'|'nemovar_O1L42') file='373-657_'${file} ;; - 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'N3.3_O1L46') file='382-735_'${file} ;; - 'Ec3.0_O1L75'|'Ec3.0_O25L75'|'glorys2v1_O25L75') file='301-773_'${file};; - esac - ;; - 'u') start=2 ; mxl=0 - case $NEMOVERSION in - 'Ec2.3_O1L42'|'N3.2_O1L42'|'nemovar_O1L42') file='0-315_'${file} ;; - 'Ec3.0_O1L46'|'Ec3.0_O25L46'|'N3.3_O1L46') file='0-322_'${file} ;; - 'Ec3.0_O1L75'|'Ec3.0_O25L75'|'glorys2v1_O25L75') file='0-271_'${file};; - esac - ;; - *) mxl=0 ; start=1 ;; - esac - - case `echo $post | cut -c${start}-$((start+3))` in - 'NAtl') file='NAtl_10N65N_'${file} ;; - 'TAtl') file='TAtl_30S30N_'${file};; - 'NPac') file='NPac_10N70N_'${file} ;; - 'TPac') file='TPac_30S30N_'${file} ;; - 'Arct') file='Arc_65N90N_'${file} ;; - 'Anta') file='Ant_90S60S_'${file} ;; - 'TInd') file='TInd_30S30N_'${file} ;; - esac - if [[ $mxl == 1 ]] ; then - file='mxl_'$file - fi - files=( $file ) - esac - pathout=${rootout}/${dirout} - mkdir -m ug+w -m o-w -p $pathout - for file in ${files[@]} ; do - prefix=${file}_${expid}_${yeari}${moni}01_fc - lsmbso=0-${listmemb[${#listmemb[@]}-1]} - # - # Merging the post-processed members together and with the previous members if existing - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - lsyrsh=${year0}$(printf "%02d" ${mon0})_${yearf}$(printf "%02d" ${monf}).nc - lsmbsh=${listmemb[0]}-${listmemb[${#listmemb[@]}-1]} - lsmbsb=0-$((${listmemb[0]}-1)) - if [ -e ${pathout}/${prefix}${lsmbsb}_${lsyrsh} ] ; then - cp ${pathout}/${prefix}${lsmbsb}_${lsyrsh} . - lsmbsh=0-${listmemb[${#listmemb[@]}-1]} - fi - gather_memb ${prefix} _${lsyrsh} ${prefix}${lsmbsh}_${lsyrsh} - for jmemb in ${listmemb[@]} ; do - rm -f ${prefix}${jmemb}_${lsyrsh} - done - # - # Concatenating the result with the previous years if existing - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -# You have created a function ? If your diagnostic provides yearly output -# you need to use the concat option rather than the ncrcat one below. -# Any doubt ---> vguemas@ic3.cat -# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - lsyrsb=${yeari}${moni}_$((year0-(1-(10#$mon0+10)/12)))$(printf "%02d" $(((mon0-13)%12+12)) ).nc - lsyrso=${yeari}${moni}_${yearf}$(printf "%02d" ${monf}).nc - if [ -e ${pathout}/${prefix}${lsmbsh}_${lsyrsb} ] ; then - case $post in - 'max_moc' ) concat ${pathout}/${prefix}${lsmbsh}_${lsyrsb} ${prefix}${lsmbsh}_${lsyrsh} $(printf "%02d" ${monf}) ${prefix}${lsmbsh}_${lsyrso} ;; - *) ncrcat -O ${pathout}/${prefix}${lsmbsh}_${lsyrsb} ${prefix}${lsmbsh}_${lsyrsh} ${prefix}${lsmbsh}_${lsyrso} ;; - esac - else - lsyrso=$lsyrsh - fi - # - # Merging the result with the previous members if existing - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - if [[ $lsyrsh != $lsyrso ]] && [[ -e ${pathout}/${prefix}${lsmbsb}_${lsyrso} ]] ; then - cp ${pathout}/${prefix}${lsmbsb}_${lsyrso} . - gather_memb ${prefix} _${lsyrso} ${prefix}${lsmbso}_${lsyrso} - else - lsmbso=$lsmbsh - fi - # - # Storing and cleaning - # ~~~~~~~~~~~~~~~~~~~~~ - cp ${prefix}${lsmbso}_${lsyrso} ${pathout}/. || { if [ -e ${pathout}/${prefix}${lsmbso}_${lsyrso} ]; - then - echo "${prefix}${lsmbso}_${lsyrso} already exists in ${pathout}" - sleep 5 - else - echo " problem writing file in ${pathout} directory" - exit - fi - } - rm -f ${pathout}/${prefix}${lsmbsh}_${lsyrsb} ${prefix}${lsmbsh}_${lsyrso} ${prefix}${lsmbsb}_${lsyrso} ${pathout}/${prefix}${lsmbsb}_${lsyrso} ${prefix}${lsmbso}_${lsyrso} ${pathout}/${prefix}${lsmbsb}_${lsyrsh} ${prefix}${lsmbsb}_${lsyrsh} - done - done -done - -trap - EXIT -rm -rf $WORKDIR diff --git a/setup_development.bash b/setup_development.bash deleted file mode 100755 index cb08c82..0000000 --- a/setup_development.bash +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -# -# This script intends to support the development of new functions in -# common_ocean_post.txt of new options to existing funtions. It allows to -# test quickly these developments -# -# History : Virginie Guemas - Initial version - 2012 -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -set -evx -# This does not need to be changed : -CON_FILES='/esnas/autosubmit/con_files' -# This option is compatible with the testing on i00k but if you want to test -# your developments on another experiment you would need to change this : -NEMOVERSION=Ec2.3_O1L42 -# This lines needs to be replaced by the path were you stored your modifed -# version of common_ocean_post.txt : -source /home/Earth/jvegas/pyCharm/ocean_diagnostics/common_ocean_post.txt -# Here we only fetch one random chunk of outputs from i00k : -# cp /esnas/exp/ecearth/a030/19900101/fc0/outputs/MMO_a030_19900101_fc0_19900101-19900331.tar . -# Here we untar and gunzip these files : -#tar -xvf MMO_a030_19900101_fc0_19900101-19900331.tar -#gunzip *.gz -# The lines below might need to be changed depending on which function you need -# to test. In the case below, the grid_T files are needed because they contain -# the 3d temperature = input to ohc function. If you test siasiesiv for exemple, -# you would need to replace grid_T by icemod. -#filein=`ls *grid_T*`*grid* -#cdo cat *grid_T* tmp.nc - -# The lines below are essential because the files have a time dimension named -# time in all the functions from common_ocean_post.txt (this is handled in -# ocean_pp.bash and in the templates) -timevar=`ncdump -h tmp.nc | grep UNLIMITED | awk '{print $1}'` -if [[ $timevar == 'time_counter' ]] ; then ncrename -v time_counter,time -d time_counter,time tmp.nc ; fi -# Some cleaning -# rm -f *grid* *icemod* -# This is the final testing line. You need to replace that line by the function -# you want to test (here it is ohc) followed by all its arguments (here we have -# only the input file tmp.nc and the output file tmpout.nc) -moc a030_1m_19900101_19900331_grid_T.nc mocfile.nc -area_moc mocfile.nc 40.0 55.0 area_mocfile.nc diff --git a/testing_ocean_pp_moore.job b/testing_ocean_pp_moore.job deleted file mode 100755 index 9e2cab3..0000000 --- a/testing_ocean_pp_moore.job +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -#$ -l h_vmem=4G -#$ -l s_rt=24:00:00 -#$ -l h_rt=24:00:00 - -set -evx -oceanpp_repository=/home/Earth/pbretonn/es_git/ocean_diagnostics -workdir=/scratch/tmp/post_ocean/$$ - -mkdir -p $workdir -cd $workdir -if [ -e ${oceanpp_repository}/ocean_pp.bash ] ; then - cp ${oceanpp_repository}/ocean_pp.bash . -else - echo "Please fill up the location of your ocean_pp repository" - exit 1 -fi - -#lstexp=('b02s_bis') -#lstexp=('b02s_ter' 'l00w_bis') #orig -lstexp=('b02s' 'i00k' 'i01t' 'l00v' 'l00w' 'glorys' 'nemovar' 'b02s_bis' 'b02s_ter' 'l00w_bis') #orig -for exp in ${lstexp[@]} ; do - tmp=${oceanpp_repository//\//\\\/} - sed -e "s/PATHCOMMONOCEANDIAG=.*/PATHCOMMONOCEANDIAG=${tmp}/g" /shared/earth/software/scripts/testing_ocean_pp/config_file-ocean_pp_${exp}.bash &> config_file-ocean_pp_${exp}.bash - ./ocean_pp.bash config_file-ocean_pp_${exp}.bash -done -- GitLab From d0838a83d370e71b1d5a87b807ba02800abcdbc4 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 5 Jul 2016 17:14:44 +0200 Subject: [PATCH 115/268] Created a class to encapsulate al the experiment management (get chunk list, get member str...) functionalities --- earthdiagnostics/datamanager.py | 162 ++++++------------ earthdiagnostics/diags.conf | 39 ++--- earthdiagnostics/diags.py | 59 +++---- earthdiagnostics/experimentmanager.py | 99 +++++++++++ earthdiagnostics/ocean/areamoc.py | 2 +- earthdiagnostics/ocean/averagesection.py | 2 +- earthdiagnostics/ocean/convectionsites.py | 2 +- earthdiagnostics/ocean/cutsection.py | 2 +- earthdiagnostics/ocean/gyres.py | 2 +- earthdiagnostics/ocean/heatcontent.py | 2 +- earthdiagnostics/ocean/heatcontentlayer.py | 2 +- earthdiagnostics/ocean/interpolate.py | 2 +- earthdiagnostics/ocean/maxmoc.py | 2 +- .../ocean/mixedlayerheatcontent.py | 2 +- .../ocean/mixedlayersaltcontent.py | 2 +- earthdiagnostics/ocean/moc.py | 2 +- earthdiagnostics/ocean/psi.py | 2 +- earthdiagnostics/ocean/siasiesiv.py | 2 +- earthdiagnostics/ocean/verticalmean.py | 2 +- earthdiagnostics/ocean/verticalmeanmeters.py | 2 +- earthdiagnostics/utils.py | 1 - testing_diags_moore.job | 2 +- 22 files changed, 204 insertions(+), 190 deletions(-) create mode 100644 earthdiagnostics/experimentmanager.py diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 5289879..ff2fb63 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -21,8 +21,8 @@ class DataManager(object): """ Class to manage the data repositories """ - def __init__(self, institution, model, expid, datafolder, frequency, chunk_size, experiment_name, num_chunks, - scratch_dir, nfrp, member_digits, calendar='standard'): + def __init__(self, exp_manager, institution, model, expid, datafolder, frequency, experiment_name, + scratch_dir, nfrp, calendar='standard'): self.initialization_method = 'to be filled' self.initialization_description = 'to be filled' self.physics_version = 'to be filled' @@ -35,18 +35,16 @@ class DataManager(object): self.expid = expid self.data_dir = datafolder self.frequency = frequency - self.chunk_size = chunk_size self.experiment_name = experiment_name self.add_startdate = True self.add_name = True - self.num_chunks = num_chunks self.calendar = calendar self.scratch_dir = scratch_dir self.nfrp = nfrp - self.member_digits = member_digits + self.exp_manager = exp_manager # noinspection PyPep8Naming - def prepare_CMOR_files(self, startdates, members, force_rebuild, ocean, atmosphere): + def prepare_CMOR_files(self, force_rebuild, ocean, atmosphere): """ Prepares the data to be used by the diagnostic. @@ -61,53 +59,50 @@ class DataManager(object): :type ocean: bool :param force_rebuild: if True, forces the creation of the CMOR files :type force_rebuild: bool - :param startdates: list of startdates that will be used by the diagnostics - :type startdates: list[str] - :param members: lists of members that will be used by the diagnostics - :type members: list[int] :return: """ # Check if cmorized and convert if not created = False - for startdate in startdates: - for member in members: - if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles', - startdate, self.get_member_str(member))): - created = True - Log.info('CMORizing startdate {0} member {1}', startdate, self.get_member_str(member)) - if ocean: - path_MMO = os.path.join(self.data_dir, self.expid, 'original_files', startdate, - self.get_member_str(member), 'outputs', 'MMO*') - for tarfile in glob.glob(path_MMO): - self._unpack_tar(member, startdate, tarfile) - - if not atmosphere: - continue - grb_path = os.path.join(self.data_dir, self.expid, 'original_files', startdate, - self.get_member_str(member), 'outputs', '*.grb') - gribfiles = glob.glob(grb_path) - if len(gribfiles) == 0: - for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, - self.get_member_str(member), - 'outputs', 'MMA*')): - self._unpack_tar(member, startdate, tarfile) - else: - self._cmorize_grib(startdate, member, gribfiles) - Log.result('CMORized startdate {0} member {1}!\n\n', startdate, self.get_member_str(member)) + for startdate, member in self.exp_manager.get_member_list(): + member_str = self.exp_manager.get_member_str(member) + if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles', + startdate, member_str)): + created = True + Log.info('CMORizing startdate {0} member {1}', startdate, member_str) + if ocean: + path_MMO = os.path.join(self.data_dir, self.expid, 'original_files', startdate, + member_str, 'outputs', 'MMO*') + for tarfile in glob.glob(path_MMO): + self._unpack_tar(member, startdate, tarfile) + + if not atmosphere: + continue + grb_path = os.path.join(self.data_dir, self.expid, 'original_files', startdate, + member_str, 'outputs', '*.grb') + gribfiles = glob.glob(grb_path) + if len(gribfiles) == 0: + for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, + member_str, + 'outputs', 'MMA*')): + self._unpack_tar(member, startdate, tarfile) + else: + self._cmorize_grib(startdate, member, gribfiles) + Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str) + if created: return - for startdate in startdates: - for member in members: - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, - self.get_member_str(member), 'outputs') - Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) - filepaths = glob.glob(os.path.join(member_path, '*.gz')) + for startdate, member in self.exp_manager.get_member_list(): + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, + self.exp_manager.get_member_str(member), 'outputs') + Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) - if len(filepaths) == 0: - continue + filepaths = glob.glob(os.path.join(member_path, '*.gz')) - self._unpack_cmorfiles(filepaths, member_path) + if len(filepaths) == 0: + continue + + self._unpack_cmorfiles(filepaths, member_path) def _cmorize_grib(self, startdate, member, gribfiles): gribfiles.sort() @@ -311,7 +306,7 @@ class DataManager(object): while os.path.exists(os.path.join(self.scratch_dir, 'ICMGG{0}+{1}.grb'.format(self.expid, date2str(chunk_start)[:-2]))): - chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') chunk_files_gg_mon = list() chunk_files_gg_day = list() @@ -321,7 +316,7 @@ class DataManager(object): chunk_files_sh_day = list() chunk_files_sh_6h = list() - for month in range(0, self.chunk_size): + for month in range(0, self.exp_manager.chunk_size): chunk_file = 'ICMGG{0}+{1}.grb'.format(self.expid, date2str(add_months(chunk_start, month, 'standard'))[:-2]) @@ -346,7 +341,7 @@ class DataManager(object): 'GG', '1d') self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_6h, 'GG', '6hr') - chunk_start = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_start = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, chunk_files, grid, frequency): merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) @@ -651,12 +646,13 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, + self.exp_manager.get_member_str(member), 'outputs', 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, frequency, domain) - chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_start = chunk_start_date(start, chunk, self.exp_manager.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') if box: @@ -726,14 +722,15 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, self.get_member_str(member), + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, + self.exp_manager.get_member_str(member), 'outputs', 'output', self.institution, self.model, self.experiment_name, 'S' + startdate, frequency, domain) if chunk is not None: - chunk_start = chunk_start_date(start, chunk, self.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.chunk_size, 'month', 'standard') + chunk_start = chunk_start_date(start, chunk, self.exp_manager.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, @@ -875,7 +872,7 @@ class DataManager(object): :rtype: str """ chunk_files = list() - for chunk in self.get_year_chunks(startdate, year): + for chunk in self.exp_manager.get_year_chunks(startdate, year): chunk_files.append(self.get_file(domain, var, startdate, member, chunk, grid=grid, box=box)) if len(chunk_files) > 1: @@ -903,63 +900,6 @@ class DataManager(object): os.remove(temp) return temp2 - def get_year_chunks(self, startdate, year): - """ - Get the list of chunks containing timesteps from the given year - :param startdate: startdate to use - :type startdate: str - :param year: reference year - :type year: int - :return: list of chunks containing data from the given year - :rtype: list[int] - """ - date = parse_date(startdate) - chunks = list() - for chunk in range(1, self.num_chunks + 1): - chunk_start = chunk_start_date(date, chunk, self.chunk_size, 'month', self.calendar) - if chunk_start.year > year: - break - elif chunk_start.year == year or chunk_end_date(chunk_start, self.chunk_size, 'month', - self.calendar).year == year: - chunks.append(chunk) - - return chunks - - def get_full_years(self, startdate): - """ - Returns the list of full years that are in the given startdate - :param startdate: startdate to use - :type startdate: str - :return: list of full years - :rtype: list[int] - """ - chunks_per_year = 12 / self.chunk_size - date = parse_date(startdate) - first_january = 0 - first_year = date.year - if date.month != 1: - month = date.month - first_year += 1 - while month + self.chunk_size < 12: - month += self.chunk_size - first_january += 1 - - years = list() - for chunk in range(first_january, self.num_chunks - chunks_per_year, chunks_per_year): - years.append(first_year) - first_year += 1 - return years - - def get_member_str(self, member): - """ - Returns the member name for a given member number. - :param member: member's number - :type member: int - :return: member's name - :rtype: str - """ - return 'fc{0}'.format(str(member).zfill(self.member_digits)) - class Variable(object): """ diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 8ad7848..70bfe04 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -5,18 +5,26 @@ SCRATCH_DIR = /scratch/Earth/jvegas DATA_DIR = /esnas/exp/nemo/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ -# Diagnostics to run +# Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or +# an alias defined in the ALIAS section (see more below) DIAGS = SIASIESIV # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin +# If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False +# Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) +# MAX_CORES = 6 [CMOR] +# If true, recreates CMOR files regardless of presence. Default = False FORCE = False +# If true, CMORizes ocean files. Default = True OCEAN_FILES = True +# If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = True +# The next bunch of parameters are used to provide metadata for the CMOR files # ASSOCIATED_EXPERIMENT = # INITIALIZATION_METHOD = 1 # INITIALIZATION_DESCRIPTION = ocean: ECMWF system4, ice: DFS4.3 , atmosphere: @@ -35,7 +43,7 @@ MODEL = NEMO # STARTDATES is the list of start dates # MEMBERS is the list of members of your experiment # CHUNK_SIZE is the size of each data file, given in months -# CHUNKS is the number of chunks to process +# CHUNKS is the number of chunks. You can specify less chunks than present on the experiment EXPID = a05p STARTDATES = 19580101 @@ -48,31 +56,10 @@ CHUNKS = 58 # Model version NEMO_VERSION = N3.6_O1L75 -# [EXPERIMENT] -# INSTITUTE = IC3 -# EXPID = a030 -# STARTDATES = 19900101 -# NAME = historical -# CHUNK_SIZE = 3 -# CHUNKS = 120 -# MEMBERS = 0 -# MODEL = EC-EARTH3 -# NEMO_VERSION = Ec3.0_O1L46 - -# [EXPERIMENT] -# INSTITUTE = IC3 -# EXPID = m04s -# NAME = horizlResImpact_series2 -# STARTDATES = 19930501 -# CHUNK_SIZE = 4 -# CHUNKS = 120 -# MEMBERS = 0 1 2 3 4 -# MODEL = EC-EARTH3 -# NEMO_VERSION = Ec3.0_O25L75 - - # This ALIAS section is a bit different -# Inside this, you can provide. +# Inside this, you can provide alias for frequent diagnostics calls. +# By default, there are some of the diagnostics available at the previos version. +# You can define an alias for one or more diagnostic calls [ALIAS] MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 8719140..ce40972 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -16,6 +16,7 @@ from earthdiagnostics import cdftools from earthdiagnostics.utils import TempFile from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.ocean import * +from experimentmanager import ExperimentManager from ocean import ConvectionSites, Gyres, Psi, MaxMoc, AreaMoc, Moc, VerticalMean, VerticalMeanMeters, Interpolate, \ AverageSection, CutSection, MixedLayerSaltContent, Siasiesiv from parser import Parser @@ -80,8 +81,7 @@ class Diags(object): parse_date('20000101') - self.data_manager.prepare_CMOR_files(self.startdates, self.members, self.CMOR_force, - self.CMOR_ocean, self.CMOR_atmosphere) + self.data_manager.prepare_CMOR_files(self.CMOR_force, self.CMOR_ocean, self.CMOR_atmosphere) # Run diagnostics Log.info('Running diagnostics') @@ -100,11 +100,12 @@ class Diags(object): time = datetime.datetime.now() Log.info("Starting to compute at {0}", time) - numthreads = min(Utils.available_cpu_count(), self.max_cores) + num_threads = min(Utils.available_cpu_count(), self.max_cores) + Log.info('Using {0} threads', num_threads) threads = list() - for numthread in range(0, numthreads): - self.time[numthread] = dict() - t = threading.Thread(target=Diags._run_jobs, args=(self, list_jobs, numthread)) + for num_thread in range(0, num_threads): + self.time[num_thread] = dict() + t = threading.Thread(target=Diags._run_jobs, args=(self, list_jobs, num_thread)) threads.append(t) t.start() @@ -115,18 +116,18 @@ class Diags(object): Log.result("Diagnostics finished at {0}", finsih_time) Log.result("Time ellapsed: {0}\n", finsih_time - time) - Log.info('Detailed time for diagnostic class') - Log.info('----------------------------------') + Log.info('Time consumed by each diagnostic class') + Log.info('--------------------------------------') total = dict() - for numthread in range(0, numthreads): - for key, value in self.time[numthread].items(): + for num_thread in range(0, num_threads): + for key, value in self.time[num_thread].items(): if key in total: total[key] += value else: total[key] = value for diag, time in sorted(total.items(), key=operator.itemgetter(1)): - Log.info('{0:20} {1:}', diag.__name__, time) + Log.info('{0:23} {1:}', diag.__name__, time) def _run_jobs(self, queue, numthread): def _run_job(current_job, retrials=1): @@ -246,15 +247,18 @@ class Diags(object): self.expid = self.parser.get_option('EXPERIMENT', 'EXPID') self.experiment_name = self.parser.get_option('EXPERIMENT', 'NAME', self.expid) - self.members = list() + members = list() for member in self.parser.get_option('EXPERIMENT', 'MEMBERS').split(): - self.members.append(int(member)) + members.append(int(member)) + + member_digits = self.parser.get_int_option('EXPERIMENT', 'MEMBER_DIGITS', 1) + startdates = self.parser.get_option('EXPERIMENT', 'STARTDATES').split() + chunk_size = self.parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') + chunks = self.parser.get_int_option('EXPERIMENT', 'CHUNKS') + cal = self.parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') + + self.exp_manager = ExperimentManager(startdates, members, chunks, chunk_size, member_digits, cal) - self.member_digits = self.parser.get_int_option('EXPERIMENT', 'MEMBER_DIGITS', 1) - self.startdates = self.parser.get_option('EXPERIMENT', 'STARTDATES').split() - self.chunk_size = self.parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') - self.chunks = self.parser.get_int_option('EXPERIMENT', 'CHUNKS') - self.calendar = self.parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') self.model = self.parser.get_option('EXPERIMENT', 'MODEL') self.nfrp = self.parser.get_int_option('EXPERIMENT', 'NFRP') self.nemo_version = self.parser.get_option('EXPERIMENT', 'NEMO_VERSION') @@ -273,10 +277,8 @@ class Diags(object): os.makedirs(self.scratch_dir) os.chdir(self.scratch_dir) - self.data_manager = DataManager(self.institute, self.model, self.expid, self.data_dir, - self.frequency, self.chunk_size, self.experiment_name, self.chunks, - self.scratch_dir, self.nfrp, self.member_digits, - self.calendar) + self.data_manager = DataManager(self.exp_manager, self.institute, self.model, self.expid, self.data_dir, + self.frequency, self.experiment_name, self.scratch_dir, self.nfrp) self.data_manager.add_startdate = self.add_startdate self.data_manager.add_name = self.add_name @@ -295,19 +297,6 @@ class Diags(object): self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', 'to be filled') self.data_manager.source = self.parser.get_option('CMOR', 'SOURCE', 'to be filled') - def get_chunk_list(self): - """ - Return a list with all the chunks - :return: List contanining tuples of startdtae, member and chunk - :rtype: tuple[str, int, int] - """ - chunk_list = list() - for startdate in self.startdates: - for member in self.members: - for chunk in range(1, self.chunks + 1): - chunk_list.append((startdate, member, chunk)) - return chunk_list - def main(): """ diff --git a/earthdiagnostics/experimentmanager.py b/earthdiagnostics/experimentmanager.py new file mode 100644 index 0000000..bfe48c4 --- /dev/null +++ b/earthdiagnostics/experimentmanager.py @@ -0,0 +1,99 @@ +# coding=utf-8 +from autosubmit.date.chunk_date_lib import chunk_start_date, chunk_end_date +from autosubmit.date.chunk_date_lib import parse_date + + +class ExperimentManager(object): + """ + Encapsulates all chunk related tasks + """ + + def __init__(self, startdates, members, num_chunks, chunk_size, member_digits, calendar='standard'): + self.startdates = startdates + self.members = members + self.num_chunks = num_chunks + self.chunk_size = chunk_size + self.member_digits = member_digits + self.calendar = calendar + + def get_chunk_list(self): + """ + Return a list with all the chunks + :return: List containing tuples of startdate, member and chunk + :rtype: tuple[str, int, int] + """ + chunk_list = list() + for startdate in self.startdates: + for member in self.members: + for chunk in range(1, self.num_chunks + 1): + chunk_list.append((startdate, member, chunk)) + return chunk_list + + def get_member_list(self): + """ + Return a list with all the members + :return: List containing tuples of startdate and member + :rtype: tuple[str, int, int] + """ + member_list = list() + for startdate in self.startdates: + for member in self.members: + member_list.append((startdate, member)) + return member_list + + def get_year_chunks(self, startdate, year): + """ + Get the list of chunks containing timesteps from the given year + :param startdate: startdate to use + :type startdate: str + :param year: reference year + :type year: int + :return: list of chunks containing data from the given year + :rtype: list[int] + """ + date = parse_date(startdate) + chunks = list() + for chunk in range(1, self.num_chunks + 1): + chunk_start = chunk_start_date(date, chunk, self.chunk_size, 'month', self.calendar) + if chunk_start.year > year: + break + elif chunk_start.year == year or chunk_end_date(chunk_start, self.chunk_size, 'month', + self.calendar).year == year: + chunks.append(chunk) + + return chunks + + def get_full_years(self, startdate): + """ + Returns the list of full years that are in the given startdate + :param startdate: startdate to use + :type startdate: str + :return: list of full years + :rtype: list[int] + """ + chunks_per_year = 12 / self.chunk_size + date = parse_date(startdate) + first_january = 0 + first_year = date.year + if date.month != 1: + month = date.month + first_year += 1 + while month + self.chunk_size < 12: + month += self.chunk_size + first_january += 1 + + years = list() + for chunk in range(first_january, self.num_chunks - chunks_per_year, chunks_per_year): + years.append(first_year) + first_year += 1 + return years + + def get_member_str(self, member): + """ + Returns the member name for a given member number. + :param member: member's number + :type member: int + :return: member's name + :rtype: str + """ + return 'fc{0}'.format(str(member).zfill(self.member_digits)) diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 5c5b1a4..b149e83 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -62,7 +62,7 @@ class AreaMoc(Diagnostic): basin = Basins.Global job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(AreaMoc(diags.data_manager, startdate, member, chunk, basin, box)) return job_list diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 1370206..19cf2c7 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -58,7 +58,7 @@ class AverageSection(Diagnostic): domain = 'ocean' job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, variable, domain, box)) return job_list diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 11e2c98..6d86584 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -44,7 +44,7 @@ class ConvectionSites(Diagnostic): if len(options) > 1: raise Exception('The convection sites diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.nemo_version)) return job_list diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index 8bc5725..f3dc217 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -59,7 +59,7 @@ class CutSection(Diagnostic): domain = 'ocean' job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(CutSection(diags.data_manager, startdate, member, chunk, variable, domain, zonal, value)) return job_list diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index bdfc97b..be9580a 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -45,7 +45,7 @@ class Gyres(Diagnostic): if len(options) > 1: raise Exception('The gyres diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.nemo_version)) return job_list diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index 6ab84f0..a22ce0f 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -59,7 +59,7 @@ class HeatContent(Diagnostic): box.min_depth = int(options[3]) box.max_depth = int(options[4]) job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(HeatContent(diags.data_manager, startdate, member, chunk, basin, mixed_layer, box)) return job_list diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index cda8135..0219e8e 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -53,7 +53,7 @@ class HeatContentLayer(Diagnostic): box.min_depth = int(options[1]) box.max_depth = int(options[2]) job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box)) return job_list diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 1aa7dda..00fe6f0 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -58,7 +58,7 @@ class Interpolate(Diagnostic): domain = 'ocean' job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(Interpolate(diags.data_manager, startdate, member, chunk, variable, domain, diags.nemo_version)) return job_list diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 93ff457..24cac19 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -65,7 +65,7 @@ class MaxMoc(Diagnostic): job_list = list() for startdate in diags.startdates: for member in diags.members: - years = diags.data_manager.get_full_years(startdate) + years = diags.exp_manager.get_full_years(startdate) if len(years) == 0: Log.user_warning('No complete years are available with the given configuration. ' 'MaxMoc can not be computed') diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index acd1abb..8c4fce8 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -44,7 +44,7 @@ class MixedLayerHeatContent(Diagnostic): if len(options) > 1: raise Exception('The mixed layer ocean heat content diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(MixedLayerHeatContent(diags.data_manager, startdate, member, chunk)) return job_list diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 8eb38b6..780d1c8 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -43,7 +43,7 @@ class MixedLayerSaltContent(Diagnostic): if len(options) > 1: raise Exception('The mixed layer salt content diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(MixedLayerSaltContent(diags.data_manager, startdate, member, chunk)) return job_list diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index 0310719..d4485bb 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -45,7 +45,7 @@ class Moc(Diagnostic): if len(options) > 1: raise Exception('The MOC diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(Moc(diags.data_manager, startdate, member, chunk)) return job_list diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 78ebcb6..3f1989a 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -40,7 +40,7 @@ class Psi(Diagnostic): if len(options) > 1: raise Exception('The PSI diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(Psi(diags.data_manager, startdate, member, chunk)) return job_list diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index a016149..c069585 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -69,7 +69,7 @@ class Siasiesiv(Diagnostic): mask_handler.close() job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk, mask)) mesh_handler = Utils.openCdf('mesh_hgr.nc') Siasiesiv.e1t = np.asfortranarray(mesh_handler.variables['e1t'][0, :]) diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 053486d..bd79f86 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -58,7 +58,7 @@ class VerticalMean(Diagnostic): box.max_depth = float(options[3]) job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(VerticalMean(diags.data_manager, startdate, member, chunk, variable, box)) return job_list diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 17b2adc..9bf768f 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -55,7 +55,7 @@ class VerticalMeanMeters(Diagnostic): box.max_depth = float(options[3]) job_list = list() - for startdate, member, chunk in diags.get_chunk_list(): + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(VerticalMeanMeters(diags.data_manager, startdate, member, chunk, variable, box)) return job_list diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index a4c47c3..77996cc 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -190,7 +190,6 @@ class Utils(object): return Utils._cpu_count except (ImportError, NotImplementedError): Utils._cpu_count = -1 - Log.info('Available cores: {0}', Utils._cpu_count) return Utils._cpu_count @staticmethod diff --git a/testing_diags_moore.job b/testing_diags_moore.job index b4b222d..8ca88b0 100755 --- a/testing_diags_moore.job +++ b/testing_diags_moore.job @@ -7,7 +7,7 @@ set -xv module load NCO/4.5.4-foss-2015a -module load CDO +module load CDO/1.6.9-foss-2015a module load CDFTOOLS/3.0-foss-2015a source /home/Earth/jvegas/virtualenvs/diags/bin/activate -- GitLab From 436187d29a758e9c7856cc2d928f2f5eb06eadce Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 5 Jul 2016 17:17:34 +0200 Subject: [PATCH 116/268] Changed gitignore --- .gitignore | 2 +- .idea/dictionaries/jvegas.xml | 23 ----------------------- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 .idea/dictionaries/jvegas.xml diff --git a/.gitignore b/.gitignore index a3f647b..92bfa24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .*.sw* .*.log* -.*.pyc* +.*.pyc .idea/* doc/build/ diff --git a/.idea/dictionaries/jvegas.xml b/.idea/dictionaries/jvegas.xml deleted file mode 100644 index 23425c0..0000000 --- a/.idea/dictionaries/jvegas.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - cdftools - cmor - cmorization - cmorized - diags - ecearth - eleftheria - esnas - exarchou - guemas - jvegas - leadtime - nemo - orca - regidor - startdate - startdates - - - \ No newline at end of file -- GitLab From 67207ed38c95bb0b576997ff8ac1f021b64197e7 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 5 Jul 2016 17:18:53 +0200 Subject: [PATCH 117/268] Removed .idea folder --- .idea/codeStyleSettings.xml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 .idea/codeStyleSettings.xml diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml deleted file mode 100644 index c4c9543..0000000 --- a/.idea/codeStyleSettings.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - \ No newline at end of file -- GitLab From 63c746f2343ae4c12df9d8657d7a24adee9159b6 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 6 Jul 2016 15:57:14 +0200 Subject: [PATCH 118/268] Added unit tests --- earthdiagnostics/box.py | 2 +- earthdiagnostics/diags.conf | 2 +- test/unit/test_box.py | 81 ++++++++++++++++++++++++++++ test/unit/test_constants.py | 23 ++++++++ test/unit/test_data_manager.py | 20 +++++++ test/unit/test_experiment_manager.py | 37 +++++++++++++ 6 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 test/unit/test_box.py create mode 100644 test/unit/test_constants.py create mode 100644 test/unit/test_data_manager.py create mode 100644 test/unit/test_experiment_manager.py diff --git a/earthdiagnostics/box.py b/earthdiagnostics/box.py index cc32dc2..b0e9063 100644 --- a/earthdiagnostics/box.py +++ b/earthdiagnostics/box.py @@ -66,7 +66,7 @@ class Box(object): @max_lon.setter def max_lon(self, value): - if value > 360 or value < -360: + if value >= 360 or value <= -360: raise ValueError('{0} is not a valid longitude. Must be between -360 and 360'.format(value)) self._max_lon = value diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 70bfe04..9a3d24a 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -15,7 +15,7 @@ CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -# MAX_CORES = 6 +MAX_CORES = 4 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False diff --git a/test/unit/test_box.py b/test/unit/test_box.py new file mode 100644 index 0000000..6cd950a --- /dev/null +++ b/test/unit/test_box.py @@ -0,0 +1,81 @@ +# coding=utf-8 +from unittest import TestCase +from earthdiagnostics.box import Box + + +class TestBox(TestCase): + + def setUp(self): + self.box1 = Box() + self.box1.max_lat = 0 + self.box1.min_lat = -20 + self.box1.max_lon = 0 + self.box1.min_lon = -20 + self.box1.min_depth = 0 + self.box1.max_depth = 20 + + self.box2 = Box(True) + self.box2.max_lat = 20 + self.box2.min_lat = 20 + self.box2.max_lon = 20 + self.box2.min_lon = 20 + self.box2.min_depth = 20 + self.box2.max_depth = 20 + + self.box3 = Box() + + def test_max_lat(self): + with self.assertRaises(ValueError): + Box().max_lat = 100 + with self.assertRaises(ValueError): + Box().max_lat = -100 + Box().max_lat = 0 + Box().max_lat = -20 + Box().max_lat = 20 + + def test_min_lat(self): + with self.assertRaises(ValueError): + Box().min_lat = 100 + with self.assertRaises(ValueError): + Box().min_lat = -100 + Box().min_lat = 0 + Box().min_lat = -90 + Box().min_lat = 90 + + def test_max_lon(self): + with self.assertRaises(ValueError): + Box().max_lon = 360 + with self.assertRaises(ValueError): + Box().max_lon = -360 + Box().max_lon = 0 + Box().max_lon = -20 + Box().max_lon = 20 + + def test_min_lon(self): + with self.assertRaises(ValueError): + Box().min_lon = 360 + with self.assertRaises(ValueError): + Box().min_lon = -360 + Box().min_lon = 0 + Box().min_lon = -80 + Box().min_lon = 80 + + def test_get_lat_str(self): + self.assertEquals('20S0N', self.box1.get_lat_str()) + self.assertEquals('20N', self.box2.get_lat_str()) + self.assertEquals('', self.box3.get_lat_str()) + + def test_get_lon_str(self): + self.assertEquals('20W0E', self.box1.get_lon_str()) + self.assertEquals('20E', self.box2.get_lon_str()) + self.assertEquals('', self.box3.get_lon_str()) + + def test_get_depth_str(self): + self.assertEquals('0-20', self.box1.get_depth_str()) + self.assertEquals('20m', self.box2.get_depth_str()) + self.assertEquals('', self.box3.get_depth_str()) + + def test__str__(self): + self.assertEquals('20S0N20W0E0-20', str(self.box1)) + self.assertEquals('20N20E20m', str(self.box2)) + self.assertEquals('', str(self.box3)) diff --git a/test/unit/test_constants.py b/test/unit/test_constants.py new file mode 100644 index 0000000..b56f152 --- /dev/null +++ b/test/unit/test_constants.py @@ -0,0 +1,23 @@ +# coding=utf-8 +from unittest import TestCase +from earthdiagnostics.constants import Basins, Basin + + +class TestBasins(TestCase): + + def test_parse(self): + self.assertEquals(Basins.Arctic, Basins.parse('Arct')) + self.assertEquals(Basins.Arctic, Basins.parse('Arctic_Ocean')) + self.assertIsNone(Basins.parse('Basin not found')) + + +class TestBasin(TestCase): + + def setUp(self): + self.basin = Basin('bas', 'Basin') + + def test_shortname(self): + self.assertEquals('bas', self.basin.shortname) + + def test_fullname(self): + self.assertEquals('Basin', self.basin.fullname) diff --git a/test/unit/test_data_manager.py b/test/unit/test_data_manager.py new file mode 100644 index 0000000..b916b1c --- /dev/null +++ b/test/unit/test_data_manager.py @@ -0,0 +1,20 @@ +# coding=utf-8 + + +from unittest import TestCase +from earthdiagnostics.datamanager import DataManager + + +class TestDataManager(TestCase): + def setUp(self): + pass + + def test_domain_abbreviation(self): + self.assertEquals('Omon', DataManager.domain_abbreviation('Ocean', 'mon')) + self.assertEquals('OImon', DataManager.domain_abbreviation('seaIce', 'mon')) + self.assertEquals('LImon', DataManager.domain_abbreviation('landIce', 'mon')) + self.assertEquals('Amon', DataManager.domain_abbreviation('atmos', 'mon')) + self.assertEquals('day', DataManager.domain_abbreviation('atmos', 'day')) + self.assertEquals('6hrPlev', DataManager.domain_abbreviation('atmos', '6hr')) + + diff --git a/test/unit/test_experiment_manager.py b/test/unit/test_experiment_manager.py new file mode 100644 index 0000000..ccd433a --- /dev/null +++ b/test/unit/test_experiment_manager.py @@ -0,0 +1,37 @@ +# coding=utf-8 + +from unittest import TestCase +from earthdiagnostics.experimentmanager import ExperimentManager + + +class TestDataManager(TestCase): + def setUp(self): + self.experiment_manager = ExperimentManager(('20000101', '20000201'), (0, 1), 5, 3, 3) + + def test_get_full_years(self): + self.assertEquals([2000], self.experiment_manager.get_full_years('20000101')) + self.assertEquals(list(), self.experiment_manager.get_full_years('20000201')) + + def test_get_member_str(self): + self.assertEquals('fc000', self.experiment_manager.get_member_str(0)) + self.assertEquals('fc001', self.experiment_manager.get_member_str(1)) + + def test_get_member_list(self): + self.assertEquals([('20000101', 0), ('20000101', 1), ('20000201', 0), ('20000201', 1)], + self.experiment_manager.get_member_list()) + + def test_get_year_chunks(self): + self.assertEquals([1, 2, 3, 4], self.experiment_manager.get_year_chunks('20000101', 2000)) + self.assertEquals([4, 5], self.experiment_manager.get_year_chunks('20000201', 2001)) + self.assertEquals(list(), self.experiment_manager.get_year_chunks('20000201', 2003)) + + def test_get_chunk_list(self): + self.assertEquals([('20000101', 0, 1), ('20000101', 0, 2), ('20000101', 0, 3), ('20000101', 0, 4), + ('20000101', 0, 5), + ('20000101', 1, 1), ('20000101', 1, 2), ('20000101', 1, 3), ('20000101', 1, 4), + ('20000101', 1, 5), + ('20000201', 0, 1), ('20000201', 0, 2), ('20000201', 0, 3), ('20000201', 0, 4), + ('20000201', 0, 5), + ('20000201', 1, 1), ('20000201', 1, 2), ('20000201', 1, 3), ('20000201', 1, 4), + ('20000201', 1, 5)], + self.experiment_manager.get_chunk_list()) -- GitLab From 939a6d4873c8b7afa25f97583b6791708ee34d7a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 6 Jul 2016 16:40:52 +0200 Subject: [PATCH 119/268] Updated doc --- EarthDiagnostics.pdf | Bin 181999 -> 184734 bytes doc/source/codedoc/earthdiagnostics.rst | 31 +++++++++++++++--------- earthdiagnostics/box.py | 8 +++--- earthdiagnostics/cdftools.py | 3 +++ earthdiagnostics/constants.py | 2 ++ earthdiagnostics/datamanager.py | 21 ++++++++++++++++ earthdiagnostics/diagnostic.py | 21 +++++++--------- earthdiagnostics/experimentmanager.py | 13 ++++++++++ test/unit/test_constants.py | 9 +++++++ test/unit/test_data_manager.py | 4 +-- 10 files changed, 81 insertions(+), 31 deletions(-) diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index 85d3422960dfecbafb188f50ea99ea2af64fdd54..6dd1ebaa9ff17a53574814b1f5f674ae857520ab 100644 GIT binary patch delta 60128 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

S;)aNkPF(gz@M3TQrmqU0{{a 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 W^tN}v Date: Wed, 6 Jul 2016 16:43:57 +0200 Subject: [PATCH 120/268] Corrected error in doc --- EarthDiagnostics.pdf | Bin 184734 -> 184723 bytes doc/source/codedoc/earthdiagnostics.rst | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index 6dd1ebaa9ff17a53574814b1f5f674ae857520ab..eafb78207931b03678ab0522fa4ca4f9cc656c8c 100644 GIT binary patch delta 3664 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 S7yyYds%SDvN*Y)gGW`Q5G1@!; delta 3710 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 diff --git a/doc/source/codedoc/earthdiagnostics.rst b/doc/source/codedoc/earthdiagnostics.rst index c7b4215..997c4c7 100644 --- a/doc/source/codedoc/earthdiagnostics.rst +++ b/doc/source/codedoc/earthdiagnostics.rst @@ -51,8 +51,8 @@ earthdiagnostics.experimentmanager :inherited-members: :members: -earthdiagnostics.ocean.utils ----------------------------- +earthdiagnostics.utils +---------------------- .. automodule:: earthdiagnostics.utils :show-inheritance: :inherited-members: -- GitLab From b3834a37206714497c5048c78b87f64592dafff8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 6 Jul 2016 17:52:34 +0200 Subject: [PATCH 121/268] Updated doc --- EarthDiagnostics.pdf | Bin 184723 -> 194287 bytes doc/source/conf.py | 4 ++-- doc/source/developers.rst | 2 +- doc/source/index.rst | 2 +- doc/source/tutorial.rst | 2 +- earthdiagnostics/ocean/areamoc.py | 12 ++++++++++++ earthdiagnostics/ocean/averagesection.py | 15 +++++++++++++++ earthdiagnostics/ocean/convectionsites.py | 10 ++++++++++ earthdiagnostics/ocean/cutsection.py | 16 ++++++++++++++++ earthdiagnostics/ocean/gyres.py | 10 ++++++++++ earthdiagnostics/ocean/heatcontent.py | 13 +++++++++++++ earthdiagnostics/ocean/heatcontentlayer.py | 10 ++++++++++ earthdiagnostics/ocean/interpolate.py | 14 ++++++++++++++ earthdiagnostics/ocean/maxmoc.py | 13 ++++++++++++- .../ocean/mixedlayerheatcontent.py | 8 ++++++++ .../ocean/mixedlayersaltcontent.py | 8 ++++++++ earthdiagnostics/ocean/moc.py | 8 ++++++++ earthdiagnostics/ocean/psi.py | 8 ++++++++ earthdiagnostics/ocean/siasiesiv.py | 12 ++++++++++++ earthdiagnostics/ocean/verticalmean.py | 12 ++++++++++++ earthdiagnostics/ocean/verticalmeanmeters.py | 13 +++++++++++++ test/unit/test_constants.py | 3 --- test/unit/test_data_manager.py | 2 +- test/unit/test_experiment_manager.py | 2 +- 24 files changed, 188 insertions(+), 11 deletions(-) diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index eafb78207931b03678ab0522fa4ca4f9cc656c8c..dcacd076ed673273039f46503c7e313558caeecf 100644 GIT binary patch delta 72325 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

_9rWZU3ju7BCC0Gt(cziLX^-m=DhCZ} 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 Y2b=9YPQXElOWrCaL(a#iqN7Uwe;rS2(*OVf delta 63199 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 z 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 eU9m9{D07 z2(6mEZrY3CUN?(_2_JybME*CF;%^Fyy32Aq>eHhuiQ~?%9WmN4LjPfg^Mi%4GR>8$Z88V+{;>eA<1-7X+aKLa=LJ;$v| zHB-5_F*}^rt4?>kR@0BOvFgC<^QW%|S4O@o(~V@GIeL0}{X)P*`cx~$$H1wD*Wz1# zt=qlz*PP+!z^N05OwYy86Di*i!yW5t@8g{4)y$t3LA7H4IeXem$DrDRnu3~fqY)!2 zqn6Y@x)PzTy33P=@Uh&_3B#AOiZ{cC&r&_anAy9_t&OFPUXw`ZMxgL$ zn5!P@naIUj5mx~HF)vQzuKDq2gL@;)a=+Zq=|44^pQMVla$byELHpK1ePR%+2$?cQ zH%6LD_nCoep*HT3Bnobwnd1z}mopS}g@abu141Dg+b%953^X~l2s{@k~z&EY53kV1N!rB5H{l)m;>O7sI=)vy{ zuN>HqN>*aw0Jl@Z!;+%hZI?YKnaRG~kph|`S z6El+4P#WKUuyhy|Wo&X!I22Yk@(pfdqZp;rEc72A$@DI@~t3H3y==jC+!0e&w<+D`k5u zW-Q_{;GBtsk%M5?ksK>-E|QlxG;G)=I-aE_;Jn{kCQXEtP&(CGZq$msC6~x3YnBlx z@uUi^Sz@d{>sr53$sOdCj)nIpsIE=C#R^9e6EAI!2+9Y?vf>GX)@$Mbcdf}9(4ACD zZUGA*i6zO6){WMLmJds7m9DW~`l&Zb{MT^f=EO++=#4A8brAZB8@uTg?a;}Fv3hT& z3#u#h9wgD&IuO5=SQ4~TZ_@`d9Zhow)|q^{V`~;Lzv6@ebMD)uU47}Zr~w@2(Vtk5@>1#ZW1;!P z^l7vCf;H+N;?Hqcw?D3ilFJ;!=|7aZy8&+dQUot?Vx9Z3^#46N(O&pple6{ny;-@{ z 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 diff --git a/doc/source/conf.py b/doc/source/conf.py index 01d7691..6b92d8e 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -62,9 +62,9 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # built documents. # # The short X.Y version. -version = '3.0' +version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0' +release = '3.0.0b' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/developers.rst b/doc/source/developers.rst index 80dffab..0a259ae 100644 --- a/doc/source/developers.rst +++ b/doc/source/developers.rst @@ -23,7 +23,7 @@ If you have any doubts, or just want help to start the development, contact javi Developing a diagnostic ----------------------- -For new diagnsotics development, we have some advice to give: +For new diagnostics development, we have some advice to give: * Do not worry about performance at first, just create a version that works. Developers can help you to optimize it later. diff --git a/doc/source/index.rst b/doc/source/index.rst index 3b25442..4516651 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -7,7 +7,7 @@ Welcome to Earth Diagnostics's documentation! ============================================= .. toctree:: - :maxdepth: 2 + :maxdepth: 3 tutorial tips diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index ee5457b..2fb78b5 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -33,7 +33,7 @@ Call the diags with -h option to see if everything is ready: Creating a config file ---------------------- -If you go into the earthdiagnsotics folder in the git repository, you will see a diags.conf that can be used as a model +If you go into the earthdiagnostics folder in the git repository, you will see a diags.conf that can be used as a model for your config file. It contains commentaries explaining what represents each one of its parameters, so please read it carefully. diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index b149e83..a88e83f 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -19,6 +19,18 @@ class AreaMoc(Diagnostic): :created: March 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param basin: basin to compute + :type basin: Basin + :param box: box to compute + :type box: Box """ def __init__(self, data_manager, startdate, member, chunk, basin, box): diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 19cf2c7..0518ed9 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -15,6 +15,21 @@ class AverageSection(Diagnostic): :created: March 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: str + :param box: box to use for the average + :type box: Box + """ def __init__(self, data_manager, startdate, member, chunk, variable, domain, box): diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 6d86584..7719eda 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -16,6 +16,16 @@ class ConvectionSites(Diagnostic): :created: October 2013 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param nemo_version: NEMO's version + :type nemo_version: str """ def __init__(self, data_manager, startdate, member, chunk, nemo_version): diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index f3dc217..5eeda21 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -17,6 +17,22 @@ class CutSection(Diagnostic): :created: September 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: str + :param zonal: specifies if section is zonal or meridional + :type zonal: bool + :param value: value of the section's coordinate + :type value: int """ def __init__(self, data_manager, startdate, member, chunk, variable, domain, zonal, value): diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index be9580a..bcbb090 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -17,6 +17,16 @@ class Gyres(Diagnostic): :created: October 2013 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param nemo_version: NEMO's version + :type nemo_version: str """ def __init__(self, data_manager, startdate, member, chunk, nemo_version): Diagnostic.__init__(self, data_manager) diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index a22ce0f..3319c6d 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -20,6 +20,19 @@ class HeatContent(Diagnostic): :created: May 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param mixed_layer: If 1, restricts calculation to the mixed layer, if -1 exclude it. If 0, no effect + :type mixed_layer: int + :param box: box to use for the average + :type box: Box + """ def __init__(self, data_manager, startdate, member, chunk, basin, mixed_layer, box): diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 0219e8e..0fdd685 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -18,6 +18,16 @@ class HeatContentLayer(Diagnostic): :created: June 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param box: box to use for the calculations + :type box: Box """ def __init__(self, data_manager, startdate, member, chunk, box): diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 00fe6f0..2dbf978 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -18,6 +18,20 @@ class Interpolate(Diagnostic): :created: November 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: str + :param nemo_version: NEMO model version + :type nemo_version: str """ def __init__(self, data_manager, startdate, member, chunk, variable, domain, nemo_version): Diagnostic.__init__(self, data_manager) diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 24cac19..e28f7be 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -19,7 +19,18 @@ class MaxMoc(Diagnostic): :created: March 2012 :last modified: June 2016 - + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param year: year to compute + :type year: int + :param basin: basin to compute + :type basin: Basin + :param box: box to compute + :type box: Box """ def __init__(self, data_manager, startdate, member, year, basin, box): diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index 8c4fce8..dbba3ca 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -16,6 +16,14 @@ class MixedLayerHeatContent(Diagnostic): :created: February 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int """ def __init__(self, data_manager, startdate, member, chunk): diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 780d1c8..bd2d33b 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -15,6 +15,14 @@ class MixedLayerSaltContent(Diagnostic): :created: February 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int """ def __init__(self, data_manager, startdate, member, chunk): diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index d4485bb..73a8c8a 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -18,6 +18,14 @@ class Moc(Diagnostic): :created: March 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int """ def __init__(self, data_manager, startdate, member, chunk): diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 3f1989a..e498cfc 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -14,6 +14,14 @@ class Psi(Diagnostic): :created: March 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int """ def __init__(self, data_manager, startdate, member, chunk): Diagnostic.__init__(self, data_manager) diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index c069585..f9198f6 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -27,6 +27,18 @@ class Siasiesiv(Diagnostic): gphit = None def __init__(self, data_manager, basin, startdate, member, chunk, mask): + """ + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param mask: mask to use + :type mask: numpy.array + """ Diagnostic.__init__(self, data_manager) self.basin = basin if basin == Basins.Global: diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index bd79f86..42e3a92 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -17,6 +17,18 @@ class VerticalMean(Diagnostic): :created: February 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable to average + :type variable: str + :param box: box used to restrict the vertical mean + :type box: Box """ def __init__(self, data_manager, startdate, member, chunk, variable, box): diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 9bf768f..1b88f0c 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -15,6 +15,19 @@ class VerticalMeanMeters(Diagnostic): :created: February 2012 :last modified: June 2016 + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable to average + :type variable: str + :param box: box used to restrict the vertical mean + :type box: Box + """ def __init__(self, data_manager, startdate, member, chunk, variable, box): diff --git a/test/unit/test_constants.py b/test/unit/test_constants.py index 9ef9796..43f57c7 100644 --- a/test/unit/test_constants.py +++ b/test/unit/test_constants.py @@ -11,9 +11,6 @@ class TestBasins(TestCase): self.assertIsNone(Basins.parse('Basin not found')) - - - class TestBasin(TestCase): def setUp(self): diff --git a/test/unit/test_data_manager.py b/test/unit/test_data_manager.py index 8745c8e..b7e6410 100644 --- a/test/unit/test_data_manager.py +++ b/test/unit/test_data_manager.py @@ -2,7 +2,7 @@ from unittest import TestCase -from earthdiagnostics.datamanager import DataManager, Variable +from earthdiagnostics.datamanager import DataManager class TestDataManager(TestCase): diff --git a/test/unit/test_experiment_manager.py b/test/unit/test_experiment_manager.py index ccd433a..38e2272 100644 --- a/test/unit/test_experiment_manager.py +++ b/test/unit/test_experiment_manager.py @@ -6,7 +6,7 @@ from earthdiagnostics.experimentmanager import ExperimentManager class TestDataManager(TestCase): def setUp(self): - self.experiment_manager = ExperimentManager(('20000101', '20000201'), (0, 1), 5, 3, 3) + self.experiment_manager = ExperimentManager(['20000101', '20000201'], [0, 1], 5, 3, 3) def test_get_full_years(self): self.assertEquals([2000], self.experiment_manager.get_full_years('20000101')) -- GitLab From 2a5a09bb37736e830ac6e655bee2a6f4411570f1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 7 Jul 2016 17:33:29 +0200 Subject: [PATCH 122/268] Renamed NEMO_VERSION to MODEL_VERSION --- earthdiagnostics/constants.py | 2 ++ earthdiagnostics/diags.conf | 7 ++++--- earthdiagnostics/diags.py | 14 ++++++------- earthdiagnostics/ocean/convectionsites.py | 24 +++++++++++------------ earthdiagnostics/ocean/gyres.py | 16 +++++++-------- earthdiagnostics/ocean/interpolate.py | 14 ++++++------- 6 files changed, 40 insertions(+), 37 deletions(-) diff --git a/earthdiagnostics/constants.py b/earthdiagnostics/constants.py index 19866ca..8fe7403 100644 --- a/earthdiagnostics/constants.py +++ b/earthdiagnostics/constants.py @@ -231,6 +231,8 @@ class Models(object): """ EC-Earth 3 ORCA0.25 L46 """ ECEARTH_3_0_O25L75 = 'Ec3.0_O25L75' """ EC-Earth 3 ORCA0.25 L75 """ + ECEARTH_3_1_O25L75 = 'Ec3.1_O25L75' + """ EC-Earth 3.1 ORCA0.25 L75 """ NEMO_3_2_O1L42 = 'N3.2_O1L42' """ NEMO 3.2 ORCA1 L42 """ diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 9a3d24a..0071f86 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -15,7 +15,7 @@ CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -MAX_CORES = 4 +# MAX_CORES = 4 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False @@ -37,6 +37,8 @@ ATMOSPHERE_FILES = True # Experiments parameters as defined in CMOR standard INSTITUTE = BSC MODEL = NEMO +# Model version +MODEL_VERSION = N3.6_O1L75 # For those who use Autosubmit, this no need documentation # For those who not, EXPID is the unique identifier of the experiment. @@ -53,8 +55,7 @@ CHUNK_SIZE = 12 # CHUNKS = 58 CHUNKS = 58 -# Model version -NEMO_VERSION = N3.6_O1L75 + # This ALIAS section is a bit different # Inside this, you can provide alias for frequent diagnostics calls. diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index ce40972..d1b7a9d 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -187,23 +187,23 @@ class Diags(object): def _prepare_mesh_files(self): Log.info('Copying mesh files') - self._copy_file(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.nemo_version)), 'mesh_hgr.nc', + self._copy_file(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.model_version)), 'mesh_hgr.nc', self.restore_meshes) self._link_file('mesh_hgr.nc', 'mesh_zgr.nc') self._link_file('mesh_hgr.nc', 'mask.nc') - self._copy_file(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.nemo_version)), 'new_maskglo.nc', + self._copy_file(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.model_version)), 'new_maskglo.nc', self.restore_meshes) - self._copy_file(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.nemo_version)), + self._copy_file(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.model_version)), 'mask_regions.nc', self.restore_meshes) - self._copy_file(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.nemo_version)), + self._copy_file(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.model_version)), 'mask_regions.3d.nc', self.restore_meshes) Log.result('Mesh files ready!') def _copy_file(self, source, destiny, force): if not os.path.exists(source): - Log.user_warning('File {0} is not available for {1}', destiny, self.nemo_version) + Log.user_warning('File {0} is not available for {1}', destiny, self.model_version) return if not force and os.path.exists(destiny): @@ -218,7 +218,7 @@ class Diags(object): def _link_file(self, source, destiny): if not os.path.exists(source): - Log.user_warning('File {0} is not available for {1}', destiny, self.nemo_version) + Log.user_warning('File {0} is not available for {1}', destiny, self.model_version) return if os.path.lexists(destiny): @@ -261,7 +261,7 @@ class Diags(object): self.model = self.parser.get_option('EXPERIMENT', 'MODEL') self.nfrp = self.parser.get_int_option('EXPERIMENT', 'NFRP') - self.nemo_version = self.parser.get_option('EXPERIMENT', 'NEMO_VERSION') + self.model_version = self.parser.get_option('EXPERIMENT', 'MODEL_VERSION') self.add_name = self.parser.get_bool_option('CMOR', 'ADD_NAME') self.add_startdate = self.parser.get_bool_option('CMOR', 'ADD_STARTDATE') diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 7719eda..b77da26 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -24,16 +24,16 @@ class ConvectionSites(Diagnostic): :type member: int :param chunk: chunk's number :type chunk: int - :param nemo_version: NEMO's version - :type nemo_version: str + :param model_version: model version + :type model_version: str """ - def __init__(self, data_manager, startdate, member, chunk, nemo_version): + def __init__(self, data_manager, startdate, member, chunk, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk - self.nemo_version = nemo_version + self.model_version = model_version self.required_vars = ['vsftbarot'] self.generated_vars = ['gyres'] @@ -55,26 +55,26 @@ class ConvectionSites(Diagnostic): raise Exception('The convection sites diagnostic has no options') job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.nemo_version)) + job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.model_version)) return job_list def compute(self): """ Runs the diagnostic """ - if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, - Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, - Models.NEMOVAR_O1L42]: + if self.model_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, + Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, + Models.NEMOVAR_O1L42]: labrador = [225, 245, 215, 255] irminger = [245, 290, 215, 245] gin = [260, 310, 245, 291] wedell = [225, 280, 1, 50] - elif self.nemo_version in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, - Models.GLORYS2_V1_O25L75]: - raise Exception("Option convection not available yet for {0}".format(self.nemo_version)) + elif self.model_version in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, + Models.GLORYS2_V1_O25L75]: + raise Exception("Option convection not available yet for {0}".format(self.model_version)) else: - raise Exception("Input grid {0} not recognized".format(self.nemo_version)) + raise Exception("Input grid {0} not recognized".format(self.model_version)) mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) output = TempFile.get() diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index bcbb090..389a053 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -25,15 +25,15 @@ class Gyres(Diagnostic): :type member: int :param chunk: chunk's number :type chunk: int - :param nemo_version: NEMO's version - :type nemo_version: str + :param model_version: model version + :type model_version: str """ - def __init__(self, data_manager, startdate, member, chunk, nemo_version): + def __init__(self, data_manager, startdate, member, chunk, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk - self.nemo_version = nemo_version + self.model_version = model_version self.required_vars = ['vsftbarot'] self.generated_vars = ['gyres'] @@ -56,7 +56,7 @@ class Gyres(Diagnostic): raise Exception('The gyres diagnostic has no options') job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.nemo_version)) + job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.model_version)) return job_list # noinspection PyPep8Naming @@ -64,7 +64,7 @@ class Gyres(Diagnostic): """ Runs the diagnostic """ - if self.nemo_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, + if self.model_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, Models.NEMOVAR_O1L42]: @@ -79,9 +79,9 @@ class Gyres(Diagnostic): elif self in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, Models.GLORYS2_V1_O25L75]: - raise Exception("Option gyres not available yet for {0}".format(self.nemo_version)) + raise Exception("Option gyres not available yet for {0}".format(self.model_version)) else: - raise Exception("Input grid {0} not recognized".format(self.nemo_version)) + raise Exception("Input grid {0} not recognized".format(self.model_version)) output = TempFile.get() vsftbarot_file = self.data_manager.get_file('ocean', 'vsftbarot', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 2dbf978..6b9db86 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -30,17 +30,17 @@ class Interpolate(Diagnostic): :type variable: str :param domain: variable's domain :type domain: str - :param nemo_version: NEMO model version - :type nemo_version: str + :param model_version: model version + :type model_version: str """ - def __init__(self, data_manager, startdate, member, chunk, variable, domain, nemo_version): + def __init__(self, data_manager, startdate, member, chunk, variable, domain, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.variable = variable self.domain = domain - self.nemo_version = nemo_version + self.model_version = model_version self.required_vars = [variable] self.generated_vars = [variable] self.tempTemplate = '' @@ -74,7 +74,7 @@ class Interpolate(Diagnostic): job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(Interpolate(diags.data_manager, startdate, member, chunk, - variable, domain, diags.nemo_version)) + variable, domain, diags.model_version)) return job_list def compute(self): @@ -115,7 +115,7 @@ class Interpolate(Diagnostic): temp2 = TempFile.get() cdo.setgrid('t106grid', input=temp, output=temp2) os.remove(temp) - if self.nemo_version[6:9] == '025': + if self.model_version[6:9] == '025': cdo.invertlatdata(input=temp2, output=temp2) if not has_levels: nco.ncks(input=temp2, output=temp2, options='-O -v sic,lat,lon,time') @@ -141,7 +141,7 @@ class Interpolate(Diagnostic): scrip_use_in = open(namelist_file, 'w') scrip_use_in.writelines("&remap_inputs\n") scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" - "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(self.nemo_version, lev + 1)) + "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(self.model_version, lev + 1)) scrip_use_in.writelines(" infile = '{0}'\n".format(temp)) scrip_use_in.writelines(" invertlat = FALSE\n") scrip_use_in.writelines(" var = '{0}'\n".format(self.variable)) -- GitLab From 55aa798f5f42e73c84bf182a8aa276e091fab99a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 8 Jul 2016 16:39:02 +0200 Subject: [PATCH 123/268] Ordered cmorization, some cleanup and minor refactoring --- earthdiagnostics/cmor_table.csv | 3 +- earthdiagnostics/datamanager.py | 48 ++++++++++++++++++++--------- earthdiagnostics/ocean/siasiesiv.py | 4 --- earthdiagnostics/utils.py | 2 ++ testing_diags_moore.job | 4 +-- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 4359ca2..18c37ca 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -144,7 +144,7 @@ snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow Volume per gridcell area u so20chgt,t20d,depth_of_isosurface_of_sea_water_potential_temperature,,ocean, sobowlin,bowlin,bowl_index,Bowl Index,ocean, sohefldo,hfds,surface_downward_heat_flux_in_sea_water,Downward Heat Flux at Sea Water Surface,ocean, -sohtatl,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, +sohtatl,hfbasin,sobarstf,Northward Ocean Heat Transport,ocean, sohtind,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, sohtipc,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, sohtpac,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, @@ -259,3 +259,4 @@ smlt,snm,surface_snow_melt_flux,Surface Snow Melt,landIce, src,src,skin_reservoir_content,Skin reservoir content,land, w,wa,vertical_velocity,Vertical velocity,atmos, iocewflx,,,,seaIce, +sobarstf,vsftbarot,ocean_barotropic_volume_streamfunction,Ocean Barotropic Volume Streamfunction ,ocean, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 1771587..967830e 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -91,10 +91,8 @@ class DataManager(object): created = True Log.info('CMORizing startdate {0} member {1}', startdate, member_str) if ocean: - path_MMO = os.path.join(self.data_dir, self.expid, 'original_files', startdate, - member_str, 'outputs', 'MMO*') - for tarfile in glob.glob(path_MMO): - self._unpack_tar(member, startdate, tarfile) + self._unpack_ocean_files('MMO', startdate, member) + self._unpack_ocean_files('diags', startdate, member) if not atmosphere: continue @@ -105,7 +103,7 @@ class DataManager(object): for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, member_str, 'outputs', 'MMA*')): - self._unpack_tar(member, startdate, tarfile) + self._unpack_tar(tarfile, startdate, member) else: self._cmorize_grib(startdate, member, gribfiles) Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str) @@ -125,6 +123,14 @@ class DataManager(object): self._unpack_cmorfiles(filepaths, member_path) + def _unpack_ocean_files(self, prefix, startdate, member): + tar_folder = os.path.join(self.data_dir, self.expid, 'original_files', startdate, + self.exp_manager.get_member_str(member), 'outputs', '{0}*'.format(prefix)) + tar_files = glob.glob(tar_folder) + tar_files.sort() + for tarfile in tar_files: + self._unpack_tar(tarfile, startdate, member) + def _cmorize_grib(self, startdate, member, gribfiles): gribfiles.sort() copied_gribfiles = list() @@ -383,7 +389,7 @@ class DataManager(object): t.start() for t in threads: t.join() - filepaths = glob.glob(os.path.join(member_path, '*.tar')) + filepaths = glob.glob(os.path.join(member_path, '*.tar')).sort() for numthread in range(0, numthreads): t = threading.Thread(target=DataManager._untar, args=(filepaths[numthread::numthreads], member_path)) @@ -416,7 +422,7 @@ class DataManager(object): Log.info('Moving {0} to {1}'.format(filename, good)) Utils.move_file(filepath, good) - def _unpack_tar(self, member, startdate, tarfile): + def _unpack_tar(self, tarfile, startdate, member): Log.info('Unpacking {0}', tarfile) scratch_dir = os.path.join(self.scratch_dir, 'CMOR') @@ -456,7 +462,10 @@ class DataManager(object): def _cmorize_nc_file(self, filename, member, startdate): Log.info('Processing file {0}', filename) file_parts = os.path.basename(filename).split('_') - frequency = file_parts[1][1].lower() + if self.expid in [file_parts[1], file_parts[2]]: + frequency = 'm' + else: + frequency = file_parts[1][1].lower() variables = dict() variables['time_counter'] = 'time' variables['time_counter_bnds'] = 'time_bnds' @@ -529,10 +538,6 @@ class DataManager(object): Utils.copy_variable(handler, handler_cmor, 'leadtime', False) handler_cmor.modeling_realm = var_cmor.domain handler_cmor.table_id = 'SPECS_' + self.domain_abbreviation(var_cmor.domain, frequency) - var_handler = handler_cmor.variables[variable] - var_handler.short_name = var_cmor.short_name - var_handler.standard_name = var_cmor.standard_name - var_handler.long_name = var_cmor.long_name handler_cmor.close() if frequency == 'd': frequency = 'day' @@ -817,21 +822,36 @@ class DataManager(object): Utils.move_file(temp, filetosend) Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') + cmor_var = Variable.get_variable(var) + if cmor_var: + handler = Utils.openCdf(filetosend) + var_handler = handler.variables[var] + var_handler.standard_name = cmor_var.standard_name + var_handler.long_name = cmor_var.long_name + var_handler.short_name = cmor_var.short_name + handler.sync() + handler.close() + temp = TempFile.get() Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) shutil.move(temp, filetosend) Utils.move_file(filetosend, filepath) + self._create_link(domain, filepath, frequency, var) + + def _create_link(self, domain, filepath, frequency, var): if frequency in ('d', 'daily', 'day'): freq_str = 'daily_mean' else: freq_str = 'monthly_mean' if domain in ['ocean', 'seaIce']: - link_path = os.path.join(self.data_dir, self.expid, freq_str, '{0}_f6h'.format(var)) + variable_folder = var + '_f6h' else: - link_path = os.path.join(self.data_dir, self.expid, freq_str, '{0}_f{1}h'.format(var, self.nfrp)) + variable_folder = var + '_f' + str(self.nfrp) +'h' + + link_path = os.path.join(self.data_dir, self.expid, freq_str, variable_folder) if not os.path.exists(link_path): # This can be a race condition diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index f9198f6..7feae9a 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -41,10 +41,6 @@ class Siasiesiv(Diagnostic): """ Diagnostic.__init__(self, data_manager) self.basin = basin - if basin == Basins.Global: - self._region = None - else: - self._region = basin.shortname self.startdate = startdate self.member = member self.chunk = chunk diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 77996cc..99edf0b 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -265,6 +265,8 @@ class Utils(object): return if variable in destiny.variables.keys(): return + if not must_exist and not set(source.variables[variable].dimensions).issubset(destiny.dimensions): + return original_var = source.variables[variable] new_var = destiny.createVariable(variable, original_var.datatype, original_var.dimensions) new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) diff --git a/testing_diags_moore.job b/testing_diags_moore.job index 8ca88b0..1d91730 100755 --- a/testing_diags_moore.job +++ b/testing_diags_moore.job @@ -1,8 +1,8 @@ #!/bin/bash #SBATCH --time=24:00:00 #SBATCH -n 8 -#SBATCH --error=/home/Earth/jvegas/job.%J.err -#SBATCH --output=/home/Earth/jvegas/job.%J.out +#SBATCH --error=~/job.%J.err +#SBATCH --output=~/job.%J.out set -xv -- GitLab From 765088585c794ea00123ae8418b170b082495754 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 8 Jul 2016 16:41:20 +0200 Subject: [PATCH 124/268] Refactored concat to use str format. Minor formatting to comply with style guide --- earthdiagnostics/datamanager.py | 4 ++-- earthdiagnostics/ocean/gyres.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 967830e..8a230c4 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -847,9 +847,9 @@ class DataManager(object): freq_str = 'monthly_mean' if domain in ['ocean', 'seaIce']: - variable_folder = var + '_f6h' + variable_folder = '{0}_f6h'.format(var) else: - variable_folder = var + '_f' + str(self.nfrp) +'h' + variable_folder = '{0}_f{1}h'.format(var, self.nfrp) link_path = os.path.join(self.data_dir, self.expid, freq_str, variable_folder) diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 389a053..4f701e8 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -65,8 +65,8 @@ class Gyres(Diagnostic): Runs the diagnostic """ if self.model_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, - Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, - Models.NEMOVAR_O1L42]: + Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, + Models.NEMOVAR_O1L42]: subpolNAtl = [230, 275, 215, 245] subpolNPac = [70, 145, 195, 235] -- GitLab From cfb0e2cbb734fda7bfc6a41363519f800f8fa4c2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 8 Jul 2016 17:57:27 +0200 Subject: [PATCH 125/268] Moved diag alias definition to diagnostic class from diags.py --- earthdiagnostics/cmor_table.csv | 6 ++++ earthdiagnostics/datamanager.py | 24 ++++++++++++-- earthdiagnostics/diagnostic.py | 11 +++++-- earthdiagnostics/diags.py | 32 +++++++++---------- earthdiagnostics/ocean/areamoc.py | 3 ++ earthdiagnostics/ocean/averagesection.py | 3 ++ earthdiagnostics/ocean/convectionsites.py | 3 ++ earthdiagnostics/ocean/cutsection.py | 3 ++ earthdiagnostics/ocean/gyres.py | 4 +++ earthdiagnostics/ocean/heatcontent.py | 6 +++- earthdiagnostics/ocean/heatcontentlayer.py | 5 ++- earthdiagnostics/ocean/interpolate.py | 4 +++ earthdiagnostics/ocean/maxmoc.py | 3 ++ .../ocean/mixedlayerheatcontent.py | 3 ++ .../ocean/mixedlayersaltcontent.py | 2 ++ earthdiagnostics/ocean/moc.py | 3 ++ earthdiagnostics/ocean/psi.py | 4 +++ earthdiagnostics/ocean/siasiesiv.py | 3 ++ earthdiagnostics/ocean/verticalmean.py | 3 ++ earthdiagnostics/ocean/verticalmeanmeters.py | 3 ++ 20 files changed, 104 insertions(+), 24 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 18c37ca..cfabd38 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -260,3 +260,9 @@ src,src,skin_reservoir_content,Skin reservoir content,land, w,wa,vertical_velocity,Vertical velocity,atmos, iocewflx,,,,seaIce, sobarstf,vsftbarot,ocean_barotropic_volume_streamfunction,Ocean Barotropic Volume Streamfunction ,ocean, +sivols,sivols,sea_ice_volume,total volume of sea ice in the Southern hemisphere,seaIce, +sivoln,sivoln,sea_ice_volume,total volume of sea ice in the Northern hemisphere,seaIce, +siextentn,siextentn,sea_ice_extent,Total area of all Northern-Hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce, +siextents,siextents,sea_ice_extent,Total area of all Southern-Hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce, +siarean,siarean,sea_ice_area,total area of sea ice in the Northern hemisphere,seaIce, +siareas,siareas,sea_ice_area,total area of sea ice in the Southern hemisphere,seaIce, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 8a230c4..dc9a66f 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -100,10 +100,17 @@ class DataManager(object): member_str, 'outputs', '*.grb') gribfiles = glob.glob(grb_path) if len(gribfiles) == 0: - for tarfile in glob.glob(os.path.join(self.data_dir, self.expid, 'original_files', startdate, - member_str, - 'outputs', 'MMA*')): + + tar_files = glob.glob( + os.path.join(self.data_dir, self.expid, 'original_files', startdate, member_str, 'outputs', + 'MMA*')) + tar_files.sort() + count = 1 + for tarfile in tar_files: + Log.info('Unpacking atmospheric file {0}/{1}'.format(count, len(tar_files))) self._unpack_tar(tarfile, startdate, member) + count += 1 + Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) else: self._cmorize_grib(startdate, member, gribfiles) Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str) @@ -128,8 +135,12 @@ class DataManager(object): self.exp_manager.get_member_str(member), 'outputs', '{0}*'.format(prefix)) tar_files = glob.glob(tar_folder) tar_files.sort() + count = 1 for tarfile in tar_files: + Log.info('Unpacking oceanic file {0}/{1}'.format(count, len(tar_files))) self._unpack_tar(tarfile, startdate, member) + count += 1 + Log.result('Oceanic file {0}/{1} finished'.format(count, len(tar_files))) def _cmorize_grib(self, startdate, member, gribfiles): gribfiles.sort() @@ -137,7 +148,10 @@ class DataManager(object): for gribfile in gribfiles: shutil.copy(gribfile, os.path.join(self.scratch_dir, os.path.basename(gribfile))) copied_gribfiles.append(os.path.join(self.scratch_dir, os.path.basename(gribfile))) + + count = 1 for gribfile in copied_gribfiles: + Log.info('Unpacking atmospheric grib file {0}/{1}'.format(count, len(copied_gribfiles))) cdo = Utils.cdo start = parse_date(gribfile[-10:-4]) month = '{0:02}'.format(start.month) @@ -329,6 +343,10 @@ class DataManager(object): for splited_file in glob.glob('{0}_???.128.grb'.format(gribfile)): os.remove(splited_file) + + count += 1 + Log.result('Atmospheric grib file {0}/{1} finished'.format(count, len(copied_gribfiles))) + chunk_start = parse_date(startdate) while os.path.exists(os.path.join(self.scratch_dir, 'ICMGG{0}+{1}.grb'.format(self.expid, diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 006e6ce..612b921 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -8,6 +8,11 @@ class Diagnostic(object): :type data_manager: DataManager """ + alias = None + """ + Alias to call the diagnostic. Must be overridden at the derived clases + """ + def __init__(self, data_manager): self.data_manager = data_manager self.required_vars = [] @@ -15,7 +20,7 @@ class Diagnostic(object): self.can_run_multiple_instances = True @staticmethod - def register(cls, alias): + def register(cls): """ Register a new diagnostic using the given alias. It must be call using the derived class. :param cls: diagnostic class to register @@ -24,10 +29,10 @@ class Diagnostic(object): :type alias: str """ try: - Diagnostic._diag_list[alias] = cls + Diagnostic._diag_list[cls.alias] = cls except AttributeError: Diagnostic._diag_list = dict() - Diagnostic._diag_list[alias] = cls + Diagnostic._diag_list[cls.alias] = cls # noinspection PyProtectedMember @staticmethod diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index d1b7a9d..2dea0db 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -62,22 +62,22 @@ class Diags(object): self._prepare_mesh_files() - Diagnostic.register(MixedLayerSaltContent, 'mlotstsc') - Diagnostic.register(Siasiesiv, 'siasiesiv') - Diagnostic.register(VerticalMean, 'vertmean') - Diagnostic.register(VerticalMeanMeters, 'vertmeanmeters') - Diagnostic.register(Interpolate, 'interp') - Diagnostic.register(Moc, 'moc') - Diagnostic.register(AreaMoc, 'mocarea') - Diagnostic.register(MaxMoc, 'mocmax') - Diagnostic.register(Psi, 'psi') - Diagnostic.register(Gyres, 'gyres') - Diagnostic.register(ConvectionSites, 'convection') - Diagnostic.register(CutSection, 'cutsection') - Diagnostic.register(AverageSection, 'avgsection') - Diagnostic.register(MixedLayerHeatContent, 'mlotsthc') - Diagnostic.register(HeatContentLayer, 'ohclayer') - Diagnostic.register(HeatContent, 'ohc') + Diagnostic.register(MixedLayerSaltContent) + Diagnostic.register(Siasiesiv) + Diagnostic.register(VerticalMean) + Diagnostic.register(VerticalMeanMeters) + Diagnostic.register(Interpolate) + Diagnostic.register(Moc) + Diagnostic.register(AreaMoc) + Diagnostic.register(MaxMoc) + Diagnostic.register(Psi) + Diagnostic.register(Gyres) + Diagnostic.register(ConvectionSites) + Diagnostic.register(CutSection) + Diagnostic.register(AverageSection) + Diagnostic.register(MixedLayerHeatContent) + Diagnostic.register(HeatContentLayer) + Diagnostic.register(HeatContent) parse_date('20000101') diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index a88e83f..4ffb8c8 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -33,6 +33,9 @@ class AreaMoc(Diagnostic): :type box: Box """ + alias = 'mocarea' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, basin, box): Diagnostic.__init__(self, data_manager) self.basin = basin diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 0518ed9..4b91a29 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -32,6 +32,9 @@ class AverageSection(Diagnostic): """ + alias = 'avgsection' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, variable, domain, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index b77da26..10b674c 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -28,6 +28,9 @@ class ConvectionSites(Diagnostic): :type model_version: str """ + alias = 'convection' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index 5eeda21..2da67d0 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -35,6 +35,9 @@ class CutSection(Diagnostic): :type value: int """ + alias = 'cutsection' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, variable, domain, zonal, value): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 4f701e8..3187999 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -28,6 +28,10 @@ class Gyres(Diagnostic): :param model_version: model version :type model_version: str """ + + alias = 'gyres' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index 3319c6d..df80de7 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -35,6 +35,9 @@ class HeatContent(Diagnostic): """ + alias = 'ohc' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, basin, mixed_layer, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate @@ -57,7 +60,8 @@ class HeatContent(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: None + :param options: basin, mixed layer option (1 to only compute at the mixed layer, -1 to exclude it, 0 to ignore), + minimum depth, maximum depth :type options: list[str] :return: """ diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 0fdd685..d39e92d 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -30,6 +30,9 @@ class HeatContentLayer(Diagnostic): :type box: Box """ + alias = 'ohclayer' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate @@ -50,7 +53,7 @@ class HeatContentLayer(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: None + :param options: minimum depth, maximum depth :type options: list[str] :return: """ diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 6b9db86..17dcdcb 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -33,6 +33,10 @@ class Interpolate(Diagnostic): :param model_version: model version :type model_version: str """ + + alias = 'interp' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, variable, domain, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index e28f7be..11beb3f 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -33,6 +33,9 @@ class MaxMoc(Diagnostic): :type box: Box """ + alias = 'mocmax' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, year, basin, box): Diagnostic.__init__(self, data_manager) self.basin = basin diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index dbba3ca..72d6243 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -26,6 +26,9 @@ class MixedLayerHeatContent(Diagnostic): :type chunk: int """ + alias = 'mlotsthc' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index bd2d33b..4b460fa 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -24,6 +24,8 @@ class MixedLayerSaltContent(Diagnostic): :param chunk: chunk's number :type chunk: int """ + alias = 'mlotstsc' + "Diagnostic alias for the configuration file" def __init__(self, data_manager, startdate, member, chunk): Diagnostic.__init__(self, data_manager) diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index 73a8c8a..c51a0c3 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -28,6 +28,9 @@ class Moc(Diagnostic): :type chunk: int """ + alias = 'moc' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index e498cfc..24db1e0 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -23,6 +23,10 @@ class Psi(Diagnostic): :param chunk: chunk's number :type chunk: int """ + + alias = 'psi' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 7feae9a..8434691 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -22,6 +22,9 @@ class Siasiesiv(Diagnostic): :last modified: June 2016 """ + alias = 'siasiesiv' + "Diagnostic alias for the configuration file" + e1t = None e2t = None gphit = None diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 42e3a92..9398842 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -31,6 +31,9 @@ class VerticalMean(Diagnostic): :type box: Box """ + alias = 'vertmean' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, variable, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 1b88f0c..911bc1f 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -30,6 +30,9 @@ class VerticalMeanMeters(Diagnostic): """ + alias = 'vertmeanmeters' + "Diagnostic alias for the configuration file" + def __init__(self, data_manager, startdate, member, chunk, variable, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate -- GitLab From d41a516b48c363cc72f097eb677c3c3ccbb98b9f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 8 Jul 2016 18:01:32 +0200 Subject: [PATCH 126/268] Moved initialization of variables dictionary to data_manager constructor to avoid race conditions --- earthdiagnostics/datamanager.py | 39 +++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index dc9a66f..0f10fbf 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -63,6 +63,7 @@ class DataManager(object): self.scratch_dir = scratch_dir self.nfrp = nfrp self.exp_manager = exp_manager + Variable.load_variables() # noinspection PyPep8Naming def prepare_CMOR_files(self, force_rebuild, ocean, atmosphere): @@ -972,6 +973,7 @@ class Variable(object): self.long_name = line[3] self.domain = line[4] self.basin = Basins.parse(line[5]) + self._dict_variables = None @classmethod def get_variable(cls, original_name): @@ -984,24 +986,27 @@ class Variable(object): """ try: return Variable._dict_variables[original_name.lower()] - - except AttributeError: - Variable._dict_variables = dict() - with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'cmor_table.csv'), 'rb') as csvfile: - reader = csv.reader(csvfile, dialect='excel') - for line in reader: - if line[0] == 'variable': - continue - - var = Variable(line) - if not var.short_name: - continue - for old_name in line[0].split(':'): - Variable._dict_variables[old_name] = var - Variable._dict_variables[var.short_name] = var - return Variable.get_variable(original_name) - except KeyError: Log.error('Variable {0} is not defined'.format(original_name)) return None + @classmethod + def load_variables(cls): + """ + Loads the cmor_table.csv and creates the variables dictionary + :return: + """ + Variable._dict_variables = dict() + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'cmor_table.csv'), 'rb') as csvfile: + reader = csv.reader(csvfile, dialect='excel') + for line in reader: + if line[0] == 'variable': + continue + + var = Variable(line) + if not var.short_name: + continue + for old_name in line[0].split(':'): + Variable._dict_variables[old_name] = var + Variable._dict_variables[var.short_name] = var + -- GitLab From c71593323e50c535fb646cfd457740c060e151df Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 12 Jul 2016 09:45:45 +0200 Subject: [PATCH 127/268] Bump version and update doc --- EarthDiagnostics.pdf | Bin 194287 -> 197355 bytes VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/diags.py | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index dcacd076ed673273039f46503c7e313558caeecf..b08247877738346636db2f7dbb527f0e5817701d 100644 GIT binary patch delta 79398 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

f@Oe1I3c&&!81$wxUO=G{7M!B0 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 A3IG5A delta 76306 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

{wp%2i}c`ALu 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%0ARX=_`8Yi6Gij?qShP$(+ zUDtrcVXd}&gx5g;^U(}!_grE8vEp`z%aqu_4(X{+V-bHqcM*st{u^@~`k*b3{w9hQ z);F7$-NfX+|1lzMmI34=Kjn#eE4OH2Ke6_)b)avn_c|9(n~|)evTz`ttzVQabXM@}EAy$hjOQN@c+t2{#Ug1`*L-_n@%Dw=c_V%ez5IfW7rpn{&JtF@; zC0iqfzttkB?eXDe?W3&OBeh^%P;mN!$ISJ_6j&1J(`rLG!Fcwv(b@I)ur-W6l*S3P!UviX2PF&){dIi^h6x6>Z{ z^tMd2OEGVq5I9X627joZ^hPR7nrue&-pfwB=ATQ)d~%*u**PD z%OFedh%jU2-E&G|Nl0f?oBlGiWi0!dM)5Aos!lX|-&f*ndI1xplfUeTfJC!@`6T48qg$_{2z3Co{Rz9u}ooU8Ip)qp5 zrWw@M4E?SPgWeijw-bo7hY}%V?42oh5td3>JY$&HBhwfOoFTrfNxCyJm7?Sw?*QZa#`j>m0t?*xJ{5@mN}g^6*nu$_bYdzn9UgS0~w3 zbKP_tZd>mn4Pkjp<12+u>Kw5<1ZbV}p1of{(^x|2td>|x`OF$sXdr2#ia&sK6D?NR z>{CvTJ_ze%VA{y>NP!(a)~_1_H5;??t8nJ$9gWj`H5+9bgqd8K1kHMJ{){x9JmfdS zU>wOeN`ROW_&2HNcLYdE(@hV#KL3Y8ds^5ma9nP`YAOmvj)Yj2d6Br{t?rJ!*brv{Was z><@`TZxR8@_XSHQa$(^1g$-tar5-TS-PpC8(K~XAE}vSPh&g91xThY`Y*FoWX=dmV z)gPnC4n{4=O6Scl<)$Q&?s}GGRYeNL=(Q zj*|MeX~eqR6HI}xKSHN+^%tNWaxcP+l=yD~hAxp8u5goGc?1?R}1cRMQ{j z`2%>~d4DK~DBA}!->FyJi;tIx6_$GDvNb|j+GWfvNtoV};=dsvK>;aP0 z1}%!I=4~ftBI42nZ=DIqYNZuxe-Cra6;l)gD*+e)I?G(QN-SzJ@~+-Y`1E~9@BGL; zlGj_ltho86@e~qzhkzm@;hM!Hy92dz^Hy^piRn975=c`{R;6{dl{V@WVj-4tEUu9m z(+Fu|T!n;8AtkA3)@YJ%YD5V{bLyP!t$&fjhM;o4@e>P?3l+>2dn^7!NqJ~$y0oMS zn?$X2lm7i?(H96netGtzE6ToAo=9?h7CovO3PA|PkIYLhWom8KL2|_;`R=7f1Z?l% z(Il-w91d0UT&Y3%v=Cx|swbxT*ySG))uv6?rK25bwaL(?Vq^JluH2@!G0&Ez5z?Y$|E=H5+?eJ$l3%jQ;cL>CnDvxT)NT_o+5HDGXM;uf}9KLvmk zHb%`=`~vuN&-qfOIqq8w)v|S0=J~WiWI}!-z3xT zV06YNWdj8~1X!wgC%DA3HXjp4HOH4QKaC(!|FTq(x(Mv{j$MqlxjYkfsmY>^?LV}R zT~rZdWUu=Hrbrz8;O1Ann^aWG)kO<#Ps zbqPA3gJN6}L#47Afw-C|neh5wm5v3y+MX|6I=xnBYKzC9)y^HYv~t2S0k{RAKqAW3 zq!0bg>(HQ?)JS}`zIN;zv1KHb;K;C@i*fm^Df-l5ruCB$5cadEFS-~*({&ke!R*Rc z9UDWG3w{c_Z=Bjy%o>RNFZPDKADLX z^Y59?E4w`_75j^Vp1eraZp`Y|mW5VXTTWbyou_VbwOn`E9$ICgy~u?)q}i5toWd_V z$qsS6;x|6LGG2&^yc)eL_U*^x`o|tb>0h%~icah>vmRD={}i0CMSSvj<`VQB@7sSN zqQ!rK6}K>x|M#uRpTd3%3%~;M1NBhZRIR+tsM%ln*J&~j?`vTm6;w7^dvk|Z zJs;n{MG0yhK~8>tF+M(SF5utIvs^$?QC61wK7z_ z!4H(4VOY0#Xzjxd?)uWuG(b6K2mIw$s-U`5(M;i9B1v^Ly^PX2n}?N0LbaOjE@c;H zzHFJjDAdrTCb%^_6DJgB;V;YS|EFNlx4|=dFH_uF=U1b()BvUOhde@IKmoaG)W?;d zBw~ssD=JahR7RW89&4$1?*^2Hy%rGix>kd_^&$5}w^zdt>nSMFpS(r&hKBT% zKj&(7AZ3;$y})uu7Pn2|@Z~j`mCFk!SBj19-5xgbn zKdj3^52y5k0b!@el)XBqJc5D6r}Cr5=%ila(Snl`Li5_y7|`$^dVLogO%{E_V=n9D_GUjd;x*{#tfLR4sIg znmQ-|9hL)m@ZU^0gqko&6Wy3y9zvrK3PvjZaP{_>p01aZK|ltG2-*a~%oqxc2BZPe z%zMdG(Jl;MzidFhw3WLGoXw1GbLP@6?973M)#%B+sG2CRapj5grI+;7I8*oageQ`9 zeR6ch^Sn~9hhb|QvYYI^o?YQ1;k^mXSVmd3No?(2vUO(j3{yA`OId#--y_NgAGVH6 z9%AB1{<%w*521J+#GDz_>PYVfUX2^z!y@`aqx*Hl5uvh&y9u+Z3&WGZzK5j=qpF+2 zlVUYKWpC!cE-to_C#<3^0{@+S8HjUpne5`N#Ox_P^Wy4{_Ff<05v}&q+}*O2X7>)Ix-Z;9L27TXoY6%97X_YeS@_>3*h z;r^S|s0<$%u2)a5L;pJ_!f{!9z(TmggnZWD(EC^9f&PYGHL(~pfA+~y(bt1;G_VvA2zQ5x-_6DcfgFpf4~aZ?(2^z&y<}F2T~o{CF+7dzoTnH z*Z9Mv8#K4h&6n1)_VV`Fox;AW+!4>dm&}pqxZBSYkFrbL6FzR8#dGQCdmAb1Nx^YD z6+|ejOEo@-3057x40+b7^kITKyZrI@f`~I+bAs+}FRUhVl!yq^?)QsfukAKmZHt2A zUJ55=Jq^j6ND;HnT9Cm)Ri?)H``zzba<5J75sKc=eBYO|(@SZIdnQgvNf`EjwKCYR zd{DWW$c9KutaUajZ2qG5jbi8Db^oGbM`XI zkUjP3=93W#a~MH2uKpVxSikUWZI~w?J;BMcq@6Z0X&xl+R+uNmdE^X3PFt9nr_~)1 z2i_bo=<%fD#wV)D|36pHlf)MOGSLwmv)icp{wS`89k}6BzPak$B#cm;i!`$S%$$0B zp)s<~V|)UG6+SDO49g9eQ712+W5M4~|5?3y$lerWDNm zo-$6~Q1;MzqC0diox;C%azwPo0y-kPMtcZ(>hU+~tTvcu`@h7f6Jr9s#{r_Kb{d?J zTQOfi2ev^tTOZK|+Sz}LMW4buQ>N>yASWw7rt`5jWZ)x_@o^Ywlq7P(MQ{RXU?u;p z0R1n`|CeG?Pa+3dd?91{JZ_T+^89HYH+_c#-Eo~^Bf_}KSN&I+)En7T#m?eM*k0D47Rn7m$%J6hyfY+wz?!4qW2rY7InL(zLs1e z91Z0M676*RYQ8};!eI`jtA3rxIp?|t3oESLY@)5aydh>$T>0OKRW7bZ&aR%$X6C5u RuVAj+yr^_^l8REO{|`k7n%4jT diff --git a/VERSION b/VERSION index 2daa89b..2aa4d8f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b1 +3.0.0b2 diff --git a/doc/source/conf.py b/doc/source/conf.py index 6b92d8e..99cd46c 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b' +release = '3.0.0b2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 2dea0db..3c71c6d 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -303,7 +303,7 @@ def main(): Entry point for the Earth Diagnostics. For more detailed documentation, use -h option """ parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') - parser.add_argument('-v', '--version', action='version', version='3.0.0b1', + parser.add_argument('-v', '--version', action='version', version='3.0.0b2', help="returns Earth Diagnostics's version number and exit") parser.add_argument('--doc', action='store_true', help="opens documentation and exits") -- GitLab From befd7c27db4136cf9f555be68d181182009e388f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 12 Jul 2016 11:32:21 +0200 Subject: [PATCH 128/268] Corrected log messages on the CMORization part --- earthdiagnostics/datamanager.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 0f10fbf..72155db 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -110,8 +110,8 @@ class DataManager(object): for tarfile in tar_files: Log.info('Unpacking atmospheric file {0}/{1}'.format(count, len(tar_files))) self._unpack_tar(tarfile, startdate, member) - count += 1 Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) + count += 1 else: self._cmorize_grib(startdate, member, gribfiles) Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str) @@ -140,8 +140,8 @@ class DataManager(object): for tarfile in tar_files: Log.info('Unpacking oceanic file {0}/{1}'.format(count, len(tar_files))) self._unpack_tar(tarfile, startdate, member) - count += 1 Log.result('Oceanic file {0}/{1} finished'.format(count, len(tar_files))) + count += 1 def _cmorize_grib(self, startdate, member, gribfiles): gribfiles.sort() @@ -572,9 +572,19 @@ class DataManager(object): else: region = var_cmor.basin.fullname + if file_parts[0] == self.expid: + # Model output + date_str = '{0}-{1}'.format(file_parts[2][0:6], file_parts[3][0:6]) + elif file_parts[1] == self.expid: + # Files generated by the old version of the diagnostics + date_str = '{0}-{1}'.format(file_parts[4][0:6], file_parts[5][0:6]) + else: + Log.error('Variable {0} can not be cmorized. Original filename does not match a recognized pattern') + return + self.send_file(temp, var_cmor.domain, var_cmor.short_name, startdate, member, frequency=frequency, rename_var=variable, - date_str='{0}-{1}'.format(file_parts[2][0:6], file_parts[3][0:6]), + date_str=date_str, region=region) @staticmethod -- GitLab From 58cc2ceefd0a8850b2c1cefccb6d29fa49e62850 Mon Sep 17 00:00:00 2001 From: ELEFTHERIA EXARCHOU Date: Wed, 13 Jul 2016 13:34:23 +0200 Subject: [PATCH 129/268] modifications to heatcontentlayer.py --- earthdiagnostics/ocean/heatcontentlayer.py | 86 +++++++++++++++------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 0fdd685..1f44d4b 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -33,8 +33,7 @@ class HeatContentLayer(Diagnostic): def __init__(self, data_manager, startdate, member, chunk, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate - self.member = member - self.chunk = chunk + self.member = membergdepth_0self.chunk = chunk self.box = box self.required_vars = ['so', 'mlotst'] self.generated_vars = ['scvertsum'] @@ -91,6 +90,15 @@ class HeatContentLayer(Diagnostic): raise Exception('e3t variable can not be found') handler.close() + + handler = Utils.openCdf('mesh_zgr.nc') + if 'gdepth_0' in handler.variables: + gdept = 'gdept_0' + else: + raise Exception('gdept_0 variable can not be found') + handler.close() + + nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*{0}"'.format(e3t_name)), thetao_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) @@ -103,31 +111,59 @@ class HeatContentLayer(Diagnostic): nco.ncks(input=heatc_sl_out, output=heatc_sl_top, options='-O -d lev,{0}.0,{1}.0'.format(self.box.min_depth, self.box.max_depth)) - # now extract a few levels below, to compute the residual ohc - # addition with float returned: - nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, - options='-O -d lev,{0}.0,{1}.0'.format(self.box.max_depth, self.box.max_depth + 200)) - - # obtain the weight for the extra level containing the 300 m - # deptht in the gridT files is positive - # weight = (300.0 - depth_top)/(depth_bottom - depth_top) - # and add the thickness down to 300 m in the next layer - nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) - nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') - nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') - - handler = Utils.openCdf(level_above) - lev_above = handler.variables['lev'][:] - handler.close() - - handler = Utils.openCdf(level_below) - layerthcknss = handler.variables['lev'][:] - lev_above - heatc_sl_below = handler.variables['heatc_sl'][:] - handler.close() + ## Eleftheria, modifications start here ############## + # Detemrine the upper boundary of the top level + for k in range (0, size(gdepth)): + if self.box.min_depth >= gdept(k) + upper_boundary = (gdept(k) - gdept (k-1) )/ 2. + top_level = gdept(k) + break + + # Detemrine the lower boundary of the bottom level + k=0 + while self.box.max_depth <= gdept: + lower_boundary = (gdept(k) - gdept (k-1) )/ 2. + bottom_level = gdept(k) + k += 1 + + # Calculate the top residuals res1 and the bottom residual res2 + tmp1 = cdo.sellevel (top_level, input=temp) + tmp2 = cdo.sellevel (bottom_level, input=temp) + res1 = cdo.mulc(upper_boundary - self.box.min_depth, tmp1) + res2 = cdo.mulc(self.box.max_depth - lower_boundary, tmp2) + + # Add the top and bottom residuals res1/res2 to the ocean heat content + cdo.add(input=' '.join([heatc_s1_out, res1]), output=heatc_sl_out1) + cdo.add(input=' '.join([heatc_s1_out1, res2]), output=heatc_sl_out2) + +# # now extract a few levels below, to compute the residual ohc +# # addition with float returned: +# nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, +# options='-O -d lev,{0}.0,{1}.0'.format(self.box.max_depth, self.box.max_depth + 200)) +# +# # obtain the weight for the extra level containing the 300 m +# # deptht in the gridT files is positive +# # weight = (300.0 - depth_top)/(depth_bottom - depth_top) +# # and add the thickness down to 300 m in the next layer +# nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) +# nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') +# nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') +# +# handler = Utils.openCdf(level_above) +# lev_above = handler.variables['lev'][:] +# handler.close() +# +# handler = Utils.openCdf(level_below) +# layerthcknss = handler.variables['lev'][:] - lev_above +# heatc_sl_below = handler.variables['heatc_sl'][:] +# handler.close() +# +# factor = (self.box.max_depth - lev_above) / layerthcknss +# +# heatc_sl_below = heatc_sl_below * factor + ## Eleftheria, modifications end here ############## - factor = (self.box.max_depth - lev_above) / layerthcknss - heatc_sl_below = heatc_sl_below * factor handler = Utils.openCdf(heatc_sl_top) heatc_sl = handler.variables['heatc_sl'][:] handler.close() -- GitLab From 7a02a973ff08223238b6ed3adc32d061bbbe97b3 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 13 Jul 2016 14:35:22 +0200 Subject: [PATCH 130/268] Bugfixes for CMOR --- earthdiagnostics/cmor_table.csv | 532 ++++++++++++++-------------- earthdiagnostics/datamanager.py | 123 +++++-- earthdiagnostics/diagnostic.py | 2 - earthdiagnostics/diags.py | 4 +- earthdiagnostics/ocean/siasiesiv.py | 76 +--- 5 files changed, 376 insertions(+), 361 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index cfabd38..87ddbdb 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -1,268 +1,264 @@ -Variable,Shortname,Name,Long name,Domain,Basin -al,al,surface_albedo,Albedo,atmos, -asn,snal,snow_albedo,Snow Albedo,landIce, -bgfrcsal,bgfrcsal,change_over_time_in_heat_content_from_forcing,Change Over Time In Salt Content from forcing,ocean, -bgfrctem,bgfrctem,change_over_time_in_heat_content_from_forcing,Change Over Time In Heat Content from forcing,ocean, -bgfrcvol,bgfrcvol,change_over_time_in_volume_from_forcing,Change Over Time In Volume From Forcing,ocean, -bgheatco,bgheatco,change_over_time_in_heat_content,Change Over Time in Sea Water Heat Content,ocean, -bgsaline,bgsaline,change_over_time_in_sea_water_practical_salinity,Change Over Time in Sea Water Salinity,ocean, -bgsaltco,bgsaltco,change_over_time_in_salt_content,Change Over Time in Sea Water Salt Content,ocean, -bgtemper,bgtemper,change_over_time_in_sea_water_potential_temperature,Change Over Time in Sea Water Potential Temperature,ocean, -bgvole3t,bgvole3t,change_over_time_in_volume_variation,Change Over Time in Volume Variation (e3t),ocean, -bgvolssh,bgvolssh,change_over_time_in_sea_surface_height,Change Over Time in Sea Surface Height,ocean, -ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,atmos, -cp,prc,convective_precipitation_flux,Convective Precipitation,atmos, -d2m,tdps,dew_point_temperature,2m Dewpoint Temperature,atmos, -e,evspsbl,water_evaporation_flux,Evaporation,atmos, -ewss,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,atmos, -fal,fal,forecast_albedo,Forecast albedo,atmos, -hcc,clh,high_cloud_area_fraction,High Cloud Fraction,atmos, -heatc,heatc,integral_of_sea_water_potential_temperature_wrt_depth_expressed_as_heat_content,Heat content vertically integrated,ocean, -hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic Northward Ocean Heat Transport,ocean, -ibgarea,sicga,sea_ice_content,Global Mean Sea Ice Content,seaIce, -ibgfrcsfx,ibgfrcsfx,global_mean_forcing_salt,global mean forcing salt (sfx),seaIce, -ibgfrcvol,ibgfrcvol,globa_mean_forcing_volume,global mean forcing volume (emp),seaIce, -ibgheatco,hcicega,global mean ice heat content,global mean ice heat content,seaIce, -ibghfxbog,ibghfxbog,heat_fluxes_causing_bottom_ice_growth,heat fluxes causing bottom ice growth,seaIce, -ibghfxbom,ibghfxbom,heat_fluxes_causing_bottom_ice_melt,heat fluxes causing bottom ice melt,seaIce, -ibghfxdhc,ibghfxdhc,Heat_content_variation_in_snow_and_ice,Heat content variation in snow and ice,seaIce, -ibghfxdif,ibghfxdif,heat_fluxes_causing_ice temperature_change,heat fluxes causing ice temperature change,seaIce, -ibghfxdyn,ibghfxdyn,heat_fluxes_from_ice-ocean_exchange_during_dynamic,heat fluxes from ice-ocean exchange during dynamic,seaIce, -ibghfxin,ibghfxin,total_heat_fluxes_at_the_ice_surface,total heat fluxes at the ice surface,seaIce, -ibghfxopw,ibghfxopw,heat_fluxes_causing_open_water_ice_formation,heat fluxes causing open water ice formation,seaIce, -ibghfxout,ibghfxout,non_solar_heat_fluxes_received_by_the_ocean,non solar heat fluxes received by the ocean,seaIce, -ibghfxres,ibghfxres,heat_fluxes_from_ice-ocean_exchange_during_resultant,heat fluxes from ice-ocean exchange during resultant,seaIce, -ibghfxsnw,ibghfxsnw,heat_fluxes_from_snow-ocean_exchange,heat fluxes from snow-ocean exchange,seaIce, -ibghfxspr,ibghfxspr,Heat_content_of_snow_precip,Heat content of snow precip,seaIce, -ibghfxsub,ibghfxsub,heat_fluxes_from_sublimation,heat fluxes from sublimation,seaIce, -ibghfxsum,ibghfxsum,heat_fluxes_causing_surface_ice_melt,heat fluxes causing surface ice melt,seaIce, -ibghfxthd,ibghfxthd,heat_fluxes_from_ice-ocean_exchange_during_thermo,heat fluxes from ice-ocean exchange during thermo,seaIce, -ibgsaline,ssiga,sea_ice_salinity,Global Mean Sea Ice Salinity ,seaIce, -ibgsaltco,sisaltcga,global mean ice salt content,global mean ice salt content,seaIce, -ibgsfx,ibgsfxga,salt_flux,global mean salt flux (total),seaIce, -ibgsfxbog,ibgsfxbogga,salt_flux_thermo,global mean salt flux (thermo),seaIce, -ibgsfxbom,ibgsfxbomga,salt_flux_bottom_melt,global mean salt flux (bottom melt),seaIce, -ibgsfxbri,ibgsfxbriga,salt_flux_brines,global mean salt flux (brines),seaIce, -ibgsfxdyn,ibgsfxdynga,salt_flux_dynamic,global mean salt flux (dynamic),seaIce, -ibgsfxopw,ibgsfxopwga,salt_flux_open_waters,global mean salt flux (open water),seaIce, -ibgsfxres,ibgsfxresga,salt_flux_resultant,global mean salt flux (resultant),seaIce,Atl -ibgsfxsni,ibgsfxsniga,salt_flux_snow_ice_growth,global mean salt flux (snow-ice growth),seaIce,Ind -ibgsfxsum,ibgsfxsumga,salt_flux_surface_melt,global mean salt flux (surface melt),seaIce,IndPac -ibgtemper,sitempga,sea_ice_temperature,Global Mean Sea Ice Temperature,seaIce,Pac -ibgvfx,ibgvfxga,volume_flux_emp,global mean volume flux (emp),seaIce, -ibgvfxbog,ibgvfxbogga,volume_flux_bottom_growth,global mean volume flux (bottom growth),seaIce, -ibgvfxbom,ibgvfxbomga,volume_flux_bottom_melt,global mean volume flux (bottom melt),seaIce, -ibgvfxdyn,ibgvfxdynga,volume_flux_dynamic_growth,global mean volume flux (dynamic growth),seaIce, -ibgvfxopw,ibgvfxopwga,volume_flux_open_water_growth,global mean volume flux (open water growth),seaIce, -ibgvfxres,ibgvfxresga,volume_flux_resultant,global mean volume flux (resultant),seaIce, -ibgvfxsni,ibgvfxsniga,volume_flux_snow_ice_growth,global mean volume flux (snow-ice growth),seaIce, -ibgvfxsnw,ibgvfxsnwga,volume_flux_snow_melt,global mean volume flux (snow melt),seaIce, -ibgvfxspr,ibgvfxsprga,snheco,global mean volume flux (snow precip),seaIce, -ibgvfxsub,ibgvfxsubga,volume_flux_snow_sublimation,global mean volume flux (snow sublimation),seaIce, -ibgvfxsum,ibgvfxsumga,volume_flux_surface_melt,global mean volume flux (surface melt),seaIce, -ibgvolgrm,ibgvolgrm,global_mean_ice_growth+melt_volume,global mean ice growth+melt volume,seaIce, -ibgvoltot,sivolga,sea_ice_volume,Global Mean Sea Ice Volume,seaIce, -ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce, -iice_etd,iiceetd,brine_volume_distribution,Brine volume distribution,seaIce, -iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce,Atl -iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce,Ind -iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,IndPac -iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of Sea Ice,seaIce,Pac -iicebome:iocewflx,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of Melt at Sea Ice Base,seaIce, -iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce, -iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thickness,seaIce, -iiceconc:siconc:soicecov:ileadfra,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce, -iicedive:sidive,divice,Strain Rate Divergence of Sea Ice,divergence_of_sea_ice_velocity,seaIce, -iicedypr,iicedypr,daily_dynamic_ice_production,Daily dynamic ice production,seaIce, -iiceheco,siheco,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea Ice Heat Content,seaIce, -iicelapr,iicelapr,daily_lateral_thermo_ice_production,Daily lateral thermo ice prod.,seaIce, -iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce,Glob -iiceprod,sigr,ice_production,Ice Production,seaIce, -iicesali:iice_std,ssi,sea_ice_salinity,Sea Ice Salinity,seaIce,Atl -iicesflx,iicesflx,solar_flux_ice_ocean_surface,Solar flux at ice/ocean surface,seaIce,Ind -iiceshea,iiceshea,shear,Shear,seaIce,IndPac -iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce,Pac -iicestre,streng,compressive_strength_of_sea_ice,Compressive Sea Ice Strength,seaIce,Atl -iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of Melt at Upper Surface of Sea Ice,seaIce,Glob -iicesurt:soicetem:sistem,tsice,surface_temperature,Surface Temperature of Sea Ice,seaIce,Ind -iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce,IndPac -iicethic:sithic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce,Pac -iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce,Atl -iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce,Glob -iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce,Ind -iicfsbri,iicfsbri,brine_salt_flux,Fsbri - brine salt flux,seaIce,IndPac -iicfseqv,iicfseqv,equivalent_FW_salt_flux,Fseqv - equivalent FW salt flux,seaIce,Pac -ioceflxb,ioceflxb,oceanic_flux_ar_ice_base,Oceanic flux at the ice base,seaIce,Atl -iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release,seaIce,Glob -iocesafl,iocesafl,salt_flux_ocean_surface,Salt Flux at Ocean Surface,seaIce,Ind -iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce,IndPac -iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce,Pac -iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce, -iowaflup,ficeocean,ice_ocean_water_flux,Ice=>ocean net freshwater,ocean, -isnoheco,snheco,snow_heat_content,Snow total heat content,seaIce, -isnowpre,prsn,snowfall_flux,Surface Snowfall Rate into the Sea Ice Portion of the Grid Cell,seaIce, -isnowthi,snthic,surface_snow_thickness,Surface Snow Thickness,seaIce, -isssalin,isssalin,sea_surface_salinity,Sea surface salinity,seaIce, -isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce, -istl1,tsice,surface_temperature,Surface Temperature of Ice,landIce, -lcc,clh,low_cloud_area_fraction,Low Cloud Fraction,atmos, -lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos, -mcc,clh,medium_cloud_area_fraction,Medium Cloud Fraction,atmos, -mldkz5,mldkz5,ocean_mixed_layer_thickness_defined_by_vertical_tracer_diffusivity,Turbocline depth (Kz = 5e-4),ocean, -mn2t,tasmin,air_temperature,Daily Minimum Near-Surface Air Temperature,atmos, -msftmyz,zomsfglo,msftmyz,Meridional Mass Streamfunction,ocean, -msftmyza,zomsfatl,msftmyza,Meridional Mass Streamfunction in the Atlantic,ocean, -msftmyzba,zomsfeiv,ocean_meridional_overturning_mass_streamfunction_due_to_bolus_advection,Meridional Mass Streamfunction Due to Bolus Advection,ocean, -msl,psl,air_pressure_at_sea_level,Sea Level Pressure,atmos, -mx2t,tasmax,air_temperature,Daily Maximum Near-Surface Air Temperature,atmos, -nsss,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,atmos, -q,hus,specific_humidity,Specific humidity,atmos, -qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,non-solar heat flux at ice surface: sum over categories,seaIce, -qt_ice,qtice,surface_downward_heat_flux_in_air,Surface Downward Heat Flux in Air,seaIce, -qt_oce,hfds,surface_downward_heat_flux_in_sea_water,Downward Heat Flux at Sea Water Surface,ocean, -ro,mrro,runoff_flux,Total Runoff,atmos, -salincat,ssicat,sea_ice_salinity_in_categories,Sea-Ice Bulk salinity for categories,seaIce, -saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrated,ocean, -sbgheatco,hcsnga,global mean snow heat content,global mean snow heat content,seaIce, -sbgvoltot,snvolga,snow_volume,Global Mean Snow Volume,seaIce, -scmastot,masso,sea_water_mass,Sea Water Mass ,ocean, -scsaltot,soga,sea_water_salinity,Global Mean Sea Water Salinity ,ocean, -scsshste,zossga,global_average_steric_sea_level_change,Global Average Steric Sea Level Change ,ocean, -scsshtot,zosga,global_average_sea_level_change,Global Average Sea Level Change ,ocean, -scsshtst,zostoga,snthic,Global Average Thermosteric Sea Level Change ,ocean, -sctemtot,thetaoga,sea_water_potential_temperature,Global Average Sea Water Potential Temperature ,ocean, -scvoltot,volo,sea_water_volume,Sea Water Volume ,ocean, -sd,snld,lwe_thickness_of_surface_snow_amount,Snow Depth,atmos, -sf,prsn,snowfall_flux,Snowfall Flux,atmos, -si,si,solar_insolation,Solar insolation,atmos, -sibricat,ibrinvolcat,brine_volume_in_categories,Brine volume for categories,seaIce, -sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea Ice Volume per gridcell area unit,seaIce, -skt,ts,surface_temperature,Surface Temperature,atmos, -slhf,hfls,surface_upward_latent_heat_flux,Surface Upward Latent Heat Flux,atmos, -sltnortha,sltnortha,northward_ocean_salt_transport,Atlantic Northward Ocean Salt Transport,ocean, -snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow Volume per gridcell area unit,seaIce, -so20chgt,t20d,depth_of_isosurface_of_sea_water_potential_temperature,,ocean, -sobowlin,bowlin,bowl_index,Bowl Index,ocean, -sohefldo,hfds,surface_downward_heat_flux_in_sea_water,Downward Heat Flux at Sea Water Surface,ocean, -sohtatl,hfbasin,sobarstf,Northward Ocean Heat Transport,ocean, -sohtind,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, -sohtipc,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, -sohtpac,hfbasin,northward_ocean_heat_transport,Northward Ocean Heat Transport,ocean, -soicealb,ialb,sea_ice_albedo,Sea Ice Albedo,seaIce, -soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,eddy induced vel. coeff. at w-point,ocean, -soleahtw,soleahtw,lateral_eddy_diffusivity,lateral eddy diffusivity,ocean, -somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (Turbocline),ocean, -somxl010:mldr10_1,mlotst,ocean_mixed_layer_thickness_defined_by_sigma_t,Ocean Mixed Layer Thickness Defined by Sigma T ,ocean, -sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward Ocean Heat Transport due to Advection ,ocean, -sophteiv,hfbasinba,northward_ocean_heat_transport_due_to_bolus_advection,Northward Ocean Heat Transport due to Bolus Advection ,ocean, -sophtldf,fhbasindif,northward_ocean_heat_transport_due_to_diffusion,Northward Ocean Heat Transport due to Diffusion,ocean, -sophtove,htovovrt,northward_ocean_heat_transport_due_to_overturning,Northward Ocean Heat Transport due to Overturning ,ocean, -sopstadv,sltbasinadv,northward_ocean_salt_transport_due_to_advection,Northward Ocean Salt Transport due to Advection ,ocean, -sopsteiv,sltbasinba,northward_ocean_salt_transport_due_to_bolus_advection,Northward Ocean Salt Transport due to Bolus Advection ,ocean, -sopstldf,sltbasindif,northward_ocean_salt_transport_due_to_diffusion,Northward Ocean Salt Transport due to Diffusion,ocean, -sopstove,sltovovrt,northward_ocean_salt_transport_due_to_overturning,Northward Ocean Salt Transport due to Overturning ,ocean, -sorunoff,friver,water_flux_into_sea_water_from_rivers,Water Flux into Sea Water From Rivers ,ocean, -sosalflx,sfs,salt_flux_surface,Surface Salt Flux,ocean, -sosaline,sos,sea_surface_salinity,Sea Surface Salinity ,ocean, -soshfldo,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net Downward Shortwave Radiation at Sea Water Surface ,ocean, -sossheigh:sossheig,zos,sea_surface_height_above_geoid,Sea Surface Height Above Geoid ,ocean, -sosstsst,tos,sea_surface_temperature,Sea Surface Temperature ,ocean, -sostatl,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean, -sostind,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean, -sostipc,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean, -sostpac,sltbasin,northward_ocean_salt_transport,Northward Ocean Salt Transport,ocean, -sothedep,sothedep,thermocline_depth,Thermocline Depth (max dT/dz),ocean, -sowaflcd,fdilution,dilution_water_flux,concentration/dilution water flux,ocean, -sowaflep,fatmosocean,atmosphere_ocean_water_flux,atmos=>ocean net freshwater,ocean, -sowaflup,fupward,upward_water_flux,Net Upward Water Flux,ocean, -sozotaux,tauuo,surface_downward_x_stress,Surface Downward X Stress ,ocean, -sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface Downward Y Stress ,ocean, -sshf,hfss,surface_upward_sensible_heat_flux,Surface Upward Sensible Heat Flux,atmos, -ssr,rss,surface_shortwave_flux_in_air,Surface Shortwave Radiation,atmos, -ssrc,rsscs,surface_shortwave_flux_in_air_assuming_clear_sky,Surface Clear-Sky Shortwave Radiation,atmos, -ssrd,rsds,surface_downwelling_shortwave_flux_in_air,Surface Downwelling Shortwave Radiation,atmos, -sstk,tos,sea_surface_temperature,Sea Surface Temperature ,atmos, -stl1,tsl1,soil_temperature_level_1,Temperature of Soil Level 1,land, -stl2,tsl2,soil_temperature_level_2,Temperature of Soil Level 2,land, -stl3,tsl3,soil_temperature_level_3,Temperature of Soil Level 3,land, -stl4,tsl4,soil_temperature_level_4,Temperature of Soil Level 4,land, -str,rls,surface_net_downward_longwave_flux,Net Longwave Surface Radiation,atmos, -strc,rls,surface_longwave_flux_in_air,Surface Longwave Radiation,atmos, -strd,rlds,surface_downwelling_longwave_flux_in_air,Surface Downwelling Longwave Radiation,atmos, -swvl1,mrlsl1,moisture_content_of_soil_layer_1, Water Content of Soil Layer 1,land, -swvl2,mrlsl2,moisture_content_of_soil_layer_2, Water Content of Soil Layer 2,land, -swvl3,mrlsl3,moisture_content_of_soil_layer_3, Water Content of Soil Layer 3,land, -swvl4,mrlsl4,moisture_content_of_soil_layer_4, Water Content of Soil Layer 4,land, -t,ta,air_temperature,Air Temperature,atmos, -t2m,tas,air_temperature,Near-Surface Air Temperature,atmos, -tcc,clt,cloud_area_fraction,Total Cloud Fraction,atmos, -tcw,clwvi,atmosphere_cloud_condensed_water_content,Condensed Water Path,atmos, -tcwv,prw,atmosphere_water_vapor_content,Water Vapor Path,atmos, -tos,sosstsst,sea_surface_temperature,Sea Surface Temperature,ocean, -tossq,tossq,square_of_sea_surface_temperature,Square of Sea Surface Temperature ,ocean, -tp,pr,precipitation_flux,Precipitation,atmos, -tsn,tsn,temperature_in_surface_snow,Snow Internal Temperature,landIce, -tsr,rsdt,toa_incoming_shortwave_flux,TOA Incident Shortwave Radiation,atmos, -tsrc,rsut,toa_outgoing_shortwave_flux,TOA Outgoing Shortwave Radiation,atmos, -ttr,rlut,toa_outgoing_longwave_flux,TOA Outgoing Longwave Radiation,atmos, -ttrc,rlutcs,toa_outgoing_longwave_flux_assuming_clear_sky,"Top net thermal radiation, clear sky",atmos, -u,ua,eastward_wind,U velocity,atmos, -u10m,uas,eastward_wind,Eastward Near-Surface Wind,atmos, -utau_ice:iocestru:iicestru,tauu,surface_downward_eastward_stress,Surface Downward Eastward Wind Stress,seaIce, -v,va,northward_wind,V velocity,atmos, -v10m,vas,northward_wind,Northward Near-Surface Wind,atmos, -voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt Vertical Eddy Diffusivity,ocean, -vomecrty,vo,sea_water_y_velocity,Sea Water Y Velocity,ocean, -vomeeivv,voeivv,sea_water_y_EIV_current,Meridional EIV Current,ocean, -vosaline,so,sea_water_salinity,Sea Water Salinity,ocean, -votemper,thetao,sea_water_potential_temperature,Sea Water Potential Temperature,ocean, -votkeavm,votkeavm,vertical_eddy_viscosity,Vertical Eddy Viscosity,ocean, -votkeavt,votkeavt,vertical_eddy_diffusivity,Vertical Eddy Diffusivity,ocean, -votkeevd,votkeevd,enhanced_vertical_diffusivity,Enhanced Vertical Diffusivity,ocean, -votkeevm,votkeevm,enhanced_vertical_viscosity,Enhanced Vertical Viscosity,ocean, -vovecrtz,zo,sea_water_z_velocity,Sea Water Z Velocity,ocean, -voveeivw,voeivz,sea_water_z_EIV_current,Vertical EIV Current,ocean, -vozocrtx,uo,sea_water_x_velocity,Sea Water X Velocity,ocean, -vozoeivu,voeivu,sea_water_x_EIV_current,Zonal EIV Current,ocean, -vtau_ice:iocestrv:iicestrv,tauv,surface_downward_northward_stress,Surface Downward Northward Wind Stress,seaIce, -z,zg,geopotential_height,Geopotential Height,atmos, -zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, -zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction,Ocean Meridional Overturning Volume Streamfunction due to Bolus Advection ,ocean, -zomsfglo,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, -zomsfind,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, -zomsfipc,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, -zomsfpac,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean Meridional Overturning Volume Streamfunction ,ocean, -zosalatl,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, -zosalglo,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, -zosalind,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, -zosalipc,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, -zosalpac,sltzmean,zonal_mean_salinity,Zonal Mean Salinity,ocean, -zosrfatl,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, -zosrfglo,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, -zosrfind,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, -zosrfipc,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, -zosrfpac,srfzmean,zonal_mean_surface,Zonal Mean Surface,ocean, -zossq,zossq,square_of_sea_surface_height_above_geoid,Square of Sea Surface Height Above Geoid ,ocean, -zotematl,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, -zotemglo,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, -zotemind,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, -zotemipc,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, -zotempac,toszmean,zonal_mean_temperature,Zonal Mean Temperature,ocean, -bld,bld,boundary_layer_dissipation,Boundary layer dissipation,atmos, -cc,cl,cloud_area_fraction_in_atmosphere_layer,Cloud Area Fraction,atmos, -ciwc,cli,mass_fraction_of_cloud_ice_in_air,Mass Fraction of Cloud Ice,atmos, -clwc,clw,mass_fraction_of_cloud_liquid_water_in_air,Mass Fraction of Cloud Liquid Water,atmos, -es,sbl,surface_snow_and_ice_sublimation_flux,Surface Snow and Ice Sublimation Flux,landIce, -gwd,gwd,gravity_wave_dissipation,Gravity wave dissipation,atmos, -rsn,srho,snow_density,Snow Density,landIce, -smlt,snm,surface_snow_melt_flux,Surface Snow Melt,landIce, -src,src,skin_reservoir_content,Skin reservoir content,land, -w,wa,vertical_velocity,Vertical velocity,atmos, -iocewflx,,,,seaIce, -sobarstf,vsftbarot,ocean_barotropic_volume_streamfunction,Ocean Barotropic Volume Streamfunction ,ocean, -sivols,sivols,sea_ice_volume,total volume of sea ice in the Southern hemisphere,seaIce, -sivoln,sivoln,sea_ice_volume,total volume of sea ice in the Northern hemisphere,seaIce, -siextentn,siextentn,sea_ice_extent,Total area of all Northern-Hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce, -siextents,siextents,sea_ice_extent,Total area of all Southern-Hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce, -siarean,siarean,sea_ice_area,total area of sea ice in the Northern hemisphere,seaIce, -siareas,siareas,sea_ice_area,total area of sea ice in the Southern hemisphere,seaIce, +Variable,Shortname,Name,Long name,Domain,Basin,Units,Valid min,Valid max +iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of sea ice,seaIce,,,, +al,al,surface_albedo,Albedo,atmos,,,, +bgfrcsal,bgfrcsal,change_over_time_in_heat_content_from_forcing,Change over time in salt content from forcing,ocean,,,, +bgfrctem,bgfrctem,change_over_time_in_heat_content_from_forcing,Change over time in heat content from forcing,ocean,,,, +bgfrcvol,bgfrcvol,change_over_time_in_volume_from_forcing,Change over time in volume from forcing,ocean,,,, +bgheatco,bgheatco,change_over_time_in_heat_content,Change over time in sea water heat content,ocean,,,, +bgsaline,bgsaline,change_over_time_in_sea_water_practical_salinity,Change over time in sea water salinity,ocean,,,, +bgsaltco,bgsaltco,change_over_time_in_salt_content,Change over time in sea water salt content,ocean,,,, +bgtemper,bgtemper,change_over_time_in_sea_water_potential_temperature,Change over time in sea water potential temperature,ocean,,,, +bgvole3t,bgvole3t,change_over_time_in_volume_variation,Change over time in volume variation (e3t),ocean,,,, +bgvolssh,bgvolssh,change_over_time_in_sea_surface_height,Change over time in sea surface height,ocean,,,, +bld,bld,boundary_layer_dissipation,Boundary layer dissipation,atmos,,,, +iicebome:iocewflx,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of melt at sea ice base,seaIce,,,, +sobowlin,bowlin,bowl_index,Bowl index,ocean,,,, +cc,cl,cloud_area_fraction_in_atmosphere_layer,Cloud area fraction,atmos,,,, +hcc,clh,high_cloud_area_fraction,High cloud fraction,atmos,,,, +lcc,clh,low_cloud_area_fraction,Low cloud fraction,atmos,,,, +mcc,clh,medium_cloud_area_fraction,Medium cloud fraction,atmos,,,, +ciwc,cli,mass_fraction_of_cloud_ice_in_air,Mass fraction of cloud ice,atmos,,,, +tcc,clt,cloud_area_fraction,Total cloud fraction,atmos,,,, +clwc,clw,mass_fraction_of_cloud_liquid_water_in_air,Mass fraction of cloud liquid water,atmos,,,, +tcw,clwvi,atmosphere_cloud_condensed_water_content,Condensed water path,atmos,,,, +iicedive:sidive,divice,Strain Rate Divergence of Sea Ice,Divergence_of_sea_ice_velocity,seaIce,,,, +e,evspsbl,water_evaporation_flux,Evaporation,atmos,,,, +fal,fal,forecast_albedo,Forecast albedo,atmos,,,, +sowaflep,fatmosocean,atmosphere_ocean_water_flux,Atmos=>ocean net freshwater,ocean,,,, +sowaflcd,fdilution,dilution_water_flux,Concentration/dilution water flux,ocean,,,, +sophtldf,fhbasindif,northward_ocean_heat_transport_due_to_diffusion,Northward ocean heat transport due to diffusion,ocean,,,, +iowaflup,ficeocean,ice_ocean_water_flux,Ice=>ocean net freshwater,ocean,,,, +sorunoff,friver,water_flux_into_sea_water_from_rivers,Water flux into sea water from rivers ,ocean,,,, +sowaflup,fupward,upward_water_flux,Net upward water flux,ocean,,,, +gwd,gwd,gravity_wave_dissipation,Gravity wave dissipation,atmos,,,, +ibgheatco,hcicega,global mean ice heat content,Global mean ice heat content,seaIce,,,, +sbgheatco,hcsnga,global mean snow heat content,Global mean snow heat content,seaIce,,,, +heatc,heatc,integral_of_sea_water_potential_temperature_wrt_depth_expressed_as_heat_content,Heat content vertically integrated,ocean,,,, +sohtatl,hfbasin,sobarstf,Northward ocean heat transport,ocean,,,, +sohtind,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,,,, +sohtipc,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,,,, +sohtpac,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,,,, +sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward ocean heat transport due to advection ,ocean,,,, +sophteiv,hfbasinba,northward_ocean_heat_transport_due_to_bolus_advection,Northward ocean heat transport due to bolus advection ,ocean,,,, +qt_oce,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,, +sohefldo,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,, +slhf,hfls,surface_upward_latent_heat_flux,Surface upward latent heat flux,atmos,,,, +sshf,hfss,surface_upward_sensible_heat_flux,Surface upward sensible heat flux,atmos,,,, +sophtove,htovovrt,northward_ocean_heat_transport_due_to_overturning,Northward ocean heat transport due to overturning ,ocean,,,, +q,hus,specific_humidity,Specific humidity,atmos,,,, +soicealb,ialb,sea_ice_albedo,Sea ice albedo,seaIce,,,, +ibgfrcsfx,ibgfrcsfx,global_mean_forcing_salt,Global mean forcing salt (sfx),seaIce,,,, +ibgfrcvol,ibgfrcvol,globa_mean_forcing_volume,Global mean forcing volume (emp),seaIce,,,, +ibghfxbog,ibghfxbog,heat_fluxes_causing_bottom_ice_growth,Heat fluxes causing bottom ice growth,seaIce,,,, +ibghfxbom,ibghfxbom,heat_fluxes_causing_bottom_ice_melt,Heat fluxes causing bottom ice melt,seaIce,,,, +ibghfxdhc,ibghfxdhc,Heat_content_variation_in_snow_and_ice,Heat content variation in snow and ice,seaIce,,,, +ibghfxdif,ibghfxdif,heat_fluxes_causing_ice temperature_change,Heat fluxes causing ice temperature change,seaIce,,,, +ibghfxdyn,ibghfxdyn,heat_fluxes_from_ice-ocean_exchange_during_dynamic,Heat fluxes from ice-ocean exchange during dynamic,seaIce,,,, +ibghfxin,ibghfxin,total_heat_fluxes_at_the_ice_surface,Total heat fluxes at the ice surface,seaIce,,,, +ibghfxopw,ibghfxopw,heat_fluxes_causing_open_water_ice_formation,Heat fluxes causing open water ice formation,seaIce,,,, +ibghfxout,ibghfxout,non_solar_heat_fluxes_received_by_the_ocean,Non solar heat fluxes received by the ocean,seaIce,,,, +ibghfxres,ibghfxres,heat_fluxes_from_ice-ocean_exchange_during_resultant,Heat fluxes from ice-ocean exchange during resultant,seaIce,,,, +ibghfxsnw,ibghfxsnw,heat_fluxes_from_snow-ocean_exchange,Heat fluxes from snow-ocean exchange,seaIce,,,, +ibghfxspr,ibghfxspr,Heat_content_of_snow_precip,Heat content of snow precip,seaIce,,,, +ibghfxsub,ibghfxsub,heat_fluxes_from_sublimation,Heat fluxes from sublimation,seaIce,,,, +ibghfxsum,ibghfxsum,heat_fluxes_causing_surface_ice_melt,Heat fluxes causing surface ice melt,seaIce,,,, +ibghfxthd,ibghfxthd,heat_fluxes_from_ice-ocean_exchange_during_thermo,Heat fluxes from ice-ocean exchange during thermo,seaIce,,,, +ibgsfxbog,ibgsfxbogga,salt_flux_thermo,Global mean salt flux (thermo),seaIce,,,, +ibgsfxbom,ibgsfxbomga,salt_flux_bottom_melt,Global mean salt flux (bottom melt),seaIce,,,, +ibgsfxbri,ibgsfxbriga,salt_flux_brines,Global mean salt flux (brines),seaIce,,,, +ibgsfxdyn,ibgsfxdynga,salt_flux_dynamic,Global mean salt flux (dynamic),seaIce,,,, +ibgsfx,ibgsfxga,salt_flux,Global mean salt flux (total),seaIce,,,, +ibgsfxopw,ibgsfxopwga,salt_flux_open_waters,Global mean salt flux (open water),seaIce,,,, +ibgsfxres,ibgsfxresga,salt_flux_resultant,Global mean salt flux (resultant),seaIce,,,, +ibgsfxsni,ibgsfxsniga,salt_flux_snow_ice_growth,Global mean salt flux (snow-ice growth),seaIce,,,, +ibgsfxsum,ibgsfxsumga,salt_flux_surface_melt,Global mean salt flux (surface melt),seaIce,,,, +ibgvfxbog,ibgvfxbogga,volume_flux_bottom_growth,Global mean volume flux (bottom growth),seaIce,,,, +ibgvfxbom,ibgvfxbomga,volume_flux_bottom_melt,Global mean volume flux (bottom melt),seaIce,,,, +ibgvfxdyn,ibgvfxdynga,volume_flux_dynamic_growth,Global mean volume flux (dynamic growth),seaIce,,,, +ibgvfx,ibgvfxga,volume_flux_emp,Global mean volume flux (emp),seaIce,,,, +ibgvfxopw,ibgvfxopwga,volume_flux_open_water_growth,Global mean volume flux (open water growth),seaIce,,,, +ibgvfxres,ibgvfxresga,volume_flux_resultant,Global mean volume flux (resultant),seaIce,,,, +ibgvfxsni,ibgvfxsniga,volume_flux_snow_ice_growth,Global mean volume flux (snow-ice growth),seaIce,,,, +ibgvfxsnw,ibgvfxsnwga,volume_flux_snow_melt,Global mean volume flux (snow melt),seaIce,,,, +ibgvfxspr,ibgvfxsprga,snheco,Global mean volume flux (snow precip),seaIce,,,, +ibgvfxsub,ibgvfxsubga,volume_flux_snow_sublimation,Global mean volume flux (snow sublimation),seaIce,,,, +ibgvfxsum,ibgvfxsumga,volume_flux_surface_melt,Global mean volume flux (surface melt),seaIce,,,, +ibgvolgrm,ibgvolgrm,global_mean_ice_growth+melt_volume,Global mean ice growth+melt volume,seaIce,,,, +ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce,,,, +sibricat,ibrinvolcat,brine_volume_in_categories,Brine volume for categories,seaIce,,,, +iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce,,,, +iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thickness,seaIce,,,, +iicedypr,iicedypr,daily_dynamic_ice_production,Daily dynamic ice production,seaIce,,,, +iice_etd,iiceetd,brine_volume_distribution,Brine volume distribution,seaIce,,,, +iicelapr,iicelapr,daily_lateral_thermo_ice_production,Daily lateral thermo ice prod.,seaIce,,,, +iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce,,,, +iicesflx,iicesflx,solar_flux_ice_ocean_surface,Solar flux at ice/ocean surface,seaIce,,,, +iiceshea,iiceshea,shear,Shear,seaIce,,,, +iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce,,,, +iicfsbri,iicfsbri,brine_salt_flux,Fsbri - brine salt flux,seaIce,,,, +iicfseqv,iicfseqv,equivalent_FW_salt_flux,Fseqv - equivalent fw salt flux,seaIce,,,, +ioceflxb,ioceflxb,oceanic_flux_ar_ice_base,Oceanic flux at the ice base,seaIce,,,, +iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release,seaIce,,,, +iocesafl,iocesafl,salt_flux_ocean_surface,Salt flux at ocean surface,seaIce,,,, +iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce,,,, +iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce,,,, +iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce,,,, +isssalin,isssalin,sea_surface_salinity,Sea surface salinity,seaIce,,,, +isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce,,K,, +scmastot,masso,sea_water_mass,Sea water mass ,ocean,,,, +mldkz5,mldkz5,ocean_mixed_layer_thickness_defined_by_vertical_tracer_diffusivity,Turbocline depth (kz = 5e-4),ocean,,,, +somxl010:mldr10_1,mlotst,ocean_mixed_layer_thickness_defined_by_sigma_t,Ocean mixed layer thickness defined by sigma T ,ocean,,,, +swvl1,mrlsl1,moisture_content_of_soil_layer_1, Water content of soil layer 1,land,,,, +swvl2,mrlsl2,moisture_content_of_soil_layer_2, Water content of soil layer 2,land,,,, +swvl3,mrlsl3,moisture_content_of_soil_layer_3, Water content of soil layer 3,land,,,, +swvl4,mrlsl4,moisture_content_of_soil_layer_4, Water content of soil layer 4,land,,,, +ro,mrro,runoff_flux,Total runoff,atmos,,,, +tp,pr,precipitation_flux,Precipitation,atmos,,,, +cp,prc,convective_precipitation_flux,Convective precipitation,atmos,,,, +lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos,,,, +isnowpre,prsn,snowfall_flux,Surface snowfall rate into the sea ice portion of the grid cell,seaIce,,,, +sf,prsn,snowfall_flux,Snowfall flux,atmos,,,, +tcwv,prw,atmosphere_water_vapor_content,Water vapor path,atmos,,,, +msl,psl,air_pressure_at_sea_level,Sea level pressure,atmos,,,, +qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,Non-solar heat flux at ice surface: sum over categories,seaIce,,,, +qt_ice,qtice,surface_downward_heat_flux_in_air,Surface downward heat flux in air,seaIce,,,, +strd,rlds,surface_downwelling_longwave_flux_in_air,Surface downwelling longwave radiation,atmos,,,, +str,rls,surface_net_downward_longwave_flux,Net longwave surface radiation,atmos,,,, +strc,rls,surface_longwave_flux_in_air,Surface longwave radiation,atmos,,,, +ttr,rlut,toa_outgoing_longwave_flux,Toa outgoing longwave radiation,atmos,,,, +ttrc,rlutcs,toa_outgoing_longwave_flux_assuming_clear_sky,"Top net thermal radiation, clear sky",atmos,,,, +ssrd,rsds,surface_downwelling_shortwave_flux_in_air,Surface downwelling shortwave radiation,atmos,,,, +tsr,rsdt,toa_incoming_shortwave_flux,Toa incident shortwave radiation,atmos,,,, +soshfldo,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net downward shortwave radiation at sea water surface ,ocean,,,, +ssr,rss,surface_shortwave_flux_in_air,Surface shortwave radiation,atmos,,,, +ssrc,rsscs,surface_shortwave_flux_in_air_assuming_clear_sky,Surface clear-sky shortwave radiation,atmos,,,, +tsrc,rsut,toa_outgoing_shortwave_flux,Toa outgoing shortwave radiation,atmos,,,, +saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrated,ocean,,,, +es,sbl,surface_snow_and_ice_sublimation_flux,Surface snow and ice sublimation flux,landIce,,,, +sosalflx,sfs,salt_flux_surface,Surface salt flux,ocean,,,, +si,si,solar_insolation,Solar insolation,atmos,,,, +siarean,siarean,sea_ice_area,Total area of sea ice in the northern hemisphere,seaIce,,,, +siareas,siareas,sea_ice_area,Total area of sea ice in the southern hemisphere,seaIce,,,, +iiceconc:siconc:soicecov:ileadfra:ci,sic,sea_ice_area_fraction,Sea ice area fraction,seaIce,,,, +iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,,,, +ibgarea,sicga,sea_ice_content,Global mean sea ice content,seaIce,,,, +siextentn,siextentn,sea_ice_extent,Total area of all northern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,,, +siextents,siextents,sea_ice_extent,Total area of all southern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,,, +iiceprod,sigr,ice_production,Ice production,seaIce,,,, +iiceheco,siheco,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea ice heat content,seaIce,,,, +ibgsaltco,sisaltcga,global mean ice salt content,Global mean ice salt content,seaIce,,,, +iicethic:sithic,sit,sea_ice_thickness,Sea ice thickness,seaIce,,,, +iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce,,,, +iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce,,,, +ibgtemper,sitempga,sea_ice_temperature,Global mean sea ice temperature,seaIce,,K,, +iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce,,,, +iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce,,,, +iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce,,,, +ibgvoltot,sivolga,sea_ice_volume,Global mean sea ice volume,seaIce,,,, +sivoln,sivoln,sea_ice_volume,Total volume of sea ice in the northern hemisphere,seaIce,,,, +sivols,sivols,sea_ice_volume,Total volume of sea ice in the southern hemisphere,seaIce,,,, +sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea ice volume per gridcell area unit,seaIce,,,, +sostatl,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, +sostind,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, +sostipc,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, +sostpac,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, +sopstadv,sltbasinadv,northward_ocean_salt_transport_due_to_advection,Northward ocean salt transport due to advection ,ocean,,,, +sopsteiv,sltbasinba,northward_ocean_salt_transport_due_to_bolus_advection,Northward ocean salt transport due to bolus advection ,ocean,,,, +sopstldf,sltbasindif,northward_ocean_salt_transport_due_to_diffusion,Northward ocean salt transport due to diffusion,ocean,,,, +sltnortha,sltnortha,northward_ocean_salt_transport,Atlantic northward ocean salt transport,ocean,,,, +sopstove,sltovovrt,northward_ocean_salt_transport_due_to_overturning,Northward ocean salt transport due to overturning ,ocean,,,, +zosalatl,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Atl,,, +zosalglo,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Glob,,, +zosalind,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Ind,,, +zosalipc,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,IndPac,,, +zosalpac,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Pac,,, +asn,snal,snow_albedo,Snow albedo,landIce,,,, +iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce,,,, +isnoheco,snheco,snow_heat_content,Snow total heat content,seaIce,,,, +sd,snld,lwe_thickness_of_surface_snow_amount,Snow depth,atmos,,,, +smlt,snm,surface_snow_melt_flux,Surface snow melt,landIce,,,, +isnowthi,snthic,surface_snow_thickness,Surface snow thickness,seaIce,,,, +sbgvoltot,snvolga,snow_volume,Global mean snow volume,seaIce,,,, +snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow volume per gridcell area unit,seaIce,,,, +vosaline,so,sea_water_salinity,Sea water salinity,ocean,,,, +scsaltot,soga,sea_water_salinity,Global mean sea water salinity ,ocean,,,, +hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic northward ocean heat transport,ocean,,,, +soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,Eddy induced vel. coeff. at w-point,ocean,,,, +soleahtw,soleahtw,lateral_eddy_diffusivity,Lateral eddy diffusivity,ocean,,,, +somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (turbocline),ocean,,,, +sosaline,sos,sea_surface_salinity,Sea surface salinity ,ocean,,,, +tos,sosstsst,sea_surface_temperature,Sea surface temperature,ocean,,K,, +sothedep,sothedep,thermocline_depth,Thermocline depth (max dt/dz),ocean,,,, +src,src,skin_reservoir_content,Skin reservoir content,land,,,, +zosrfatl,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Atl,,, +zosrfglo,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Glob,,, +zosrfind,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Ind,,, +zosrfipc,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,IndPac,,, +zosrfpac,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Pac,,, +rsn,srho,snow_density,Snow density,landIce,,,, +iicesali:iice_std,ssi,sea_ice_salinity,Sea ice salinity,seaIce,,,, +salincat,ssicat,sea_ice_salinity_in_categories,Sea-ice bulk salinity for categories,seaIce,,,, +ibgsaline,ssiga,sea_ice_salinity,Global mean sea ice salinity ,seaIce,,,, +iicestre,streng,compressive_strength_of_sea_ice,Compressive sea ice strength,seaIce,,,, +so20chgt,t20d,depth_of_isosurface_of_sea_water_potential_temperature,,ocean,,,, +t,ta,air_temperature,Air temperature,atmos,,K,, +t2m,tas,air_temperature,Near-surface air temperature,atmos,,K,, +mx2t,tasmax,air_temperature,Daily maximum near-surface air temperature,atmos,,K,, +mn2t,tasmin,air_temperature,Daily minimum near-surface air temperature,atmos,,K,, +ewss,tauu,surface_downward_eastward_stress,Surface downward eastward wind stress,atmos,,,, +utau_ice:iocestru:iicestru,tauu,surface_downward_eastward_stress,Surface downward eastward wind stress,seaIce,,,, +sozotaux,tauuo,surface_downward_x_stress,Surface downward x stress ,ocean,,,, +nsss,tauv,surface_downward_northward_stress,Surface downward northward wind stress,atmos,,,, +vtau_ice:iocestrv:iicestrv,tauv,surface_downward_northward_stress,Surface downward northward wind stress,seaIce,,,, +sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface downward y stress ,ocean,,,, +d2m,tdps,dew_point_temperature,2m dewpoint temperature,atmos,,K,, +votemper,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,,, +sctemtot,thetaoga,sea_water_potential_temperature,Global average sea water potential temperature ,ocean,,K,, +iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of melt at upper surface of sea ice,seaIce,,,, +sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,, +sstk,tos,sea_surface_temperature,Sea surface temperature ,atmos,,K,, +tossq,tossq,square_of_sea_surface_temperature,Square of sea surface temperature ,ocean,,K,, +zotematl,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Atl,K,, +zotemglo,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Glob,K,, +zotemind,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Ind,K,, +zotemipc,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,IndPac,K,, +zotempac,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Pac,K,, +skt,ts,surface_temperature,Surface temperature,atmos,,K,, +iicesurt:soicetem:sistem,tsice,surface_temperature,Surface temperature of sea ice,seaIce,,K,, +istl1,tsice,surface_temperature,Surface temperature of ice,landIce,,K,, +stl1,tsl1,soil_temperature_level_1,Temperature of soil level 1,land,,,, +stl2,tsl2,soil_temperature_level_2,Temperature of soil level 2,land,,,, +stl3,tsl3,soil_temperature_level_3,Temperature of soil level 3,land,,,, +stl4,tsl4,soil_temperature_level_4,Temperature of soil level 4,land,,,, +tsn,tsn,temperature_in_surface_snow,Snow internal temperature,landIce,,,, +u,ua,eastward_wind,U velocity,atmos,,,, +u10m,uas,eastward_wind,Eastward near-surface wind,atmos,,,, +vozocrtx,uo,sea_water_x_velocity,Sea water x velocity,ocean,,,, +v,va,northward_wind,V velocity,atmos,,,, +v10m,vas,northward_wind,Northward near-surface wind,atmos,,,, +vomecrty,vo,sea_water_y_velocity,Sea water y velocity,ocean,,,, +voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt vertical eddy diffusivity,ocean,,,, +vozoeivu,voeivu,sea_water_x_EIV_current,Zonal eiv current,ocean,,,, +vomeeivv,voeivv,sea_water_y_EIV_current,Meridional eiv current,ocean,,,, +voveeivw,voeivz,sea_water_z_EIV_current,Vertical eiv current,ocean,,,, +scvoltot,volo,sea_water_volume,Sea water volume ,ocean,,,, +votkeavm,votkeavm,vertical_eddy_viscosity,Vertical eddy viscosity,ocean,,,, +votkeavt,votkeavt,vertical_eddy_diffusivity,Vertical eddy diffusivity,ocean,,,, +votkeevd,votkeevd,enhanced_vertical_diffusivity,Enhanced vertical diffusivity,ocean,,,, +votkeevm,votkeevm,enhanced_vertical_viscosity,Enhanced vertical viscosity,ocean,,,, +sobarstf,vsftbarot,ocean_barotropic_volume_streamfunction,Ocean barotropic volume streamfunction ,ocean,,,, +zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Atl,,, +zomsfglo,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Glob,,, +zomsfind,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Ind,,, +zomsfipc,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,IndPac,,, +zomsfpac,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Pac,,, +zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction_due_to_bolus_advection,Ocean meridional overturning volume streamfunction due to bolus advection ,ocean,,,, +w,wa,vertical_velocity,Vertical velocity,atmos,,,, +z,zg,geopotential_height,Geopotential height,atmos,,,, +vovecrtz,zo,sea_water_z_velocity,Sea water z velocity,ocean,,,, +sossheigh:sossheig,zos,sea_surface_height_above_geoid,Sea surface height above geoid ,ocean,,,, +scsshtot,zosga,global_average_sea_level_change,Global average sea level change ,ocean,,,, +scsshste,zossga,global_average_steric_sea_level_change,Global average steric sea level change ,ocean,,,, +zossq,zossq,square_of_sea_surface_height_above_geoid,Square of sea surface height above geoid ,ocean,,,, +scsshtst,zostoga,snthic,Global average thermosteric sea level change ,ocean,,,, +iocewflx,,,,seaIce,,,, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 72155db..2afcc6c 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -44,9 +44,9 @@ class DataManager(object): """ def __init__(self, exp_manager, institution, model, expid, datafolder, frequency, experiment_name, scratch_dir, nfrp, calendar='standard'): - self.initialization_method = 'to be filled' + self.initialization_method = 1 self.initialization_description = 'to be filled' - self.physics_version = 'to be filled' + self.physics_version = 1 self.physics_description = 'to be filled' self.associated_model = 'to be filled' self.source = 'to be filled' @@ -64,6 +64,7 @@ class DataManager(object): self.nfrp = nfrp self.exp_manager = exp_manager Variable.load_variables() + UnitConversion.load_conversions() # noinspection PyPep8Naming def prepare_CMOR_files(self, force_rebuild, ocean, atmosphere): @@ -540,6 +541,14 @@ class DataManager(object): var_cmor = Variable.get_variable(variable) if var_cmor is None: return + if frequency == 'd': + frequency = 'day' + elif frequency == 'm': + frequency = 'mon' + elif frequency == 'h': + frequency = '6hr' + else: + raise Exception('Frequency {0} not supported'.format(frequency)) Utils.nco.ncks(input=file_path, output=temp, options='-v {0}'.format(variable)) if var_cmor.domain == 'ocean': Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev', @@ -556,16 +565,8 @@ class DataManager(object): if 'time' in handler_cmor.dimensions.keys(): Utils.copy_variable(handler, handler_cmor, 'leadtime', False) handler_cmor.modeling_realm = var_cmor.domain - handler_cmor.table_id = 'SPECS_' + self.domain_abbreviation(var_cmor.domain, frequency) + handler_cmor.table_id = 'Table {0} (December 2013)'.format(self.domain_abbreviation(var_cmor.domain, frequency)) handler_cmor.close() - if frequency == 'd': - frequency = 'day' - elif frequency == 'm': - frequency = 'mon' - elif frequency == 'h': - frequency = '6hr' - else: - raise Exception('Frequency {0} not supported'.format(frequency)) if var_cmor.basin is None: region = None @@ -632,17 +633,17 @@ class DataManager(object): def _add_common_attributes(self, frequency, handler, member, startdate): handler.associated_experiment = self.associated_experiment - handler.batch = '{0}{1}'.format(self.institution, datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')) + handler.batch = '{0}{1}'.format(self.institution, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ 'Javier Vegas-Regidor, javier.vegas@bsc.es ' - handler.conventions = 'CF-1.6' - handler.creation_date = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ') + handler.Conventions = 'CF-1.6' + handler.creation_date = datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)') handler.experiment_id = self.experiment_name - handler.forecast_reference_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ') + handler.forecast_reference_time = parse_date(startdate).strftime('%Y-%m-%d(T%H:%M:%SZ)') if frequency == 'd': - handler.frequency = 'daily' + handler.frequency = 'day' elif frequency == 'm': - handler.frequency = 'monthly' + handler.frequency = 'mon' handler.institute_id = self.institution handler.institution = self.institution handler.initialization_method = self.initialization_method @@ -652,7 +653,7 @@ class DataManager(object): handler.model_id = self.model handler.associated_model = self.associated_model handler.project_id = 'SPECS' - handler.realization = member + 1 + handler.realization = str(member + 1) handler.source = self.source handler.startdate = 'S{0}'.format(startdate) handler.tracking_id = str(uuid.uuid1()) @@ -858,8 +859,18 @@ class DataManager(object): var_handler.standard_name = cmor_var.standard_name var_handler.long_name = cmor_var.long_name var_handler.short_name = cmor_var.short_name + if cmor_var.units and cmor_var.units != var_handler.units: + factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, cmor_var.units) + if factor is not None: + if factor != 1 or offset != 0: + var_handler[:] = var_handler[:]*factor + offset + var_handler.units = cmor_var.units + var_handler.missingValue = 1.0e20 handler.sync() handler.close() + Utils.nco.ncatted(input=filetosend, output=filetosend, options='-O -a _FillValue,{0},m,f,"1.e20"'.format(var)) + else: + Log.warning('Variable {0} is not defined in the table. Please add it', var) temp = TempFile.get() Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) @@ -976,6 +987,7 @@ class Variable(object): Class to characterize a CMOR variable. It also contains the static method to make the match between thje original name and the standard name. Requires cmor_table.csv to work. """ + _dict_variables = None def __init__(self, line): self.short_name = line[1] @@ -983,7 +995,8 @@ class Variable(object): self.long_name = line[3] self.domain = line[4] self.basin = Basins.parse(line[5]) - self._dict_variables = None + self.units = line[6] + @classmethod def get_variable(cls, original_name): @@ -995,7 +1008,7 @@ class Variable(object): :rtype: Variable """ try: - return Variable._dict_variables[original_name.lower()] + return cls._dict_variables[original_name.lower()] except KeyError: Log.error('Variable {0} is not defined'.format(original_name)) return None @@ -1020,3 +1033,73 @@ class Variable(object): Variable._dict_variables[old_name] = var Variable._dict_variables[var.short_name] = var + +class UnitConversion(object): + _dict_conversions = None + + @classmethod + def load_conversions(cls): + cls._dict_conversions = dict() + cls.add_conversion(UnitConversion('C', 'K', 1, 273.15)) + cls.add_conversion(UnitConversion('degC', 'K', 1, 273.15)) + cls.add_conversion(UnitConversion('m2', 'km2', 1e6, 0)) + cls.add_conversion(UnitConversion('m3', 'km3', 1e9, 0)) + + @classmethod + def add_conversion(cls, conversion): + cls._dict_conversions[(conversion.source, conversion.destiny)] = conversion + + def __init__(self, source, destiny, factor, offset): + self.source = source + self.destiny = destiny + self.factor = float(factor) + self.offset = float(offset) + + @classmethod + def get_conversion_factor_offset(cls, input_units, output_units): + units = input_units.split() + if len(units) == 1: + scale_unit = 1 + unit = units[0] + else: + if '^' in units[0]: + values = units[0].split('^') + scale_unit = pow(int(values[0]), int(values[1])) + else: + scale_unit = float(units[0]) + unit = units[1] + + units = output_units.split() + if len(units) == 1: + scale_new_unit = 1 + new_unit = units[0] + else: + if '^' in units[0]: + values = units[0].split('^') + scale_new_unit = pow(int(values[0]), int(values[1])) + else: + scale_new_unit = float(units[0]) + new_unit = units[1] + + factor, offset = UnitConversion._get_factor(new_unit, unit) + if factor is None: + raise Exception("Conversion from {0} to {1} not supported".format(input_units, output_units)) + factor = factor * scale_unit / float(scale_new_unit) + offset /= float(scale_new_unit) + + return factor, offset + + @classmethod + def _get_factor(cls, new_unit, unit): + # Add only the conversions with a factor greater than 1 + if unit == new_unit: + return 1, 0 + elif (unit, new_unit) in cls._dict_conversions: + conversion = cls._dict_conversions[(unit, new_unit)] + return conversion.factor, conversion.offset + elif (new_unit, unit) in cls._dict_conversions: + conversion = cls._dict_conversions[(unit, new_unit)] + return 1/conversion.factor, -conversion.offset + else: + return None, None + diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 612b921..9f8ac93 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -25,8 +25,6 @@ class Diagnostic(object): Register a new diagnostic using the given alias. It must be call using the derived class. :param cls: diagnostic class to register :type cls: Diagnostic - :param alias: alias for the diagnostic - :type alias: str """ try: Diagnostic._diag_list[cls.alias] = cls diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 3c71c6d..09ebc69 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -292,9 +292,9 @@ class Diags(object): self.data_manager.initialization_description = self.parser.get_option('CMOR', 'INITIALIZATION_DESCRIPTION', 'to be filled') self.data_manager.initialization_method = self.parser.get_option('CMOR', 'INITIALIZATION_METHOD', - 'to be filled') + '1') self.data_manager.physics_description = self.parser.get_option('CMOR', 'PHYSICS_DESCRIPTION', 'to be filled') - self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', 'to be filled') + self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', '1') self.data_manager.source = self.parser.get_option('CMOR', 'SOURCE', 'to be filled') diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 8434691..b6a2897 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -114,33 +114,27 @@ class Siasiesiv(Diagnostic): except Exception as ex: print ex - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[4, :], 'sivols', - "10^3 km3", "10^9 m3"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[4, :], 'sivols'), 'seaIce', 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[5, :], 'siareas', - "10^6 km2", "10^9 m2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[5, :], 'siareas'), 'seaIce', 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[7, :], 'siextents', - "10^6 km2", "10^9 m2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[7, :], 'siextents'), 'seaIce', 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[0, :], 'sivoln', - "10^3 km3", "10^9 m3"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[0, :], 'sivoln'), 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[1, :], 'siarean', - "10^6 km2", "10^9 m2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[1, :], 'siarean'), 'seaIce', 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[3, :], 'siextentn', - "10^6 km2", "10^9 m2"), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[3, :], 'siextentn'), 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) - def _extract_variable_and_rename(self, reference_file, values, cmor_name, output_units, target_units): + def _extract_variable_and_rename(self, reference_file, values, cmor_name): temp = TempFile.get() reference_handler = Utils.openCdf(reference_file) os.remove(temp) @@ -158,65 +152,9 @@ class Siasiesiv(Diagnostic): reference_handler.close() new_var = handler.createVariable(cmor_name, float, 'time', fill_value=0.0) - factor = self._get_conversion_factor(target_units, output_units) - values *= factor - new_var[:] = values - new_var.units = output_units new_var.short_name = cmor_name new_var.valid_min = 0.0 new_var.valid_max = np.max(values) handler.close() return temp - def _get_conversion_factor(self, input_units, output_units): - units = input_units.split() - if len(units) == 1: - scale_unit = 1 - unit = units[0] - else: - if '^' in units[0]: - values = units[0].split('^') - scale_unit = pow(int(values[0]), int(values[1])) - else: - scale_unit = float(units[0]) - unit = units[1] - - units = output_units.split() - if len(units) == 1: - scale_new_unit = 1 - new_unit = units[0] - else: - if '^' in units[0]: - values = units[0].split('^') - scale_new_unit = pow(int(values[0]), int(values[1])) - else: - scale_new_unit = float(units[0]) - new_unit = units[1] - - factor = self._get_factor(new_unit, unit) - invert = False - if factor is None: - factor = self._get_factor(unit, new_unit) - invert = True - - if factor is None: - raise Exception("Conversion from {0} to {1} not supported".format(input_units, output_units)) - - if invert: - factor = scale_unit / float(scale_new_unit * factor) - else: - factor = (factor * scale_unit) / float(scale_new_unit) - return factor - - @staticmethod - def _get_factor(new_unit, unit): - # Add only the conversions with a factor greater than 1 - if unit == new_unit: - return 1 - if unit == 'km3': - if new_unit == 'm3': - return pow(1000, 3) - elif unit == 'km2': - if new_unit == 'm2': - return pow(1000, 2) - return None -- GitLab From ae8498ad09e0d35c370709b27a0bd87373ec51fa Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 13 Jul 2016 17:09:30 +0200 Subject: [PATCH 131/268] Bug fix in ohc_layer (not finished) --- earthdiagnostics/diags.conf | 4 +- earthdiagnostics/ocean/heatcontentlayer.py | 159 +++++++++------------ 2 files changed, 66 insertions(+), 97 deletions(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 0071f86..1b633da 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -7,7 +7,7 @@ DATA_DIR = /esnas/exp/nemo/ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below) -DIAGS = SIASIESIV +DIAGS = OHC_SPECIFIED_LAYER # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -53,7 +53,7 @@ MEMBERS = 0 MEMBER_DIGITS = 2 CHUNK_SIZE = 12 # CHUNKS = 58 -CHUNKS = 58 +CHUNKS = 1 diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index f6cd9e0..00d02b2 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -33,11 +33,13 @@ class HeatContentLayer(Diagnostic): alias = 'ohclayer' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, box): + def __init__(self, data_manager, startdate, member, chunk, box, weight): Diagnostic.__init__(self, data_manager) self.startdate = startdate - self.member = membergdepth_0self.chunk = chunk + self.member = member + self.chunk = chunk self.box = box + self.weight = weight self.required_vars = ['so', 'mlotst'] self.generated_vars = ['scvertsum'] @@ -65,116 +67,83 @@ class HeatContentLayer(Diagnostic): box.min_depth = int(options[1]) box.max_depth = int(options[2]) job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box)) - return job_list - - def compute(self): - """ - Runs the diagnostic - """ - nco = Utils.nco - temp = TempFile.get() - heatc_sl_out = TempFile.get() - heatc_sl_top = TempFile.get() - level_above = TempFile.get() - level_below = TempFile.get() - heatc_sl_bottom = TempFile.get() - heatc_sl_top_invert = TempFile.get() - e3tfile = TempFile.get() - results = TempFile.get() handler = Utils.openCdf('mesh_zgr.nc') + + tmask = handler.variables['tmask'][:] + if 'e3t' in handler.variables: - e3t_name = 'e3t' + tmask = handler.variables['e3t'][:] * tmask elif 'e3t_0' in handler.variables: - e3t_name = 'e3t_0' + tmask = handler.variables['e3t_0'][:] * tmask else: raise Exception('e3t variable can not be found') - handler.close() - - handler = Utils.openCdf('mesh_zgr.nc') - if 'gdepth_0' in handler.variables: - gdept = 'gdept_0' + if 'gdept' in handler.variables: + depth = handler.variables['gdept'][:] + if 'gdept_0' in handler.variables: + depth = handler.variables['gdept_0'][:] else: raise Exception('gdept_0 variable can not be found') handler.close() + def calculate_weight(a): + level = 0 + previous_level = 0 + + while a[level] <= box.min_depth: + previous_level = a[level] + a[level] = 0 + level += 1 + if level >= a.size: + return a + + if previous_level != box.min_depth: + weight = (a[level] - box.min_depth) / (a[level] - previous_level) + previous_level = a[level] + a[level] = weight + level += 1 + if level >= a.size: + return a + + while a[level] <= box.max_depth: + previous_level = a[level] + a[level] = 1 + level += 1 + if level >= a.size: + return a + + if previous_level != box.max_depth: + weight = (box.max_depth - previous_level) / (a[level] - previous_level) + a[level] = weight + level += 1 + if level >= a.size: + return a + + a[level:] = 0 + return a + + weight = tmask * np.apply_along_axis(calculate_weight, 1, depth) + + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box, weight)) + return job_list - nco.ncap2(input='mesh_zgr.nc', output=e3tfile, options='-v -O -s "heatc_sl=tmask*{0}"'.format(e3t_name)), + def compute(self): + """ + Runs the diagnostic + """ + nco = Utils.nco + results = TempFile.get() thetao_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) - nco.ncks(input=thetao_file, output=temp, options='-O -v thetao') - Utils.rename_variable(temp, 'thetao', 'heatc_sl') - cdo.mul(input=' '.join([temp, e3tfile]), output=heatc_sl_out) - - # extract the data between the two given depths --> heatc_sl_top.nc - nco.ncks(input=heatc_sl_out, output=heatc_sl_top, - options='-O -d lev,{0}.0,{1}.0'.format(self.box.min_depth, self.box.max_depth)) - - ## Eleftheria, modifications start here ############## - # Detemrine the upper boundary of the top level - for k in range (0, size(gdepth)): - if self.box.min_depth >= gdept(k) - upper_boundary = (gdept(k) - gdept (k-1) )/ 2. - top_level = gdept(k) - break - - # Detemrine the lower boundary of the bottom level - k=0 - while self.box.max_depth <= gdept: - lower_boundary = (gdept(k) - gdept (k-1) )/ 2. - bottom_level = gdept(k) - k += 1 - - # Calculate the top residuals res1 and the bottom residual res2 - tmp1 = cdo.sellevel (top_level, input=temp) - tmp2 = cdo.sellevel (bottom_level, input=temp) - res1 = cdo.mulc(upper_boundary - self.box.min_depth, tmp1) - res2 = cdo.mulc(self.box.max_depth - lower_boundary, tmp2) - - # Add the top and bottom residuals res1/res2 to the ocean heat content - cdo.add(input=' '.join([heatc_s1_out, res1]), output=heatc_sl_out1) - cdo.add(input=' '.join([heatc_s1_out1, res2]), output=heatc_sl_out2) - -# # now extract a few levels below, to compute the residual ohc -# # addition with float returned: -# nco.ncks(input=heatc_sl_out, output=heatc_sl_bottom, -# options='-O -d lev,{0}.0,{1}.0'.format(self.box.max_depth, self.box.max_depth + 200)) -# -# # obtain the weight for the extra level containing the 300 m -# # deptht in the gridT files is positive -# # weight = (300.0 - depth_top)/(depth_bottom - depth_top) -# # and add the thickness down to 300 m in the next layer -# nco.ncpdq(options="-a '-lev'", input=heatc_sl_top, output=heatc_sl_top_invert) -# nco.ncks(input=heatc_sl_top_invert, output=level_above, options='-O -d lev,0,0,1') -# nco.ncks(input=heatc_sl_bottom, output=level_below, options='-O -d lev,0,0,1') -# -# handler = Utils.openCdf(level_above) -# lev_above = handler.variables['lev'][:] -# handler.close() -# -# handler = Utils.openCdf(level_below) -# layerthcknss = handler.variables['lev'][:] - lev_above -# heatc_sl_below = handler.variables['heatc_sl'][:] -# handler.close() -# -# factor = (self.box.max_depth - lev_above) / layerthcknss -# -# heatc_sl_below = heatc_sl_below * factor - ## Eleftheria, modifications end here ############## - - - handler = Utils.openCdf(heatc_sl_top) - heatc_sl = handler.variables['heatc_sl'][:] + handler = Utils.openCdf(thetao_file) + heatc_sl = np.sum(handler.variables['thetao'][:] * 1020 * 4000 * self.weight, 1) + handler.sync() + handler.renameVariable('thetao', 'heatc_sl') handler.close() - heatc_sl = np.sum(heatc_sl, 1) - heatc_sl = heatc_sl[:] + heatc_sl_below[:, 0, :] - heatc_sl = heatc_sl[:] * 1020 * 4000 - nco.ncks(input=thetao_file, output=results, options='-O -v lon,lat,time') Utils.rename_variables(results, {'x': 'i', 'y': 'j'}, False, True) handler_results = Utils.openCdf(results) -- GitLab From f16c7da93eaa72249d8e25edf17cf4f72390955d Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 13 Jul 2016 18:05:45 +0200 Subject: [PATCH 132/268] Bug fix in ohc_layer --- earthdiagnostics/cmor_table.csv | 2 +- earthdiagnostics/datamanager.py | 14 ++--- earthdiagnostics/ocean/heatcontentlayer.py | 70 ++++++++++++---------- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 87ddbdb..0935b88 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -139,7 +139,7 @@ sosalflx,sfs,salt_flux_surface,Surface salt flux,ocean,,,, si,si,solar_insolation,Solar insolation,atmos,,,, siarean,siarean,sea_ice_area,Total area of sea ice in the northern hemisphere,seaIce,,,, siareas,siareas,sea_ice_area,Total area of sea ice in the southern hemisphere,seaIce,,,, -iiceconc:siconc:soicecov:ileadfra:ci,sic,sea_ice_area_fraction,Sea ice area fraction,seaIce,,,, +iiceconc:siconc:soicecov:ileadfra:ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce,,,, iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,,,, ibgarea,sicga,sea_ice_content,Global mean sea ice content,seaIce,,,, siextentn,siextentn,sea_ice_extent,Total area of all northern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,,, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 2afcc6c..518050e 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -868,7 +868,8 @@ class DataManager(object): var_handler.missingValue = 1.0e20 handler.sync() handler.close() - Utils.nco.ncatted(input=filetosend, output=filetosend, options='-O -a _FillValue,{0},m,f,"1.e20"'.format(var)) + Utils.nco.ncatted(input=filetosend, output=filetosend, + options='-O -a _FillValue,{0},m,f,"1.e20"'.format(var)) else: Log.warning('Variable {0} is not defined in the table. Please add it', var) @@ -990,13 +991,12 @@ class Variable(object): _dict_variables = None def __init__(self, line): - self.short_name = line[1] - self.standard_name = line[2] - self.long_name = line[3] - self.domain = line[4] + self.short_name = line[1].strip() + self.standard_name = line[2].strip() + self.long_name = line[3].strip() + self.domain = line[4].strip() self.basin = Basins.parse(line[5]) - self.units = line[6] - + self.units = line[6].strip() @classmethod def get_variable(cls, original_name): diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 00d02b2..d4e39a1 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -3,7 +3,6 @@ import numpy as np from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic -from earthdiagnostics import cdo from earthdiagnostics.utils import Utils, TempFile @@ -79,51 +78,56 @@ class HeatContentLayer(Diagnostic): else: raise Exception('e3t variable can not be found') - if 'gdept' in handler.variables: - depth = handler.variables['gdept'][:] - if 'gdept_0' in handler.variables: - depth = handler.variables['gdept_0'][:] + if 'gdepw' in handler.variables: + depth = handler.variables['gdepw'][:] + elif 'gdepw_0' in handler.variables: + depth = handler.variables['gdepw_0'][:] else: - raise Exception('gdept_0 variable can not be found') + raise Exception('gdepw variable can not be found') handler.close() - def calculate_weight(a): + def calculate_weight(array): + """ + Calculates the weight for each level for the given later + :param array: + :return: + """ level = 0 - previous_level = 0 - while a[level] <= box.min_depth: - previous_level = a[level] - a[level] = 0 + while array[level+1] <= box.min_depth: + array[level] = 0 level += 1 - if level >= a.size: - return a + if level == array.size - 1: + array[level] = 0 + return array - if previous_level != box.min_depth: - weight = (a[level] - box.min_depth) / (a[level] - previous_level) - previous_level = a[level] - a[level] = weight + if array[level] != box.min_depth: + weight_value = (array[level + 1] - box.min_depth) / (array[level + 1] - array[level]) + array[level] = weight_value level += 1 - if level >= a.size: - return a + if level == array.size - 1: + array[level] = 0 + return array - while a[level] <= box.max_depth: - previous_level = a[level] - a[level] = 1 + while array[level + 1] <= box.max_depth: + array[level] = 1 level += 1 - if level >= a.size: - return a + if level == array.size - 1: + array[level] = 0 + return array - if previous_level != box.max_depth: - weight = (box.max_depth - previous_level) / (a[level] - previous_level) - a[level] = weight + if array[level] != box.max_depth: + weight_value = (box.max_depth - array[level]) / (array[level + 1] - array[level]) + array[level] = weight_value level += 1 - if level >= a.size: - return a + if level == array.size - 1: + array[level] = 0 + return array - a[level:] = 0 - return a + array[level:] = 0 + return array - weight = tmask * np.apply_along_axis(calculate_weight, 1, depth) + weight = tmask * np.apply_along_axis(calculate_weight, 1, depth) * 1020 * 4000 for startdate, member, chunk in diags.exp_manager.get_chunk_list(): job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box, weight)) @@ -139,7 +143,7 @@ class HeatContentLayer(Diagnostic): thetao_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) handler = Utils.openCdf(thetao_file) - heatc_sl = np.sum(handler.variables['thetao'][:] * 1020 * 4000 * self.weight, 1) + heatc_sl = np.sum(handler.variables['thetao'][:] * self.weight, 1) handler.sync() handler.renameVariable('thetao', 'heatc_sl') handler.close() -- GitLab From b62db66cf5db86c8cff7db8f23c1b5d5c4ad78c0 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 14 Jul 2016 11:27:42 +0200 Subject: [PATCH 133/268] Optimizations for ohc_layer and bugfixes in siasiesiv and datamanager.send_file --- earthdiagnostics/cmor_table.csv | 20 ++++++++++---------- earthdiagnostics/datamanager.py | 14 +++++++------- earthdiagnostics/diags.conf | 6 +++--- earthdiagnostics/ocean/heatcontentlayer.py | 19 ++++++++++++++++--- earthdiagnostics/ocean/siasiesiv.py | 18 ++++++++++-------- 5 files changed, 46 insertions(+), 31 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 0935b88..472f178 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -137,26 +137,26 @@ saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrate es,sbl,surface_snow_and_ice_sublimation_flux,Surface snow and ice sublimation flux,landIce,,,, sosalflx,sfs,salt_flux_surface,Surface salt flux,ocean,,,, si,si,solar_insolation,Solar insolation,atmos,,,, -siarean,siarean,sea_ice_area,Total area of sea ice in the northern hemisphere,seaIce,,,, -siareas,siareas,sea_ice_area,Total area of sea ice in the southern hemisphere,seaIce,,,, -iiceconc:siconc:soicecov:ileadfra:ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce,,,, +siarean,siarean,sea_ice_area,Total area of sea ice in the northern hemisphere,seaIce,,10^6 km2,, +siareas,siareas,sea_ice_area,Total area of sea ice in the southern hemisphere,seaIce,,10^6 km2,, +iiceconc:siconc:soicecov:ileadfra:ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce,,%,, iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,,,, ibgarea,sicga,sea_ice_content,Global mean sea ice content,seaIce,,,, -siextentn,siextentn,sea_ice_extent,Total area of all northern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,,, -siextents,siextents,sea_ice_extent,Total area of all southern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,,, +siextentn,siextentn,sea_ice_extent,Total area of all northern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,, +siextents,siextents,sea_ice_extent,Total area of all southern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,, iiceprod,sigr,ice_production,Ice production,seaIce,,,, iiceheco,siheco,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea ice heat content,seaIce,,,, ibgsaltco,sisaltcga,global mean ice salt content,Global mean ice salt content,seaIce,,,, -iicethic:sithic,sit,sea_ice_thickness,Sea ice thickness,seaIce,,,, +iicethic:sithic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce,,m,, iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce,,,, -iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce,,,, +iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce,,K,, ibgtemper,sitempga,sea_ice_temperature,Global mean sea ice temperature,seaIce,,K,, iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce,,,, iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce,,,, iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce,,,, ibgvoltot,sivolga,sea_ice_volume,Global mean sea ice volume,seaIce,,,, -sivoln,sivoln,sea_ice_volume,Total volume of sea ice in the northern hemisphere,seaIce,,,, -sivols,sivols,sea_ice_volume,Total volume of sea ice in the southern hemisphere,seaIce,,,, +sivoln,sivoln,sea_ice_volume,Total volume of sea ice in the northern hemisphere,seaIce,,10^3 km3,, +sivols,sivols,sea_ice_volume,Total volume of sea ice in the southern hemisphere,seaIce,,10^3 km3,, sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea ice volume per gridcell area unit,seaIce,,,, sostatl,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, sostind,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, @@ -261,4 +261,4 @@ scsshtot,zosga,global_average_sea_level_change,Global average sea level change , scsshste,zossga,global_average_steric_sea_level_change,Global average steric sea level change ,ocean,,,, zossq,zossq,square_of_sea_surface_height_above_geoid,Square of sea surface height above geoid ,ocean,,,, scsshtst,zostoga,snthic,Global average thermosteric sea level change ,ocean,,,, -iocewflx,,,,seaIce,,,, +heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,,, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 518050e..7f7b678 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -766,6 +766,7 @@ class DataManager(object): :return: path to the copy created on the scratch folder :rtype: str """ + cmor_var = Variable.get_variable(var) if box: var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() @@ -852,7 +853,7 @@ class DataManager(object): Utils.move_file(temp, filetosend) Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') - cmor_var = Variable.get_variable(var) + if cmor_var: handler = Utils.openCdf(filetosend) var_handler = handler.variables[var] @@ -865,13 +866,12 @@ class DataManager(object): if factor != 1 or offset != 0: var_handler[:] = var_handler[:]*factor + offset var_handler.units = cmor_var.units - var_handler.missingValue = 1.0e20 + var_type = var_handler.dtype handler.sync() handler.close() Utils.nco.ncatted(input=filetosend, output=filetosend, - options='-O -a _FillValue,{0},m,f,"1.e20"'.format(var)) - else: - Log.warning('Variable {0} is not defined in the table. Please add it', var) + options='-O -a _FillValue,{0},m,{1},"1.e20" ' + '-a missingValue,{0},m,{1},"1.e20"'.format(var, var_type.char)) temp = TempFile.get() Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) @@ -1001,7 +1001,7 @@ class Variable(object): @classmethod def get_variable(cls, original_name): """ - Returns the cmor variable instance given a varuiable name + Returns the cmor variable instance given a variable name :param original_name: original variable's name :type original_name: str :return: CMOR variable @@ -1010,7 +1010,7 @@ class Variable(object): try: return cls._dict_variables[original_name.lower()] except KeyError: - Log.error('Variable {0} is not defined'.format(original_name)) + Log.warning('Variable {0} is not defined in the CMOR table. Please add it'.format(original_name)) return None @classmethod diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 1b633da..89e1a06 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -7,7 +7,7 @@ DATA_DIR = /esnas/exp/nemo/ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below) -DIAGS = OHC_SPECIFIED_LAYER +DIAGS = OHC_SPECIFIED_LAYER siasiesiv # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -15,7 +15,7 @@ CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -# MAX_CORES = 4 +MAX_CORES = 4 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False @@ -53,7 +53,7 @@ MEMBERS = 0 MEMBER_DIGITS = 2 CHUNK_SIZE = 12 # CHUNKS = 58 -CHUNKS = 1 +CHUNKS = 58 diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index d4e39a1..7ed1fae 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -32,13 +32,15 @@ class HeatContentLayer(Diagnostic): alias = 'ohclayer' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, box, weight): + def __init__(self, data_manager, startdate, member, chunk, box, weight, min_level, max_level): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.box = box self.weight = weight + self.min_level = min_level + self.max_level = max_level self.required_vars = ['so', 'mlotst'] self.generated_vars = ['scvertsum'] @@ -129,8 +131,19 @@ class HeatContentLayer(Diagnostic): weight = tmask * np.apply_along_axis(calculate_weight, 1, depth) * 1020 * 4000 + # Now we will reduce to the levels with any weigth != 0 + levels = weight.shape[1] + min_level = 0 + while min_level < levels and not weight[:, min_level, :].any(): + min_level += 1 + max_level = min_level + while max_level < (levels - 1) and weight[:, max_level + 1, :].any(): + max_level += 1 + weight = weight[:, min_level:max_level, :] + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box, weight)) + job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box, + weight, min_level, max_level)) return job_list def compute(self): @@ -143,7 +156,7 @@ class HeatContentLayer(Diagnostic): thetao_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) handler = Utils.openCdf(thetao_file) - heatc_sl = np.sum(handler.variables['thetao'][:] * self.weight, 1) + heatc_sl = np.sum(handler.variables['thetao'][:, self.min_level:self.max_level, :] * self.weight, 1) handler.sync() handler.renameVariable('thetao', 'heatc_sl') handler.close() diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index b6a2897..9920944 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -114,27 +114,27 @@ class Siasiesiv(Diagnostic): except Exception as ex: print ex - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[4, :], 'sivols'), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[4, :], 'sivols', '10^9 m3'), 'seaIce', 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[5, :], 'siareas'), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[5, :], 'siareas', '10^9 m2'), 'seaIce', 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[7, :], 'siextents'), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[7, :], 'siextents', '10^9 m2'), 'seaIce', 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[0, :], 'sivoln'), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[0, :], 'sivoln', '10^9 m3'), 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[1, :], 'siarean'), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[1, :], 'siarean', '10^9 m2'), 'seaIce', 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[3, :], 'siextentn'), + self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[3, :], 'siextentn', '10^9 m2'), 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) - def _extract_variable_and_rename(self, reference_file, values, cmor_name): + def _extract_variable_and_rename(self, reference_file, values, cmor_name, units): temp = TempFile.get() reference_handler = Utils.openCdf(reference_file) os.remove(temp) @@ -151,9 +151,11 @@ class Siasiesiv(Diagnostic): Utils.copy_variable(reference_handler, handler, 'leadtime') reference_handler.close() - new_var = handler.createVariable(cmor_name, float, 'time', fill_value=0.0) + new_var = handler.createVariable(cmor_name, float, 'time', fill_value=1.0e20) + new_var.units = units new_var.short_name = cmor_name new_var.valid_min = 0.0 + new_var[:] = values new_var.valid_max = np.max(values) handler.close() return temp -- GitLab From 135f1fc1c8da0c204cd9f218c32bc8d161876e29 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 14 Jul 2016 12:26:07 +0200 Subject: [PATCH 134/268] Fixed bug on heatcontentlayer when gdepw is not available --- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/ocean/heatcontentlayer.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 89e1a06..c91b5d4 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -15,7 +15,7 @@ CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -MAX_CORES = 4 +MAX_CORES = 2 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 7ed1fae..1df2192 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -86,6 +86,8 @@ class HeatContentLayer(Diagnostic): depth = handler.variables['gdepw_0'][:] else: raise Exception('gdepw variable can not be found') + while len(depth.shape) < 4: + depth = np.expand_dims(depth, -1) handler.close() def calculate_weight(array): -- GitLab From 5f110880cf513736b36cb691fc1664d96b651701 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 14 Jul 2016 12:48:24 +0200 Subject: [PATCH 135/268] Fixed bug on datamanager --- earthdiagnostics/datamanager.py | 5 ++++- earthdiagnostics/ocean/heatcontentlayer.py | 7 +++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 7f7b678..c2f7eea 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -766,12 +766,15 @@ class DataManager(object): :return: path to the copy created on the scratch folder :rtype: str """ + original_var = var cmor_var = Variable.get_variable(var) if box: var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() if rename_var: Utils.rename_variable(filetosend, rename_var, var) + elif original_var != var: + Utils.rename_variable(filetosend, original_var, var) if not frequency: frequency = self.frequency @@ -853,13 +856,13 @@ class DataManager(object): Utils.move_file(temp, filetosend) Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') - if cmor_var: handler = Utils.openCdf(filetosend) var_handler = handler.variables[var] var_handler.standard_name = cmor_var.standard_name var_handler.long_name = cmor_var.long_name var_handler.short_name = cmor_var.short_name + var_handler.missingValue = 1.e20 if cmor_var.units and cmor_var.units != var_handler.units: factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, cmor_var.units) if factor is not None: diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 1df2192..e4b685d 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -86,6 +86,7 @@ class HeatContentLayer(Diagnostic): depth = handler.variables['gdepw_0'][:] else: raise Exception('gdepw variable can not be found') + while len(depth.shape) < 4: depth = np.expand_dims(depth, -1) handler.close() @@ -166,10 +167,8 @@ class HeatContentLayer(Diagnostic): nco.ncks(input=thetao_file, output=results, options='-O -v lon,lat,time') Utils.rename_variables(results, {'x': 'i', 'y': 'j'}, False, True) handler_results = Utils.openCdf(results) - handler_results.createVariable('ohc', float, ('time', 'j', 'i')) - handler_results.close() - - handler_results = Utils.openCdf(results) + handler_results.createVariable('ohc', float, ('time', 'j', 'i'), fill_value=1.e20) + handler_results.sync() handler_results.variables['ohc'][:] = heatc_sl handler_results.close() -- GitLab From 6520dcc8db665e71a492147ecffad9652ef570b2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 14 Jul 2016 16:15:34 +0200 Subject: [PATCH 136/268] Fixed bug on CMORization when model output files starts with ORCA* instead of expid --- earthdiagnostics/datamanager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index c2f7eea..610c663 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -573,14 +573,15 @@ class DataManager(object): else: region = var_cmor.basin.fullname - if file_parts[0] == self.expid: + if file_parts[0] == self.expid or file_parts[0].startswith('ORCA'): # Model output date_str = '{0}-{1}'.format(file_parts[2][0:6], file_parts[3][0:6]) elif file_parts[1] == self.expid: # Files generated by the old version of the diagnostics date_str = '{0}-{1}'.format(file_parts[4][0:6], file_parts[5][0:6]) else: - Log.error('Variable {0} can not be cmorized. Original filename does not match a recognized pattern') + Log.error('Variable {0} can not be cmorized. Original filename does not match a recognized pattern', + var_cmor.short_name) return self.send_file(temp, var_cmor.domain, var_cmor.short_name, startdate, member, -- GitLab From 861957dd75850b53c50436865d518f5c0f42898d Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 14 Jul 2016 17:57:50 +0200 Subject: [PATCH 137/268] Unit conversions now loaded from file --- earthdiagnostics/conversions.csv | 7 +++++++ earthdiagnostics/datamanager.py | 20 +++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 earthdiagnostics/conversions.csv diff --git a/earthdiagnostics/conversions.csv b/earthdiagnostics/conversions.csv new file mode 100644 index 0000000..4131d02 --- /dev/null +++ b/earthdiagnostics/conversions.csv @@ -0,0 +1,7 @@ +original,converted,factor ,offset +C,K,1,273.15 +degC,K,1,273.15 +m,km,1000,0 +m2,km2,1.00E+006,0 +m3,km3,1.00E+009,0 +[0 1],%,100,1 diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 610c663..45c2787 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1039,15 +1039,23 @@ class Variable(object): class UnitConversion(object): + """ + Class to manage unit conversions + """ _dict_conversions = None @classmethod def load_conversions(cls): + """ + Load conversions from the configuration file + """ cls._dict_conversions = dict() - cls.add_conversion(UnitConversion('C', 'K', 1, 273.15)) - cls.add_conversion(UnitConversion('degC', 'K', 1, 273.15)) - cls.add_conversion(UnitConversion('m2', 'km2', 1e6, 0)) - cls.add_conversion(UnitConversion('m3', 'km3', 1e9, 0)) + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'conversions.csv'), 'rb') as csvfile: + reader = csv.reader(csvfile, dialect='excel') + for line in reader: + if line[0] == 'original': + continue + cls.add_conversion(UnitConversion(line[0], line[1], line[2], line[3])) @classmethod def add_conversion(cls, conversion): @@ -1087,7 +1095,9 @@ class UnitConversion(object): factor, offset = UnitConversion._get_factor(new_unit, unit) if factor is None: - raise Exception("Conversion from {0} to {1} not supported".format(input_units, output_units)) + Log.warning("Conversion from {0} to {1} not defined. Please add it to the table".format(input_units, + output_units)) + return None, None factor = factor * scale_unit / float(scale_new_unit) offset /= float(scale_new_unit) -- GitLab From 92028c44b8ab26ad464e0f68fb1b4830b47648a6 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 14 Jul 2016 18:47:57 +0200 Subject: [PATCH 138/268] Updated doc --- EarthDiagnostics.pdf | Bin 197355 -> 199024 bytes VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/datamanager.py | 19 ++++++++++++++++++- earthdiagnostics/diags.py | 2 +- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index b08247877738346636db2f7dbb527f0e5817701d..437e221fedf628f7ff812bb9268e64602e385cc8 100644 GIT binary patch delta 120053 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 z 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

h%l890Za$& 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 diff --git a/VERSION b/VERSION index 2aa4d8f..005e92c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b2 +3.0.0b3 diff --git a/doc/source/conf.py b/doc/source/conf.py index 99cd46c..d725d7d 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b2' +release = '3.0.0b3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 45c2787..62b9263 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1006,6 +1006,7 @@ class Variable(object): def get_variable(cls, original_name): """ Returns the cmor variable instance given a variable name + :param original_name: original variable's name :type original_name: str :return: CMOR variable @@ -1021,7 +1022,6 @@ class Variable(object): def load_variables(cls): """ Loads the cmor_table.csv and creates the variables dictionary - :return: """ Variable._dict_variables = dict() with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'cmor_table.csv'), 'rb') as csvfile: @@ -1059,6 +1059,12 @@ class UnitConversion(object): @classmethod def add_conversion(cls, conversion): + """ + Adds a conversion to the dictionary + + :param conversion: conversion to add + :type conversion: UnitConversion + """ cls._dict_conversions[(conversion.source, conversion.destiny)] = conversion def __init__(self, source, destiny, factor, offset): @@ -1069,6 +1075,17 @@ class UnitConversion(object): @classmethod def get_conversion_factor_offset(cls, input_units, output_units): + """ + Gets the conversion factor and offset for two units . The conversion has to be done in the following way: + converted = original * factor + offset + + :param input_units: original units + :type input_units: str + :param output_units: destiny units + :type output_units: str + :return: factor and offset + :rtype: [float, float] + """ units = input_units.split() if len(units) == 1: scale_unit = 1 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 09ebc69..c2ff36e 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -303,7 +303,7 @@ def main(): Entry point for the Earth Diagnostics. For more detailed documentation, use -h option """ parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') - parser.add_argument('-v', '--version', action='version', version='3.0.0b2', + parser.add_argument('-v', '--version', action='version', version='3.0.0b3', help="returns Earth Diagnostics's version number and exit") parser.add_argument('--doc', action='store_true', help="opens documentation and exits") -- GitLab From 63730797782d24779d31f479119b6f5813d38e09 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 15 Jul 2016 11:25:01 +0200 Subject: [PATCH 139/268] Fixed bug on CMORization. Added control for errors due to file corruption --- earthdiagnostics/datamanager.py | 40 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 62b9263..f845d6b 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -86,6 +86,7 @@ class DataManager(object): """ # Check if cmorized and convert if not created = False + errors = list() for startdate, member in self.exp_manager.get_member_list(): member_str = self.exp_manager.get_member_str(member) if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles', @@ -93,8 +94,8 @@ class DataManager(object): created = True Log.info('CMORizing startdate {0} member {1}', startdate, member_str) if ocean: - self._unpack_ocean_files('MMO', startdate, member) - self._unpack_ocean_files('diags', startdate, member) + errors += self._unpack_ocean_files('MMO', startdate, member) + errors += self._unpack_ocean_files('diags', startdate, member) if not atmosphere: continue @@ -110,7 +111,7 @@ class DataManager(object): count = 1 for tarfile in tar_files: Log.info('Unpacking atmospheric file {0}/{1}'.format(count, len(tar_files))) - self._unpack_tar(tarfile, startdate, member) + errors += self._unpack_tar(tarfile, startdate, member) Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) count += 1 else: @@ -118,6 +119,8 @@ class DataManager(object): Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str) if created: + for error in errors: + Log.error('File {0} could not be unzipped.', error) return for startdate, member in self.exp_manager.get_member_list(): @@ -137,10 +140,11 @@ class DataManager(object): self.exp_manager.get_member_str(member), 'outputs', '{0}*'.format(prefix)) tar_files = glob.glob(tar_folder) tar_files.sort() + errors = list() count = 1 for tarfile in tar_files: Log.info('Unpacking oceanic file {0}/{1}'.format(count, len(tar_files))) - self._unpack_tar(tarfile, startdate, member) + errors += self._unpack_tar(tarfile, startdate, member) Log.result('Oceanic file {0}/{1} finished'.format(count, len(tar_files))) count += 1 @@ -451,7 +455,7 @@ class DataManager(object): shutil.rmtree(scratch_dir) os.makedirs(scratch_dir) self._untar((tarfile,), scratch_dir) - self._unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) + errors = self._unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) if os.path.basename(tarfile).startswith('MMA'): temp = TempFile.get() @@ -478,6 +482,7 @@ class DataManager(object): for filename in glob.glob(os.path.join(scratch_dir, '*.nc')): self._cmorize_nc_file(filename, member, startdate) + return errors def _cmorize_nc_file(self, filename, member, startdate): Log.info('Processing file {0}', filename) @@ -573,7 +578,7 @@ class DataManager(object): else: region = var_cmor.basin.fullname - if file_parts[0] == self.expid or file_parts[0].startswith('ORCA'): + if file_parts[0] == self.expid or file_parts[0].startswith('ORCA') or file_parts[0] in ('MMA', 'MMO'): # Model output date_str = '{0}-{1}'.format(file_parts[2][0:6], file_parts[3][0:6]) elif file_parts[1] == self.expid: @@ -662,9 +667,15 @@ class DataManager(object): @staticmethod def _unzip(files): + errors = list() for filepath in files: Log.debug('Unzipping {0}', filepath) - Utils.execute_shell_command('gunzip {0}'.format(filepath)) + try: + Utils.execute_shell_command('gunzip {0}'.format(filepath)) + except Exception as ex: + Log.error('Can not unzip {0}: {1}', filepath, ex) + errors.append(filepath) + return errors @staticmethod def _untar(files, member_path): @@ -863,14 +874,17 @@ class DataManager(object): var_handler.standard_name = cmor_var.standard_name var_handler.long_name = cmor_var.long_name var_handler.short_name = cmor_var.short_name + var_type = var_handler.dtype var_handler.missingValue = 1.e20 - if cmor_var.units and cmor_var.units != var_handler.units: - factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, cmor_var.units) - if factor is not None: - if factor != 1 or offset != 0: - var_handler[:] = var_handler[:]*factor + offset + if cmor_var.units: + if 'units' in var_handler.ncattrs(): + if cmor_var.units != var_handler.units: + factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, cmor_var.units) + if factor is not None: + if factor != 1 or offset != 0: + var_handler[:] = var_handler[:]*factor + offset var_handler.units = cmor_var.units - var_type = var_handler.dtype + handler.sync() handler.close() Utils.nco.ncatted(input=filetosend, output=filetosend, -- GitLab From 6aefd012f90a858ffe94dfc00d696e82826b73d5 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 15 Jul 2016 16:04:42 +0200 Subject: [PATCH 140/268] Fixed bug on CMORization (missing and fill value append) --- earthdiagnostics/conversions.csv | 2 +- earthdiagnostics/datamanager.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/earthdiagnostics/conversions.csv b/earthdiagnostics/conversions.csv index 4131d02..054c565 100644 --- a/earthdiagnostics/conversions.csv +++ b/earthdiagnostics/conversions.csv @@ -4,4 +4,4 @@ degC,K,1,273.15 m,km,1000,0 m2,km2,1.00E+006,0 m3,km3,1.00E+009,0 -[0 1],%,100,1 +"[0,1]",%,100,1 diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index f845d6b..ef298c0 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -147,6 +147,7 @@ class DataManager(object): errors += self._unpack_tar(tarfile, startdate, member) Log.result('Oceanic file {0}/{1} finished'.format(count, len(tar_files))) count += 1 + return errors def _cmorize_grib(self, startdate, member, gribfiles): gribfiles.sort() @@ -486,6 +487,9 @@ class DataManager(object): def _cmorize_nc_file(self, filename, member, startdate): Log.info('Processing file {0}', filename) + temp = TempFile.get() + Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filename, temp]) + shutil.move(temp, filename) file_parts = os.path.basename(filename).split('_') if self.expid in [file_parts[1], file_parts[2]]: frequency = 'm' @@ -875,7 +879,7 @@ class DataManager(object): var_handler.long_name = cmor_var.long_name var_handler.short_name = cmor_var.short_name var_type = var_handler.dtype - var_handler.missingValue = 1.e20 + if cmor_var.units: if 'units' in var_handler.ncattrs(): if cmor_var.units != var_handler.units: @@ -887,9 +891,10 @@ class DataManager(object): handler.sync() handler.close() + Utils.nco.ncatted(input=filetosend, output=filetosend, - options='-O -a _FillValue,{0},m,{1},"1.e20" ' - '-a missingValue,{0},m,{1},"1.e20"'.format(var, var_type.char)) + options='-O -a _FillValue,{0},o,{1},"1.e20" ' + '-a missingValue,{0},o,{1},"1.e20"'.format(var, var_type.char)) temp = TempFile.get() Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) -- GitLab From 252734d9af53d40e69c1985c034868fbea385f39 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 18 Jul 2016 10:19:55 +0200 Subject: [PATCH 141/268] Added basin option to heatcontentlayer --- earthdiagnostics/ocean/heatcontentlayer.py | 23 ++++++++++++---------- earthdiagnostics/ocean/siasiesiv.py | 9 +-------- earthdiagnostics/utils.py | 14 +++++++++++++ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index e4b685d..fc25e14 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -1,6 +1,7 @@ # coding=utf-8 import numpy as np +from constants import Basins from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile @@ -55,28 +56,30 @@ class HeatContentLayer(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: minimum depth, maximum depth + :param options: minimum depth, maximum depth, basin=Global :type options: list[str] - :return: """ num_options = len(options) - 1 if num_options < 2: raise Exception('You must specify the minimum and maximum depth to use') - if num_options > 2: - raise Exception('You must specify 2 for the heat content layer diagnostic') + if num_options > 3: + raise Exception('You must specify between 2 and 3 parameters for the heat content layer diagnostic') box = Box(True) box.min_depth = int(options[1]) box.max_depth = int(options[2]) + if len(options) > 3: + basin = Basins.parse(options[3]) + else: + basin = Basins.Global job_list = list() handler = Utils.openCdf('mesh_zgr.nc') - - tmask = handler.variables['tmask'][:] + mask = Utils.get_mask(basin) if 'e3t' in handler.variables: - tmask = handler.variables['e3t'][:] * tmask + mask = handler.variables['e3t'][:] * mask elif 'e3t_0' in handler.variables: - tmask = handler.variables['e3t_0'][:] * tmask + mask = handler.variables['e3t_0'][:] * mask else: raise Exception('e3t variable can not be found') @@ -132,9 +135,9 @@ class HeatContentLayer(Diagnostic): array[level:] = 0 return array - weight = tmask * np.apply_along_axis(calculate_weight, 1, depth) * 1020 * 4000 + weight = mask * np.apply_along_axis(calculate_weight, 1, depth) * 1020 * 4000 - # Now we will reduce to the levels with any weigth != 0 + # Now we will reduce to the levels with any weight != 0 levels = weight.shape[1] min_level = 0 while min_level < levels and not weight[:, min_level, :].any(): diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 9920944..3f8ddb8 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -70,14 +70,7 @@ class Siasiesiv(Diagnostic): raise Exception('You must specify the basin for the siasiesiv diagnostic (and nothing else)') basin = Basins.parse(options[1]) - if basin != Basins.Global: - mask_handler = Utils.openCdf('mask_regions.nc') - mask = mask_handler.variables[basin.fullname][:, 0, :] - mask_handler.close() - else: - mask_handler = Utils.openCdf('mask.nc') - mask = np.asfortranarray(mask_handler.variables['tmask'][0, 0, :]) - mask_handler.close() + mask = Utils.get_mask(basin) job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 99edf0b..eea00ce 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -12,6 +12,8 @@ from autosubmit.config.log import Log from cdo import Cdo from nco import Nco +from constants import Basins + class Utils(object): """ @@ -23,6 +25,18 @@ class Utils(object): cdo = Cdo() """An instance of Cdo class ready to be used""" + @staticmethod + def get_mask(basin): + if basin != Basins.Global: + mask_handler = Utils.openCdf('mask_regions.nc') + mask = mask_handler.variables[basin.fullname][:, 0, :] + mask_handler.close() + else: + mask_handler = Utils.openCdf('mask.nc') + mask = np.asfortranarray(mask_handler.variables['tmask'][0, 0, :]) + mask_handler.close() + return mask + @staticmethod def setminmax(filename, variable_list): """ -- GitLab From 370dce54e791aa95d5a4ba9388501841a3304617 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 18 Jul 2016 10:28:46 +0200 Subject: [PATCH 142/268] Updated doc --- EarthDiagnostics.pdf | Bin 199024 -> 199865 bytes earthdiagnostics/ocean/heatcontentlayer.py | 2 +- earthdiagnostics/ocean/siasiesiv.py | 3 ++- earthdiagnostics/utils.py | 10 +++++++++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index 437e221fedf628f7ff812bb9268e64602e385cc8..142af2bf403d7fcc4df3a991724142fc16367b49 100644 GIT binary patch delta 51587 zcmZs>Q*bU!xNaNI*q*U%+qP}nPQKW-Z9AExIBBt~5ErmK+?LeV|gnft*&JLS37(MXgbKAcH z5p7kf)x9YfYZj~kIJgY5j_N)_z<`uK*bBul-A9C?9madL@A&jU=zLdEzqb}?L5HG9 zYiAEwLHs1V=3{>ip#N6XmG9@Q)R?UjYAInYLepWj7h5i_Zin-zIH`ir06Q%#J2M>TRMsrpY0 z2n$1!;2dR=2_zn1Zez$Wknq?v%jXk~K<6)3qvSD3%s&wUocp(5@24&TkbY=^J3El+ zw^5&mPwff+C(==zDSBYIV0v)SYzV#+5#60v-qFh`Czviu}~XqpI(ot;SxWFi9LdDQUp z4+5+4>ED_1AFFyc(Dy_}<_i6FLCox*l%tSHV^tB$M(fex=*!*Do#=jIobu$_)2s3* zFm&4O6~$k6)9-tD1snfdlY-EU>MpDm^GYmq%Ln%0HJxhs!+L83xU=vFECshih{B#? z)T#QBs6Yq+{f-D6s!UPVR-bI@v|xg0)TIwYbi8mdQWq4leixA3;+5B-$8OOd*B;KLvkYZmSKS*cj=Rc+8^*%uB1=`JFZvnW)bygHMwF>Wn#6 zahxe2U7dEuA%O({;=9Q$5Vy0v;ZnGR=CEG3Hp;2ydUMf2u{0+oTz2sF5jU?@GEw*R z^zSKxs+!KXgCn)EMED5K{?M=EG8#|E;NVo+T&ae0_08(>*>BR$&jC#yo&7HkwuN%P zuZqiM4h9wFm22p6c)@@_uIexv#6pyzr)Dw0(nfJlDAw8t2Ex6a%mP2Uglb8Pw4zMsuh14? z7jb3JCndxxN6S+W*~g{?jci8g&yD?C^aWn%36ycEvp62z%T2xWSEg&URQhtIuAB1{+{G0Jd!^}8w?*Y*J%8 zM6>ol$b4Psbue|6`3okZOI__;LCrI+x|JA(YGj*f6%&!=vz`~n?qO_)evmlqA_e`d zK3C8pT^O%|2bwkdBPW^;$<2i@mmn<)2qDT|OT|}o_>yfPtDMUatdXNwQfQ(8cgjur1OK(LPH#$-nO2QfBa`6_a|R!y5#l z>biPds6>!eNG6gKQ^uBxI7?Aw4g;B;rM9w@T#1hyuvq^7h{mAhR zaVh)yNulq+6~dj4;Y2w+^6YGcL6B#0~6DHdu ztAT`K@n|884G2Lr$+5t)mqU&ReKnsF& zQ(>|AeW8+sgn7F>xR#ut<7`m4gF^|LQw>U~P1W}(8bw4q%DR0sheI^J0z^ zcTBOu0S(7az~r{X?f{00MPmmF)C%1t4m8xj`-WVCA#NUh;6VRu%XLP4N&q@@VI**w_9Sjo@{ z3rmYlMbV(?iA+p(u~0u2%bNYfFYz}XQ&;HEvZhsCnUCbk$pKH>?p5|Pufm(l%Qxc~ zp}sq?uA7k01|N;*VODKb9xgLF_)~fASf$gXs?C;JanGc_)$Z@(Bn1a|5tlHQe zUXK-dxf1+$9~IYp_dLDJgJ|7;pI;f7&Rz!WN*nH1?UtP~pFJH@&ao$ZZ-@N)-FU?3 zWx|xD{JN^3aQL*g+LinZzMW-N7i`2F6S}Kzi$5=WzeKwyy532hfTTSHJiv`J^VQ9{ z<}aoFIsfMt^OH>a&)!Gn_KiE1qTS1?fJQmOZy$^Lw!`zE!BM8}-#hX;O8)zTZtbUK zl%8@KR99x2S-VoiR{XHmZCcPZD1Td4l~vWCi%WFIEz}X2LjIsTX2eOsV5nQ4Fs2&L z@6k|X^7t3w?#t5&bE=eUGJyK@K(kk4xR|}7;dF-`dlZEi-Z7i|Ts{X)V1_1x%Gq^) zdtKNTec`%i^S1*HEjx^h=Ps_`$gI&4oLWK_`Y(ki66F+;uDbhZG3`vylDlVT)s6G2 zdM9uP0>!E56ib{Z7&WOmq1}fUmQhdjXUE0m)@s|Nz++0xz=(27CxGulm08?a*IZ@b zN&B~Eu2JOe#IN1zFV!z6eU@!cmg^#dciJc{y~iv0Ic?4C#Xj#}KHm zU0VG7DuQv-`NosWAGSA}zHQ^*?ff`ldZr?;zTV;(iE$(xG{MEYbwKm|7@z#C8)$F* z@}H0Ny$|sG?F2-vUMkamZQlHrWurxd`ZhBHaUA8$HhyUE7-0q;#NotZo_&1tllQ=S zm+ZQoo@swN1j6ZOEPQisAwF>L?$^4%iQMXbch?#+^rF9+6Ca-D(X+p`S@KoSueNQ|+Y~K6y+5lT#~<$@*!Ucre~*|c2ovbca~wkB zeBK6~IB>N0lLMETGx_VXgGF43_KQ!Vkq+ONMfX9IK(H?HP4C|g&x(0ekYnXTC?WAP z(ooqd!0|p@c%+nQPU3ua+@*@|@jw9`BD`5>zD}$T59osTj=SOI4iIvB9%$yvbNYnT zY?w&(g;wYNpcf+4U8^uWJ%M<5T+tY?0;7e-plrfSG5Velq7sEj4+ z2XD|MDyWCss3Hv$Nz01G9K8-}i)CP>gem)<n63egR${?|=10@WK#rVr|PMYZ(%R90xq z1mf!W1frHQ2YV-U5)$zYu^LiAS*mw_ zFJx7xFvv4Y*mO{Nx)|#?VNIV>Y?Whw+bAC0h^YW66+&wC*Bji5k<~~qp@oPcZ7x5L z)2kTvc65Hdef7SW2A#OVlIdXYCkNlNhV_BZbwP;p$$tQtm9l+C@T*L3_XlB7a}jv( zs^JF-(3mep5vqjrO{MeNfEV;Po&}^p%-Dd40%Xmal`5i37U3GI35fOAL_&ZJ$`Hq; z-WNb}5o?+&p|5z}-!Fhtm=e<^fKjSwtmg$gdQoTN6>;8)Kuo!Y<5UnX`UQR0a;67@ zav%ru;YB^6s>liR0bEW&D#yK!grlZB_{9;GOF9E^Tdci_DoZ!PR26Kq&1{|r{_k9-if+WW2A*>Q7^aeGgn_qI$mW zU3}(ccbk~jS?RW?n5|MYymKTjFpmWKJ8;~~rqva<1eoiCP!KjV_fvNcp9)0P`U7?% z4d(8L8Ji3sy-tjuq{%%L17<6A-d4^t5Db)~Y>xd4widNtwKl_-8I#|j7n|x6Cocq- zB2|QrtGL+$P;v`7UJMS>$v_JsOB{9=gNsq6KyEof%RqmjdT2zE@E?3Zytvw&4zk{@ zXdia7fur!ePK-hv;<%7c(G*@TJ^-|rhptJKuXZg?v5tkajx3<}e|H&oKDT>Po}9IBo)3eW|AlvECQVCcgI?D z7fn*5pv2=baRj**(onkcx9)eesDYoGH)I(>s*v57i1mfzP)fps=f|_zY>QHb$Y0|` zi}bdqiY(OHluM%ultj+Q_hkz)=Q;2~+P2UOqqz#{x2;AVbeI+6So_@ri7Zb(4v)hd&K?aXRVZ3NB>?-Febdx+DG*rad37Q=1g5A*%`JU6;PZh?lXLQ&oJuFI(kF!9aOSf_DfXY} zJw7DX#Nx9Uf9gt~zCCW!Q!d|28$BgYi=m8%!4lr8`vC1J51^7`Dkmjp z?KisI4(3e4>)~neERB;U9g6j|`f4nN);w3LORlTvZSG;woc&T3EN&P0bSZN^i!NZ} z?m~j&fvZ*LUuZNM;Y1^OtdZeyMD{5fY}V<)2B_;cE>WzE(S6oPoFxknqZ_;iY;wU+ zyxpZK3sc9F3z+wU$$&Zs4niZ5J$)Z9!6F89hAWI_c6{0O1v1MnJG3j}2|AH#y^|BC zs;H>fJ*S?050RCSv=G7GF!cI7!ko_DgxB)&n_{+m`c;t7H6;tWxu$ZXA|$bYS%!w^ zj@50iW(J=74hXN^K6gr#F>s#;I#!axm8-b@cLkeD8`hiA?f}0f1Ur+e)|y7tG^;k> zB^!gS@$ZJ458Zg373_=UWZ+LY*o>Wi#T5DBPs8;8^C?zzJ^;p$uE6J=b+xFyH`%dxeUIl&x6^h@cOS^IPccIh4DZ1J-5~8 zxK>UJ=`=^b^TTt8^UwtOyk{@bH-&S&QSV3sfXjit_q|HX-_?YeLFzx_DH<`xHF<;8 z6Q-N0jbh^+#J4lbUI*kt&eb(ZZvuG-9-T}M64sa$!hkK%(hZ`j%?8^=Oi{;&E1lX| z!_>=aO+aE2n02XbY3UkLdd1s$#7gdFY$lSig1}55lNGNhR)()P?mAjgxF!?pIx+V2 z-p9Itj_`sj#1C_MB~6SOE*7g{;W)1K202a>#Wi;FMU9=gn3H7NbAPNseO>Hb1X-U_ z*W4&3JYYl&@Ex~pUPrhlkCxYrzh*LRuN+nabpVzJnzvaUfaMCpi7EQ^@oaXNlE3kDBD2gnLh)E`{*3)<5W(gEc)DBEzn}1EK+IA^>{u{9r3V%TB>OH zdsazL(W|@c&I5g09;B$zp0@F%Apdn31IeSv^BwKH*caWXZu{hyt^krgy6 zThe?o3K$a;3-kX)__mgI+$I~kU!HzJ+nT`C1JMOC%P?6|slXgd=XpN8C1XD6Ofg+@C)OS9#{J9{Ip9Q*MM2mN+I^P4d0-1Ytk!z@$X7f!xg2 zD8Y&#vrKRASNP^j_wu})M-uR4q>{*3L$GXU4Jn7}GbQUi`mfWQ9N4rV2}P(7Q%9{k zY#AfxC<{b{03osOX8nrdRI+_oFG&ieBOb{>2)6ahukg+RI$|%8dXKdhYciY0=#>2B<(GdbCi&RaMDeP@{gJ~YXkSnl&;%O)?oa zG#)BIza9desNlD>)@KLyW$DoNr+-d4ECl289JCJkzC+dpDyTH8u9qV z8&wW}1`r14&dxzgX2KdaRXBe?WO%U+ru&!T>xtVm84=inT=G8p09EAdr1+|Ia04D! zI13X7;nY3t^XxWd(6{?6D*oAHRPjq6k&!D=&o-E#ItRon(i@gW28b%`XbKL<R4jVPcJ5k z1Pq|eaq;2SBpF*w8zYbJdz4RpA!}w!4=*%$^T|{$Sj2P+9|^(lkI9j@t+#HM=n0v9 ziO;*y)2AxYWnSYPQxHYS$d_%=h<43UXa5mr!1QOl!Dk+^@C3$khk1XQY@5`eQ(2!` zr%yS-;dob(76!?#RuUR4cQ+|&NRa@81n9aA+gk1n45yKX`PN)EyA7x++uKO5bMpUt zMCkl@MA)RayC-OLcEfu#`j_Zd|)t#XA^~aX`W{#B$@ro_pF+niT{28D&P&pndPs20)Yd z>IG95?;V<^ID%JqyECGUP9r*j-e-V^)UmCC<=?*A)KyGvT`nK+>F-xMhM+x{*}XY= zUHao>oU?&PPSE^-?F(L}?#fOEwZ&!WRh~W3Nv<`PINVVyjp}ry#Bvp28;-<|#W}p6 zfVampv{o^CY2&T2rS;(+axaC+2naMP!X>*+y>7zyG~hmgiW4F38`tFc#rCmB01_Gd z(LVRkGa2dK^c3NPACrjSMT$#G(rkA4f*dnd=?n1TI*ANV(irNg`!!Wy&&0$|D@N)e z_AiG(7D@<>s;=cyRS|WKxdl;NW~+8jFSWYfnoZ}z#%aG5uk>?^tK3T`oS4QsWZh>^c%lih+i zk39ghFBsjo<=V5|IJ_2EII#V|7}9}-R+3}I^`upsg$~Z9%h^u|9O_RsUt)d!u$t1alMwJPr(eO3`xZ4E)kJ4*(X7jMIYOX~$r4{4>9QKPv;Sjj+CV-OEp#2{e}`L1YftO|O6I z)%Asy^^ov!O0}$Snz{-yiGjsgRie+s4OMjB<-FVkLI~tqQzVt-=>EK!&8sQbRLVgp z=}Ay%kTYQ)$+xM7Z}#}mD0^piUaJ7jVu%bVf1@z7Xf#|#4j`Yq`n;tGnSk54DE}9a z8HA&LV9mY%SF0tx{GS$uECc2NVpN{wkySy`%(oVWPi1{jPp5SfyYM4Nn#9bf1a}>K z+vd!cKU3Ch|D&pUCA4Km+bjM|LqBk}bC%`$&vUnS2tJFxg8=)*hRNufEi=D`jf?V8 zx_H`4_eg~uA7F>N9c>E_A~fGKIex}vb4yWklNdz1qjPa%+BA>djS+tK=xHn3c)9JI zp7lyL^BRmS>!;ON;yaVZS?8 z8l7I<#q4(ul|W^-Yr~EGd7jIA3JOD5;=3_gpxz8>9l)$WnJwkFb`j&0CbG--01edC zizMh|Yw>NnZ6@-m>XiPzeV^EAx-1#m~&RmOok6Xm{w5V<4mr^)mt z!xZb(9SmEf>)T8(s>d#m`0_BmZu+2HQU+!6#IknB; zIPn&=ss!WW1ov8G)wz#c+UN54c7wE|kKpiXr+setcy@MTS8%#du0taCdqgNarYZLm zH~Irm_7@qGCH0ZWO09xqIt*)UOWD%^+8Z!NS^H$SE@@&(@-IOJW=~2OKm}oD{I8y) zO7a|s0py$gXZ5T!!fGV72{h_yr#}+Wacvu7xuhpt#v{K!a3hjwsTz&A$3uaA8%#Bi zI8V9TZWY$FJ=eUMJv})+e>TeW!i5Aw{*$RN>}5b}CZ z0ebL-H(Oohra{%$ez1(l&6_!aSC2Jku|2WyfkpnGxVVr6(~h=f4C*aNCleY<++$xe z=y}hLE^eMZAQ-^VSiB%Dg({v0Y(hL=_1ilqr=9;ta6izJkdeoclB26tCq`| zbHHK}!G!s7f6P2}O8~I@LWIh>RB|uBV?D5Y!u<*pco=yxV`*YXfct*s zOCNeR-l9{(aL6<}nhMuyXk$K%@4L0L&jHAH-tpAAfrxCY=jn7{=d)Blpooom@Y{^yNT8x<4+0(g#a zJC7%-pr(p=ay+sin*ebuEA!sQfEqs}u^GXHz2!1=De%dhZWl9zr#veE*2pi> zx_)!O?jMx@Toidt>S~S?cQ&)PXYKFyBgq{|fB5B?z7>ILZC@G}J%oEFV3Lji2Z8Rz zaMUv>*173DA!^-{`svN6mljSm%~Xq=4T@3ad3|4%9|u-WTo;qDyx85@j9px7RMZoE z=zb7U)06`8bL6v&6|XjtBPNN8k$*+uW`b&A_6l$@8T%XDNw>g$?D`q@!BoduG09+Q zhM&Yaz=Y9M4*%??xM{Bs=+ZQYX~Cn{1Q};=N$8z31@{e*U)*OH4WG-@RqVeQ3!Iq) z)A}_-v0xC)KV{flhT;zsb zi-13H4|>?4n+EFx1O#A75=fXZ|2aF@9Q2kw+YoXy8+pObxiQkI&75|V3*$Xs07_|% z28kT7z5XH#yV4vb53{R2z&d^*?7X_AS+-y^kH<`-EoiUFv&z}s;{3h7E~)8wk;~@d zKJD0XQLRa_4XEOYg)bn6tGiPC&U^GgD^u8xDTanTIaB-tsHdA?%lNe;6POPD8l-Dj z{**0AN*w~Y@44unikJ>fKZ3D$*p}w0u^bzZUV1S6)07C(+P8dMJK2P>s?a&n?`M zEzCyW9;W(rWg!Wbju127nK1S;@E=f2#xZ<6x&bhM5+d@hZ^VHOXdMnW)krcnwt5d4?733zy*>19mql4k#a1GA>>!2(ky z%?`iks|NsxD6`Y3FwQ^Py$aaFNFLy4!(Zjb2b zizNabY?fV9Pfb#1Bg|8$jH;@TYP{)m8qnn2qN-St`8SkdfV%a~$C1t3m+{kDtPkP} zX}0_^p>H5+asAl*s%HN^BMb?q0hW8JK>@zj@o{zqgPX(e%W30A~=NF}0NnhD#U(Q91s#N4K(2xE~fTvj{( zz)JMYG?COYpZ>JXwN0$lbEhw=L!qCZQ27h8XAl^Scr&stRA7gJS=^fmeqwfKms6&g z*ga*8X1ZufBftc^ZINA737|s{o^85c3iAW4BHRQiZGuB&A7}TmNJP+5Jp^IB0EzW+ zFdxTE3{b@&7`q2W^GuVDb)C1^+}W`87$XQc;L(2b@GCP)5{jS`KFrz_gaVc0D?jLF z;#d1i`5-w*2D@f7)ow4O&x>t|iaJNwe2GfF9f?rW4?4^g-1VBb1fVXY>R8ZT_AmbJ zPsLpaiAM{TYk@2DwIfePd+V}c(h#tra7Dpvu0*1Z_YQufq(v^I-GHi)QZHIz+P1+% zUK}Q0!Lrkul;|{}xFi4813CHW>t@lfx?aXzgYZa2tV>XEjPSTS`x!5eBLSTul4WIx z(gWtD26%X3KyG))0bWkd?V{yg9SK)uh-WAX$&28)#;HmcfAUV)dhI$ro2Xp{GDYmm z5LWb0UFTPNUXFW)KiOY%W$hqyT(&**NwP?yT2rf*`mQ1=N&IgVR%{#NqJXmfZQ`Bd z6E(0;n*q}{>g2Msk8{!Y^q+6$_{^M^ zL%qm-umc9^!6%d8b^b*}V(>#C@+)jhgCKpAt@ z@B_g&5nr0S0!q1#`-`1A?*wY4!Iw1OT_D_hKW)S=IT%Ew&K)`JS9#?GU+KA*y$Mew z8~~B;R^%Va>Hx{jj@FJ4DVF^1V9+9%u|O4HqpcYe0f3e zJib2tvV13+TSFpH0@Z%th~_+KiJ@#hZyBEa7}2GxfGZ31R+h{4r*Q-UCJyV%gz->0EYL0Gyx5BXzU@Ek zu1MD$fE>R@)uh_khW5ieqKBefqKRL5Bz(unv7TS$p&}fjMB(sdz$Iz|9?2>!9octP9dRwq4BtZ%-kgIb z+Gr8o4(19(FcD-M?!katOI%kRnuOEh$8T0gG4iUtr}3DB${?s~fshktW-4P}we}+L zP=F3yG)p&frBOP2K2n;slPGo!FRI9>rUM7c)-_|?(&66%#i4O&a2%tt;NK|fbjsC> zRu-Ay z&73iz$5{h7_eDdb9KWOJC|T*AQlqV+$mk3BIYET-HVmbpPAG++Oe&>I+N;(_-F zQ-#{40QdX~QF$09^XUt>|j(HINp1Q%3<-%vgkw9BpKbBL;bl%vik;Dqy_;Cp?Hp&@MW2+2{sN5(40NGp?`TKjfp`qqDa zIxElX_4aDbo+{mrx>-H#UHfIXPn&$*b=%HbUmxiGZTI2M`dI(!>P*j`kq4aMcmC?h zeImj9y1m~V*e9JojJxl~+?gZ)p6M~Z;B7gte!txQ?(yjCAE1>ocXzdWe3!Kc_cDYh zRcf&DTTK7doxrL>PR9VsRtLgUlbb`45y)_vSwj9?F) zx0~?ebYGpmMi*>@HL&iQk{<8NKY>AF$|k`NjOn8_uZ`R|`Tx>?5NrUR>h80~$6uTH zb?i^kzocXtw#~_%qeYhr&}v^Jz|~j>7&N09)NHM2Ti9N&Srgn|D*y^z!!yWxG8|f9 z0C`9WNS2;*Kgv2Snp15(SMdy_X&-++CsceS(?Svtf;aYk%^nSs^qimA<6C;RMkslM zvgAEch6b>*BqLhmzvm39x>X3J2bsKM(;{`_Hg0AJ?rwpb{v_wAdVyL z9)c*Wp#a(``cQ|lF`nCc1mtH(^FfZcyperh0-O)7u9z{jlaax8FdfWXgxoM5OY((I zAp>>ETa>Kr5r6G!PyL0-d*+2AFZqQg=pu6Vi5gvgY3oV7Vn7=iVzI)GRS0W9zR=^> z@xaCoSm0At3PQIrDa?eLrG>zY*dIv(C>&iyAkzk)fw5YTrGoI;F_L!%(HV)5$dp!z z$bMg_!mK(%##aiR-oPna-c@>!M|7j#`gIT{!p9qmU@wruAZTLfQw_+1DT+Hwd@;TD zo3i!E4B@YLGXUdF$$Mwqdqk&{3FnoViMoT@D7wCVWcI2f)&e-*2w{L!1MGo<>L5Ra zVMhGa5mz`d1#RMgCwE>w68Sr!c_(tK9R0H3YmtZ9KzRh#iSw9& zcC&yjT9~6|s#;UHw=e_#5<3`!(Rrr|8h}M=n<9F50t`8in8vOs2=q~gDki>NakIDW zVk*^7f=WSak1Piv0%3WFee%%|-wjB#4UkTl5~`7nM1z;#)Cq!ITaDT5+$)FXS}FMt zI2VDihMK1#+sNkBm4!Uj|M5_%h^1e!iT(ZcOgu z7KbzN0ra_7q`9hM3DN88iV%zH0qwx%)$XacuSp0=_getWyj_y)5Rdf)$z$wCOK{b5 z2D!lAiidv?P0(^oa0g5@C9s2g=zPT-(ZYsVc2pX5`+e$s$NTR}VjHy&@uUm1JRcFX zx6<)ie8dvRpU5Vg8QoH6o2~eEOdH<8s+-|W0G0!q7!GOT86~aF6KY#N+egbR`AwgV zlf}&&+}qrGB>|%jS2)cYzO}+#Z6TFqUn10jf8Emz2*lo|Vq@u!RADlONT$~QZp9+< z%g9nBjgZEL^Q$6pk7P%+Ov1ed8`5+S>)Ehziiq_J@k@0C_uHB--2p$XsWeP)R`%Bl z0NT(Vs;z&;8_I|x+SKA;J%$0)Y9jhaJAqDwr9PbmPySBLRr@+cZSJks7$@;O>UdJr zPr#&>Q1BVHNVdp0fsV&CaS40z$1UHVSA6{i!4qkh{UjW2u1G}x-A0a~B=R@}J~E&h z*ykg!l`8solSWL$2>_!fNlE>MW@W%XUny`|fY;EH3$^r_1(tqZ zehEzVdU0Z=2v+3j#f!ql?R?f!1>N3TD<8&g+MB%O&gm8F*+QclHc0P7_lbzWth+%6 zHRtmiwZ~n--6u^CS#hYX)>XnBs|kuY!Y7k`QubY&=51zz+QTWxxVr4%AW515_Ova! zjNhJyEdW~5{iap`=4R1Ic-}4Gf%V%L)=g{+W;fcHkLDKEtke2t_vH=MN;9< zOLvNi#&U^?VafTfp+=(I$4?|>fc>#hf8gMjDnvb-(t4fWfW$E`VF+QHcC zGXhd07U?-d^B9Fb450JRv(Y^j5fxIY-4_yE={h%Jkm;)nPB|+4y~w#UH0lOB z0z}9?Di)%6fQ)L`T^^OR9lG(^pN0&v>_JP@2JkwhX0IM3#u(|qKx!`O;V-c_D2i(| ztw$T4o~M4!4@yKS%txNo+KyA|SlIReGz5 zZ5MikNV0@`*8$6(f){BUPaY&!k94~C)J$KY1UdL94L+Hy`-Fq6bRVS)VL|C^LCO)> z4tTisyxHYp4E*j335&+7|7PW~qc59gIYP%4nv#<7vj%&LMYHD$)VWI(@$T z0<5W$qD@f!nF$tDzv<*xB&k`dCmw0?8ugSU(5_Q`G~PUNk6;Q<2uSDECN8Dy2S*C@ z-RH7!LfSPWF^4ikdfc1jN**U;1)6J30pC4TM8zn3~WoEP2jZ0x?JLo!!f*h0?JN_eiK56`eY>+5`T9LYqMDsH8Ydz@jCL z55!sX=#6a3h1x&ZL90r88jwMel*Vdri=W8(@|g}Rm=(0gT6;L0?igra;&h43n9a${4fTPwZH^tons{+0r<(R36-Fx zOc=UQqfr_xM;mMg%`3&_fPQHbaWibSiz2`D@jKfIImBq}Q`@k-#m@C+JZ&?myA^~wxsym`s zCWZGr(XZI{?xFSwm`?f^qF_<$Vc*O*Z<_MAgP0cn=-|`m7r9gizRYE~cH z{^!#EADth|u0Azx;YUO;q~+q%Wsa@-W4<@j$U;*W%=j!>gqbttZN!ngiEQH6;&Bmr za~?N>(JP@EDuH-b<39U{X~T|B57;MAhtbh;l+cWf6C4&iz)>EJ-K5>q@G*SsuK(fB zb(LIH@fX{QuUZw;EL~!GN#kPs_pE3uR8}#sA5NKsvnxXJKQEr*e;2o7*AmXZ^GPRu zw>AB=5|3=1-BAGdDM?Ae`RtP1* zd0iS`sZ;wVvi1#@UgYpje&VyuH+~VaQT_iPYO%5>_5VQuVdYHQhXtnme@!YqcB`Sq zB05~F-DF@-u_&2#b_Wr~&b~e0G2W zkBrF=$6%BI{nPAT6R1G(rU%g*L1iLr4ZqO3a(6~I8@&Bkf3zK`*{#!(+RO>Q~q*70;oNhRLvfS(M=EIdNB>B zD9Os=H;TsI)rMZ@DUd|x?-KF8syR5 zirH5Lzo}<_DGN<&5G;fV{juLSRkyN^@7u0$mRweu%-?(H#eU6=@ai_KHli)akhD z79B_(W81pTF5ATbprI6wboj8LexstN&L!dqBAv1xmO6G*aB0spbbn>9>MH1-cYr-y z5s$bu&|M{Jk|PjH^QIGlhlzY(%{(qodkLrQL?R*=54cepMLijqImm|Ot*>)YbKjH8 zHukXk0RZij?KFmHJrgJxjcJ4kNaQ{!4?^bHhzn_}@6}h53Q`L2mD&RaO0BYm6kk!yGtQe<&1Xu49ItlTY|bYwtP@Wa1YX0QiA4EFcNDirs=pa4bK#!bF9B}&+bbM5#k#I0+{XO$I6c|P0%*v;MutL2 zmdU4cegXX|%AR$!E65wl&Pn@55nv~L0Ls@WhXDg+r?@yodv0gDO0O`x64;3NEBi|} zx&@EcD_Pva0Uv;}WKZNGU&h&@c3uIcA@aOKQJ9FhUuK3KNx8a+4x#-gQP5Ix6KC2z}a-=Y`iJI$UzV6txK*2O<)bqk!%sY9lny0682~3f|G;S1;ETY4I zzU-EYoh7d6huey60W1f!!u^$&!1RA{M(}= zfCub&EPv>cejMQ~f2a>62Pk%maAEM5_GdY*6HmH-S7*&J5!Zq0Jl*qmam}*{BJ25^ zEjp7M?5_{+9N(M3<_$?S?@9amp~z<**PNQXZ~ipCSN^uI`m`WTM7O@`uJ15Bnb3bi zcDi8^j3RZ%-HIiHX`;|U#+1FQ7uXiZUpI+loDzhQ`G2NF0NVdg`q?xgFq4!jE;ht% zC9@4M5NxCQpZL>U!u4M@=Q6$k=pBr*QA|MNwyO`j9xgPw*XeOSMsiz$ciWlK)1B7q zy01Vf2v@$*@pS{a0P_p~8gs5SI^FQ4t$YtOYWo);jo4vck&bdz8`WsHplXYkTE!+G zDaHb@)XY9JPm@dy=bC578-S$mejlxRT)(VZ*JlQ~Y7l1O#s}wcPxbnuCG7djhE$p+a%ZA)l7Tk|xyag8JZ2 zkHa(+kn8T0i!4T#eK?o?SN*)%*ZW5i=phuay@}5-7-}*{9#LrUC}$(UyyUauoq&84 zrucd?4oQhGN_ehEVNW_@Y%~w)=_gNBICo=!?Vua)PlWScPe5TLbIVnOJg1GFVyJ!w zh=^UR+J_5X}$x zp$b4v0n#Q@<(0DiKWx2IbS6=|t{vO9Z5tiiPRF*bH?}%9I=0h!V|Hw_W82QoxAy+W z-s4~Ephnd}ozxsP=A-MrX91n^ji6X4o*RuhxEli?kWkmJy(D=>x`M`4QggRDs8&zIE%?NR1 zIO-Kx6S^ZEc?1k}w)#)*0@6gqzb+6NX}4W62Qu9Rn4`&~K8|dLC8NY>q>T<2b<3&? z)~p8gD{g(di8MblAUvFP(w@jQDFXiK0EifWVgy4-p)in|B>F9uYRym&OAq^XjTdQRzlXjzJi+S z4q7)X{i$plgA7&8`UC8y6-NHVl$ed4=*)D>xhs}69a-EIF4^~_1|-3u={M{o0kRN9 zPwCkM*(ydsa5?-G@UzLj`uA7&TUkFuN*1)i^To!5c(lbu@w+`W+7(lqD>7GA~}K&foHtMs}(dkyU#&0sbNAGXW1{#xqGldEWC)g((q zv^F!-_vot8CwR`V^&Z#t*JB3b12w1-M?I+W%9sO3p6XTz&w6Pyyo!4+?NF#98z(g7TuZS?y(FjUA3bidi?7{p5^UG6Kz9=--W##da%x zOrKt-Rg{K->G&P;T$}^I$nd^lXqaN(twuhMB+>&H-}ZT^xK!I@Es|Ppb&;j4KpkJH zlCX{~@acy%VfhIwjJseHBPosS$5Fpjlb?^eOeXP=MZrB;u*(Egi@aF{%aL4_-&#m| zde$hhQ&yBnEEfk!j-jW6hOQ*iaG5l}iFkuw>9u*ss+EM07IbG%| zWt3L0utTSSqaYQ8HEFr?YB{wL9(?W}G?n7&)F-VyeJC(fVe7!3kECMWIpVm0wPHZ# zpHUaWN#j-Qw~`F>o%GrE=(}pLA5se59%N=mEA`mQNMm8Hqy|#v){lbxpbKl}DP)Sh z+JE4xo5D9a#>_Y562cs2R`cN>oW}MinQ)70XEB@Ig!&RhAyYzqB6KI!^Mqkf!O5(W}WYNtV=O1 zXO?353Z-5S?^@Y7rHuYjWduUF8rrLONTIJ^TGLHF7ULTgA#!Ot>QfkEe?z9fThQ_B ztExIP*aV9s8>!&8rYIlPr2P*FLkPB)(^@=eSVx00M2m+8tN9!UfRwwnG}b)Xx4JKnN3uv+=z+sbF+pKDi{>nt~+_ zFp0P3#12r0I=Yl=pNR40`KU-`4o#@Nc=~mqUlyIe`q62+NWmtN}QaTSM4Ykcd>)Ae;BnbrMs2ez*^M1rsbg7`) zC&8@^`gT9341Vl_8^H#P$`A!+U0D0BVT-eC_#iZb zH`yuAA({~mB`X6^!^)}Dlph$bjDAyGz4Wj_6b>E&@>!$y-%i<}T(7oCG zTsc#};P2F-PDau-VJmNSR)}<96Gg&E@D%y`XHFDsTK!&-|DVM{@8^NgBb5X9@`ipv zkKV!fFaC&a>BMlKx+DhB&?Myi+o2VIYJ?rlic7co@+<2DX`#TD&YEn~lpONS*0uL0 z-u7AB49Qpk@x-B0*HmdG-S=sLbtRbtidmRZ7?gQm*tD#YyO;5J>+Y zlUI~C@}e2i6c$8T4|ZBSx`d2XM8BLO+87>L4|{FegR9O}g-B-zH> zprWiD9vTp?;mO6^K7XA?531sxIeD6dp4UO@gyBPeakN1oZ5Vb5t|Zo8WejV7xK;UPkG7PL~i~GaY^uze986 zn42NML`mLkf&BaW!~RQUpl^ATitRQ#e`MrM$qaAF7Yma=-tCVw!rS98>;0GW1n6GI zj-!SXWZ~_0ex<|bAQTx-m@SQc#gIT^%GO_mL(n35*Zk8$ZveQ9RDR-r-~72)IsYFn zP~F=p-GKrW7nzmyzaT+NH!Bi0wr^Xf|I*g~{OO1f#QYw|kj$hj5cBKYsev!2<$%nd)N=9tITp6x{?GTe_zMCg}a6eq+gL+*9<|HwX~P7 zmY@)5h~np(+1{wwu41-o>LJWRY@n31V}OSS({JEKovK8miZztkMuLm8g~2_-Zhjfi1%!U!Pn+oU z%kEMr({{`(h3itmx82TSu^H0DQu>SCAmOS2H;W$I0hr9Bc?>WxE`aV)A2wrbYn(p( z%*Rf2=-r5dRrXLW14KMD3jzTD`$ZvGGIrGhf(X}C_@karwf?z$l?)0gk+ts^Pgv33 zUeV>lQ3Ct2VD2>bS<&V2(Cwz(3l)jRMM}v5=<-jIaBHN1RYckHN&(x}c!YW&Vty;7>z_!_BJ8D`r6Jv?qXAk(p^Z=IYD! z^~9w0KHuV~tV*~`Klf$zbQD>bVCSFK-??R%!nT`rsX*mc;ozK7jECwZvJ!6_uzn%f!9|5dSF$dnB-ZviJ?e7~OZ#G;18g8$aiJ89Yb(!-w)(^E8 zq45bT4H)huVsQ^MfvbGfYW^DLY_cl8R1 zUyGKATRzJlq?SK&&uI~0aGQpC`tYZWheBPE?fhh|8ISnw;R$FDC~gO@^4cMv55&wP_OWMT_K>ybDDAPJeMbeX6G=3^_MpgN;6(GE%ivKdq=*@Cxgtp@ecJXoNWuCkNXnub6ACOy zBJ<+zC?5eN)bo!BgK?Qeog6s##dM%t<|LimEFPRflcVcnLN2RU_mcj_i zabv?22u{W5tuG9g3UxQ$a)snppSba0Fp@$>L0?Ym>V#|b4%;i-id zMWs(TMWu9%Q8M+Jomog1KZL5R9{}|z??;MSF^1-+FhN!qxzkb?dC*h`J${j^?2Uty zE&`h?59FXD`EQS}^Go@ypUn?tHNvU>s^O&bC8~alh$|e>j2~;OfWkftFofN9$ZS}a z^10?ds>A-Dg|>^lppc8!byAdpBqfY1q1eB-4`k}3g8Y1ku941ENG64n-i2$VWFSlb zxNil`LH5(1kZ;3EzBE6?e;27qP0>OS1@#Z>B-xap^r9l;W*}jVi)%vDAT)LrTyq@h z5Rsq_;}-t{Ikczz0D%l~V`uR8O&qManOSaWrM=xL7u`WE5qti=GV={ImDg#axV=ei z7o0&Evj325!PX_7PTD2Kw^zK7ZNX--q-hoB4hsn+Lv#90zHg-afv+rF_|MC3{6ft| zmgWSX%2JCMAQ-78dP?v#J_L*CA`A0v-X=PQ@xseqPU^UTWw9vco}q^BnejC3hsy=) z2=vX)uUq=oX0ggkxm?-zXubm=IW!(( z#*u%ktAAJ_^Mfx7nOzRL5;?#4YWMxAK@)p{$e;AkrQxKzuMsErmG{C8niz45L~5M3 zz{Eih=#~7S2dtxP6%h`2qg{JeHGqGJ+AE!09?8f8+6Z0NX4&_}^D1LcX@3{(-+bao zPq6i75aD7}dFvr7PfWpW;SOvd{6qr2XAdmnly2b-`5MGC@>AFSD z4+>1Eb~5_w{R37^;of+W*a*~cJf@L-<#$jz zju7TArU|(sazM#xZpl$f&q{hOZ2s`NRvT3B{N1_k3PLctSJvdW^zQBUn{NrvCz!K*nEsW-aNxW~XIFCAJynu-*W zSZsOjZnb4`f;>6iY`g>5C1x8KbvFO>ZB2$zDW!=j6#H-G!DDc}#)fR*B-DE!hl!|A zt#GUEUNO#tREWhO@znXN5baMG!eQyS`rRqkbI^F5jg-+Vv4FzJiXM6;q#JnrJ30G@ zLN-Yua=cfrI{=CC+VsY+!UkXRo4!+ld+*CY5^A#Xf*n4yU@1^2hz#7ktLJ2 zBG#Vp;FiNpz6-EhM%(WIwGGM!I^JzSrwJn?VblW_KHB`-$VaC}JMy>u!&Xqzl;6e) zbTebHTDQLrSv=tiQ%bvj??nhtUU6FQ*fe9f{c_@*+3}2rxwi1Ihxn8oM|GCwIe%_2 zJ_({wIUD%cXR!8rqEtL|)XBnF+)5*++)RTdDE4gS5&LXK^k@Y@z^Hqc4Cc&Z!TvWf zO_9(|E^-^46LOh7s7h@0@wZ$Lyu?X=7R2V^P2Rxn3naL|XnFDR%puCM^5AG|1L$VU zS_j=M$SRslLC_}KV)ozqykLHf*MNA=uovYLFU0Ow_LU@96!~L+H#y`J58Tj{v5-t( zK)N>TO`i#tM!+TDl}?x;Q7@E04;&|*COX9sJZ~UI=5z8!9qVOZ{E=$-k|_6z{DDp8MN#J>d9-|UN3 zDVEl%W;cFt6RKEy(mMxAdl$}aEQ@*5&OaTu6bmJg>{C0dDqs|ZI_v@l$2ojKj+OXd zX3C4EQ@@!ZXx?7ZYxbH)`$a6q;a+xWmCl2zWh&dB6w$DR8mAsUvH%Y69UG7K*eWD{ zy^hc^plKu^hOOb}fr~nD-OD6G0uv=eXa~|~e6vaCyd$z^!MiV(ZK# zC}rD}Q3~?+x|N1l{-Gz|ml?K1-6~ly3FRoPg>$xyzlyRAo$>6fg z#B4IoYoZJSM=i9xiQYOz&pk=0RC9uGB&tv&Iy5W5-?azHBpizM{GV{7cM9*sw=x{S z6&h@tvuK6>AzF` zeN$DlF;%m7uIYTBa1fYNi*W-il7mI@N3SD@8Lph3wZoRiT$!o@Ob$CcFMIPmIVb`K z6yIC3iUZetx!!0oObm|#K=FR7L~o2G{gwDz+{Vu34RB}W>%jZqBr^i{h*Ya^{S_fd zts7VS&(sp>4I4?4;W~GE@hAN-rjS7TRQ4<}x!t*AUS!}4j!NGGtw;`nkXOAo@FoKV z!$~o9TviZtKBKG)Gm=b{j{RwQPfv;Wuj#6|gTpXF$u9)-lwo5cz_@_HQ>AaflmtEZ zN~S6{hLgQzGs2x-u5SQR;cBNOtqUwp@jozlx`TBLa>hPeda|GhEAkzM^}q2407NRWZ zqlr$V_0~Z>tc(-F51aT1s@nAF9*AykintaqW{Un8%9Ycdfx6Q@^JOSQ-E`2?VLi3X zZY6Hq%&B^)%{4G6t3ICGwr*<-&^6VA3a}eg7O{SrwU=X}fCq}&(>Vqg+*1jHOu`DV z0K*?r^I!SLQW=Ym;iG!YOX%g-Zm^rvk<$0BX_|=Wntxm{k39ddB?Gsl*~tg2dXiP% zkxc30Mylt!0~MoR@l^m3foDW0)6ce9PmVgBk;zWh7->WHS%_g1MUjn%!QHtqPBhsl z#MLq;dplLCfPTukv#T?|s=N?AcMR5l+%K1Qnz_!M4zS`evP()$0-|hx5JI>C=h`;j z{G6q_m)-KoWHFX>l;*7GwAdpNnWh3C8j3U#dZHU8GTYv`{%}oQoAPUDvkH`U%))Vn z!#8)0Ig6iN6JtG3k4$PV$`E8&=t$4vFcht9XdwL%19Wz7Lm9TK|k0KEh4N(zPX`2}ZQG zFn$g=0OVTFSZQGiVz#DXPM^{7bbNLqf<{4|2FqM?=Vw=iN1DsbXeIeuYx1wmAIMVm za*2*{M(@WsRQ07BkLQi@xA7l$_IpW=-07`OhqC<}8BazMmt=}w_P3%`Xk-+^e)5+7 zD+_lZhr)==cpEuSMf^{!Zp;0GC%Llv%w|X^09Q{*q22_LepYl>mF3FH`3<}?l+Y>v zBx5rY5p`qU+~VeLQ~wb&xkDlmutBNdRquEGA=U{|>5_?C#?XOVjL^2&mGmdV62IfW z1E{l#29CSuF12-i^FK`a0W-nUnVz0e@VOJce+7u`cJPK%`r4o=fP3(O!3IHtYMwyBtNf8vHywpQpVZao{@bdrS# zpA)whIh~YDykMCC63@#wWJcLJ37qz~J1ndUt1tRwO8n z_BR-QN`hYnxCD-qXLWHEn^f|N!y`xvfR*)#=BB~`hQO8E+||}UO*BU9Y7g;v_XJT> z0_W7bp`@q6Tmo5jQ1K%@%f?s{P3Cp$M(Bt9_?&WAzPECEZK{5rWLILs2%#3Y`#+6t zIR&~E<~xaic%f&$b)IRAuPx1)-WnRzT$qmV+5r_uJoZ9?pN{I2W;Z%Z1kr1%08MME zpL{+Hqxtg3ALJ-LU+bjzpT>IiCnc70-rzKFHVSX<9>^3AT#QeTs$5{dK3$~8*Yhu< z257pT^Xm;7gwO25CxJQU<{ADkj%bEIfxKQMJY__QC|@W}2FMQ*S6&d}al8#WX zw8sHmDqWm|1l}8jU{zyLT;hhDfPc%SO$lstd@Q+6y+XSvvg{DL+g$UA#P$((!*pk$ z4~#=0gguR5{3yH+rPCZYt2=jiZ9-EqZu$iYoUS|BN_5K18D6Z)L zAHp0L?|;e-a892882$f0jL6Ub5^(?DPbQB?V-lfIqaiT+COdx2{RoE(Lxp$1>brRM&QU7G zNEpWyD8@6SxC!09Vf%Iy$;5VG&(^}vO>@o!n4Oq*c-AcQF*Semp-6iDrTTU{m6~>x z1jNJC4}&(Gi&8Wo9A?j6;1e(yeX;dMO3*!53AMnA7H$KP0`Nch`W4;ID|&y@B_@7v zoj=fw#)=pBI7>P${%!c)ibgL{Dg!N4iSx{fCsvX4qg7zcHZzwqOyy8is$+ZELVF4U zXd*}im-YtuX}u;&38a!94Eefgj5mI{6w%t*+@J$4b_-}8=4Q3n8im*%8WxY4XTK+s zy-z%})|gt+`-l0Ux&PXBG|f8mnH5`OkoIe^)C?7BW_aZehH+v$5?f$2|2uigJ-B{b z5=Um?tR_OV7J$483+_!WfPq<7CwbKa?CZFsd3O1w9}s>V>b&BawpZWsG3E9dS=K07w1?hLY@lqlbtl`py!1;Xq&|lXbn@|p8EVJZUig@z zWK+I zA+70Mm#rv#{lknnRhZ2am%hdeXi$Vn5MfCr?SIEm^X@x|f@h3l^$@n)z66D@PX65) z#`aMffoCZ#88YTbog$V&abs6Q%>R(gv8s-bo%mX-#|fEeN)za`we;0exV#Z1OaQQ~ zr$MbG5#-O^)lJuMfGPg?6^j~lh9VH0xgE4?IIQZ~6i*4l$dzh6spNzK5Y<(}6_e#L zgcC=fg%@vLZmZJDpCv)Ly2kb?vji>$JWn$gcbN#no+P)QJ z^B2pcCg_wi@C#!LGTM=7i;b)YHZi2H$FL|ytalWRGfcjmRXD_nLz);{Uy-^#GPi{@=<)-8LUJ)D93si zWo%s55pVz9eh+ic1O)k)GdRc3v(zaIeYD|qERp7F>kk(CLupT+^NZ)VKCT_{hXwz% zlIvEs>>r#pW5x zI)JMRKoV#UR5z&2I-XTKj%uFB^RE7+U!kQp<`EOwcczh8*KscKrR2P0fXcl}#>y-^ z00slX@;2tIQ{pqMhrs5Etpw4oE(+8@j&M9RaMXRo@(YXrq|DucZRrcQgKTN}ESoybl-WBc{KzxU0^`@GLUd^@ON}6@@c~EQLNZw=zLkiAAl#@s! zPR?dVr*xa9kOHz#`L5@cD1&4Q1=6SIN99Xl?Y%ZQ5~W`^U#U`Pj#G$|_8zL8NgOEj z(6OJnC!RM6U}{-NkdI>yk2Rgi6X@ev#}YU`M5U1(NzalZYP~5XZ56q^R^y(o_R4o? z2x_o<&OE(e=1FT|e2(0y{sOzbnzZ0&b^Bap5I(ch{1DC-G~pWWeqTM;k!&h6s;jf( zl2c+?l(J~rL2c4`$)B*W=ON@x*(82MnEx1rlL(8JDe9?z48TD8b_Z#}k`xK18FYEK z!~B=pLR^9e&jG3~KCHF+TekzbC+0DIr}i5G(fE?u{U4&rcQo0-KnLUarrE)1laJ|< z00fr#ro;5VN!*Lfs`!edXn$pib5uOPY0HGIHL~P>%Yv_b6ShGh>UJwI5}22M^lrz7 z+=6Gov~X|R2XV2aAle;N@>NVE<_OJShxs|sm&g#k8t1I}bViE#Uz!MOsPW$;$FxQb zYsWe3;J{i>+i2AeRbm*5QbU0uHswkv0fQDu+Nbg?G@NSu4G&43;Ld=(f-YUK0Q;X7<9j5UyoZ4b#>V!aPZjSbF5`8d?95Pe#oNsgJuSVd^kQyE zFpf8$0fX#5u{q+ly8x_GC%*^;GaN~4H_ss0b%PB>Kr z%o^%&Q>46jF67@Aho)5a+KxRC79My;T>si_n88u0iB)~Kwo&>JUHSCu%e+%%xeEY? z!PN}>@88eE%JTn=gyqeXYj4>BqYmpVDB)KDa75?@CL^S@zn015@SA0@v8_<|d)H#= zf5_3XR@^-j{&Yd5X~Bm8JQFTiSpL_wN{ITXFo1MII`D%`4PXraWlOX!k(Mr$mwIp6UCn1d>*7$Z8koD> zwWZF0kwFz3ExoI8nur1OG(FCYjqcKv2X(~nx&j8zMYd8PS%KBN`aX5!t;(fhf>2BV zkLw|(i6|HHPcz$JBIOCSz4d7hhkF9Ha7=i@3C~qg0PtF8`pY(okttXh zv6fxIi0WObGoR{}@s*B7XE4+Q)r8C+;(h0K>dFI_GhJX!(Eo`19hCVAI`n-6YUXhI z+r8-UOgo9M!oF^{9Ah6jBSf*C~?W$6wcxyK-MCScc9{;ZKQWrh-ukQIIF6Z zN>NxF!A;uWOZPtSJ#O#q2Vx$2WUOCW&W~P=((%MP1;dKVC`@>wW|kyp|CBs@es!TV z;&^HLq@iTfql^gk%k``M3fqC~1XDl+`9xQnIx{qG&_^!VH%zgukNNMvH#ZAUx)B8^ z6$%e8`~QU;*tx!U!2dcx;NLgofEuuDC{n$2&)gxoYb%_GiLvu@plS(<^9)!2xEdI{#`Ii!$5z z6b+kJX2k&aZIBX5>0tv(+}y3QMp4~TMSZ;O9*8!x(g>cIFi_qi)z(V z-bd4Azirr{&oE=tAkpZK@cjkI8KaRO)i$}i97a!0>i}8?E3$g13kB(siq%9TH%{{C znFOkJW*Yrud!|d9(=b+~r~cr09X%21r~XB2oy>cBwj6%%umJZzu zI4E84b){V!w#lmYG3CHsKHG3oInF%=cat`1kQo^K zdg=yn7J!~r6`YTSNbt8gc!NP0JA~D;9Z5g)*#5EA+{d|rGz+ocX*=NKO?XP&I3#BL z?k+u}dIH?8BGsCJZ`b*U$~JYnGtYUe*+IaBym7@n`pNN!X(9 zaGp5*Y7;)YPJ6%n9&KJ;%WDafM}qmut3lhO9NT||g8_@{jVpZV?~--*J5 zod(~dm+NtKx3}o_Q0VIqJkD>swmjoL0sz{z>xe+FKUm0HpN&WrtCZ3R$llQcHv54rNssNdhwOaM137lC%xkxiE3%Cdc0 z#iKd!X=ZX>8~nHI%OCD9ekUkk-5nVZR-Xtx%Tf*;6cFHndo0j6!RB_4p&ZlSLtfSJ z#F-lD$LsVY|NMEeTU;4B%ttI$<6xb$&-G^uK4C-V9ssvt?iBW2rf^qISEj-H!Sn9m zG!v0OW+#l6bXM0*;$ZOEt}0{qzKf;bS8jLqwC3mLxf{wxuBWrDFf3^~*}IAca-HHJ zk-+YFw)TVVWBrgou&QdQ{)AXK;HmPYz?3Ko4|644K=t9Fo}4H((22AoGQuxT^HUm? znd;7AOQLf{>PMH_AiI#bTNpC#ICk9ud*@{q!Et_~l5WHS&U>_(HWOO^!L=7cM2fMO z-hvuoUYcy^(pbe@%$0i1NnN}T`kKBtXWoQT0rl%ZKJanzyz3B@u#z%A(@&rKDN zh2O(&O%h+ND6V4m?}C-7O*1R!S_U5C0T&WC-k80B!=5vK!X38NVHdhr-zX@pZF=wI zoXkEcninVpzfCKIfs;oP_{cvQ|GzhQWuA`1vu4r#QG#?CHCwn_CXWuS*LBQF0ok>Z zy;y!xn*QY@%e~=y1lV@EfFJ6`ewI#EU`kU|_%WCBrLJMFQw* zAp>DYlaQj{?bP6hofunKhWN|Uoc(53P)POc{J(F`{xF8cdj5tf>(6AtP3fZ0KT1cj z$#rtJ{YmEgi8_g$M(H;NwI`-5>y|B>7X3~wuZ(Xk$H!;w@@Q}Yo|~%zL5)^|^8Lhx zJsF;%!dNpmdPITOPXe{2gge|s*eCU{fLI=2D&Y=v&p^;+0W4q|Px$sDGOdw-!Yomc zc%-tKN1YTx6i8cMHG3+HY>Fjmr}M;*t(V+U;`SajVPCSRH0V+()QB*ylZldrmt^`Y zd*hwm1-3h3;Ike;Ah0xM@mK~S*TK#oCQI%0x;dB( z@zR+u?CLYEITRBZ6Fz*06exK$pEbXztbfXUih3!L-)7ops_qQ&0vOaZa~NGdu*_u% ztjOivv`WqNECXOHQt953ytPUZa7V?F%H(Nz-1`$?UVio>?GS_TJdRk6%+E49W_K)oO9t>F)j*+uti6=5HVFZ&C6Kpju)$(9M7 zNiC51J`nBpwoZb#r5ok2#64jAuk}FD>zAK9z-4P zx0D+5Y7zs)h*HM=bvh8n!?r4+4o2eX+`T%>ht|`HLR^5)6SpmpTU7|xc-)Gt&|pPPeo7b84=O9eVHl$X-Aj7F-g4S$pNW-;<&j)2R6BO;og@1wzf3b z+uL<;wd&)q*T&f||82E3U2kc)SX=S6-?JBnsmKQ0H2X6Yk+!DkX6ugEOx7^gq^jr$ zuz4vqdRI&@BEV*D2+4&w{zJ=PPWY*OKNPYWkDUh#ku}<#WSaBIut_>eTOYI_y9GTF z3G6qJbFMF!+3GHCsx<0XVPFp$xC9TEglNjm5&cq(b9toQok^~C8+$9*Vby3_#olkQ zBQ^oJ4DArFTR1X`ZbHiwp~^RD*NzZ@Es8s-ys^z~T^@C*t4WHJFQQWp!)3QP>d^~8 z=mb?QT0YIi#YUE9!ou$mWSo=hDoH2WIZAsWZ_Z>~5}MW%o(Qj#UMEVMJqFv>H>Ny_ zi1mQu6&1KZDy(5eLC?nG+Cxkb6^D~6YYXZdHbp3?fuYa)*Iz&Pgf9eik8>wBU6&> z35V?5)_Qx(M*dh6f|-St3dXhle@|mvDB!FXtPF1`PW$w(Q;R??Eo_)9vS0^av%N0i z)2@yNLX7QRb0$1NvIvL_Wo#hRFj1iuhse|42&Lt#FSed|p<1f$jvLzFT!*dW_Z;Jg z2CRT-I2fwf)VtdIoH%5Xkzj8FW!=b8GlJ46YxF(CWIoB112%@qJuR#BZ{yiEbf-=9nB;$B$(I}wwAjg>eFzfY^cxB&G#P`bTO~aV} zIvTo@{!qD-o}7yczfqGRWZxwZ23ihOT>v_0zzyvXKLggqp0HdaMZTR~6I2sKoQYtL`-X)Q;s?+MOVAeC-$x?ZX*S{8y4?fhy`F_j|7b2$_ zHdt^Z&m{^ldElK0#2;D83Li6uB4edOtL0)nG-4tL86}WDV_Fa&Sd+dfp2tAXAyS4! z?HHY3w16ik%R37amWNxE;&g!~r`F=I%!NFs!Y}70b@;=(iMjVLQ>Ub(N*oZyz%ZsH z`A?f(njeT3HReoAk+xrAP0fPKPGgI(irGt#2@Zw0a8MJ}zQHRtS7y)AOm<5OI-%TN zPg20>oufIU^GR>z1zw=jKVqUg0QjPPS{TKFDy_MchBmNtCY&(xE9} zp7NzlQQ5SkN`H{q`K(2C;0w6Bxy`@}UdtrzcIb z9?U0oYwm7#l36A`*p8EvqWz54j`Jza3kNWq<4c+MxwU0r zC~$i4AqpeM#OY^XO7Juk1FPq`uSiqjDYm#oZPVW}n&ZziG3tcin{Lg^VRdF?zs73w zM6!UJBXozxY7Q=T2XtQhocd|TTi$1NZ#NT%4Q>w z!T5<}*@#hg^tM0aNDNTyJnW2PNjDpV+3QwIVA-TD{{!m*k(K8j{=;^dI^LXZ($eJn z1iGPUmB$(hhhhJ-Gy=AQ>kk)5$M`X@O|Nn`QcRv@172*iMroe*=atg!u7U)5y@^>Q9wQe z4pHydR808)YI!?AYqot1z$su-?X zJoKRlRQ*W(hjDp)|MaJ#Enz{pbO@Dw*8Pchi{k25eAtF!t}Z)_*)JSpP$; z0XB6vle4){08fT}MS|$`Nk71dn4cEScCGO{{AJi;W8FR7o}EM#nZNugd%0SJ*hvhN zg;silXRfF(YCW(;_GSbBejIO_+&@nBhr{bdS2TFB*x9Y5fio;~VA1d0J*Sl<(}tVg zP$0Lmcf+ng^xc@|n2}vKsb)N9M-B%^0Z5|$VKgcU>@(~Qg~5^p%DLXU-x#}f;Cu** zHu_o>{N{&Wnc;f3x__bP&{X~G3+#0x+{=Hj7^yEOPbg$1{tya=o*6}Tqj+Pz0Bg?| zKa1NoBni5Wpi)B@5ztJ}DcQBgtY?I;7l!8UPzzgP(ceZflSc((A{~k$XUa=T1^66g z=b%F1@WD0Oj{?RECFxl6V1zdlVyD&Qw{d_H9ZAuwHD?D9LM|kg5&6$KLxCkZ5>d#t z`_5^4C_=41eRYJNC$#dqodsidWSrOQ5WiTJR>`N^>M#)X6zr*5h%PZ2n zB}KMS=H88g^|3qoljYODm`f)M0g4%ITC6L2P}g5Nwjxh+7HRvOkeacf&03wk-t)#P z+O)n-b!=fK_ykri!Ph8?5#3PW^Jl1O!@x%r3#lxVU9RZ+TMSA}>$5U(OW-@%D;s3~oAD~zIKXpzksE?w20H&+`yh`W zO}kY@arRJ>lUG(Xm3Q24nK9oecv71oIo+*C-d;h@;4qCcp$xVPV26W=7_nd2>`tnG z)8cg-yh6XBJ}%lWpV!y15A+I#{RJhL+KB1U#Lc%5U7J+yiQm2n{EN^H^>c}EiDY=0 z$g?^rax~Ly+u!kpt~|ZL6Wc4&(C5l_AO9XDg$5(Aot$8#E)) zGT5JS(0E9b7d$^AYAu|;a6HcPt4L10C+B}?1U@KfXbC{KDChD_Xnw7Q7PY!mprvi-hP-Cn?kD01$z9p!rM|n*>hudt`)FJMz z9p36U8s)w2jA#d7uzX#o7LE`)CZwpWHZU@SJymOVtG%+K()=WpWNq?xU@@@s{%*D0 z%h1AiRV_@50mRo^jhC#9SHsZso2-gs*$^4Wln^0mrK%!i>2Wx>=S!5@RGCca79U;d%Mu zY$rc8Y$mZNnU}M&M;z!Sb-RahHEg;!DeK;38QhTJ0iLIPbsH7QNKKmA1h(?wXXLY; zYQX#F-zTmh;%Oxwv#(4rKm&eX zQn+?Go&Cv!2}rigzS=HuTJi#FUi&=_lIgX6l0_??6+S|%1k5pS-<43~39>D=L8%PR zH`a|x0Jlq911t?A=i#SBocBJflKJJuM=C>8*GF4znty2OG}wUtCU0J05K^#v=+tYV zZ|9NIDVgi|IAJU6=?K@F=k{z2>UsNvQ^d7bK79j7simW9&1R;paUcrQ6Vv_>`hY5% z-M9zv-oKMB{e+z63k>{S7WjYDZutK^{^uMv9#;1M^hK$WS-JjiTa=sQe`~+Gekvpo z3?p_;*Oi;PRL}-!G=TI4+Kb2pLZC1Z=D_fc+>)V~oa3!wZoj_?JUV$$P}|h(Z9!p` zXKpzx*(ON{VcB-7SP$W2tNx`4(`U6&;fmF)=KpIT8RLw>O{b`Sh#^oEmId><^USip zZ5CF($AuTxCPuYG)CYkiLV*SN>W9{fEYh*!J3P|NfN{xyYx3~h?q{PC0!cz8&S`Pd z3It;z0#9&d762Xc#<1?)J(sXDg3FT#CDGAE)sV)b%OFS!i;0CA?PaWWbDAY{9Te0| z(cPH8`9yn){msS_=A{y%OQ6-V*Z98(dj}xdqGnyNby}xw+qP}nwry8;pSEq=wr$(C zyHD#hr~iBJi}zw?VkTnkRhd~?dskFc?7dcIe)(Bbb8+1$QvE<*L&2*ByNvk??I0ik zWQUmS!tu~FG49NlY0?lX+>Gcbh5@UtXqmW9RmnRgbQL!^ZVYs~FzlI0HGJ@PT3)AZ z>r(h_SFi5wvEJZOzi>M}F~JP&8eyIp1gV7$iAGrl2f*s)&I~~eu;l6tR+-Gw@z22$5?Jit@OgC^&$P=1}{n_Bf@sNEGHz3zjn$`2?`(hGC%}xdcAUiuJjwC8S&u!U`y@*5oJJe+|PjT7qS&*@Kw2yo~x)rTm^!L zBjTyJ|Dz(@M2N$F1{R}<7>m$~<_x9TEC@d^uxZHo&Tycn>m>2UK;(A~_%w7d5ngUm zLxkUq--4lZ}DJ9SGB(a{McVIdB3qat4+NbOh7`p%Wp4m!Yb60Tu`f=Xq zK1-q)`zXFPF9SzFrWm+<0Mm{!=xRyG9I zPyFC!?@HA9$9#$K+d29hrgorvbClP*G30H=adr$5;#7`6KW$1^W*D&X|M zOB=YqgAno$0F~y#`Tr{)TxzjDg2`hUVcF*QH)H zfblLRbiG*%I%HBtm`tFBBytU-asP!<*mW^PlD6V5fruC_j^XbpvIvHU<|fk3cM})H zkQwjXC?c5Rb2);(lfn_9HZ86|S*y&JC4&X`0fViSEzHeFw~b1z0#qpm-AaG_L5zOV z0%tEaaQT`QH<0|0pySDyj|TYp{#wK;z#4YhPq)-HhCkR=GZHz9j>9Km`6nU|M>oqQ zSJ>5sb!Vvt(?Jbumh`2MSkndrKNKIMC@8yvPudWg^}gK+;6g$AEP`d@!EPXkC}y1U z0YTLvP0L+yzZLdctp9b|r!!)mX`-<2wa_l8-I!yK**5xm9Cx!~7_UaM_A$F&0A}a{ zbk=|V@IeIo-T@MFp;E>pipfPTWdUzSA=UsUtY#{y`?Ew(L982B000+!T zSHePjgCUfihw2Jo1k%^W7t(T@ztHL;ryV*a4Rd*nYuOuYmZ(|<#s||y5?5GVdmBTp z_-JB_X{|<_%Wj%M3HHy8U*Y|Mg9vEN-Y_dWA{Hti#?uz36ue!AX6O0KcRgS2iX9d>T7+N%OWscXmy6+ z_v7%ql@I3DgzbE zzYsE^C1GP}>jE?oapJhbzU3|h`-l(7(e{#sChx&xcJ(b>Y~3yjB4{$i+mU-~41>`< zK5R;B?E3B6*MFhO3M-rts(9nTFBLnpSr7>QOGm8l6$g$gd<&|pKnVlb{|v5t3!6^75WA> z?n+N&1V;wp<8GqtEaVxa3nX7F5uOsb4RRxjB%*OW$-ZW0^Y5D)~> z^7MJ)dwNjv*FMxAW{p6sKI;$1i5SQEmfz?I!rLx3#(IzWhk8^72Hf90EbPx2ecUdB zUhTwOgg_qj6Oy{LY3YB18b?}E=$XjnBj_`{G;6`ZzN@t8U4X>!si1^@{&RxR;X1v!3#6;}rKJ}o6DyvmAT>jE zd5fw{F>3VUd=x0?#UZDOpiiIbv`vR~Ai_WZe zLO6Xt!eU=d@Wm=Wj)VQ>h6YJs73Fyz7v?VBW?*vcZsy6mQv=X>QE-@}hUwFfiPQun zpF5l<5pcG-!HlFO@&Do`k@52TVP zol;Y4>t-_h_0^I3Nmu)KDFws_DyGNx)@r3&4+()tZkIX6 zR9A>FAkIO#r176ghyd$&u78KM&pdX-?9HZ$EwNi&a_un|HC8Bw?z6#Jqyz53Z!WtW z;*^5#$oC;fi11hYUR!#%KPL^7-!d=KK;Hqd;}%$>{q%7jgoxe(cH%^CFKa_^?^B5p zFIbqvaVBy}5oAQ)iter}6N~Fn<}TjsoQ(R<7sr)?w($S(7y%fhVT`?G-B~auEh@dQ zc&=X>^tA}|9?1P``|{hepKM`(iwGH$cnlg7jFWmd%#tk{6=a;_P3_AH>A%j~QFQCV z3nrs-8Cat2@ny$Yxy~Qr;QOXoa3Wm+1BQQqkJ8F;vcq|#s7jHfOy~Ow*0QMDBUP`W zlk}v}ePAMEK>$HWwbgOM8u@H>BZ5czwTG9nxlg6pz3(iqQh~8c-6wQOV@Z7fxCd}7 z=y4}Jc2_K%jU3V?(}##K!F?$WCdIc}#4Lr}D9o)8dJ(>kczT>BA0$l4bfQNKi@NN% z;@5*|(QLopXi+GJ1X~8n_%gs4%cHMGg~#2!?iS9A#Q+BcddtkWC4)S&a-!4Pdpfqk z&Ztt?Y>FCQy!H1yZnQ>r#>BinwAk(9=0A+lgbB)~K5=xPMaZR)#NEEZ8C!(bQp9ur zyfmNAwoP?Y8MUlh-K5U$f+<#7xgwsL2_vi_Vmc?UYj~A(;DRw>)}mjBsCWO(;UMUt zBI1jX1p=f$eYu{Yd8=(p*|9?@q^_4Iz2p(b-=Oo&!`VG=kIOd zg1o&BsuB66`1ipCFg?0j$d4(remcjdi3&X==`|;6yKodkMf%A0OIYOL?-3~(rBgyi2Bf!{dCuK-$f9j)32%N5T=*TmHId&_eWW#PJ&QaAo-Otp z0maeA*J1$i-^LPgbYypj|K2=>V51)2X-SKFV5Dd7g5{ytf)gOkt*egGiPwtq~0E?9(GfaaQWB@MUcV6XUpX z_;q_l{CYM2Mh7_8;3{ z%@dXhykYdK@$Qmpe`XFnCn_#&llxft1qcFH*sT{a&WNJct6b`_R?vbreGGF>BCWuF z`V!m0I!v}3gi>JL4ks%)MwLBWX(+Tef6fn^;_>=x-G`10{lLQz3)7(Kmp{nLCDC|uQl-ZHOar`-!wxiNQ>yhxl(uLyOtH@n-9EqAc4+E3W?QG&G zFr9fwlmxy>G;P0zm{AsW$W;xR-kttHg9r$xo&H7PN4&SZ^Z0!6PJ;g7E$;N%KvSpa zdc>TPJ?y^O-S^39qip%OaI%#=#^wc{#yYQ6G+hZ>)motx!>5yM+tQuCw!Mtd)nEr0 z0PNV(`pv;;9@Y^vXKVnQH|Wlkj-V3Q_po$Mrcu;^C0?6(pVogcbNz<|% zPy%&Nv((R%%&DDgaWaYf$ zADUeD`gLP|T0~?6tfx`WW?4K`WnpCdx;Y~WyWzMzL{sbi%*WE1g0;&M9FqstC#|>I zR;7O{4X@X6nz(zGE2A_N>%P|-#slu9_Q~4K`u!o<8G4F zJfxOa<1cOu4W+59T{B%S+x(02V5s$h=GI?Xie!}lItGYaFo^tDUKN-*Ri6Zy5|;IU zhtJvmn-%~tt*u>&+luP9+ba}%9oe#?ij*dRbl5T%SpPY<^4jkTN6PXFrcdzs^0|Uz zdAlfN9?B$+l3?*{a!CQ|#l2ODSMVpQ=lC#C?N>%@5t%8vKP|6hO`>8ifIE{#e9YqxvGt1;jn-_409}I84036xnkp|dq9P-7Opion!rfK%8DS&4O`MgxgDAoYl*CFYS5F(M1sY!y@q9^(Pu5$Z0NFQpNtU~+~%UowH~ zPm7iVPzm}g6=5_q$u?BOXKb+L_sab+$p|*a2@*RmueTf5PtbSP z{ruy4H1(J%v=4%n&J$DD~YVYCZ#m!*q zqguD=-~^}ih}@r(lq!VANV74-S>H@R4zKj->iI|K4?O1lgXi<)^aap6dDSbs>*GAY z4-sd<8@hvJ8q=*rf!(u}&TP58uMm6WKc3&d;%x@0(`gbil?@HnNFL^f12vz69R&*` z0Cz|t*Zvch;5^C4MfwzwY&&55P0I;L+RbWQ z!j+WZR3fj#G|-gI%SBnqY8)WS+~>QN5IPe;>NZsG<8~M(>xT?B!GKEyAD_cQy3=Y; zPTOj*PxKDS1)>~P+fD?-r-1UQ?_1K2zjDZmFhzh;f*!v*I}QkpBjfDSC>K>ho?ppJh}H47PJyIW`hVNf)D}; z5`e-6>PA_BHB5#Wb;V8cD#2`;h9ZZf2-XFGvOr6mD?ql;xTeRU91{y5iK8;)tceE; zRo?w=e%6;p1;RO0HMT`VT*QO~h8Ex3ufnQpQWr`9$=x7=#qmqgpz?w!5%*?Milmto zy}(oP&d z)N$`$-`{{!&{>EacpiKYzPpRQO3+%kF0TKZz`NJYE!GQVDRrr6Uj9RwIXE~WV3G`= zlG(`t<(m5~hXnUcuQ-lDfntjXuK;PU#2gaZe$>fv}*pbPLqoJ0_ zMYLQg2H{Fkt{{R;U?IUksd!9D#1GBN|i8J%Wr z5qJYgBKi#%RFM=Rwx|amkTGN;kh*nL0twVQXAV}=2 zolXcruC|JwiTC{%^BIAjKfAUh--5{CA+?n=l0hS97PdjQ0i`|z@yxa+oeJ6le+OW< zd`y$ypqd_&7luui^y&Ocm?VISo~ikRX$RfA^!R1*QgtWoV@5iXy%H3>L!ki&K=LSt zX|#m_Rzkn#O51uL&w`J27Gx>R9%=Q_Y(A^2wv%V{J2J*nM_zQqV_(dhHttuw5 z3?ww(F?<9wz4miCD&us{B$o?moSeud1|Ktf8x3_%^Uh3b42=jzm2#1XN+acwxzZ)aVSpySKhec#loQ2}i-dfv3S!zq8TV=za8-Jm*h_MM}bDkkiSSWKA;0 zSmG^-7XRBo&LnS=GsY9|N%U9bBzy`v{Xd5EF{XG^qDhgIa2jMyvId#|GPn|5is11A zhTTV37|kxYE-~1ZSB<583Yo!HOCQRZk0dgD5TV3|5Fy;M3I{r}mj(R%my+WX&od6N zh#v#Vyu$}6H`_f)emg$5m<0WboS-CA>=$~ALLivAJGC(P#<`;EhyY0d_UUadV-|*s z;h>QN<#usN#?VU2EL5b>G!$!hj^XP7u#(*AqCK6dIJ4}-cCuuAf%QLL@7V%VY90a# z-(p#8C((JostQLuG2`aOR5z%S4LrU%4zb3icD0bUF5EmuFDi`4nMhv~udh^Gf(pL0 z4p11VnJ!fm)@a;Rkbd~vS0Bvk^V8-jsa$1GQhI#=5L6SBq$-=x68@#zzE^HgkyqB9hsM_8o{Z3s zlOKd7HDYxprd>gPKMDY=AQvUgDl$Xz^%hPb;e!kik<^tWltlZIuq;DYNuh$IYL~() zCj{M=w#MoHo$L}|B0z{)MqR@IW+wsus6LPg1EWNVG@e|O#6}{VE`=%2lvJIRSdXqw zX^&z;0Z-slg-%6l;ji;oN?Q1-sjTUNM0QdNTkxr=vT2z_-5QX@)9jzHp_!1cTKtDh z_iogIo)AFGzRObpa0{gZMUBG-?A~3|NoJod|ie*kE zAvrmxF3_`TQDt_(uLw)3#EDG{n9ZHg$W-^(^$Pyt4Po3s7`2G(I=d|J@Ufg&kOymK zSkW1RGDgKcV+tU$5ndEL+9<&=k8g;|N~~ad5z3IDrpzybf(cS}t)PVEA;}cpfRjSH zLt#!3Apy+iVTAJfD?gdMxjBe;o>nSiOyskF2IMop+RdP?PURtvCcK9$uewMN2A1@~ zGN@5Jq$DUFBasv%%BjZ*&lfAY|Cju&3=3lY=o%#W{1kvAp)WjkWE4|q=+`KWBylt& zmEhoT-c>w77foqSKevT=Zh{T9rOzIl6pO8el!hn^5e|(ZGL$9kGI7KjOLtjtv`ZnH zTxH=;(TEZKcb5&78&CF3iul#=^1G>zA4|@c*U-)E$?5b5Z7BEN?ON*<_w!zL7`*tE zr*liy4m6<>=8aR}sxJGbgkb*GzkAeY?M>V5m5ghBiyp!G^R0tuWOwf=T zSVhWAVGamWxay#kW>s9$sEYpKK_?+d{Z0;1Bys?Qqm?CGl?V{Lq}zNzCYIp|0~dxR zFwlV@Li0Xa{Lm^I9|TsPzu6sj))fk+wXNlLOx^w0iv*_ zBMBmRKA8F)`h~#I)QQ5z!1ve+&V+y2iNXvOva;eC5K?d&v{`?{J;Mz2WgeFSCDotm zdX4}j@El~R{%qr8*R(aoDMH)_-(IHBASb1_K^etAA_;153xRnWzpjIOsu;!vt^K39^HO)w%5@o(f$mynG^pV!{|pbP z|CF{R9qecXBh#3*vz@(q4(okCln7ni)WtnW=#;7_j&~~EyRhkwz{y)`&%Z7mu-IB3 zLsWTNsK?;VMet_M&giksH5tvy$x%Ny{OhXPd4l+cp~9_)IO|HMLvIR<;avn^pf^_j z(`=OR&i-kPdE&#UAIfip7Acf`jtblmV)cwK+(&@ZLPmm0DeZk(gtnMRof&1-nBrkS11#$H?`s<4INPD?^QK%=gW^57qnU}Dg8d%1M_iR1-J<1)CWwbi z)5g@53%v=qM)kq=ip)~%`ARHz^V$u^B3^XvE7e^sBYHZB>GOzLkb-kSB@7nqu+7Y& zH)!cayu?t42ma=}`3jlciL=r8bW1IUfDk*s;5~{ULHGy^)1%p^|Nr z%Kas$Q~Tp8ms9g&dZ2RwyGrQoD>{Ga)>2VJiX^zMqe}Kyp$rx)Nz$7Oy~WlM)u#gf zalwn=LzqMt)5CGQ2H^!D6_KXQ{W8T{u$pJo>yfWes!e3eVKvBYrSeRIX`-9EWku;< z_oS`&A@P*+cQO1z{Ef>#vqnNs()&xt{1d$vME64PW^0>nr_zf)+9&_a=z+L24$*fD zW@uF8^K{Rxm}A(7bqw`L+Da*O&YyWN0wP2JJAxwqwP=9EJ(~`|9`>8lL17!|hO(-4 zzc-N#L1NqQK%gW0r{}9^*O@pGOH4e)Zs+YLTlg9XIU}U6(7Pg=uahJwXp;O!q?3QKVuq61~>R#~-e4 zp1HP8HXCPD<+KGWt%n8cnw1W{R&+wtxNFoSaOcbBt82P;SAgBQTMde}+imdYc2-xm zcGD1jx@AuRXc*@YH{LYPgDD&;sLti@WPQhpbF}q=`I;y|S@i04C!o4{S=ruL zJ^PrBmRLSxc-_aRJ!^Wg;bHs?B=_U-;(c^C`{Q){_26^);NIr#Z0B?R2#1xdFg8-E zwBqG3XM?x8!n-J{_}Er;*uh2J1P%7vno-^U7+5uR-2s>TA-^6xpr6#Ad{7F+{gv zcP)!{t>9mGdc*K5vv$LAspn$dF+Q`~a81eSw2vczEtCDq{TbqY>dORB-<$F8Y7%Vt z9D^8vhYWc3-5a`7@auU0evo}sH!hbQzqaL1l<6mLc^{q!CA}9xCf``i?*=z+ffe1T zagG>6Z}(_`{J@jEmJ`gPLl2DuFQNtKL53AgpB(Z;`E|4f=* z!P-^<0^mc|YZIFW?Hm_V6fg9A}^{92{;=S)|&F!yIqgNf*+mmvg8 zZkU7djAvWKG)Pe$m5f|NXd727qkkbCK*yMbB4Gwo0^YT!PucnL`MtJrU;S&r+Hc1J z9yqy?&4Q6%d7^+hD+o|u_aUWiS|ZlZ`*-c(h{Muay)Lhu(QhBOdlNLg?Lzt%Hvt3Q zE4%Y_hh-drq^gW(#U1s&b3kkzT^k|74#*C-lXv_uT zTHc@wR)e9E@1JrTWVM`H2w{=>KdfS61!q42O*@}nR-6B3nBE8^)E$qk&j6)I;J^~t=~B0s1uo|!`$Li&avm#D&G zN0I>%IB_9yCQ&WYH}Qp$bVW@-PFq$UjgP%%#JT(S(YAzF1wjXLBXk8jJ0f8xL#@n$ zu7E9F=0t+!x~zSNUjAzsiO88kmO#c;@?A@6b(GMZ%^@E2`-%qOupJHSpnCE=dOuO_Z&WRh4>V`d04twk& z&pEF;b0yl|-#i}@Xr?P@+6nEosj6@*+Mhic4ST%R;pD{bVMyNrYqp2|77Tm&+()e5 zsWf*x+R@2$?0Wn$(p6VdiF2Dz{#>x7fYq6w+Y#(|t+#|dvCg){{O3Y(pjm15TD1Fe zArKa|HXV<5l-$0E2)7HMJvZJ-Ek(1z>~gx!nlL**XlT1tLx6LBTeQSlg(FBM+CVmaSU zr>>%*EtBh*bM+@cdD{X{Xp;Hglb2WFmzqY&>1JJ4b>ZnqH2E_X?Rm>;`t|2xq1sxb zmm&!#BJ1d6eO5N%XjOUm`fBR#3n>^EQg7jnnq_F+^Nh-@{kUs?V2OD zyklq!MzAJ_?jHg#{VD@=;krn?D<|wLqhFmEf!Qwx=$i)2=+tZf5U#o)I@iFt_4{W+ z4NiI2Jb%A`13B!o1^jPR$NvI#Ffy{Tq}JbqY*YPobz)*?W~F9eB4=PAr-Y`LwKoy@ z*(MTDh;T76FtRbQGyacDYTE-y83-rSf41S+SR6lS5HU+9XBPqv29E!o+2UmU4?3GN zweK$o6!;t?G67yf>g-<-VnD8#GLdGjo}y~3m8LOz<58Q4787mCXTrk)4DC3*$yCCX z5Fafg-4&CVCu2z0t3~QwYTpgn8mU%0VI+xOmyBtvL&}p$f_~M0Q=M*=YlB)+FCh&{ zj}A;^m8Ike7v?D0&KSZZBdywqC$y7uy&zh=p<>=d8HHaJ@X8Tw4M1aW!=JjB0~@!- z#Bd-%jK~@1Fj}X0_!m=McxM`rgpgx8P7PRw&2L|xZ-`ixf2U9XdeMVazB+sD(Gp-aSML*D%d|(~R`zXixphiqx)09H zGq{+C?Z{doKLDuxv+%LN@0&P z;?G9Wj$8IQZgIr;HONffL&|PZ#5{YX&pqHm_>4y1B9KqMx?wI%21PG37_zRJrBgTg zrAHg_=dZP*gaQxy6|Tin>Y2l7JYiSvz_spX#BSO3LIX-|daXw;Z=^eq*<0Gpu|*5R zola0C9d2T$41Vjy=gA_Z!D+eg+oc1A0& ztzbj0b+}0mN!K@fF!WW6_AOFrR**_@SZ|l5kfgY({kHwv5zPgZV(Mk1OQ5pqBRbYFF-)}@HK4U}+-NNuMMF<|fS}>2>juQ2# z#+ap_LF`wq>l}va$dOxWmco{hu}5UWas%MbUuqT8pkDnVXXcg;K9}FO7cEhBfJ$fW z@me6by4~_FO}v@Iikj5ajltZMOa;7l3dUK%Y-y%QN+-4)pZ|AWl5S;Ip3ib=J!4@A z=`^X8@WJ{unbYc0wiE>1%aH=fjw~KQ zffxCGfbnA`k;6jCBpP95_ca<}@dCzv=IF7;3YjypoIyvRzNOgQUqB_AjL~i>sv2jQ zIjD53-~g zEW&{6TvR|a17&VaIt;+EEy#F~S42pf##-c5r4*O9*w}I~RkSQQ&~K?q4)N*@75{Uc z{kh{N`>ZY(V>u4L^N}o`sS3s-pvH|XsHABvhYM1X45=`%64&2y1{>7OaIBia$^A|0 z@B(z=D#@EL6OZ*3p+7(C-mJk!C71~VF00?qq4eJeV3}?zk4BC~=Y~`yM=A`aOy|TgrkR5>w*>_m#V-cWd-LFT+VMapoj-a>*+^fZux#=i z9#}@!IE&1}ntr%(-Z61#77W3ar4kU}L8_`xP%4RvRCZn$i)fUwG!LPbaRuhC?r5Rr zkk=~-aMhu*|9WmCEF7oW%3Gld%UiiYhJuy7WWxa|ty!3>niFtOahCe+z8va1vgD_O-i)P_uTCqF|{)jiBiX&5&novb;# zb7G)z03=(sqE48;QV615=A!FYvrN%Qpw^QY08%Uc%%jjjUHRim2E`&;lSJ+5z=~@CQmH<1^X9B`cggOTiVh;gom`HdxVR$ zk9)Cm5tFoRL4q<#SFbV!C0g8$G!^ks8nRjqn9Be*hHl9`VWz!62A}Pt~Mu^OmWMI|NHsg2juzazl{U4!gVxRq$+<+G`$mv72+)Oro zaD2m*%;RH=UY^w4ba%eN$Oj`AdlZ7r&VRM`nf<077(4xhpBAN6VUIAlg8U!=avwY| z>d=qB@Xhzn&ie#kWrbtC0%yM%@yPv3yIlJDIV~)@vCk-k%FjpLnlc zf=@;d?@zDj&6Sy#=6RQ+gR7Am^h(`j3RVA3^m{cH&1_-&R)B0^_q?iT^s)5m2U>eh z>~<4uYpf7jzzwYtY97w1a87%kg3(}g+OhsrGPeCpSsl=$#r8aN;CKL!3PJ_g04qop z%;JcUSL|fFP5Dal3Pgoye=9H*s2|%jv+iB{>G|9A&711eQ$a|7vPw;y#~b2ul0c21 z%#L975f6O3SS`E|Zq{J1UUsgD%fE@v&y#C_{>s`ll`XwY z34WIMKg)A<0&PYDW&*|^tCGFF%YUrQKOJ0^py?&;%%E2MRNAUmSg7D+>b14~9yZ@pGWo7#>rWF9`n&cJU zxaR16&C65ItzUQaXeaN^b??iz-R-8w%NjEty+8aoqhipW{~iJq6tEH0K|;dfoPPUgBQquTN6E^ibXT|JQ!L}!Z9N#{m+6o}QTp-=j|7=-3 zt+r@=h+C&j>xaGF{@blmcIole1Ky{|O_EmSD%jU5b$JczHWbu~ep%>Hkb~ty?Di0A z|APTX@zCi(?k~ku*|maqr6){G<@xD2_B67C(zS8(YDVeaW0M+p^DOIZpC;=pw`Z{@ z+)QP)^1IAm5FHinqGv$)329rEo6L3b3F_IhT}Ag?7xb#wB1CTKbNGpCTfUp%b^D2I z+pkt-_OH^jKi=h;f4{pOA%YB@U~2|x!*JpE{4P$uNZ`IO@cNBCK;-u^hn5f64!#aX z4#N)=3*if#3swub3v;0`j9`@5hQ^3J!|ut@grk@Qv5aiOcMt%?QW~Kc;s?A#XN&|P z7|dc52*d>72ZKw~n@H#p^NkD2J2KnJ*NV(6;Kqg;*&WIJv070m#)b$NhQ1eSpHyx` zb8AOnBbz}HhTJx?+a;@xVPo)4Tvrm?5CH7vY`7llOQ0+1?Uvqf+y-u(KunIbj_ckq zTyX&-h|nWuY75fgFA5&1+$quA}ga z&9=XFIrshh8ll9WIT#(dMLRB67PqaCcR#e==n@T>0wx|XU`#L*gg8L~@c$8L!0R!F zj1VFXu_9TJcl1hbKJZ6=cvL;i#UY@?7(z4|umLB1I%yDp4S{KXz+MU~lgzbXx3tAe4b{yfzIvkj2l8D*`*=!G(C_endLVS7AHUjfl~rRzE% zJ{R5W6t}gpZ%ygl>1D3N@0c+|>?7cW5Idll?P1`AB0C_-^;>d)n(yOeh5mNHtm$KJ zO9FI2e519_5308P(8Ymo1!+5A-}LFWLA>l6djP@jBl3ih@9i2OjrxMn?~(dI=k`;- z;t;{u@6m<{m@$OTotAq)k6fSlYnarJ8O0A1MT(|`(I9GKYy>WS4yzxaJH@3AFloSD znLjhXr+-fQnejK~uFw9DiUWwe!aaRuHsK%DC#ck%dMH@>>`!%c3?D;^Cnb^=NeN4h z2L(k<4Fd&51bmo1|7G#gk2XvuC5kle0sDWP66T`zcyn33#Qk4NdXkst*$PaSP0TPnD%d6_EDh1V@&1kc zH|F1@fA{`9maurYtnc0Xe-+j#3i>Jm4@~dO07}jN?)Z35;XRA|Ip*i2pV#+(b}Lfe zd6aq59gjQ}^GVVt-)a`zT(|6FoOTVd27mp3evCin zX?|Gj2G{Kb>o+a7^&bR*h0q3hz5|XOFJC2gc)kkkSozYhgYzY4N9KykN5Ai`{C#uw zjvtx^;;mq*!?HWLzdw+)X?(fi z|IzxRrSF~Rd{MM%Iu1Ojr&0WakX`Hf2ck86>mTy&F+Dw(Kk-B6tA9W1*FTmz6!3Jx zDaWbJTI{8Mul_y1FB>#-olp3(*GUmf-i}^c&!>JqRrz#J9Y@Tym)(!-uN`0c1gbog zWfez=;0mPxuzKywrR*1CQy0Hud!+qw>JP6P)qO(om8;iWJG=7tr|E_42x~%FvT6z@ z#5^{BEK`5vIO}CoJ54>u8jqO9A2kUZ{GNC2{}~$7{P$E{>i$jfo$HT;gUq{S^_TC* z+wLEcHGd3ZJ=b0C{96CN_Km_mJ66q=Z^FN6|DFofaC1G7n|-7HIrFk+7G;UUIx~2S z6@osglKFMdcUg6njG<(h`68@R#_OGR)CN3g$6 zWX@^v{lJ*h#-GTY)0(?Mw(Nl44c6U>{534qiSlpSnF|E?4klVKxhJyq9W1n9RDUQk zr_H!P?A*cB9UR@kQhzn99@)e+%B^#%af@sJQL%?}`vbE(jk^o@-yJ^wfkEz&as`k7 z15KM|gXbSO_cToZpjpGV{y}jCFQ^1);GbJ4*r>$h%F@LlBB-Gh08Cyp__-Ti9;%Dv znQq9=EG+!I^@-3q{iP=F!|t5kHKpudVa~?s5$w!X_4_x(&(IThU^%5aq2o|pB9MDS z|Bd)J?%%C{oyrsU=Xhk^{r>1=zI1AdxTQu>z>@_h96Mzp^u%T*c2~YG84;KSOkhg+ zI|tNQbZA>#S0BT5&6VSJ5K-B>`|_4q@UIX;*DkNkMMa>~AcZ*N%5y<}f!zwO+T zFGtOjU+2s^$Cms$re138@35S?{)=m`C%<-*`g<`y`E`=i-w)@LwA1+eA95Zszq{Gw z*WdlOZogg~7ytFws_Wr<_q|FkHJuim{5J$7aG&k=!9&sOU;m2m>-~B;!k||)$o9(X zg}|GQb}hN?yI1dJspop{UlCSURblMO1zdiIB|A*7M!49z@lQMRt6PA(cjKmviHrM9 zudYt$U9;Wo+I@!Z!o62F-COY@d9JBgShDI>EzkGsH`Ox$tAZE%|9MLN&5NFX?4|YH c|BSUa1$?Hvb27_un;RILa;d7i`nz!f0BJl?IsgCw delta 50788 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≻#KS9lq~fmT1(3ze#!| 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�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 LT&k+B{%%|VuJ$j; diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index fc25e14..9b02816 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -1,7 +1,7 @@ # coding=utf-8 import numpy as np -from constants import Basins +from earthdiagnostics.constants import Basins from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 3f8ddb8..c0e73b5 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -127,7 +127,8 @@ class Siasiesiv(Diagnostic): 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) - def _extract_variable_and_rename(self, reference_file, values, cmor_name, units): + @staticmethod + def _extract_variable_and_rename(reference_file, values, cmor_name, units): temp = TempFile.get() reference_handler = Utils.openCdf(reference_file) os.remove(temp) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index eea00ce..9eb62d5 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -12,7 +12,7 @@ from autosubmit.config.log import Log from cdo import Cdo from nco import Nco -from constants import Basins +from earthdiagnostics.constants import Basins class Utils(object): @@ -27,6 +27,14 @@ class Utils(object): @staticmethod def get_mask(basin): + """ + Returns a numpy array containing the mask for the given basin + + :param basin: basin to retrieve + :type basin: Basin + :return: mask + :rtype: numpy.array + """ if basin != Basins.Global: mask_handler = Utils.openCdf('mask_regions.nc') mask = mask_handler.variables[basin.fullname][:, 0, :] -- GitLab From 4af351c555da4508a2e9d6bdea0e9d4318c97a4b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 18 Jul 2016 10:42:05 +0200 Subject: [PATCH 143/268] Added monthly mean diagnostic --- earthdiagnostics/general/__init__.py | 0 earthdiagnostics/general/monthlymean.py | 90 +++++++++++++++++++++++++ earthdiagnostics/ocean/interpolate.py | 2 +- 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 earthdiagnostics/general/__init__.py create mode 100644 earthdiagnostics/general/monthlymean.py diff --git a/earthdiagnostics/general/__init__.py b/earthdiagnostics/general/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/earthdiagnostics/general/monthlymean.py b/earthdiagnostics/general/monthlymean.py new file mode 100644 index 0000000..05788ee --- /dev/null +++ b/earthdiagnostics/general/monthlymean.py @@ -0,0 +1,90 @@ +# coding=utf-8 +import shutil + +import os +from autosubmit.config.log import Log +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile + + +class MonthlyMean(Diagnostic): + """ + 3-dimensional conservative interpolation to the regular atmospheric grid. + It can also be used for 2D (i,j) variables + + :original author: Javier Vegas-Regidor + + :created: July 2016 + + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: str + """ + + alias = 'monmean' + "Diagnostic alias for the configuration file" + + def __init__(self, data_manager, startdate, member, chunk, variable, domain, frequency): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.frequency = frequency + + def __str__(self): + return 'Calculate monthly mean Startdate: {0} Member: {1} Chunk: {2} ' \ + 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, domain, frequency=day + :type options: list[str] + :return: + """ + num_options = len(options) - 1 + if num_options < 2: + raise Exception('You must specify the variable and domain to average monthly') + if num_options > 3: + raise Exception('You must specify between 2 and 3 parameters for the monthly mean diagnostic') + variable = options[1] + domain = options[2] + if num_options >= 3: + frequency = options[3] + else: + frequency = 'day' + + job_list = list() + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + job_list.append(MonthlyMean(diags.data_manager, startdate, member, chunk, + variable, domain, frequency)) + return job_list + + def compute(self): + """ + Runs the diagnostic + """ + temp = TempFile.get() + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk, + frequency=self.frequency) + Utils.cdo.monmean(input=variable_file, output=temp, options='-O') + os.remove(variable_file) + + self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, + frequency='mon') + diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 17dcdcb..d39b524 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -71,7 +71,7 @@ class Interpolate(Diagnostic): raise Exception('You must specify between 1 and 2 parameters for the interpolation diagnostic') variable = options[1] if num_options >= 2: - domain = int(options[2]) + domain = options[2] else: domain = 'ocean' -- GitLab From b05847d7b802442de139055b7a04ed1a1bdc61bc Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 18 Jul 2016 16:32:16 +0200 Subject: [PATCH 144/268] Fixed some errors on CMORization --- earthdiagnostics/conversions.csv | 2 +- earthdiagnostics/datamanager.py | 29 +++++++++++++++++----- earthdiagnostics/diags.conf | 6 ++--- earthdiagnostics/diags.py | 2 ++ earthdiagnostics/general/__init__.py | 1 + earthdiagnostics/ocean/heatcontentlayer.py | 2 +- 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/earthdiagnostics/conversions.csv b/earthdiagnostics/conversions.csv index 054c565..1052c7a 100644 --- a/earthdiagnostics/conversions.csv +++ b/earthdiagnostics/conversions.csv @@ -4,4 +4,4 @@ degC,K,1,273.15 m,km,1000,0 m2,km2,1.00E+006,0 m3,km3,1.00E+009,0 -"[0,1]",%,100,1 +"[0,1]",%,100,0 diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index ef298c0..98ad852 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -498,9 +498,7 @@ class DataManager(object): variables = dict() variables['time_counter'] = 'time' variables['time_counter_bnds'] = 'time_bnds' - # variables['time_counter_bounds'] = 'time_bnds' variables['tbnds'] = 'bnds' - # variables['axis_nbounds'] = 'bnds' variables['nav_lat'] = 'lat' variables['nav_lon'] = 'lon' variables['x'] = 'i' @@ -573,8 +571,6 @@ class DataManager(object): Utils.copy_variable(handler, handler_cmor, 'lat', False) if 'time' in handler_cmor.dimensions.keys(): Utils.copy_variable(handler, handler_cmor, 'leadtime', False) - handler_cmor.modeling_realm = var_cmor.domain - handler_cmor.table_id = 'Table {0} (December 2013)'.format(self.domain_abbreviation(var_cmor.domain, frequency)) handler_cmor.close() if var_cmor.basin is None: @@ -879,6 +875,8 @@ class DataManager(object): var_handler.long_name = cmor_var.long_name var_handler.short_name = cmor_var.short_name var_type = var_handler.dtype + handler.modeling_realm = cmor_var.domain + handler.table_id = 'Table {0} (December 2013)'.format(self.domain_abbreviation(cmor_var.domain, frequency)) if cmor_var.units: if 'units' in var_handler.ncattrs(): @@ -887,6 +885,16 @@ class DataManager(object): if factor is not None: if factor != 1 or offset != 0: var_handler[:] = var_handler[:]*factor + offset + else: + if var_handler.units[-1] == '2' and cmor_var.units[-1] == 2: + factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units[:-1], + cmor_var.units[:-1]) + if factor is None: + Log.warning('Variable {0} can not be converted from {1} to {2}. ' + 'Please add conversion to table', + cmor_var.short_name, var_handler.units, cmor_var.units) + else: + var_handler[:] = np.square(np.sqrt(var_handler[:]) * factor + offset) var_handler.units = cmor_var.units handler.sync() @@ -896,6 +904,17 @@ class DataManager(object): options='-O -a _FillValue,{0},o,{1},"1.e20" ' '-a missingValue,{0},o,{1},"1.e20"'.format(var, var_type.char)) + variables = dict() + variables['x'] = 'i' + variables['y'] = 'j' + variables['nav_lat_grid_V'] = 'lat' + variables['nav_lon_grid_V'] = 'lon' + variables['nav_lat_grid_U'] = 'lat' + variables['nav_lon_grid_U'] = 'lon' + variables['nav_lat_grid_T'] = 'lat' + variables['nav_lon_grid_T'] = 'lon' + Utils.rename_variables(filetosend, variables, False, True) + temp = TempFile.get() Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) shutil.move(temp, filetosend) @@ -1131,8 +1150,6 @@ class UnitConversion(object): factor, offset = UnitConversion._get_factor(new_unit, unit) if factor is None: - Log.warning("Conversion from {0} to {1} not defined. Please add it to the table".format(input_units, - output_units)) return None, None factor = factor * scale_unit / float(scale_new_unit) offset /= float(scale_new_unit) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index c91b5d4..110ff2b 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -7,7 +7,7 @@ DATA_DIR = /esnas/exp/nemo/ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below) -DIAGS = OHC_SPECIFIED_LAYER siasiesiv +DIAGS = monmean,tauuo,ocean,day # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -19,7 +19,7 @@ MAX_CORES = 2 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = False +FORCE = True # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True @@ -53,7 +53,7 @@ MEMBERS = 0 MEMBER_DIGITS = 2 CHUNK_SIZE = 12 # CHUNKS = 58 -CHUNKS = 58 +CHUNKS = 1 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index c2ff36e..f114ffd 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -16,6 +16,7 @@ from earthdiagnostics import cdftools from earthdiagnostics.utils import TempFile from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.ocean import * +from earthdiagnostics.general import * from experimentmanager import ExperimentManager from ocean import ConvectionSites, Gyres, Psi, MaxMoc, AreaMoc, Moc, VerticalMean, VerticalMeanMeters, Interpolate, \ AverageSection, CutSection, MixedLayerSaltContent, Siasiesiv @@ -78,6 +79,7 @@ class Diags(object): Diagnostic.register(MixedLayerHeatContent) Diagnostic.register(HeatContentLayer) Diagnostic.register(HeatContent) + Diagnostic.register(MonthlyMean) parse_date('20000101') diff --git a/earthdiagnostics/general/__init__.py b/earthdiagnostics/general/__init__.py index e69de29..3dbedc8 100644 --- a/earthdiagnostics/general/__init__.py +++ b/earthdiagnostics/general/__init__.py @@ -0,0 +1 @@ +from earthdiagnostics.general.monthlymean import MonthlyMean \ No newline at end of file diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 9b02816..8fd383e 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -137,7 +137,7 @@ class HeatContentLayer(Diagnostic): weight = mask * np.apply_along_axis(calculate_weight, 1, depth) * 1020 * 4000 - # Now we will reduce to the levels with any weight != 0 + # Now we will reduce to the levels with any weight != 0 to avoid loading too much data on memory levels = weight.shape[1] min_level = 0 while min_level < levels and not weight[:, min_level, :].any(): -- GitLab From 485a4466487e9c1b23fa471f7a1b49c5cd1c0b37 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 19 Jul 2016 09:34:17 +0200 Subject: [PATCH 145/268] Updated cmor_table --- earthdiagnostics/cmor_table.csv | 4 ++-- earthdiagnostics/diags.conf | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 472f178..b4dfee4 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -217,7 +217,7 @@ sctemtot,thetaoga,sea_water_potential_temperature,Global average sea water poten iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of melt at upper surface of sea ice,seaIce,,,, sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,, sstk,tos,sea_surface_temperature,Sea surface temperature ,atmos,,K,, -tossq,tossq,square_of_sea_surface_temperature,Square of sea surface temperature ,ocean,,K,, +tossq,tossq,square_of_sea_surface_temperature,Square of sea surface temperature ,ocean,,K2,, zotematl,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Atl,K,, zotemglo,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Glob,K,, zotemind,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Ind,K,, @@ -261,4 +261,4 @@ scsshtot,zosga,global_average_sea_level_change,Global average sea level change , scsshste,zossga,global_average_steric_sea_level_change,Global average steric sea level change ,ocean,,,, zossq,zossq,square_of_sea_surface_height_above_geoid,Square of sea surface height above geoid ,ocean,,,, scsshtst,zostoga,snthic,Global average thermosteric sea level change ,ocean,,,, -heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,,, +heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,Joules,, diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 110ff2b..48d9145 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -15,11 +15,11 @@ CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -MAX_CORES = 2 +MAX_CORES = 4 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = True +FORCE = False # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True @@ -53,7 +53,7 @@ MEMBERS = 0 MEMBER_DIGITS = 2 CHUNK_SIZE = 12 # CHUNKS = 58 -CHUNKS = 1 +CHUNKS = 58 -- GitLab From d7961f6775ddf0869cdbf4665da1aa9155342058 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 19 Jul 2016 12:30:05 +0200 Subject: [PATCH 146/268] Changed order of variable renaming at send_file to avoid errors. Better management of valid_min and valid_max attributes --- earthdiagnostics/datamanager.py | 27 +++++++++++++++++++++++---- earthdiagnostics/diags.conf | 4 ++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 98ad852..88bf14e 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -868,6 +868,10 @@ class DataManager(object): Utils.move_file(temp, filetosend) Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') + temp = TempFile.get() + Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) + shutil.move(temp, filetosend) + if cmor_var: handler = Utils.openCdf(filetosend) var_handler = handler.variables[var] @@ -895,14 +899,29 @@ class DataManager(object): cmor_var.short_name, var_handler.units, cmor_var.units) else: var_handler[:] = np.square(np.sqrt(var_handler[:]) * factor + offset) + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = float(var_handler.valid_min) * factor + offset + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = float(var_handler.valid_max) * factor + offset var_handler.units = cmor_var.units handler.sync() handler.close() + if cmor_var.valid_min != '': + valid_min = '-a valid_min, {0}, o, {1}, "{2}" '.format(var, var_type.char, cmor_var.valid_min) + else: + valid_min = '' + + if cmor_var.valid_max != '': + valid_max = '-a valid_max, {0}, o, {1}, "{2}" '.format(var, var_type.char, cmor_var.valid_max) + else: + valid_max = '' + Utils.nco.ncatted(input=filetosend, output=filetosend, options='-O -a _FillValue,{0},o,{1},"1.e20" ' - '-a missingValue,{0},o,{1},"1.e20"'.format(var, var_type.char)) + '-a missingValue,{0},o,{1},"1.e20" {2}{3}'.format(var, var_type.char, + valid_min, valid_max)) variables = dict() variables['x'] = 'i' @@ -915,9 +934,7 @@ class DataManager(object): variables['nav_lon_grid_T'] = 'lon' Utils.rename_variables(filetosend, variables, False, True) - temp = TempFile.get() - Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) - shutil.move(temp, filetosend) + Utils.move_file(filetosend, filepath) @@ -1039,6 +1056,8 @@ class Variable(object): self.domain = line[4].strip() self.basin = Basins.parse(line[5]) self.units = line[6].strip() + self.valid_min = line[7].strip() + self.valid_max = line[8].strip() @classmethod def get_variable(cls, original_name): diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 48d9145..cde3336 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -7,7 +7,7 @@ DATA_DIR = /esnas/exp/nemo/ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below) -DIAGS = monmean,tauuo,ocean,day +DIAGS = 3dsal # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -15,7 +15,7 @@ CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -MAX_CORES = 4 +# MAX_CORES = 4 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -- GitLab From 70e8d3e60b2e2f0845bf1313b1d9e78ebb1fc236 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 19 Jul 2016 16:40:58 +0200 Subject: [PATCH 147/268] Added rewrite diagnostic. Added some units and conversions --- earthdiagnostics/cmor_table.csv | 23 ++++---- earthdiagnostics/conversions.csv | 1 + earthdiagnostics/datamanager.py | 14 +++-- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/diags.py | 1 + earthdiagnostics/general/__init__.py | 4 +- earthdiagnostics/general/monthlymean.py | 7 ++- earthdiagnostics/general/rewrite.py | 72 +++++++++++++++++++++++++ earthdiagnostics/ocean/interpolate.py | 5 ++ 9 files changed, 108 insertions(+), 21 deletions(-) create mode 100644 earthdiagnostics/general/rewrite.py diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index b4dfee4..b3b11f7 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -103,7 +103,6 @@ iocesafl,iocesafl,salt_flux_ocean_surface,Salt flux at ocean surface,seaIce,,,, iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce,,,, iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce,,,, iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce,,,, -isssalin,isssalin,sea_surface_salinity,Sea surface salinity,seaIce,,,, isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce,,K,, scmastot,masso,sea_water_mass,Sea water mass ,ocean,,,, mldkz5,mldkz5,ocean_mixed_layer_thickness_defined_by_vertical_tracer_diffusivity,Turbocline depth (kz = 5e-4),ocean,,,, @@ -167,11 +166,11 @@ sopsteiv,sltbasinba,northward_ocean_salt_transport_due_to_bolus_advection,Northw sopstldf,sltbasindif,northward_ocean_salt_transport_due_to_diffusion,Northward ocean salt transport due to diffusion,ocean,,,, sltnortha,sltnortha,northward_ocean_salt_transport,Atlantic northward ocean salt transport,ocean,,,, sopstove,sltovovrt,northward_ocean_salt_transport_due_to_overturning,Northward ocean salt transport due to overturning ,ocean,,,, -zosalatl,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Atl,,, -zosalglo,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Glob,,, -zosalind,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Ind,,, -zosalipc,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,IndPac,,, -zosalpac,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Pac,,, +zosalatl,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Atl,psu,, +zosalglo,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Glob,psu,, +zosalind,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Ind,psu,, +zosalipc,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,IndPac,psu,, +zosalpac,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Pac,psu,, asn,snal,snow_albedo,Snow albedo,landIce,,,, iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce,,,, isnoheco,snheco,snow_heat_content,Snow total heat content,seaIce,,,, @@ -180,13 +179,13 @@ smlt,snm,surface_snow_melt_flux,Surface snow melt,landIce,,,, isnowthi,snthic,surface_snow_thickness,Surface snow thickness,seaIce,,,, sbgvoltot,snvolga,snow_volume,Global mean snow volume,seaIce,,,, snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow volume per gridcell area unit,seaIce,,,, -vosaline,so,sea_water_salinity,Sea water salinity,ocean,,,, -scsaltot,soga,sea_water_salinity,Global mean sea water salinity ,ocean,,,, +vosaline,so,sea_water_salinity,Sea water salinity,ocean,,psu,, +scsaltot,soga,sea_water_salinity,Global mean sea water salinity ,ocean,,psu,, hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic northward ocean heat transport,ocean,,,, soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,Eddy induced vel. coeff. at w-point,ocean,,,, soleahtw,soleahtw,lateral_eddy_diffusivity,Lateral eddy diffusivity,ocean,,,, somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (turbocline),ocean,,,, -sosaline,sos,sea_surface_salinity,Sea surface salinity ,ocean,,,, +sosaline:isssalin,sos,sea_surface_salinity,Sea surface salinity ,ocean,,psu,, tos,sosstsst,sea_surface_temperature,Sea surface temperature,ocean,,K,, sothedep,sothedep,thermocline_depth,Thermocline depth (max dt/dz),ocean,,,, src,src,skin_reservoir_content,Skin reservoir content,land,,,, @@ -196,9 +195,9 @@ zosrfind,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Ind,,, zosrfipc,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,IndPac,,, zosrfpac,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Pac,,, rsn,srho,snow_density,Snow density,landIce,,,, -iicesali:iice_std,ssi,sea_ice_salinity,Sea ice salinity,seaIce,,,, -salincat,ssicat,sea_ice_salinity_in_categories,Sea-ice bulk salinity for categories,seaIce,,,, -ibgsaline,ssiga,sea_ice_salinity,Global mean sea ice salinity ,seaIce,,,, +iicesali:iice_std,ssi,sea_ice_salinity,Sea ice salinity,seaIce,,psu,, +salincat,ssicat,sea_ice_salinity_in_categories,Sea-ice bulk salinity for categories,seaIce,,psu,, +ibgsaline,ssiga,sea_ice_salinity,Global mean sea ice salinity ,seaIce,,psu,, iicestre,streng,compressive_strength_of_sea_ice,Compressive sea ice strength,seaIce,,,, so20chgt,t20d,depth_of_isosurface_of_sea_water_potential_temperature,,ocean,,,, t,ta,air_temperature,Air temperature,atmos,,K,, diff --git a/earthdiagnostics/conversions.csv b/earthdiagnostics/conversions.csv index 1052c7a..5e07878 100644 --- a/earthdiagnostics/conversions.csv +++ b/earthdiagnostics/conversions.csv @@ -5,3 +5,4 @@ m,km,1000,0 m2,km2,1.00E+006,0 m3,km3,1.00E+009,0 "[0,1]",%,100,0 +1e-3,psu,1,0 diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 88bf14e..9283439 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -906,6 +906,17 @@ class DataManager(object): var_handler.units = cmor_var.units handler.sync() + if 'lev' in handler.variables: + handler.variables['lev'].short_name = 'lev' + if domain == 'ocean': + handler.variables['lev'].standard_name = 'depth' + if 'lon' in handler.variables: + handler.variables['lon'].short_name = 'lon' + handler.variables['lon'].standard_name = 'longitude' + if 'lat' in handler.variables: + handler.variables['lat'].short_name = 'lat' + handler.variables['lat'].standard_name = 'latitude' + handler.close() if cmor_var.valid_min != '': @@ -934,10 +945,7 @@ class DataManager(object): variables['nav_lon_grid_T'] = 'lon' Utils.rename_variables(filetosend, variables, False, True) - - Utils.move_file(filetosend, filepath) - self._create_link(domain, filepath, frequency, var) def _create_link(self, domain, filepath, frequency, var): diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index cde3336..5d45ebb 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -7,7 +7,7 @@ DATA_DIR = /esnas/exp/nemo/ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below) -DIAGS = 3dsal +DIAGS = rewrite,so,ocean # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index f114ffd..033efc4 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -80,6 +80,7 @@ class Diags(object): Diagnostic.register(HeatContentLayer) Diagnostic.register(HeatContent) Diagnostic.register(MonthlyMean) + Diagnostic.register(Rewrite) parse_date('20000101') diff --git a/earthdiagnostics/general/__init__.py b/earthdiagnostics/general/__init__.py index 3dbedc8..d934d63 100644 --- a/earthdiagnostics/general/__init__.py +++ b/earthdiagnostics/general/__init__.py @@ -1 +1,3 @@ -from earthdiagnostics.general.monthlymean import MonthlyMean \ No newline at end of file +# coding=utf-8 +from earthdiagnostics.general.monthlymean import MonthlyMean +from earthdiagnostics.general.rewrite import Rewrite diff --git a/earthdiagnostics/general/monthlymean.py b/earthdiagnostics/general/monthlymean.py index 05788ee..a9d771a 100644 --- a/earthdiagnostics/general/monthlymean.py +++ b/earthdiagnostics/general/monthlymean.py @@ -1,16 +1,13 @@ # coding=utf-8 -import shutil import os -from autosubmit.config.log import Log from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile class MonthlyMean(Diagnostic): """ - 3-dimensional conservative interpolation to the regular atmospheric grid. - It can also be used for 2D (i,j) variables + Calculates monthly mean for a given variable :original author: Javier Vegas-Regidor @@ -28,6 +25,8 @@ class MonthlyMean(Diagnostic): :type variable: str :param domain: variable's domain :type domain: str + :param frequency: original frequency + :type frequency: str """ alias = 'monmean' diff --git a/earthdiagnostics/general/rewrite.py b/earthdiagnostics/general/rewrite.py new file mode 100644 index 0000000..6833b8a --- /dev/null +++ b/earthdiagnostics/general/rewrite.py @@ -0,0 +1,72 @@ +# coding=utf-8 +from earthdiagnostics.diagnostic import Diagnostic + + +class Rewrite(Diagnostic): + """ + Rewrites files without doing any calculations. + Can be useful to convert units or to correct wrong metadata + + :original author: Javier Vegas-Regidor + + :created: July 2016 + + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: str + """ + + alias = 'rewrite' + "Diagnostic alias for the configuration file" + + def __init__(self, data_manager, startdate, member, chunk, variable, domain): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + + def __str__(self): + return 'Rewrites output Startdate: {0} Member: {1} Chunk: {2} ' \ + 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, domain, frequency=day + :type options: list[str] + :return: + """ + num_options = len(options) - 1 + if num_options < 2: + raise Exception('You must specify the variable and domain to average monthly') + if num_options > 2: + raise Exception('You must specify 2 parameters for the rewrite diagnostic') + variable = options[1] + domain = options[2] + job_list = list() + for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + job_list.append(Rewrite(diags.data_manager, startdate, member, chunk, variable, domain)) + return job_list + + def compute(self): + """ + Runs the diagnostic + """ + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + self.data_manager.send_file(variable_file, self.domain, self.variable, self.startdate, self.member, self.chunk) + diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index d39b524..6d7382a 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -1,5 +1,6 @@ # coding=utf-8 import shutil +import threading import os from autosubmit.config.log import Log @@ -37,6 +38,8 @@ class Interpolate(Diagnostic): alias = 'interp' "Diagnostic alias for the configuration file" + lock = threading.Lock() + def __init__(self, data_manager, startdate, member, chunk, variable, domain, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate @@ -101,8 +104,10 @@ class Interpolate(Diagnostic): temp = TempFile.get() if has_levels: + Interpolate.lock.acquire() nco.ncrcat(input=self._get_level_file(0), output=temp, options="-n {0},2,1 -v '{1}'".format(num_levels, self.variable)) + Interpolate.lock.release() else: Utils.move_file(self._get_level_file(0), temp) -- GitLab From 058d5d0711464a09ca291f6c937bdd6b8cfccc51 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 20 Jul 2016 10:00:59 +0200 Subject: [PATCH 148/268] Fixes on interpolation and launch script --- earthdiagnostics/diags.conf | 4 ++-- earthdiagnostics/ocean/interpolate.py | 4 ++-- testing_diags_moore.job => launch_diags.sh | 13 ++++++------- 3 files changed, 10 insertions(+), 11 deletions(-) rename testing_diags_moore.job => launch_diags.sh (75%) mode change 100755 => 100644 diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 5d45ebb..9687488 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -7,7 +7,7 @@ DATA_DIR = /esnas/exp/nemo/ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below) -DIAGS = rewrite,so,ocean +DIAGS = 3dsal # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -53,7 +53,7 @@ MEMBERS = 0 MEMBER_DIGITS = 2 CHUNK_SIZE = 12 # CHUNKS = 58 -CHUNKS = 58 +CHUNKS = 1 diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 6d7382a..42f9212 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -127,7 +127,7 @@ class Interpolate(Diagnostic): if self.model_version[6:9] == '025': cdo.invertlatdata(input=temp2, output=temp2) if not has_levels: - nco.ncks(input=temp2, output=temp2, options='-O -v sic,lat,lon,time') + nco.ncks(input=temp2, output=temp2, options='-O -v {0},lat,lon,time'.format(self.variable)) self.data_manager.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, grid='regular') @@ -142,7 +142,7 @@ class Interpolate(Diagnostic): nco = Utils.nco temp = TempFile.get() if has_levels: - nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1}'.format(lev, self.variable)) + nco.ncks(input=input_file, output=temp, options='-O -d lev,{0} -v {1},lat,lon'.format(lev, self.variable)) nco.ncwa(input=temp, output=temp, options='-O -h -a lev') else: shutil.copy(input_file, temp) diff --git a/testing_diags_moore.job b/launch_diags.sh old mode 100755 new mode 100644 similarity index 75% rename from testing_diags_moore.job rename to launch_diags.sh index 1d91730..ab333e2 --- a/testing_diags_moore.job +++ b/launch_diags.sh @@ -1,8 +1,9 @@ -#!/bin/bash -#SBATCH --time=24:00:00 -#SBATCH -n 8 -#SBATCH --error=~/job.%J.err -#SBATCH --output=~/job.%J.out +#!/usr/bin/env bash + +#SBATCH -n 1 +#SBATCH --time 1:00:00 +#SBATCH --error=job.%J.err +#SBATCH --output=job.%J.out set -xv @@ -11,8 +12,6 @@ module load CDO/1.6.9-foss-2015a module load CDFTOOLS/3.0-foss-2015a source /home/Earth/jvegas/virtualenvs/diags/bin/activate - export PYTHONPATH=/home/Earth/jvegas/pyCharm/ocean_diagnostics/:$PYTHONPATH - cd /home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/ ./diags.py -lc DEBUG -- GitLab From 0c7059419b4181ddc821142c756534523fc24c22 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 20 Jul 2016 10:11:57 +0200 Subject: [PATCH 149/268] Improved launch script --- launch_diags.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/launch_diags.sh b/launch_diags.sh index ab333e2..6a2aefe 100644 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -7,11 +7,15 @@ set -xv +PATH_TO_DIAGNOSTICS=~/pyCharm/ocean_diagnostics +PATH_TO_VIRTUALENV=/home/Earth/jvegas/virtualenvs/diags/bin + module load NCO/4.5.4-foss-2015a module load CDO/1.6.9-foss-2015a -module load CDFTOOLS/3.0-foss-2015a +module load netCDF-Fortran/4.2-foss-2015a + +source ${PATH_TO_VIRTUALENV}/activate -source /home/Earth/jvegas/virtualenvs/diags/bin/activate -export PYTHONPATH=/home/Earth/jvegas/pyCharm/ocean_diagnostics/:$PYTHONPATH -cd /home/Earth/jvegas/pyCharm/ocean_diagnostics/earthdiagnostics/ +export PYTHONPATH=${PATH_TO_DIAGNOSTICS}:${PYTHONPATH} +cd ${PATH_TO_DIAGNOSTICS}/earthdiagnostics/ ./diags.py -lc DEBUG -- GitLab From 787c1b2512d22c205e5ccd121ae652a3760d8590 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 20 Jul 2016 12:08:48 +0200 Subject: [PATCH 150/268] Added module purge to solve problems in moore --- launch_diags.sh | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 launch_diags.sh diff --git a/launch_diags.sh b/launch_diags.sh old mode 100644 new mode 100755 index 6a2aefe..26380b9 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -10,6 +10,7 @@ set -xv PATH_TO_DIAGNOSTICS=~/pyCharm/ocean_diagnostics PATH_TO_VIRTUALENV=/home/Earth/jvegas/virtualenvs/diags/bin +module purge module load NCO/4.5.4-foss-2015a module load CDO/1.6.9-foss-2015a module load netCDF-Fortran/4.2-foss-2015a -- GitLab From 7563e09806274f374bc1d4b4947ab40145e589d2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 21 Jul 2016 15:28:54 +0200 Subject: [PATCH 151/268] Updated doc. Bumping version to 3.0.0b4 --- EarthDiagnostics.pdf | Bin 199865 -> 199946 bytes VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/datamanager.py | 4 ++-- earthdiagnostics/ocean/heatcontentlayer.py | 5 +++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index 142af2bf403d7fcc4df3a991724142fc16367b49..076bd2cce44664cafd9e8595c1be14ae073d59e7 100644 GIT binary patch delta 33549 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

Y3|(N+iN+2$30K9;^jiyK90uj-GLoW#G=AD%uh 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 JV)EiJ{|h%pMN0qx delta 95900 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 Ic`>;E0&wHl{{R30 diff --git a/doc/source/errors.rst b/doc/source/errors.rst index 2e3681f..c47c9e4 100644 --- a/doc/source/errors.rst +++ b/doc/source/errors.rst @@ -7,8 +7,9 @@ good issue reports. Remember: a good issue report reduces the time required to s .. hint:: - Reading is good. Most times the error message will point you to the problem's source and sometimes even give you - a hint of how to solve it by yourself. + Please, read carefully yhe error messsage. Most times the error message will point you to the problem's source and + sometimes even give you a hint of how to solve it by yourself. And if this it not the case or you find it obscure, + even if it was helpful, please contact the developers so it can be improved in further versions Try this simple steps BEFORE reporting an issue diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 110f140..b7cfdb2 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -255,7 +255,8 @@ class DataManager(object): 'GG', '6hr') chunk_start = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') - def _ungrib_6_hourly_vars(self, cdo_reftime, gribfile, month): + @staticmethod + def _ungrib_6_hourly_vars(cdo_reftime, gribfile, month): Log.info('Preparing 6-hourly variables') var_codes = (129, 130, 131, 132, 151, 167, 168, 164, 165, 166, 129) for param in var_codes: @@ -297,7 +298,8 @@ class DataManager(object): h_file = '{0}_6hr.nc'.format(gribfile) Utils.concat_variables(h_var_file, h_file, True) - def _ungrib_daily_vars(self, cdo_reftime, gribfile, month, nfrp): + @staticmethod + def _ungrib_daily_vars(cdo_reftime, gribfile, month, nfrp): Log.info('Preparing daily variables') var_codes = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) for param in var_codes: @@ -344,7 +346,8 @@ class DataManager(object): daily_file = '{0}_day.nc'.format(gribfile) Utils.concat_variables(daily_variable_file, daily_file, True) - def _ungrib_monthly_files(self, cdo_reftime, gribfile, month, nfrp): + @staticmethod + def _ungrib_monthly_files(cdo_reftime, gribfile, month, nfrp): Log.info('Preparing monthly variables') var_codes = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, @@ -759,6 +762,13 @@ class DataManager(object): return temp_path def get_startdate_path(self, startdate): + """ + Returns the path to the startdate's CMOR folder + :param startdate: target startdate + :type startdate: str + :return: path to the startdate's CMOR folder + :rtype: str + """ return os.path.join(self.data_dir, self.expid, 'cmorfiles', self.institution, self.model, self.experiment_name, 'S' + startdate) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index c10b1a5..8f3c21d 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -219,6 +219,9 @@ class Utils(object): """ Checks if a file is in netCDF4 format and converts to netCDF4 if not + :param force: if true, converts the file regardless of original encoding. Useful to make sure that a file has + deflation and shuffle activated + :type force: bool :param filetoconvert: file to convert :type filetoconvert: str """ @@ -274,6 +277,9 @@ class Utils(object): """ Copies the given variable from source to destiny + :param add_dimensions: if it's true, dimensions required by the variable will be automatically added to the + file. It will also add the dimension variable + :type add_dimensions: bool :param source: origin file :type source: netCDF4.Dataset :param destiny: destiny file @@ -308,6 +314,15 @@ class Utils(object): @staticmethod def concat_variables(source, destiny, remove_source=False): + """ + Add variables from a nc file to another + :param source: path to source file + :type source: str + :param destiny: path to destiny file + :type destiny: str + :param remove_source: if True, removes source file + :type remove_source: bool + """ if os.path.exists(destiny): handler_total = Utils.openCdf(destiny) handler_variable = Utils.openCdf(source) @@ -324,9 +339,17 @@ class Utils(object): shutil.copy(source, destiny) Utils.convert2netcdf4(destiny, True) - def expand_path(self, path): + @staticmethod + def expand_path(path): + """ + Expands character ~ and system variables on the given path + :param path: path to expand + :type path: str + :return: path after the expansion + """ return os.path.expandvars(os.path.expanduser(path)) + class TempFile(object): """ Class to manage temporal files -- GitLab From da8260dc1a94371c83aef16fca60c9f6f3876547 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 22 Aug 2016 12:55:06 +0200 Subject: [PATCH 158/268] Improved logging --- earthdiagnostics/datamanager.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index b7cfdb2..6ba66cf 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -420,9 +420,13 @@ class DataManager(object): merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) for x in range(0, len(chunk_files)): chunk_files[x] = os.path.join(self.scratch_dir, chunk_files[x]) - Utils.cdo.mergetime(input=' '.join(chunk_files), output=merged_file, options='-O') - for filepath in chunk_files: - os.remove(filepath) + if len(chunk_files) > 1: + Log.info('Merging...') + Utils.cdo.mergetime(input=' '.join(chunk_files), output=merged_file, options='-O') + for filepath in chunk_files: + os.remove(filepath) + else: + shutil.move(chunk_files[0], merged_file) self._cmorize_nc_file(merged_file, member, startdate) def _unpack_cmorfiles(self, filepaths, member_path): -- GitLab From 11b0d83b4dd07d20e988a4b0835f36b4fa36003f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 22 Aug 2016 12:55:32 +0200 Subject: [PATCH 159/268] Bumped version to 3.0b5 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 9414e12..09fb39d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b4 +3.0.0b5 -- GitLab From 23a0c1ab26a3c19739ba3c4fcedc34b31888eb29 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 22 Aug 2016 14:47:54 +0200 Subject: [PATCH 160/268] Corrected bug on pressure levels (given in hPa while model output is in Pa) --- earthdiagnostics/datamanager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6ba66cf..4c2157f 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -268,15 +268,15 @@ class DataManager(object): new_units = "m" cdo_operator = "-divc,9.81 -sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, - range(300, 900, 50)))) + range(30000, 90000, 5000)))) elif param == 129: # upper air temperature new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, range(300, 500, 50)))) + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, range(30000, 50000, 5000)))) elif param in (131, 132): # upper air wind new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, (500, 700, 850)))) + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, (50000, 70000, 85000)))) else: # default, plain monthly mean cdo_operator = "-selmon,{0}".format(month) -- GitLab From deaa859a10b8934ed7a29af84ad73be2c1487a0c Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 23 Aug 2016 10:48:32 +0200 Subject: [PATCH 161/268] Changed extracted levels for 6-hourly data. Now all variables will have the same levels to avoid concatenation errors --- earthdiagnostics/datamanager.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 4c2157f..a967a31 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -11,6 +11,7 @@ from datetime import datetime import netCDF4 import numpy as np import os +import stat from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day, add_months, \ date2str @@ -187,20 +188,21 @@ class DataManager(object): add_months(start, -1, 'standard'), gribfile)) os.remove('rules_files') - + full_file = 'ICM' else: - shutil.copy(gribfile, 'ICM') + full_file = gribfile # remap on regular Gauss grid if grid == 'SH': - Utils.cdo.splitparam(input='-sp2gpl ICM', output=gribfile + '_') + Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_') else: - Utils.cdo.splitparam(input='ICM', output=gribfile + '_', options='-R') + Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R') # total precipitation (remove negative values) Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' '{0}_{{142,143}}.128.grb'.format(gribfile), output='{0}_228.128.grb'.format(gribfile)) - os.remove('ICM') + if full_file == 'ICM': + os.remove('ICM') cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') @@ -208,7 +210,7 @@ class DataManager(object): self._ungrib_daily_vars(cdo_reftime, gribfile, month, nfrp) self._ungrib_monthly_files(cdo_reftime, gribfile, month, nfrp) - for splited_file in glob.glob('{0}_???.128.grb'.format(gribfile)): + for splited_file in glob.glob('{0}_*.128.grb'.format(gribfile)): os.remove(splited_file) Log.result('Atmospheric grib file {0}/{1} finished'.format(count, len(copied_gribfiles))) @@ -259,6 +261,7 @@ class DataManager(object): def _ungrib_6_hourly_vars(cdo_reftime, gribfile, month): Log.info('Preparing 6-hourly variables') var_codes = (129, 130, 131, 132, 151, 167, 168, 164, 165, 166, 129) + levels = ','.join(map(str, range(30000, 90000, 5000))) for param in var_codes: if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): continue @@ -266,17 +269,15 @@ class DataManager(object): if param == 129: # geopotential new_units = "m" - cdo_operator = "-divc,9.81 -sellevel,{1} -selmon,{0}".format(month, - ','.join(map(str, - range(30000, 90000, 5000)))) + cdo_operator = "-divc,9.81 -sellevel,{1} -selmon,{0}".format(month, levels) elif param == 129: # upper air temperature new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, range(30000, 50000, 5000)))) + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, levels) elif param in (131, 132): # upper air wind new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, (50000, 70000, 85000)))) + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, levels) else: # default, plain monthly mean cdo_operator = "-selmon,{0}".format(month) @@ -965,6 +966,8 @@ class DataManager(object): Utils.rename_variables(filetosend, variables, False, True) Utils.move_file(filetosend, filepath) + st = os.stat(filepath) + os.chmod(filepath, st.st_mode | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) self._create_link(domain, filepath, frequency, var) def _create_link(self, domain, filepath, frequency, var): -- GitLab From 9ad7102c2c55728a3a507d27d695c748cf70647a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 23 Aug 2016 12:31:20 +0200 Subject: [PATCH 162/268] Refactored grib cmorizartion to reduce scratch usage --- earthdiagnostics/datamanager.py | 191 +++++++++++++++----------------- 1 file changed, 90 insertions(+), 101 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index a967a31..a3cdacb 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -117,7 +117,7 @@ class DataManager(object): Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) count += 1 else: - self._cmorize_grib(startdate, member, gribfiles) + self._cmorize_grib(startdate, member) Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str) if created: @@ -150,113 +150,102 @@ class DataManager(object): count += 1 return errors - def _cmorize_grib(self, startdate, member, gribfiles): - gribfiles.sort() - copied_gribfiles = list() - for gribfile in gribfiles: - shutil.copy(gribfile, os.path.join(self.scratch_dir, os.path.basename(gribfile))) - copied_gribfiles.append(os.path.join(self.scratch_dir, os.path.basename(gribfile))) - + def _cmorize_grib(self, startdate, member): count = 1 - for gribfile in copied_gribfiles: - Log.info('Unpacking atmospheric grib file {0}/{1}'.format(count, len(copied_gribfiles))) - start = parse_date(gribfile[-10:-4]) - month = '{0:02}'.format(start.month) - grib_handler = pygrib.open(gribfile) - mes1 = grib_handler.message(1) - mes2 = grib_handler.readline() - while mes2['name'] != mes1['name']: - mes2 = grib_handler.readline() - nfrp = mes2.analDate - mes1.analDate - nfrp = int(nfrp.total_seconds() / 3600) - grib_handler.close() - - grid = os.path.basename(gribfile)[3:5] - - if os.path.exists('ICM{0}{1}+{2.year}{2.month:02}.grb'.format(grid, self.expid, - add_months(start, -1, - 'standard'))): - fd = open('rules_files', 'w') - fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(start)) - fd.close() - # get first timestep for each month from previous file (if possible) - if os.path.exists('ICM'): - os.remove('ICM') - Utils.execute_shell_command('grib_filter -o ICM rules_files ' - 'ICM{0}{1}+{2.year}{2.month:02}.grb ' - '{3}'.format(grid, self.expid, - add_months(start, -1, 'standard'), - gribfile)) - os.remove('rules_files') - full_file = 'ICM' - else: - full_file = gribfile - - # remap on regular Gauss grid - if grid == 'SH': - Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_') - else: - Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R') - # total precipitation (remove negative values) - Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' - '{0}_{{142,143}}.128.grb'.format(gribfile), - output='{0}_228.128.grb'.format(gribfile)) - if full_file == 'ICM': - os.remove('ICM') - - cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') - - self._ungrib_6_hourly_vars(cdo_reftime, gribfile, month) - self._ungrib_daily_vars(cdo_reftime, gribfile, month, nfrp) - self._ungrib_monthly_files(cdo_reftime, gribfile, month, nfrp) - - for splited_file in glob.glob('{0}_*.128.grb'.format(gribfile)): - os.remove(splited_file) + chunk_start = parse_date(startdate) + member_str = self.exp_manager.get_member_str(member) + data_folder = os.path.join(self.data_dir, self.expid, 'original_files', startdate, member_str, 'outputs') - Log.result('Atmospheric grib file {0}/{1} finished'.format(count, len(copied_gribfiles))) - count += 1 + while os.path.exists(os.path.join(data_folder, 'ICMGG{0}+{1}.grb'.format(self.expid, + date2str(chunk_start)[:-2]))): - chunk_start = parse_date(startdate) - while os.path.exists(os.path.join(self.scratch_dir, - 'ICMGG{0}+{1}.grb'.format(self.expid, - date2str(chunk_start)[:-2]))): chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') - chunk_files_gg_mon = list() - chunk_files_gg_day = list() - chunk_files_gg_6h = list() - - chunk_files_sh_mon = list() - chunk_files_sh_day = list() - chunk_files_sh_6h = list() - - for month in range(0, self.exp_manager.chunk_size): - chunk_file = 'ICMGG{0}+{1}.grb'.format(self.expid, - date2str(add_months(chunk_start, month, - 'standard'))[:-2]) - os.remove(chunk_file) - os.remove('ICMSH' + chunk_file[5:]) - chunk_files_gg_mon.append(chunk_file + '_mon.nc') - chunk_files_gg_day.append(chunk_file + '_day.nc') - chunk_files_gg_6h.append(chunk_file + '_6hr.nc') - chunk_files_sh_mon.append('ICMSH' + chunk_file[5:] + '_mon.nc') - chunk_files_sh_day.append('ICMSH' + chunk_file[5:] + '_day.nc') - chunk_files_sh_6h.append('ICMSH' + chunk_file[5:] + '_6hr.nc') - - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_mon, - 'SH', '1m') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_day, - 'SH', '1d') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_sh_6h, - 'SH', '6hr') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_mon, - 'GG', '1m') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_day, - 'GG', '1d') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_gg_6h, - 'GG', '6hr') + + for grid in ('SH', 'GG'): + chunk_files_mon = list() + chunk_files_day = list() + chunk_files_6h = list() + + for month in range(0, self.exp_manager.chunk_size): + current_month = add_months(chunk_start, month, 'standard') + original_gribfile = os.path.join(data_folder, 'ICM{0}{1}+{2}.grb'.format(grid, self.expid, + date2str(current_month)[:-2])) + Log.info('Processing {0} file for {1}', grid, date2str(current_month)) + gribfile = os.path.join(self.scratch_dir, os.path.basename(original_gribfile)) + if not os.path.isfile(gribfile): + Log.info('Copying {0} file for {1}', grid, date2str(current_month)) + shutil.copy(original_gribfile, gribfile) + + Log.info('Unpacking atmospheric grib file {0}/{1}', count, len(gribfiles)) + grib_handler = pygrib.open(gribfile) + mes1 = grib_handler.message(1) + mes2 = grib_handler.readline() + while mes2['name'] != mes1['name']: + mes2 = grib_handler.readline() + nfrp = mes2.analDate - mes1.analDate + nfrp = int(nfrp.total_seconds() / 3600) + grib_handler.close() + + previous_gribfile = os.path.join(self.scratch_dir, 'ICM{0}{1}+{2}.grb'.format(grid, self.expid, + date2str(add_months( + current_month, -1, + 'standard'))[:-2])) + if os.path.exists(previous_gribfile): + fd = open('rules_files', 'w') + fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(current_month)) + fd.close() + # get first timestep for each month from previous file (if possible) + if os.path.exists('ICM'): + os.remove('ICM') + Utils.execute_shell_command('grib_filter -o ICM rules_files ' + 'ICM{0}{1}+{2.year}{2.month:02}.grb ' + '{3}'.format(grid, self.expid, + add_months(current_month, -1, 'standard'), + gribfile)) + os.remove('rules_files') + os.remove(previous_gribfile) + full_file = 'ICM' + else: + full_file = gribfile + + # remap on regular Gauss grid + if grid == 'SH': + Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_') + else: + Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R') + # total precipitation (remove negative values) + Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' + '{0}_{{142,143}}.128.grb'.format(gribfile), + output='{0}_228.128.grb'.format(gribfile)) + if full_file == 'ICM': + os.remove('ICM') + + cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') + + self._ungrib_6_hourly_vars(cdo_reftime, gribfile, month) + self._ungrib_daily_vars(cdo_reftime, gribfile, month, nfrp) + self._ungrib_monthly_files(cdo_reftime, gribfile, month, nfrp) + + for splited_file in glob.glob('{0}_*.128.grb'.format(gribfile)): + os.remove(splited_file) + + Log.result('Atmospheric grib file {0} finished', gribfile) + count += 1 + + chunk_files_mon.append(gribfile + '_mon.nc') + chunk_files_day.append(gribfile + '_day.nc') + chunk_files_6h.append(gribfile + '_6hr.nc') + + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_mon, + grid, '1m') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_day, + grid, '1d') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_6h, + grid, '6hr') chunk_start = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') + @staticmethod def _ungrib_6_hourly_vars(cdo_reftime, gribfile, month): Log.info('Preparing 6-hourly variables') -- GitLab From db85cca208076ddaf45b99146d9596ed405018d3 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 23 Aug 2016 13:00:00 +0200 Subject: [PATCH 163/268] More refactoring in grib cmorizartion --- earthdiagnostics/datamanager.py | 40 ++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index a3cdacb..2eb8a62 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -150,34 +150,36 @@ class DataManager(object): count += 1 return errors + def _get_grib_filename(self, grid, month): + return 'ICM{0}{1}+{2}.grb'.format(grid, self.expid, date2str(month)[:-2]) + def _cmorize_grib(self, startdate, member): count = 1 chunk_start = parse_date(startdate) member_str = self.exp_manager.get_member_str(member) data_folder = os.path.join(self.data_dir, self.expid, 'original_files', startdate, member_str, 'outputs') - while os.path.exists(os.path.join(data_folder, 'ICMGG{0}+{1}.grb'.format(self.expid, - date2str(chunk_start)[:-2]))): + while os.path.exists(os.path.join(data_folder, self._get_grib_filename('GG', chunk_start))): chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') - + Log.info('CMORizing chunk {0}-{1}', date2str(chunk_start), date2str(chunk_end)) for grid in ('SH', 'GG'): + Log.info('Processing {0} variables', grid) chunk_files_mon = list() chunk_files_day = list() chunk_files_6h = list() for month in range(0, self.exp_manager.chunk_size): current_month = add_months(chunk_start, month, 'standard') - original_gribfile = os.path.join(data_folder, 'ICM{0}{1}+{2}.grb'.format(grid, self.expid, - date2str(current_month)[:-2])) - Log.info('Processing {0} file for {1}', grid, date2str(current_month)) + original_gribfile = os.path.join(data_folder, self._get_grib_filename(grid, current_month)) + Log.info('Processing month {1}', grid, date2str(current_month)) gribfile = os.path.join(self.scratch_dir, os.path.basename(original_gribfile)) if not os.path.isfile(gribfile): - Log.info('Copying {0} file for {1}', grid, date2str(current_month)) + Log.info('Copying file...', grid, date2str(current_month)) shutil.copy(original_gribfile, gribfile) - Log.info('Unpacking atmospheric grib file {0}/{1}', count, len(gribfiles)) + Log.info('Unpacking... ') grib_handler = pygrib.open(gribfile) mes1 = grib_handler.message(1) mes2 = grib_handler.readline() @@ -187,11 +189,10 @@ class DataManager(object): nfrp = int(nfrp.total_seconds() / 3600) grib_handler.close() - previous_gribfile = os.path.join(self.scratch_dir, 'ICM{0}{1}+{2}.grb'.format(grid, self.expid, - date2str(add_months( - current_month, -1, - 'standard'))[:-2])) - if os.path.exists(previous_gribfile): + prev_gribfile = os.path.join(self.scratch_dir, + self._get_grib_filename(grid, + add_months(current_month, -1, 'standard'))) + if os.path.exists(prev_gribfile): fd = open('rules_files', 'w') fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(current_month)) fd.close() @@ -199,12 +200,9 @@ class DataManager(object): if os.path.exists('ICM'): os.remove('ICM') Utils.execute_shell_command('grib_filter -o ICM rules_files ' - 'ICM{0}{1}+{2.year}{2.month:02}.grb ' - '{3}'.format(grid, self.expid, - add_months(current_month, -1, 'standard'), - gribfile)) + '{0} {1}'.format(grid, os.path.basename(prev_gribfile), gribfile)) os.remove('rules_files') - os.remove(previous_gribfile) + os.remove(prev_gribfile) full_file = 'ICM' else: full_file = gribfile @@ -220,6 +218,12 @@ class DataManager(object): output='{0}_228.128.grb'.format(gribfile)) if full_file == 'ICM': os.remove('ICM') + next_gribfile = os.path.join(self.scratch_dir, + self._get_grib_filename(grid, + add_months(current_month, 1, 'standard'))) + + if not os.path.exists(next_gribfile): + os.remove(gribfile) cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') -- GitLab From 3e89a0c4d37475b2355e3d179cd617fa1820688d Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 23 Aug 2016 16:23:14 +0200 Subject: [PATCH 164/268] Small fix and now we are only checking once the nfrp value --- earthdiagnostics/datamanager.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 2eb8a62..42157c1 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -155,6 +155,7 @@ class DataManager(object): def _cmorize_grib(self, startdate, member): count = 1 + nfrp = None chunk_start = parse_date(startdate) member_str = self.exp_manager.get_member_str(member) data_folder = os.path.join(self.data_dir, self.expid, 'original_files', startdate, member_str, 'outputs') @@ -179,20 +180,22 @@ class DataManager(object): Log.info('Copying file...', grid, date2str(current_month)) shutil.copy(original_gribfile, gribfile) - Log.info('Unpacking... ') - grib_handler = pygrib.open(gribfile) - mes1 = grib_handler.message(1) - mes2 = grib_handler.readline() - while mes2['name'] != mes1['name']: + if nfrp is None: + Log.info('Getting timestep...') + grib_handler = pygrib.open(gribfile) + mes1 = grib_handler.message(1) mes2 = grib_handler.readline() - nfrp = mes2.analDate - mes1.analDate - nfrp = int(nfrp.total_seconds() / 3600) - grib_handler.close() + while mes2['name'] != mes1['name']: + mes2 = grib_handler.readline() + nfrp = mes2.analDate - mes1.analDate + nfrp = int(nfrp.total_seconds() / 3600) + grib_handler.close() prev_gribfile = os.path.join(self.scratch_dir, self._get_grib_filename(grid, add_months(current_month, -1, 'standard'))) if os.path.exists(prev_gribfile): + Log.info('Merging data from different files...') fd = open('rules_files', 'w') fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(current_month)) fd.close() @@ -207,6 +210,7 @@ class DataManager(object): else: full_file = gribfile + Log.info('Unpacking... ') # remap on regular Gauss grid if grid == 'SH': Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_') @@ -227,14 +231,14 @@ class DataManager(object): cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') - self._ungrib_6_hourly_vars(cdo_reftime, gribfile, month) - self._ungrib_daily_vars(cdo_reftime, gribfile, month, nfrp) - self._ungrib_monthly_files(cdo_reftime, gribfile, month, nfrp) + self._ungrib_6_hourly_vars(cdo_reftime, gribfile, current_month.month) + self._ungrib_daily_vars(cdo_reftime, gribfile, current_month.month, nfrp) + self._ungrib_monthly_files(cdo_reftime, gribfile, current_month.month, nfrp) for splited_file in glob.glob('{0}_*.128.grb'.format(gribfile)): os.remove(splited_file) - Log.result('Atmospheric grib file {0} finished', gribfile) + Log.result('Month {0} finished', date2str(current_month)) count += 1 chunk_files_mon.append(gribfile + '_mon.nc') -- GitLab From 2b90421af302dab5d10d0772f2edfc515d0abc07 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 24 Aug 2016 10:47:14 +0200 Subject: [PATCH 165/268] Refactored data_manager to avoid a problem arising when variables have different number of levels. Added test.py to run unit tests with coveraga report --- .gitignore | 4 +- earthdiagnostics/datamanager.py | 55 +++++++++------------- earthdiagnostics/diags.py | 2 +- earthdiagnostics/ocean/convectionsites.py | 3 +- earthdiagnostics/ocean/gyres.py | 2 +- earthdiagnostics/ocean/heatcontentlayer.py | 2 +- earthdiagnostics/ocean/interpolate.py | 2 +- earthdiagnostics/ocean/maxmoc.py | 2 +- test/unit/test.py | 25 ++++++++++ test/unit/test_experiment_manager.py | 2 +- 10 files changed, 57 insertions(+), 42 deletions(-) create mode 100644 test/unit/test.py diff --git a/.gitignore b/.gitignore index 4abe78e..c583596 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ .idea/* doc/build/* *.err -*.out \ No newline at end of file +*.out +.coverage +htmlcov \ No newline at end of file diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 42157c1..1c343ae 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -46,7 +46,7 @@ class DataManager(object): :type calendar: str """ def __init__(self, exp_manager, institution, model, expid, datafolder, frequency, experiment_name, - scratch_dir, nfrp, calendar='standard'): + scratch_dir, nfrp, calendar='standard'): self.initialization_method = 1 self.initialization_description = 'to be filled' self.physics_version = 1 @@ -165,7 +165,7 @@ class DataManager(object): chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') Log.info('CMORizing chunk {0}-{1}', date2str(chunk_start), date2str(chunk_end)) - for grid in ('SH', 'GG'): + for grid in ('GG', 'SH'): Log.info('Processing {0} variables', grid) chunk_files_mon = list() chunk_files_day = list() @@ -177,7 +177,7 @@ class DataManager(object): Log.info('Processing month {1}', grid, date2str(current_month)) gribfile = os.path.join(self.scratch_dir, os.path.basename(original_gribfile)) if not os.path.isfile(gribfile): - Log.info('Copying file...', grid, date2str(current_month)) + Log.info('Copying file...', grid, date2str(current_month)) shutil.copy(original_gribfile, gribfile) if nfrp is None: @@ -245,15 +245,11 @@ class DataManager(object): chunk_files_day.append(gribfile + '_day.nc') chunk_files_6h.append(gribfile + '_6hr.nc') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_mon, - grid, '1m') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_day, - grid, '1d') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, chunk_files_6h, - grid, '6hr') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1m') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1d') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '6hr') chunk_start = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') - @staticmethod def _ungrib_6_hourly_vars(cdo_reftime, gribfile, month): Log.info('Preparing 6-hourly variables') @@ -291,10 +287,6 @@ class DataManager(object): var.units = new_units break handler.close() - # concat all vars in one file for 6hr - - h_file = '{0}_6hr.nc'.format(gribfile) - Utils.concat_variables(h_var_file, h_file, True) @staticmethod def _ungrib_daily_vars(cdo_reftime, gribfile, month, nfrp): @@ -340,9 +332,6 @@ class DataManager(object): var.units = new_units break handler.close() - # concat all vars in one file for day - daily_file = '{0}_day.nc'.format(gribfile) - Utils.concat_variables(daily_variable_file, daily_file, True) @staticmethod def _ungrib_monthly_files(cdo_reftime, gribfile, month, nfrp): @@ -411,21 +400,19 @@ class DataManager(object): output='{0}_{1}_mon.nc'.format(gribfile, param), options='-O -v {0}'.format(var_name)) - # concat all vars in one file for mon - Utils.concat_variables('{0}_{1}_mon.nc'.format(gribfile, param), '{0}_mon.nc'.format(gribfile), True) - - def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, chunk_files, grid, frequency): + def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, grid, frequency): merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) - for x in range(0, len(chunk_files)): - chunk_files[x] = os.path.join(self.scratch_dir, chunk_files[x]) - if len(chunk_files) > 1: - Log.info('Merging...') - Utils.cdo.mergetime(input=' '.join(chunk_files), output=merged_file, options='-O') - for filepath in chunk_files: - os.remove(filepath) - else: - shutil.move(chunk_files[0], merged_file) - self._cmorize_nc_file(merged_file, member, startdate) + files = glob.glob(os.path.join(self.scratch_dir, + '{0}_*_{1}.nc'.format(self._get_grib_filename(grid, chunk_start), frequency))) + for first_file in files: + shutil.move(first_file, merged_file) + current_month = add_months(chunk_start, 1, 'standard') + while current_month < chunk_end: + month_file = first_file.replace('_{0}_'.format(parse_date(chunk_start)[:-2]), + '_{0}_'.format(parse_date(current_month)[:-2])) + Utils.concat_variables(month_file, merged_file, True) + + self._cmorize_nc_file(merged_file, member, startdate) def _unpack_cmorfiles(self, filepaths, member_path): threads = list() @@ -543,7 +530,7 @@ class DataManager(object): 'depth', 'depth_2', 'depth_3', 'depth_4', 'mlev', 'hyai', 'hybi', 'hyam', 'hybm'): continue - self.extract_variable(filename, handler, frequency, member, startdate, temp, variable) + self.extract_variable(filename, handler, frequency, member, startdate, temp, variable) Log.result('File {0} cmorized!', filename) handler.close() os.remove(filename) @@ -1077,7 +1064,7 @@ class DataManager(object): for domain in os.listdir(freq_path): domain_path = os.path.join(freq_path, domain) for var in os.listdir(domain_path): - member_path = os.path.join(domain_path, var, 'r{0}i1p1'.format(member+1)) + member_path = os.path.join(domain_path, var, 'r{0}i1p1'.format(member + 1)) if os.path.exists(member_path): return True return False @@ -1226,7 +1213,7 @@ class UnitConversion(object): return conversion.factor, conversion.offset elif (new_unit, unit) in cls._dict_conversions: conversion = cls._dict_conversions[(unit, new_unit)] - return 1/conversion.factor, -conversion.offset + return 1 / conversion.factor, -conversion.offset else: return None, None diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 98f2836..e08d41a 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -281,7 +281,7 @@ class Diags(object): os.chdir(self.scratch_dir) self.data_manager = DataManager(self.exp_manager, self.institute, self.model, self.expid, self.data_dir, - self.frequency, self.experiment_name, self.scratch_dir, self.nfrp) + self.frequency, self.experiment_name, self.scratch_dir, self.nfrp) self.data_manager.add_startdate = self.add_startdate self.data_manager.add_name = self.add_name diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 10b674c..5638755 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -113,4 +113,5 @@ class ConvectionSites(Diagnostic): self.startdate, self.member, self.chunk) def _convection_site(self, site): - return np.max(self.mlotst_handler.variables['mlotst'][:, site[2]-1:site[3]-1, site[0]-1:site[1]-1], (1, 2)) + return np.max(self.mlotst_handler.variables['mlotst'][:, site[2] - 1:site[3] - 1, site[0] - 1:site[1] - 1], + (1, 2)) diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 3187999..603e654 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -153,7 +153,7 @@ class Gyres(Diagnostic): if site[0] <= site[1]: return self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0] - 1:site[1] - 1] else: - return np.concatenate((self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0]-1:], + return np.concatenate((self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0] - 1:], self.var_vsftbarot[:, site[2] - 1:site[3] - 1, :site[1] - 1]), axis=2) else: diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 27b3088..459ca56 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -103,7 +103,7 @@ class HeatContentLayer(Diagnostic): """ level = 0 - while array[level+1] <= box.min_depth: + while array[level + 1] <= box.min_depth: array[level] = 0 level += 1 if level == array.size - 1: diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 42f9212..bd626a5 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -110,7 +110,7 @@ class Interpolate(Diagnostic): Interpolate.lock.release() else: - Utils.move_file(self._get_level_file(0), temp) + Utils.move_file(self._get_level_file(0), temp) handler = Utils.openCdf(temp) handler.renameDimension('record', 'lev') diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 57f051a..468080e 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -111,7 +111,7 @@ class MaxMoc(Diagnostic): lat = handler.variables['lat'][:] if self.box.min_lat == self.box.max_lat: - lat_inds = ((np.abs(lat-self.box.min_lat)).argmin(),) + lat_inds = ((np.abs(lat - self.box.min_lat)).argmin(),) else: lat_inds = np.where((lat > self.box.min_lat) & (lat < self.box.max_lat))[0] diff --git a/test/unit/test.py b/test/unit/test.py new file mode 100644 index 0000000..463a992 --- /dev/null +++ b/test/unit/test.py @@ -0,0 +1,25 @@ +# coding=utf-8 +import coverage +import unittest +cov = coverage.Coverage() +cov.set_option("run:branch", True) +cov.start() + +from test_box import TestBox +from test_constants import TestBasin, TestBasins +from test_data_manager import TestDataManager +from test_experiment_manager import TestExperimentManager + +suite = unittest.TestLoader().loadTestsFromTestCase(TestBox) +suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestBasin)) +suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestBasins)) +suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestDataManager)) +suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestExperimentManager)) +unittest.TextTestRunner(verbosity=2).run(suite) +cov.stop() +cov.save() + +cov.report(('earthdiagnostics/utils.py', 'earthdiagnostics/diags.py', 'earthdiagnostics/constants.py')) +cov.html_report() + + diff --git a/test/unit/test_experiment_manager.py b/test/unit/test_experiment_manager.py index 38e2272..0c1f4e1 100644 --- a/test/unit/test_experiment_manager.py +++ b/test/unit/test_experiment_manager.py @@ -4,7 +4,7 @@ from unittest import TestCase from earthdiagnostics.experimentmanager import ExperimentManager -class TestDataManager(TestCase): +class TestExperimentManager(TestCase): def setUp(self): self.experiment_manager = ExperimentManager(['20000101', '20000201'], [0, 1], 5, 3, 3) -- GitLab From 593e50962a3e95d2b18bd5ff8dd172d2d473a1a8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 24 Aug 2016 11:29:51 +0200 Subject: [PATCH 166/268] Improved tes.py. Improved test_boc and test_constantas to achieve 100% coverage --- earthdiagnostics/constants.py | 2 +- test.py | 26 ++++++++++++++++++++++++++ test/__init__.py | 0 test/unit/__init__.py | 4 ++++ test/unit/test.py | 25 ------------------------- test/unit/test_box.py | 12 ++++++++++++ test/unit/test_constants.py | 12 +++++++----- 7 files changed, 50 insertions(+), 31 deletions(-) create mode 100644 test.py create mode 100644 test/__init__.py create mode 100644 test/unit/__init__.py delete mode 100644 test/unit/test.py diff --git a/earthdiagnostics/constants.py b/earthdiagnostics/constants.py index 8fe7403..c37af21 100644 --- a/earthdiagnostics/constants.py +++ b/earthdiagnostics/constants.py @@ -20,7 +20,7 @@ class Basin(object): def __init__(self, shortname, fullname, box=None): self._shortname = shortname self._fullname = fullname - if not box: + if box is None: box = Box() self.box = box diff --git a/test.py b/test.py new file mode 100644 index 0000000..bed5d23 --- /dev/null +++ b/test.py @@ -0,0 +1,26 @@ +# coding=utf-8 +import coverage +import unittest +import os +cov = coverage.Coverage() +cov.set_option("run:branch", True) +cov.start() + +import test.unit + +suite = unittest.TestLoader().loadTestsFromModule(test.unit) +unittest.TextTestRunner(verbosity=2).run(suite) +cov.stop() +cov.save() + +source_files = list() +for path, dirs, files in os.walk('earthdiagnostics'): + for filename in files: + if filename.endswith('.py'): + source_files.append(os.path.join(path, filename)) + +cov.report(source_files) +cov.html_report(source_files) + + + diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/unit/__init__.py b/test/unit/__init__.py new file mode 100644 index 0000000..3939a2f --- /dev/null +++ b/test/unit/__init__.py @@ -0,0 +1,4 @@ +from test_data_manager import * +from test_constants import * +from test_experiment_manager import * +from test_box import * \ No newline at end of file diff --git a/test/unit/test.py b/test/unit/test.py deleted file mode 100644 index 463a992..0000000 --- a/test/unit/test.py +++ /dev/null @@ -1,25 +0,0 @@ -# coding=utf-8 -import coverage -import unittest -cov = coverage.Coverage() -cov.set_option("run:branch", True) -cov.start() - -from test_box import TestBox -from test_constants import TestBasin, TestBasins -from test_data_manager import TestDataManager -from test_experiment_manager import TestExperimentManager - -suite = unittest.TestLoader().loadTestsFromTestCase(TestBox) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestBasin)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestBasins)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestDataManager)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestExperimentManager)) -unittest.TextTestRunner(verbosity=2).run(suite) -cov.stop() -cov.save() - -cov.report(('earthdiagnostics/utils.py', 'earthdiagnostics/diags.py', 'earthdiagnostics/constants.py')) -cov.html_report() - - diff --git a/test/unit/test_box.py b/test/unit/test_box.py index 6cd950a..37b5ce4 100644 --- a/test/unit/test_box.py +++ b/test/unit/test_box.py @@ -24,6 +24,14 @@ class TestBox(TestCase): self.box3 = Box() + self.box4 = Box() + self.box4.max_lat = -10 + self.box4.min_lat = -20 + self.box4.max_lon = -10 + self.box4.min_lon = -20 + self.box4.min_depth = 0 + self.box4.max_depth = 20 + def test_max_lat(self): with self.assertRaises(ValueError): Box().max_lat = 100 @@ -64,18 +72,22 @@ class TestBox(TestCase): self.assertEquals('20S0N', self.box1.get_lat_str()) self.assertEquals('20N', self.box2.get_lat_str()) self.assertEquals('', self.box3.get_lat_str()) + self.assertEquals('20S10S', self.box4.get_lat_str()) def test_get_lon_str(self): self.assertEquals('20W0E', self.box1.get_lon_str()) self.assertEquals('20E', self.box2.get_lon_str()) self.assertEquals('', self.box3.get_lon_str()) + self.assertEquals('20W10W', self.box4.get_lon_str()) def test_get_depth_str(self): self.assertEquals('0-20', self.box1.get_depth_str()) self.assertEquals('20m', self.box2.get_depth_str()) self.assertEquals('', self.box3.get_depth_str()) + self.assertEquals('0-20', self.box4.get_depth_str()) def test__str__(self): self.assertEquals('20S0N20W0E0-20', str(self.box1)) self.assertEquals('20N20E20m', str(self.box2)) self.assertEquals('', str(self.box3)) + self.assertEquals('20S10S20W10W0-20', str(self.box4)) diff --git a/test/unit/test_constants.py b/test/unit/test_constants.py index 43f57c7..f8010d5 100644 --- a/test/unit/test_constants.py +++ b/test/unit/test_constants.py @@ -1,11 +1,13 @@ # coding=utf-8 from unittest import TestCase from earthdiagnostics.constants import Basins, Basin +from earthdiagnostics.box import Box class TestBasins(TestCase): def test_parse(self): + self.assertEquals(Basins.Arctic, Basins.parse(Basins.Arctic)) self.assertEquals(Basins.Arctic, Basins.parse('Arct')) self.assertEquals(Basins.Arctic, Basins.parse('Arctic_Ocean')) self.assertIsNone(Basins.parse('Basin not found')) @@ -14,7 +16,7 @@ class TestBasins(TestCase): class TestBasin(TestCase): def setUp(self): - self.basin = Basin('bas', 'Basin') + self.basin = Basin('bas', 'Basin', Box()) def test_shortname(self): self.assertEquals('bas', self.basin.shortname) @@ -23,7 +25,7 @@ class TestBasin(TestCase): self.assertEquals('Basin', self.basin.fullname) def test__eq__(self): - self.assertEquals(Basin('bas', 'Basin'), self.basin) - self.assertNotEquals(Basin('bas', 'OtherBasin'), self.basin) - self.assertNotEquals(Basin('otbas', 'Basin'), self.basin) - self.assertNotEquals(Basin('otbas', 'OtherBasin'), self.basin) + self.assertTrue(Basin('bas', 'Basin') == self.basin) + self.assertFalse(Basin('bas', 'OtherBasin') == self.basin) + self.assertFalse(Basin('otbas', 'Basin') == self.basin) + self.assertFalse(Basin('otbas', 'OtherBasin') == self.basin) -- GitLab From 7711461ab24a45c6be7806c43a66b7236ddfe82b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 24 Aug 2016 12:51:02 +0200 Subject: [PATCH 167/268] Added tests for Diagnostic class --- earthdiagnostics/diagnostic.py | 18 ++++++++--------- test/unit/__init__.py | 9 +++++---- test/unit/test_diagnostic.py | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 test/unit/test_diagnostic.py diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 9f8ac93..1560dcc 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -12,6 +12,7 @@ class Diagnostic(object): """ Alias to call the diagnostic. Must be overridden at the derived clases """ + _diag_list = dict() def __init__(self, data_manager): self.data_manager = data_manager @@ -26,11 +27,11 @@ class Diagnostic(object): :param cls: diagnostic class to register :type cls: Diagnostic """ - try: - Diagnostic._diag_list[cls.alias] = cls - except AttributeError: - Diagnostic._diag_list = dict() - Diagnostic._diag_list[cls.alias] = cls + if not issubclass(cls, Diagnostic): + raise ValueError('Class {0} must be derived from Diagnostic'.format(cls)) + if cls.alias is None: + raise ValueError('Diagnostic class {0} must have defined an alias'.format(cls)) + Diagnostic._diag_list[cls.alias] = cls # noinspection PyProtectedMember @staticmethod @@ -43,11 +44,8 @@ class Diagnostic(object): :return: the selected Diagnostic class, None if name can not be found :rtype: Diagnostic """ - try: - if name in Diagnostic._diag_list.keys(): - return Diagnostic._diag_list[name] - except AttributeError: - pass + if name in Diagnostic._diag_list.keys(): + return Diagnostic._diag_list[name] return None def compute(self): diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 3939a2f..5c523d5 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -1,4 +1,5 @@ -from test_data_manager import * -from test_constants import * -from test_experiment_manager import * -from test_box import * \ No newline at end of file +from test_data_manager import TestDataManager +from test_constants import TestBasin, TestBasins +from test_experiment_manager import TestExperimentManager +from test_box import TestBox +from test_diagnostic import TestDiagnostic \ No newline at end of file diff --git a/test/unit/test_diagnostic.py b/test/unit/test_diagnostic.py new file mode 100644 index 0000000..4bac0a1 --- /dev/null +++ b/test/unit/test_diagnostic.py @@ -0,0 +1,37 @@ +# coding=utf-8 +from earthdiagnostics.diagnostic import Diagnostic +from unittest import TestCase + + +class TestDiagnostic(TestCase): + + class MockDiag(Diagnostic): + alias = 'mockdiag' + + def setUp(self): + self.diagnostic = Diagnostic(None) + Diagnostic.register(TestDiagnostic.MockDiag) + + + def test_register(self): + with self.assertRaises(ValueError): + Diagnostic.register(str) + with self.assertRaises(ValueError): + Diagnostic.register(Diagnostic) + + def test_get_diagnostic(self): + self.assertIsNone(Diagnostic.get_diagnostic('none')) + self.assertIs(TestDiagnostic.MockDiag, Diagnostic.get_diagnostic('mockdiag')) + + def test_generate_jobs(self): + with self.assertRaises(NotImplementedError): + Diagnostic.generate_jobs(None, ['']) + + def test_compute(self): + with self.assertRaises(NotImplementedError): + self.diagnostic.compute() + + def test_str(self): + self.assertEquals('Developer must override base class __str__ method', str(self.diagnostic)) + + -- GitLab From 355650785dbf537f179d129f4175c6a9d037c1f7 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 24 Aug 2016 13:21:28 +0200 Subject: [PATCH 168/268] Fixed bug on CMOR --- earthdiagnostics/datamanager.py | 11 ++--------- earthdiagnostics/diags.conf | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 1c343ae..37f3280 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -167,9 +167,6 @@ class DataManager(object): Log.info('CMORizing chunk {0}-{1}', date2str(chunk_start), date2str(chunk_end)) for grid in ('GG', 'SH'): Log.info('Processing {0} variables', grid) - chunk_files_mon = list() - chunk_files_day = list() - chunk_files_6h = list() for month in range(0, self.exp_manager.chunk_size): current_month = add_months(chunk_start, month, 'standard') @@ -241,12 +238,8 @@ class DataManager(object): Log.result('Month {0} finished', date2str(current_month)) count += 1 - chunk_files_mon.append(gribfile + '_mon.nc') - chunk_files_day.append(gribfile + '_day.nc') - chunk_files_6h.append(gribfile + '_6hr.nc') - - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1m') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1d') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, 'mon') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, 'day') self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '6hr') chunk_start = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 7628202..97ac8dd 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -19,7 +19,7 @@ RESTORE_MESHES = False [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = False +FORCE = True # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True -- GitLab From 54e2c5c3b6c369880419d3018a79e5197ab46305 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 24 Aug 2016 15:13:28 +0200 Subject: [PATCH 169/268] Added tests for CDFTools class --- earthdiagnostics/cdftools.py | 12 +++++------ earthdiagnostics/datamanager.py | 16 +++++++-------- test/unit/__init__.py | 3 ++- test/unit/test_cdftools.py | 35 +++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 test/unit/test_cdftools.py diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index d717d2f..293407b 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -21,30 +21,30 @@ class CDFTools(object): Runs one of the CDFTools :param command: executable to run - :type command: str + :type command: str | iterable :param input: input file :type input: str :param output: output file. Not all tools support this parameter :type options: str :param options: options for the tool. - :type options: str | list + :type options: str | Set | Tuple | List :param log_level: log level at which the output of the cdftool command will be added :type log_level: int """ line = [os.path.join(self.path, command)] if not os.path.exists(line[0]): - raise Exception('Error executing {0}\n Command does not exist in {1}', command, self.path) + raise ValueError('Error executing {0}\n Command does not exist in {1}', command, self.path) if input: if isinstance(input, basestring): line.append(input) if not os.path.exists(input): - raise Exception('Error executing {0}\n Input file {1} file does not exist', command, input) + raise ValueError('Error executing {0}\n Input file {1} file does not exist', command, input) else: for element in input: line.append(element) if not os.path.exists(element): - raise Exception('Error executing {0}\n Input file {1} file does not exist', command, element) + raise ValueError('Error executing {0}\n Input file {1} file does not exist', command, element) if options: if isinstance(options, basestring): options = options.split() @@ -52,7 +52,7 @@ class CDFTools(object): line.append(str(option)) if output: if input == output: - raise Exception('Input and output file can not be the same on CDFTools') + raise ValueError('Input and output file can not be the same on CDFTools') line.append('-o') line.append(output) Log.debug('Executing {0}', ' '.join(line)) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 37f3280..60a5883 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -238,8 +238,8 @@ class DataManager(object): Log.result('Month {0} finished', date2str(current_month)) count += 1 - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, 'mon') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, 'day') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1m') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1d') self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '6hr') chunk_start = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') @@ -314,10 +314,10 @@ class DataManager(object): Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' '{1} {2}_{3}.128.grb ' - '{2}_{3}_day.nc'.format(cdo_reftime, cdo_operator, + '{2}_{3}_1d.nc'.format(cdo_reftime, cdo_operator, gribfile, param)) - daily_variable_file = '{0}_{1}_day.nc'.format(gribfile, param) + daily_variable_file = '{0}_{1}_1d.nc'.format(gribfile, param) if new_units: handler = Utils.openCdf(daily_variable_file) for var in handler.variables.values(): @@ -374,9 +374,9 @@ class DataManager(object): Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' '{1} {2}_{3}.128.grb ' - '{2}_{3}_mon.nc'.format(cdo_reftime, cdo_operator, + '{2}_{3}_1m.nc'.format(cdo_reftime, cdo_operator, gribfile, param)) - handler = Utils.openCdf('{0}_{1}_mon.nc'.format(gribfile, param)) + handler = Utils.openCdf('{0}_{1}_1m.nc'.format(gribfile, param)) if new_units: for var in handler.variables.values(): if 'code' in var.ncattrs() and var.code == param: @@ -389,8 +389,8 @@ class DataManager(object): handler.close() if var_name is not None: - Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), - output='{0}_{1}_mon.nc'.format(gribfile, param), + Utils.nco.ncks(input='{0}_{1}_1m.nc'.format(gribfile, param), + output='{0}_{1}_1m.nc'.format(gribfile, param), options='-O -v {0}'.format(var_name)) def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, grid, frequency): diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 5c523d5..a4c688c 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -2,4 +2,5 @@ from test_data_manager import TestDataManager from test_constants import TestBasin, TestBasins from test_experiment_manager import TestExperimentManager from test_box import TestBox -from test_diagnostic import TestDiagnostic \ No newline at end of file +from test_diagnostic import TestDiagnostic +from test_cdftools import TestCDFTools \ No newline at end of file diff --git a/test/unit/test_cdftools.py b/test/unit/test_cdftools.py new file mode 100644 index 0000000..5376014 --- /dev/null +++ b/test/unit/test_cdftools.py @@ -0,0 +1,35 @@ +# coding=utf-8 +from unittest import TestCase +from earthdiagnostics.cdftools import CDFTools +import mock + + +class TestCDFTools(TestCase): + def setUp(self): + self.cdftools = CDFTools('') + mock.patch('os.path.join') + + def test_run(self): + with mock.patch('os.path.exists') as exists_mock: + def mock_exists(path): + return not path.startswith('bad') + exists_mock.side_effect = mock_exists + with mock.patch('earthdiagnostics.utils.Utils.execute_shell_command') as execute_mock: + execute_mock.return_value = ['Command output'] + with self.assertRaises(ValueError): + self.cdftools.run('badcommand', input='input_file', output='output_file') + with self.assertRaises(ValueError): + self.cdftools.run('command', input='badinput_file', output='output_file') + with self.assertRaises(ValueError): + self.cdftools.run('command', input=('input_file', 'badinput_file'), output='output_file') + with self.assertRaises(ValueError): + self.cdftools.run('command', input='input_file', output='input_file') + with self.assertRaises(Exception): + self.cdftools.run('command', input='input_file', output='badoutput_file') + + self.cdftools.run('command', input='input_file', output='output_file') + self.cdftools.run('command', input='input_file') + self.cdftools.run('command', input=None) + self.cdftools.run('command', input=('input_file', 'input_file2')) + self.cdftools.run('command', input='input_file', options='-o -p') + self.cdftools.run('command', input='input_file', options=('-o', '-p')) -- GitLab From 54e557940c5c4eda4f31ad4861aec1f161cf254b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 24 Aug 2016 18:15:42 +0200 Subject: [PATCH 170/268] Changed splitparam calls to also perform the conversion from grib to nc4 --- earthdiagnostics/datamanager.py | 31 ++++++------ earthdiagnostics/utils.py | 1 - test/unit/__init__.py | 3 +- test/unit/test_utils.py | 83 +++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 test/unit/test_utils.py diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 60a5883..a4746c8 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -165,7 +165,7 @@ class DataManager(object): chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') Log.info('CMORizing chunk {0}-{1}', date2str(chunk_start), date2str(chunk_end)) - for grid in ('GG', 'SH'): + for grid in ('SH', 'GG'): Log.info('Processing {0} variables', grid) for month in range(0, self.exp_manager.chunk_size): @@ -210,13 +210,14 @@ class DataManager(object): Log.info('Unpacking... ') # remap on regular Gauss grid if grid == 'SH': - Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_') + Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_', + options='-f nc4') else: - Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R') + Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R -f nc4') # total precipitation (remove negative values) Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' - '{0}_{{142,143}}.128.grb'.format(gribfile), - output='{0}_228.128.grb'.format(gribfile)) + '{0}_{{142,143}}.128.nc'.format(gribfile), + output='{0}_228.128.nc'.format(gribfile)) if full_file == 'ICM': os.remove('ICM') next_gribfile = os.path.join(self.scratch_dir, @@ -232,7 +233,7 @@ class DataManager(object): self._ungrib_daily_vars(cdo_reftime, gribfile, current_month.month, nfrp) self._ungrib_monthly_files(cdo_reftime, gribfile, current_month.month, nfrp) - for splited_file in glob.glob('{0}_*.128.grb'.format(gribfile)): + for splited_file in glob.glob('{0}_*.128.nc'.format(gribfile)): os.remove(splited_file) Log.result('Month {0} finished', date2str(current_month)) @@ -249,7 +250,7 @@ class DataManager(object): var_codes = (129, 130, 131, 132, 151, 167, 168, 164, 165, 166, 129) levels = ','.join(map(str, range(30000, 90000, 5000))) for param in var_codes: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, param)): continue new_units = None if param == 129: @@ -268,8 +269,8 @@ class DataManager(object): # default, plain monthly mean cdo_operator = "-selmon,{0}".format(month) - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' + Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.nc ' '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, gribfile, param)) h_var_file = '{0}_{1}_6hr.nc'.format(gribfile, param) @@ -286,7 +287,7 @@ class DataManager(object): Log.info('Preparing daily variables') var_codes = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) for param in var_codes: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, param)): continue new_units = None if param in (169, 177, 179): @@ -312,8 +313,8 @@ class DataManager(object): # default, plain daily mean cdo_operator = "-daymean -selmon,{0}".format(month) - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' + Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.nc ' '{2}_{3}_1d.nc'.format(cdo_reftime, cdo_operator, gribfile, param)) @@ -333,7 +334,7 @@ class DataManager(object): var_codes = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, 177, 175, 212, 141, 180, 181, 179, 168, 243, 129, 130, 131, 132, 133) for param in var_codes: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, param)): continue new_units = None if param in (146, 147, 176, 169, 177, 175, 179, 212): @@ -372,8 +373,8 @@ class DataManager(object): # default, plain monthly mean cdo_operator = "-monmean -selmon,{0}".format(month) - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' + Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.nc ' '{2}_{3}_1m.nc'.format(cdo_reftime, cdo_operator, gribfile, param)) handler = Utils.openCdf('{0}_{1}_1m.nc'.format(gribfile, param)) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 8f3c21d..515c61d 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -391,7 +391,6 @@ class TempFile(object): if filename: path = os.path.join(TempFile.scratch_folder, filename) else: - fd, path = tempfile.mkstemp(dir=TempFile.scratch_folder, prefix=TempFile.prefix, suffix=suffix) os.close(fd) diff --git a/test/unit/__init__.py b/test/unit/__init__.py index a4c688c..7c1c20b 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -3,4 +3,5 @@ from test_constants import TestBasin, TestBasins from test_experiment_manager import TestExperimentManager from test_box import TestBox from test_diagnostic import TestDiagnostic -from test_cdftools import TestCDFTools \ No newline at end of file +from test_cdftools import TestCDFTools +from test_utils import TestTempFile, TestUtils \ No newline at end of file diff --git a/test/unit/test_utils.py b/test/unit/test_utils.py new file mode 100644 index 0000000..dbbe5f5 --- /dev/null +++ b/test/unit/test_utils.py @@ -0,0 +1,83 @@ +# coding=utf-8 +from unittest import TestCase +import mock + +from earthdiagnostics.utils import TempFile, Utils + + +class TestTempFile(TestCase): + def setUp(self): + TempFile.scratch_folder = '/tmp' + TempFile.prefix = 'prefix' + + def test_get(self): + self.assertEquals(TempFile.get('tempfile', clean=False), '/tmp/tempfile') + self.assertEquals(TempFile.get('tempfile2', clean=True), '/tmp/tempfile2') + self.assertNotIn('/tmp/tempfile', TempFile.files) + self.assertIn('/tmp/tempfile2', TempFile.files) + + TempFile.autoclean = True + self.assertEquals(TempFile.get('tempfile3'), '/tmp/tempfile3') + self.assertIn('/tmp/tempfile3', TempFile.files) + + TempFile.autoclean = False + self.assertEquals(TempFile.get('tempfile4'), '/tmp/tempfile4') + self.assertNotIn('/tmp/tempfile4', TempFile.files) + + with mock.patch('tempfile.mkstemp') as mkstemp_mock: + with mock.patch('os.close') as close_mock: + mkstemp_mock.return_value = (34, 'path_to_tempfile') + TempFile.get() + TempFile.get(suffix='suffix') + + mkstemp_mock.assert_has_calls((mock.call(dir='/tmp', prefix='prefix', suffix='.nc'), + mock.call(dir='/tmp', prefix='prefix', suffix='suffix'))) + close_mock.assert_has_calls((mock.call(34), mock.call(34))) + + def test_clean(self): + with mock.patch('os.path.exists') as exists_mock: + with mock.patch('tempfile.mkstemp'): + with mock.patch('os.close'): + with mock.patch('os.remove'): + TempFile.clean() + TempFile.clean() + exists_mock.side_effect = [True, False] + TempFile.autoclean = True + TempFile.get('tempfile') + TempFile.get('tempfile2') + TempFile.clean() + self.assertEquals(len(TempFile.files), 0) + + +class TestUtils(TestCase): + + def test_rename_variable(self): + with mock.patch('earthdiagnostics.utils.Utils.rename_variables') as rename_mock: + Utils.rename_variable('file', 'old', 'new') + Utils.rename_variable('file', 'old', 'new', False, True) + rename_mock.assert_has_calls((mock.call('file', {'old': 'new'}, True, False), + mock.call('file', {'old': 'new'}, False, True))) + + def test_rename_variables(self): + mock_handler = mock.Mock() + mock_handler.variables = dict() + mock_handler.dimensions = dict() + mock_handler.variables['old'] = mock.Mock() + mock_handler.variables['old_var'] = mock.Mock() + mock_handler.dimensions['old'] = mock.Mock() + + with mock.patch('earthdiagnostics.utils.Utils.openCdf') as opencdf_mock: + opencdf_mock.return_value = mock_handler + Utils.rename_variables('file', {'old': 'old_var'}) + Utils.rename_variables('file', {'old': 'new'}, False, True) + Utils.rename_variables('file', {'new': 'new'}, False) + Utils.rename_variables('file', {'old_var': 'new'}, False, True) + + with self.assertRaises(Exception): + Utils.rename_variables('file', {'new': 'new'}) + with self.assertRaises(Exception): + Utils.rename_variables('file', {'old_var': 'new'}, rename_dimension=True) + + def test_available_cpu_count(self): + Utils.available_cpu_count() + Utils.available_cpu_count() -- GitLab From 5c48628c2f0869de3d8faa5c0ccaf168cb3d14c6 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 25 Aug 2016 10:47:18 +0200 Subject: [PATCH 171/268] Added NEMO version for EC-EARTH 3.2 ORCA1 L75 --- earthdiagnostics/constants.py | 2 ++ earthdiagnostics/datamanager.py | 6 +++--- earthdiagnostics/diags.conf | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/earthdiagnostics/constants.py b/earthdiagnostics/constants.py index c37af21..b8b63d3 100644 --- a/earthdiagnostics/constants.py +++ b/earthdiagnostics/constants.py @@ -233,6 +233,8 @@ class Models(object): """ EC-Earth 3 ORCA0.25 L75 """ ECEARTH_3_1_O25L75 = 'Ec3.1_O25L75' """ EC-Earth 3.1 ORCA0.25 L75 """ + ECEARTH_3_2_O1L75 = 'Ec3.2_O1L75' + """ EC-Earth 3.2 ORCA1 L75 """ NEMO_3_2_O1L42 = 'N3.2_O1L42' """ NEMO 3.2 ORCA1 L42 """ diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index a4746c8..d8d9491 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -601,7 +601,7 @@ class DataManager(object): @staticmethod def _update_time_variables(handler, startdate): time_var = handler.variables['time'] - times = netCDF4.num2date(time_var[:], time_var.units, time_var.calendar) + times = Utils.get_datetime_from_netcdf(handler) if type(times[0]) is not datetime: for x in range(0, times.shape[0]): # noinspection PyProtectedMember @@ -617,7 +617,7 @@ class DataManager(object): time_bounds_var = handler.variables['time_bnds'] time_var.bounds = "time_bnds" - time_bounds = netCDF4.num2date(time_bounds_var[:], time_var.units, time_var.calendar) + time_bounds = Utils.get_datetime_from_netcdf(handler, 'time_bnds') if type(time_bounds[0, 0]) is not datetime: for x in range(0, time_bounds.shape[0]): for y in range(0, time_bounds.shape[1]): @@ -637,7 +637,7 @@ class DataManager(object): var.units = "days" var.long_name = "Time elapsed since the start of the forecast" var.standard_name = "forecast_period" - leadtime = (netCDF4.num2date(time_var[:], time_var.units, time_var.calendar) - parse_date(startdate)) + leadtime = (Utils.get_datetime_from_netcdf(handler) - parse_date(startdate)) for lt in range(0, leadtime.shape[0]): var[lt] = leadtime[lt].days diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 97ac8dd..2407c20 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -36,9 +36,9 @@ ATMOSPHERE_FILES = True [EXPERIMENT] # Experiments parameters as defined in CMOR standard INSTITUTE = BSC -MODEL = NEMO +MODEL = EC-EARTH # Model version -MODEL_VERSION = N3.6_O1L75 +MODEL_VERSION =Ec3.2_O1L75 # For those who use Autosubmit, this no need documentation # For those who not, EXPID is the unique identifier of the experiment. @@ -52,7 +52,7 @@ STARTDATES = 19900101 MEMBERS = 0 MEMBER_DIGITS = 1 CHUNK_SIZE = 1 -CHUNKS = 1 +CHUNKS = 12 # CHUNKS = 1 -- GitLab From 6716bda4a59c93f8b1e0ec147b103fe2a7495577 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 25 Aug 2016 12:21:22 +0200 Subject: [PATCH 172/268] Added some tests --- earthdiagnostics/datamanager.py | 2 +- test/unit/__init__.py | 4 ++-- test/unit/test_data_manager.py | 36 +++++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index d8d9491..97287bf 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1106,7 +1106,7 @@ class Variable(object): with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'cmor_table.csv'), 'rb') as csvfile: reader = csv.reader(csvfile, dialect='excel') for line in reader: - if line[0] == 'variable': + if line[0] == 'Variable': continue var = Variable(line) diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 7c1c20b..5328631 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -1,7 +1,7 @@ -from test_data_manager import TestDataManager +from test_data_manager import TestDataManager, TestVariable from test_constants import TestBasin, TestBasins from test_experiment_manager import TestExperimentManager from test_box import TestBox from test_diagnostic import TestDiagnostic from test_cdftools import TestCDFTools -from test_utils import TestTempFile, TestUtils \ No newline at end of file +from test_utils import TestTempFile, TestUtils diff --git a/test/unit/test_data_manager.py b/test/unit/test_data_manager.py index b7e6410..6f1d1e1 100644 --- a/test/unit/test_data_manager.py +++ b/test/unit/test_data_manager.py @@ -2,12 +2,15 @@ from unittest import TestCase -from earthdiagnostics.datamanager import DataManager +from earthdiagnostics.datamanager import DataManager, Variable +from experimentmanager import ExperimentManager +from datetime import date class TestDataManager(TestCase): def setUp(self): - pass + self.data_manager = DataManager(ExperimentManager(['20000101'], [0], 5, 3, 3), 'institution', 'model', 'expid', + 'datafolder', 'mon', 'experiment', 'scratch', 6) def test_domain_abbreviation(self): self.assertEquals('Omon', DataManager.domain_abbreviation('Ocean', 'mon')) @@ -16,3 +19,32 @@ class TestDataManager(TestCase): self.assertEquals('Amon', DataManager.domain_abbreviation('atmos', 'mon')) self.assertEquals('day', DataManager.domain_abbreviation('atmos', 'day')) self.assertEquals('6hrPlev', DataManager.domain_abbreviation('atmos', '6hr')) + + def test_get_grib_filename(self): + self.assertEqual(self.data_manager._get_grib_filename('SH', date(2000, 1, 1)), 'ICMSHexpid+200001.grb') + + def test_get_startdate_path(self): + self.assertEqual(self.data_manager.get_startdate_path('20000101'), + 'datafolder/expid/cmorfiles/institution/model/experiment/S20000101') + + +class TestVariable(TestCase): + + def test__init__(self): + variable = Variable('alias:alias2,name,standard_name,long_name,domain,basin,units,' + 'valid_min,valid_max'.split(',')) + self.assertEqual(variable.short_name, 'name') + self.assertEqual(variable.standard_name, 'standard_name') + self.assertEqual(variable.long_name, 'long_name') + self.assertEqual(variable.domain, 'domain') + self.assertEqual(variable.basin, None) + self.assertEqual(variable.units, 'units') + self.assertEqual(variable.valid_min, 'valid_min') + self.assertEqual(variable.valid_max, 'valid_max') + + def test_get_variable(self): + Variable._dict_variables = dict() + variable = Variable('alias:alias2,name,standard_name,long_name,domain,basin,units,valid_min,valid_max'.split(',')) + Variable._dict_variables['var'] = variable + self.assertIs(Variable.get_variable('var'), variable) + self.assertIsNone(Variable.get_variable('novar')) -- GitLab From f39f98b96c18277561e9ef32b81adadfe5142b9a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 25 Aug 2016 15:38:09 +0200 Subject: [PATCH 173/268] Added more tests --- launch_diags.sh | 4 ++-- test/unit/test_utils.py | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/launch_diags.sh b/launch_diags.sh index 5364683..7d0cc73 100755 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -#SBATCH -n 1 -#SBATCH --time 24:00:00 +#SBATCH -n 2 +#SBATCH --time 72:00:00 #SBATCH --error=job.%J.err #SBATCH --output=job.%J.out diff --git a/test/unit/test_utils.py b/test/unit/test_utils.py index dbbe5f5..2ae94e3 100644 --- a/test/unit/test_utils.py +++ b/test/unit/test_utils.py @@ -78,6 +78,24 @@ class TestUtils(TestCase): with self.assertRaises(Exception): Utils.rename_variables('file', {'old_var': 'new'}, rename_dimension=True) - def test_available_cpu_count(self): - Utils.available_cpu_count() - Utils.available_cpu_count() + def test_convert2netcdf4(self): + mock_handler = mock.Mock() + + with mock.patch('earthdiagnostics.utils.Utils.openCdf') as opencdf_mock: + with mock.patch('earthdiagnostics.utils.Utils.execute_shell_command') as execute_mock: + with mock.patch('earthdiagnostics.utils.TempFile.get') as tempfile_mock: + with mock.patch('shutil.move'): + tempfile_mock.return_value = 'tempfile' + opencdf_mock.return_value = mock_handler + mock_handler.file_format = 'NETCDF4' + Utils.convert2netcdf4('file', False) + + mock_handler.file_format = 'OTHER' + Utils.convert2netcdf4('file2', False) + execute_mock.assert_called_with(['nccopy', '-4', '-d4', '-s', 'file2', 'tempfile']) + + mock_handler.file_format = 'NETCDF4' + Utils.convert2netcdf4('file3', True) + execute_mock.assert_called_with(['nccopy', '-4', '-d4', '-s', 'file3', 'tempfile']) + + self.assertEqual(execute_mock.call_count, 2) -- GitLab From 2d9254b3cd893066bfdb2283352265c818befe32 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 25 Aug 2016 17:50:24 +0200 Subject: [PATCH 174/268] Added clean command to clean scratch folder after execution --- earthdiagnostics/diags.py | 13 ++++++++++++- launch_diags.sh | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index e08d41a..70fb608 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -132,6 +132,12 @@ class Diags(object): for diag, time in sorted(total.items(), key=operator.itemgetter(1)): Log.info('{0:23} {1:}', diag.__name__, time) + def clean(self): + Log.info('Removing scratch folder...') + if os.path.exists(self.scratch_dir): + shutil.rmtree(self.scratch_dir) + Log.result('Scratch folder removed') + def _run_jobs(self, queue, numthread): def _run_job(current_job, retrials=1): while retrials >= 0: @@ -310,6 +316,8 @@ def main(): help="returns Earth Diagnostics's version number and exit") parser.add_argument('--doc', action='store_true', help="opens documentation and exits") + parser.add_argument('--clean', action='store_true', + help="clean the scratch folder and exits") parser.add_argument('-lf', '--logfile', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), default='DEBUG', type=str, @@ -336,7 +344,10 @@ def main(): Log.set_file(Utils.expand_path(args.logfilepath)) diags = Diags(Utils.expand_path(args.configfile)) - diags.run() + if args.clean: + diags.clean() + else: + diags.run() TempFile.clean() diff --git a/launch_diags.sh b/launch_diags.sh index 7d0cc73..94ec71f 100755 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -#SBATCH -n 2 +#SBATCH -n 1 #SBATCH --time 72:00:00 #SBATCH --error=job.%J.err #SBATCH --output=job.%J.out -- GitLab From 095647b0f2ecddde659babf3c8d5f3e5477d0964 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 26 Aug 2016 12:38:33 +0200 Subject: [PATCH 175/268] Added some tests --- earthdiagnostics/box.py | 5 +++ earthdiagnostics/diagnostic.py | 3 ++ earthdiagnostics/ocean/areamoc.py | 4 +++ earthdiagnostics/ocean/averagesection.py | 8 +++-- earthdiagnostics/ocean/psi.py | 3 ++ test/unit/__init__.py | 3 ++ test/unit/test_areamoc.py | 43 ++++++++++++++++++++++++ test/unit/test_averagesection.py | 42 +++++++++++++++++++++++ test/unit/test_psi.py | 25 ++++++++++++++ 9 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 test/unit/test_areamoc.py create mode 100644 test/unit/test_averagesection.py create mode 100644 test/unit/test_psi.py diff --git a/earthdiagnostics/box.py b/earthdiagnostics/box.py index 2295b5e..68b24bc 100644 --- a/earthdiagnostics/box.py +++ b/earthdiagnostics/box.py @@ -25,6 +25,11 @@ class Box(object): :rtype: float """ + def __eq__(self, other): + return self.depth_in_meters == other.depth_in_meters and self.max_lat == other.max_lat and \ + self.min_lat == other.min_lat and self.max_lon == other.max_lon and self.min_lon == other.min_lon and \ + self.max_depth == other.max_depth and self.min_depth == other.min_depth + def __str__(self): return self.get_lat_str() + self.get_lon_str() + self.get_depth_str() diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index 1560dcc..f19364b 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -20,6 +20,9 @@ class Diagnostic(object): self.generated_vars = [] self.can_run_multiple_instances = True + def __repr__(self): + return str(self) + @staticmethod def register(cls): """ diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 4ffb8c8..7e0c93d 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -46,6 +46,10 @@ class AreaMoc(Diagnostic): self.generated_vars = ['vsftmyz'] self.box = box + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.basin == other.basin and self.box == other.box + def __str__(self): return 'Area MOC Startdate: {0} Member: {1} Chunk: {2} Box: {3}'.format(self.startdate, self.member, self.chunk, self.box) diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index a002d82..56d01c4 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -35,7 +35,7 @@ class AverageSection(Diagnostic): alias = 'avgsection' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, variable, domain, box): + def __init__(self, data_manager, startdate, member, chunk, domain, variable, box): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member @@ -44,6 +44,10 @@ class AverageSection(Diagnostic): self.domain = domain self.box = box + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.domain == other.domain and self.variable == other.variable and self.box == other.box + def __str__(self): return 'Average section Startdate: {0} Member: {1} Chunk: {2} Box: {3} ' \ 'Variable: {4}:{5}'.format(self.startdate, self.member, self.chunk, self.box, self.domain, self.variable) @@ -77,7 +81,7 @@ class AverageSection(Diagnostic): job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, variable, domain, box)) + job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, domain, variable, box)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 24db1e0..f40d9e4 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -35,6 +35,9 @@ class Psi(Diagnostic): self.required_vars = ['vo', 'uo'] self.generated_vars = ['vsftbarot'] + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk + def __str__(self): return 'PSI Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 5328631..97eb6a5 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -5,3 +5,6 @@ from test_box import TestBox from test_diagnostic import TestDiagnostic from test_cdftools import TestCDFTools from test_utils import TestTempFile, TestUtils +from test_psi import TestPsi +from test_areamoc import TestAreaMoc +from test_averagesection import TestAverageSection diff --git a/test/unit/test_areamoc.py b/test/unit/test_areamoc.py new file mode 100644 index 0000000..db88d51 --- /dev/null +++ b/test/unit/test_areamoc.py @@ -0,0 +1,43 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from constants import Basins +from earthdiagnostics.ocean.areamoc import AreaMoc +from mock import Mock + + +class TestAreaMoc(TestCase): + + def setUp(self): + self.data_manager = Mock() + self.diags = Mock() + + self.box = Box() + self.box.min_lat = 0 + self.box.max_lat = 0 + self.box.min_depth = 0 + self.box.max_depth = 0 + + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.psi = AreaMoc(self.data_manager, '20000101', 1, 1, Basins.Antarctic, self.box) + + def test_generate_jobs(self): + jobs = AreaMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], AreaMoc(self.data_manager, '20010101', 0, 0, Basins.Global, self.box)) + self.assertEqual(jobs[1], AreaMoc(self.data_manager, '20010101', 0, 1, Basins.Global, self.box)) + + jobs = AreaMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', 'atl']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], AreaMoc(self.data_manager, '20010101', 0, 0, Basins.Atlantic, self.box)) + self.assertEqual(jobs[1], AreaMoc(self.data_manager, '20010101', 0, 1, Basins.Atlantic, self.box)) + + with self.assertRaises(Exception): + AreaMoc.generate_jobs(self.diags, ['psi']) + with self.assertRaises(Exception): + AreaMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0']) + + + def test_str(self): + self.assertEquals(str(self.psi), 'Area MOC Startdate: 20000101 Member: 1 Chunk: 1 Box: 0N0') diff --git a/test/unit/test_averagesection.py b/test/unit/test_averagesection.py new file mode 100644 index 0000000..3707fa2 --- /dev/null +++ b/test/unit/test_averagesection.py @@ -0,0 +1,42 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from earthdiagnostics.ocean.averagesection import AverageSection +from mock import Mock + + +class TestAverageSection(TestCase): + + def setUp(self): + self.data_manager = Mock() + self.diags = Mock() + + self.box = Box() + self.box.min_lat = 0 + self.box.max_lat = 0 + self.box.min_lon = 0 + self.box.max_lon = 0 + + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.psi = AverageSection(self.data_manager, '20000101', 1, 1, 'domain', 'var', self.box) + + def test_generate_jobs(self): + jobs = AverageSection.generate_jobs(self.diags, ['psi', 'var', '0', '0', '0', '0']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], AverageSection(self.data_manager, '20010101', 0, 0, 'ocean', 'var', self.box)) + self.assertEqual(jobs[1], AverageSection(self.data_manager, '20010101', 0, 1, 'ocean', 'var', self.box)) + + jobs = AverageSection.generate_jobs(self.diags, ['psi', 'var', '0', '0', '0', '0', 'domain']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], AverageSection(self.data_manager, '20010101', 0, 0, 'domain', 'var', self.box)) + self.assertEqual(jobs[1], AverageSection(self.data_manager, '20010101', 0, 1, 'domain', 'var', self.box)) + + with self.assertRaises(Exception): + AverageSection.generate_jobs(self.diags, ['psi']) + with self.assertRaises(Exception): + AverageSection.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.psi), 'Average section Startdate: 20000101 Member: 1 Chunk: 1 Box: 0N0E ' + 'Variable: domain:var') diff --git a/test/unit/test_psi.py b/test/unit/test_psi.py new file mode 100644 index 0000000..fe53231 --- /dev/null +++ b/test/unit/test_psi.py @@ -0,0 +1,25 @@ +# coding=utf-8 +from unittest import TestCase +from earthdiagnostics.ocean.psi import Psi +from mock import Mock + + +class TestPsi(TestCase): + + def setUp(self): + self.data_manager = Mock() + self.diags = Mock() + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.psi = Psi(self.data_manager, '20000101', 1, 1) + + def test_generate_jobs(self): + jobs = Psi.generate_jobs(self.diags, ['psi']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], Psi(self.data_manager, '20010101', 0, 0)) + self.assertEqual(jobs[1], Psi(self.data_manager, '20010101', 0, 1)) + + with self.assertRaises(Exception): + Psi.generate_jobs(self.diags, ['psi', 'badoption']) + + def test_str(self): + self.assertEquals(str(self.psi), 'PSI Startdate: 20000101 Member: 1 Chunk: 1') -- GitLab From 85d83cf408242d190bcca81aab2c1d60bc0ff0d1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 26 Aug 2016 12:58:30 +0200 Subject: [PATCH 176/268] Added more tests --- earthdiagnostics/ocean/convectionsites.py | 4 +++ earthdiagnostics/ocean/cutsection.py | 11 ++++-- test/unit/__init__.py | 2 ++ test/unit/test_convectionsites.py | 30 ++++++++++++++++ test/unit/test_cutsection.py | 42 +++++++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 test/unit/test_convectionsites.py create mode 100644 test/unit/test_cutsection.py diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 5638755..43e6fa5 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -43,6 +43,10 @@ class ConvectionSites(Diagnostic): def __str__(self): return 'Convection sites Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.model_version == other.model_version + @classmethod def generate_jobs(cls, diags, options): """ diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index 2da67d0..bf62c53 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -38,7 +38,7 @@ class CutSection(Diagnostic): alias = 'cutsection' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, variable, domain, zonal, value): + def __init__(self, data_manager, startdate, member, chunk, domain, variable, zonal, value): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member @@ -48,8 +48,13 @@ class CutSection(Diagnostic): self.zonal = zonal self.value = value + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.domain == other.domain and self.variable == other.variable and self.zonal == other.zonal and \ + self.value == other.value + def __str__(self): - return 'Cut section Startdate: {0} Member: {1} Chunk: {2} Variable: {3}:{4}' \ + return 'Cut section Startdate: {0} Member: {1} Chunk: {2} Variable: {3}:{4} ' \ 'Zonal: {5} Value: {6}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable, self.zonal, self.value) @@ -79,7 +84,7 @@ class CutSection(Diagnostic): job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(CutSection(diags.data_manager, startdate, member, chunk, variable, domain, zonal, value)) + job_list.append(CutSection(diags.data_manager, startdate, member, chunk, domain, variable, zonal, value)) return job_list def compute(self): diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 97eb6a5..e7211c5 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -8,3 +8,5 @@ from test_utils import TestTempFile, TestUtils from test_psi import TestPsi from test_areamoc import TestAreaMoc from test_averagesection import TestAverageSection +from test_cutsection import TestCutSection +from test_convectionsites import TestConvectionSites diff --git a/test/unit/test_convectionsites.py b/test/unit/test_convectionsites.py new file mode 100644 index 0000000..5959512 --- /dev/null +++ b/test/unit/test_convectionsites.py @@ -0,0 +1,30 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from earthdiagnostics.ocean.convectionsites import ConvectionSites +from mock import Mock + + +class TestConvectionSites(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.psi = ConvectionSites(self.data_manager, '20000101', 1, 1, 'model_version') + + def test_generate_jobs(self): + jobs = ConvectionSites.generate_jobs(self.diags, ['psi']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], ConvectionSites(self.data_manager, '20010101', 0, 0, 'model_version')) + self.assertEqual(jobs[1], ConvectionSites(self.data_manager, '20010101', 0, 1, 'model_version')) + + with self.assertRaises(Exception): + ConvectionSites.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.psi), 'Convection sites Startdate: 20000101 Member: 1 Chunk: 1') diff --git a/test/unit/test_cutsection.py b/test/unit/test_cutsection.py new file mode 100644 index 0000000..cf91f1e --- /dev/null +++ b/test/unit/test_cutsection.py @@ -0,0 +1,42 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from earthdiagnostics.ocean.cutsection import CutSection +from mock import Mock + + +class TestCutSection(TestCase): + + def setUp(self): + self.data_manager = Mock() + self.diags = Mock() + + self.box = Box() + self.box.min_lat = 0 + self.box.max_lat = 0 + self.box.min_lon = 0 + self.box.max_lon = 0 + + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.psi = CutSection(self.data_manager, '20000101', 1, 1, 'domain', 'var', True, 0) + + def test_generate_jobs(self): + jobs = CutSection.generate_jobs(self.diags, ['psi', 'var', 'true', '10']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], CutSection(self.data_manager, '20010101', 0, 0, 'ocean', 'var', True, 10)) + self.assertEqual(jobs[1], CutSection(self.data_manager, '20010101', 0, 1, 'ocean', 'var', True, 10)) + + jobs = CutSection.generate_jobs(self.diags, ['psi', 'var', 'false', '0', 'domain']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], CutSection(self.data_manager, '20010101', 0, 0, 'domain', 'var', False, 0)) + self.assertEqual(jobs[1], CutSection(self.data_manager, '20010101', 0, 1, 'domain', 'var', False, 0)) + + with self.assertRaises(Exception): + CutSection.generate_jobs(self.diags, ['psi']) + with self.assertRaises(Exception): + CutSection.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.psi), 'Cut section Startdate: 20000101 Member: 1 Chunk: 1 Variable: domain:var ' + 'Zonal: True Value: 0') -- GitLab From 9ad283a112b75417fcbaea50c14f04be76e3908b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 26 Aug 2016 15:05:21 +0200 Subject: [PATCH 177/268] Added more tests. Some cleanup --- earthdiagnostics/cdftools.py | 2 +- earthdiagnostics/datamanager.py | 4 +-- earthdiagnostics/ocean/gyres.py | 7 +++-- earthdiagnostics/ocean/heatcontent.py | 9 +++++-- test/__init__.py | 1 + test/unit/__init__.py | 4 +++ test/unit/test_areamoc.py | 1 - test/unit/test_cdftools.py | 5 ++-- test/unit/test_convectionsites.py | 2 -- test/unit/test_data_manager.py | 3 ++- test/unit/test_diagnostic.py | 11 +++++++- test/unit/test_gyres.py | 29 ++++++++++++++++++++ test/unit/test_heatcontent.py | 39 +++++++++++++++++++++++++++ test/unit/test_heatcontentlayer.py | 26 ++++++++++++++++++ 14 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 test/unit/test_gyres.py create mode 100644 test/unit/test_heatcontent.py create mode 100644 test/unit/test_heatcontentlayer.py diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 293407b..5db174b 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -27,7 +27,7 @@ class CDFTools(object): :param output: output file. Not all tools support this parameter :type options: str :param options: options for the tool. - :type options: str | Set | Tuple | List + :type options: str | list[str] | Tuple[str] :param log_level: log level at which the output of the cdftool command will be added :type log_level: int """ diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 97287bf..5a43c2b 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -316,7 +316,7 @@ class DataManager(object): Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' '{1} {2}_{3}.128.nc ' '{2}_{3}_1d.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) + gribfile, param)) daily_variable_file = '{0}_{1}_1d.nc'.format(gribfile, param) if new_units: @@ -376,7 +376,7 @@ class DataManager(object): Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' '{1} {2}_{3}.128.nc ' '{2}_{3}_1m.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) + gribfile, param)) handler = Utils.openCdf('{0}_{1}_1m.nc'.format(gribfile, param)) if new_units: for var in handler.variables.values(): diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 603e654..6624569 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -41,9 +41,12 @@ class Gyres(Diagnostic): self.required_vars = ['vsftbarot'] self.generated_vars = ['gyres'] + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.model_version == other.model_version + def __str__(self): - return 'Gyres Startdate: {0} Member: {1} Chunk: {2} '.format(self.startdate, self.member, - self.chunk) + return 'Gyres Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) @classmethod def generate_jobs(cls, diags, options): diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index df80de7..963e282 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -49,9 +49,14 @@ class HeatContent(Diagnostic): self.required_vars = ['so', 'mlotst'] self.generated_vars = ['scvertsum'] + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.box == other.box and self.basin == other.basin and self.mxloption == other.mxloption + def __str__(self): - return 'Heat content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, - self.chunk) + return 'Heat content Startdate: {0} Member: {1} Chunk: {2} Mixed layer: {3} Box: {4} ' \ + 'Basin: {5}'.format(self.startdate, self.member, self.chunk, self.mxloption, self.box, + self.basin.fullname) @classmethod def generate_jobs(cls, diags, options): diff --git a/test/__init__.py b/test/__init__.py index e69de29..9bad579 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -0,0 +1 @@ +# coding=utf-8 diff --git a/test/unit/__init__.py b/test/unit/__init__.py index e7211c5..26772d2 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -1,3 +1,4 @@ +# coding=utf-8 from test_data_manager import TestDataManager, TestVariable from test_constants import TestBasin, TestBasins from test_experiment_manager import TestExperimentManager @@ -10,3 +11,6 @@ from test_areamoc import TestAreaMoc from test_averagesection import TestAverageSection from test_cutsection import TestCutSection from test_convectionsites import TestConvectionSites +from test_gyres import TestGyres +from test_heatcontent import TestHeatContent +from test_heatcontentlayer import TestHeatContentLayer diff --git a/test/unit/test_areamoc.py b/test/unit/test_areamoc.py index db88d51..6992604 100644 --- a/test/unit/test_areamoc.py +++ b/test/unit/test_areamoc.py @@ -38,6 +38,5 @@ class TestAreaMoc(TestCase): with self.assertRaises(Exception): AreaMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0']) - def test_str(self): self.assertEquals(str(self.psi), 'Area MOC Startdate: 20000101 Member: 1 Chunk: 1 Box: 0N0') diff --git a/test/unit/test_cdftools.py b/test/unit/test_cdftools.py index 5376014..266535c 100644 --- a/test/unit/test_cdftools.py +++ b/test/unit/test_cdftools.py @@ -9,6 +9,7 @@ class TestCDFTools(TestCase): self.cdftools = CDFTools('') mock.patch('os.path.join') + # noinspection PyTypeChecker def test_run(self): with mock.patch('os.path.exists') as exists_mock: def mock_exists(path): @@ -21,7 +22,7 @@ class TestCDFTools(TestCase): with self.assertRaises(ValueError): self.cdftools.run('command', input='badinput_file', output='output_file') with self.assertRaises(ValueError): - self.cdftools.run('command', input=('input_file', 'badinput_file'), output='output_file') + self.cdftools.run('command', input=['input_file', 'badinput_file'], output='output_file') with self.assertRaises(ValueError): self.cdftools.run('command', input='input_file', output='input_file') with self.assertRaises(Exception): @@ -30,6 +31,6 @@ class TestCDFTools(TestCase): self.cdftools.run('command', input='input_file', output='output_file') self.cdftools.run('command', input='input_file') self.cdftools.run('command', input=None) - self.cdftools.run('command', input=('input_file', 'input_file2')) + self.cdftools.run('command', input=['input_file', 'input_file2']) self.cdftools.run('command', input='input_file', options='-o -p') self.cdftools.run('command', input='input_file', options=('-o', '-p')) diff --git a/test/unit/test_convectionsites.py b/test/unit/test_convectionsites.py index 5959512..282dcd9 100644 --- a/test/unit/test_convectionsites.py +++ b/test/unit/test_convectionsites.py @@ -1,7 +1,5 @@ # coding=utf-8 from unittest import TestCase - -from box import Box from earthdiagnostics.ocean.convectionsites import ConvectionSites from mock import Mock diff --git a/test/unit/test_data_manager.py b/test/unit/test_data_manager.py index 6f1d1e1..074b628 100644 --- a/test/unit/test_data_manager.py +++ b/test/unit/test_data_manager.py @@ -44,7 +44,8 @@ class TestVariable(TestCase): def test_get_variable(self): Variable._dict_variables = dict() - variable = Variable('alias:alias2,name,standard_name,long_name,domain,basin,units,valid_min,valid_max'.split(',')) + variable = Variable('alias:alias2,name,standard_name,long_name,domain,basin,units,valid_min,' + 'valid_max'.split(',')) Variable._dict_variables['var'] = variable self.assertIs(Variable.get_variable('var'), variable) self.assertIsNone(Variable.get_variable('novar')) diff --git a/test/unit/test_diagnostic.py b/test/unit/test_diagnostic.py index 4bac0a1..3804844 100644 --- a/test/unit/test_diagnostic.py +++ b/test/unit/test_diagnostic.py @@ -5,19 +5,28 @@ from unittest import TestCase class TestDiagnostic(TestCase): + # noinspection PyMissingOrEmptyDocstring class MockDiag(Diagnostic): + def compute(self): + pass + + @classmethod + def generate_jobs(cls, diags, options): + pass + alias = 'mockdiag' def setUp(self): self.diagnostic = Diagnostic(None) Diagnostic.register(TestDiagnostic.MockDiag) - def test_register(self): with self.assertRaises(ValueError): + # noinspection PyTypeChecker Diagnostic.register(str) with self.assertRaises(ValueError): Diagnostic.register(Diagnostic) + Diagnostic.register(TestDiagnostic.MockDiag) def test_get_diagnostic(self): self.assertIsNone(Diagnostic.get_diagnostic('none')) diff --git a/test/unit/test_gyres.py b/test/unit/test_gyres.py new file mode 100644 index 0000000..ded1acd --- /dev/null +++ b/test/unit/test_gyres.py @@ -0,0 +1,29 @@ +# coding=utf-8 +from unittest import TestCase + +from earthdiagnostics.ocean.gyres import Gyres +from mock import Mock + + +class TestGyres(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.gyres = Gyres(self.data_manager, '20000101', 1, 1, 'model_version') + + def test_generate_jobs(self): + jobs = Gyres.generate_jobs(self.diags, ['psi']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], Gyres(self.data_manager, '20010101', 0, 0, 'model_version')) + self.assertEqual(jobs[1], Gyres(self.data_manager, '20010101', 0, 1, 'model_version')) + + with self.assertRaises(Exception): + Gyres.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.gyres), 'Gyres Startdate: 20000101 Member: 1 Chunk: 1') diff --git a/test/unit/test_heatcontent.py b/test/unit/test_heatcontent.py new file mode 100644 index 0000000..1e3d3eb --- /dev/null +++ b/test/unit/test_heatcontent.py @@ -0,0 +1,39 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from constants import Basins +from earthdiagnostics.ocean.heatcontent import HeatContent +from mock import Mock + + +class TestHeatContent(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.box = Box(True) + self.box.min_depth = 0 + self.box.max_depth = 100 + + self.heat_content = HeatContent(self.data_manager, '20000101', 1, 1, Basins.Global, 1, self.box) + + def test_generate_jobs(self): + jobs = HeatContent.generate_jobs(self.diags, ['psi', 'atl', '-1', '0', '100']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], HeatContent(self.data_manager, '20010101', 0, 0, Basins.Atlantic, -1, self.box)) + self.assertEqual(jobs[1], HeatContent(self.data_manager, '20010101', 0, 1, Basins.Atlantic, -1, self.box)) + + with self.assertRaises(Exception): + HeatContent.generate_jobs(self.diags, ['psi']) + + with self.assertRaises(Exception): + HeatContent.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.heat_content), 'Heat content Startdate: 20000101 Member: 1 Chunk: 1 Mixed layer: 1 ' + 'Box: 0m-100m Basin: Global_Ocean') diff --git a/test/unit/test_heatcontentlayer.py b/test/unit/test_heatcontentlayer.py new file mode 100644 index 0000000..7d8b4d4 --- /dev/null +++ b/test/unit/test_heatcontentlayer.py @@ -0,0 +1,26 @@ +# coding=utf-8 +from unittest import TestCase +from box import Box +from earthdiagnostics.ocean.heatcontentlayer import HeatContentLayer +from mock import Mock + + +class TestHeatContentLayer(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.weight = Mock() + + self.box = Box(True) + self.box.min_depth = 0 + self.box.max_depth = 100 + + self.psi = HeatContentLayer(self.data_manager, '20000101', 1, 1, self.box, self.weight, 0, 10) + + def test_str(self): + self.assertEquals(str(self.psi), 'Heat content layer Startdate: 20000101 Member: 1 Chunk: 1 Box: 0m-100m') -- GitLab From 0e3cfe3085e57e150822e0bb4985f54232714486 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 26 Aug 2016 15:56:34 +0200 Subject: [PATCH 178/268] Even more test added --- earthdiagnostics/ocean/interpolate.py | 10 ++++-- earthdiagnostics/ocean/maxmoc.py | 9 +++-- test/unit/__init__.py | 2 ++ test/unit/test_interpolate.py | 38 ++++++++++++++++++++ test/unit/test_maxmoc.py | 52 +++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 test/unit/test_interpolate.py create mode 100644 test/unit/test_maxmoc.py diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index bd626a5..a9f74b2 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -40,7 +40,7 @@ class Interpolate(Diagnostic): lock = threading.Lock() - def __init__(self, data_manager, startdate, member, chunk, variable, domain, model_version): + def __init__(self, data_manager, startdate, member, chunk, domain, variable, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member @@ -52,6 +52,10 @@ class Interpolate(Diagnostic): self.generated_vars = [variable] self.tempTemplate = '' + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.model_version == other.model_version and self.domain == other.domain and self.variable == other.variable + def __str__(self): return 'Interpolate Startdate: {0} Member: {1} Chunk: {2} ' \ 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) @@ -80,8 +84,8 @@ class Interpolate(Diagnostic): job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(Interpolate(diags.data_manager, startdate, member, chunk, - variable, domain, diags.model_version)) + job_list.append( + Interpolate(diags.data_manager, startdate, member, chunk, domain, variable, diags.model_version)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 468080e..cbcdeec 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -47,8 +47,13 @@ class MaxMoc(Diagnostic): self.box = box def __str__(self): - return 'Max moc Startdate: {0} Member: {1} Year: {2} Basin: {3}'.format(self.startdate, self.member, - self.year, self.box) + return 'Max moc Startdate: {0} Member: {1} Year: {2} Box: {3} ' \ + 'Basin: {4}'.format(self.startdate, self.member, self.year, self.box, self.basin.fullname) + + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.year == other.year and \ + self.box == other.box and self.basin == other.basin + @classmethod def generate_jobs(cls, diags, options): diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 26772d2..5f42083 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -14,3 +14,5 @@ from test_convectionsites import TestConvectionSites from test_gyres import TestGyres from test_heatcontent import TestHeatContent from test_heatcontentlayer import TestHeatContentLayer +from test_interpolate import TestInterpolate +from test_maxmoc import TestMaxMoc \ No newline at end of file diff --git a/test/unit/test_interpolate.py b/test/unit/test_interpolate.py new file mode 100644 index 0000000..cfddaa5 --- /dev/null +++ b/test/unit/test_interpolate.py @@ -0,0 +1,38 @@ +# coding=utf-8 +from unittest import TestCase + +from earthdiagnostics.ocean.interpolate import Interpolate +from mock import Mock + + +class TestInterpolate(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.interpolate = Interpolate(self.data_manager, '20000101', 1, 1, 'domain', 'var', 'model_version') + + def test_generate_jobs(self): + jobs = Interpolate.generate_jobs(self.diags, ['interp', 'var']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], Interpolate(self.data_manager, '20010101', 0, 0, 'ocean', 'var', 'model_version')) + self.assertEqual(jobs[1], Interpolate(self.data_manager, '20010101', 0, 1, 'ocean', 'var', 'model_version')) + + jobs = Interpolate.generate_jobs(self.diags, ['interp', 'var', 'domain']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], Interpolate(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'model_version')) + self.assertEqual(jobs[1], Interpolate(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'model_version')) + + with self.assertRaises(Exception): + Interpolate.generate_jobs(self.diags, ['interp']) + + with self.assertRaises(Exception): + Interpolate.generate_jobs(self.diags, ['interp', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.interpolate), 'Interpolate Startdate: 20000101 Member: 1 Chunk: 1 ' + 'Variable: domain:var') diff --git a/test/unit/test_maxmoc.py b/test/unit/test_maxmoc.py new file mode 100644 index 0000000..e812290 --- /dev/null +++ b/test/unit/test_maxmoc.py @@ -0,0 +1,52 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from constants import Basins +from earthdiagnostics.ocean.maxmoc import MaxMoc +from mock import Mock + + +class TestMaxMoc(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.box = Box() + self.box.min_lat = 0 + self.box.max_lat = 0 + self.box.min_depth = 0 + self.box.max_depth = 0 + + self.maxmoc = MaxMoc(self.data_manager, '20000101', 1, 2000, Basins.Global, self.box) + + def test_generate_jobs(self): + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.startdates = ('20010101',) + self.diags.members = (0,) + self.diags.exp_manager.get_full_years.return_value = (2000, 2001) + + jobs = MaxMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], MaxMoc(self.data_manager, '20010101', 0, 2000, Basins.Global, self.box)) + self.assertEqual(jobs[1], MaxMoc(self.data_manager, '20010101', 0, 2001, Basins.Global, self.box)) + + jobs = MaxMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', 'atl']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], MaxMoc(self.data_manager, '20010101', 0, 2000, Basins.Atlantic, self.box)) + self.assertEqual(jobs[1], MaxMoc(self.data_manager, '20010101', 0, 2001, Basins.Atlantic, self.box)) + + self.diags.exp_manager.get_full_years.return_value = list() + jobs = MaxMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0']) + self.assertEqual(len(jobs), 0) + + with self.assertRaises(Exception): + MaxMoc.generate_jobs(self.diags, ['psi']) + + with self.assertRaises(Exception): + MaxMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.maxmoc), 'Max moc Startdate: 20000101 Member: 1 Year: 2000 ' + 'Box: 0N0 Basin: Global_Ocean') -- GitLab From dc0bcad705a9d0547b2604fcd85faed2d62eabfb Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 26 Aug 2016 16:18:58 +0200 Subject: [PATCH 179/268] Another natch of tests --- earthdiagnostics/ocean/interpolate.py | 2 +- earthdiagnostics/ocean/maxmoc.py | 1 - .../ocean/mixedlayerheatcontent.py | 3 ++ .../ocean/mixedlayersaltcontent.py | 3 ++ earthdiagnostics/ocean/moc.py | 3 ++ earthdiagnostics/ocean/siasiesiv.py | 4 +-- test/unit/__init__.py | 6 +++- test/unit/test_mixedlayerheatcontent.py | 29 +++++++++++++++++++ test/unit/test_mixedlayersaltcontent.py | 29 +++++++++++++++++++ test/unit/test_moc.py | 29 +++++++++++++++++++ test/unit/test_siasiesiv.py | 21 ++++++++++++++ 11 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 test/unit/test_mixedlayerheatcontent.py create mode 100644 test/unit/test_mixedlayersaltcontent.py create mode 100644 test/unit/test_moc.py create mode 100644 test/unit/test_siasiesiv.py diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index a9f74b2..4f67602 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -54,7 +54,7 @@ class Interpolate(Diagnostic): def __eq__(self, other): return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ - self.model_version == other.model_version and self.domain == other.domain and self.variable == other.variable + self.model_version == other.model_version and self.domain == other.domain and self.variable == other.variable def __str__(self): return 'Interpolate Startdate: {0} Member: {1} Chunk: {2} ' \ diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index cbcdeec..6b70bc3 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -54,7 +54,6 @@ class MaxMoc(Diagnostic): return self.startdate == other.startdate and self.member == other.member and self.year == other.year and \ self.box == other.box and self.basin == other.basin - @classmethod def generate_jobs(cls, diags, options): """ diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index 72d6243..f967e5f 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -37,6 +37,9 @@ class MixedLayerHeatContent(Diagnostic): self.required_vars = ['so', 'mlotst'] self.generated_vars = ['scvertsum'] + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk + def __str__(self): return 'Mixed layer heat content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 4b460fa..915c38c 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -39,6 +39,9 @@ class MixedLayerSaltContent(Diagnostic): return 'Mixed layer salt content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk + @classmethod def generate_jobs(cls, diags, options): """ diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index c51a0c3..76ff9ec 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -42,6 +42,9 @@ class Moc(Diagnostic): def __str__(self): return 'MOC Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk + @classmethod def generate_jobs(cls, diags, options): """ diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index c0e73b5..7f36ff0 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -29,7 +29,7 @@ class Siasiesiv(Diagnostic): e2t = None gphit = None - def __init__(self, data_manager, basin, startdate, member, chunk, mask): + def __init__(self, data_manager, startdate, member, chunk, basin, mask): """ :param data_manager: data management object :type data_manager: DataManager @@ -74,7 +74,7 @@ class Siasiesiv(Diagnostic): job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(Siasiesiv(diags.data_manager, basin, startdate, member, chunk, mask)) + job_list.append(Siasiesiv(diags.data_manager, startdate, member, chunk, basin, mask)) mesh_handler = Utils.openCdf('mesh_hgr.nc') Siasiesiv.e1t = np.asfortranarray(mesh_handler.variables['e1t'][0, :]) Siasiesiv.e2t = np.asfortranarray(mesh_handler.variables['e2t'][0, :]) diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 5f42083..f751ed5 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -15,4 +15,8 @@ from test_gyres import TestGyres from test_heatcontent import TestHeatContent from test_heatcontentlayer import TestHeatContentLayer from test_interpolate import TestInterpolate -from test_maxmoc import TestMaxMoc \ No newline at end of file +from test_maxmoc import TestMaxMoc +from test_mixedlayerheatcontent import TestMixedLayerHeatContent +from test_mixedlayersaltcontent import TestMixedLayerSaltContent +from test_moc import TestMoc +from test_siasiesiv import TestSiasiesiv diff --git a/test/unit/test_mixedlayerheatcontent.py b/test/unit/test_mixedlayerheatcontent.py new file mode 100644 index 0000000..35809b0 --- /dev/null +++ b/test/unit/test_mixedlayerheatcontent.py @@ -0,0 +1,29 @@ +# coding=utf-8 +from unittest import TestCase + +from earthdiagnostics.ocean.mixedlayerheatcontent import MixedLayerHeatContent +from mock import Mock + + +class TestMixedLayerHeatContent(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.mixed = MixedLayerHeatContent(self.data_manager, '20000101', 1, 1) + + def test_generate_jobs(self): + jobs = MixedLayerHeatContent.generate_jobs(self.diags, ['psi']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], MixedLayerHeatContent(self.data_manager, '20010101', 0, 0)) + self.assertEqual(jobs[1], MixedLayerHeatContent(self.data_manager, '20010101', 0, 1)) + + with self.assertRaises(Exception): + MixedLayerHeatContent.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.mixed), 'Mixed layer heat content Startdate: 20000101 Member: 1 Chunk: 1') diff --git a/test/unit/test_mixedlayersaltcontent.py b/test/unit/test_mixedlayersaltcontent.py new file mode 100644 index 0000000..2f89929 --- /dev/null +++ b/test/unit/test_mixedlayersaltcontent.py @@ -0,0 +1,29 @@ +# coding=utf-8 +from unittest import TestCase + +from earthdiagnostics.ocean.mixedlayersaltcontent import MixedLayerSaltContent +from mock import Mock + + +class TestMixedLayerSaltContent(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.mixed = MixedLayerSaltContent(self.data_manager, '20000101', 1, 1) + + def test_generate_jobs(self): + jobs = MixedLayerSaltContent.generate_jobs(self.diags, ['psi']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], MixedLayerSaltContent(self.data_manager, '20010101', 0, 0)) + self.assertEqual(jobs[1], MixedLayerSaltContent(self.data_manager, '20010101', 0, 1)) + + with self.assertRaises(Exception): + MixedLayerSaltContent.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.mixed), 'Mixed layer salt content Startdate: 20000101 Member: 1 Chunk: 1') diff --git a/test/unit/test_moc.py b/test/unit/test_moc.py new file mode 100644 index 0000000..fb081f9 --- /dev/null +++ b/test/unit/test_moc.py @@ -0,0 +1,29 @@ +# coding=utf-8 +from unittest import TestCase + +from earthdiagnostics.ocean.moc import Moc +from mock import Mock + + +class TestMoc(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.mixed = Moc(self.data_manager, '20000101', 1, 1) + + def test_generate_jobs(self): + jobs = Moc.generate_jobs(self.diags, ['psi']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], Moc(self.data_manager, '20010101', 0, 0)) + self.assertEqual(jobs[1], Moc(self.data_manager, '20010101', 0, 1)) + + with self.assertRaises(Exception): + Moc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.mixed), 'MOC Startdate: 20000101 Member: 1 Chunk: 1') diff --git a/test/unit/test_siasiesiv.py b/test/unit/test_siasiesiv.py new file mode 100644 index 0000000..6dcfc37 --- /dev/null +++ b/test/unit/test_siasiesiv.py @@ -0,0 +1,21 @@ +# coding=utf-8 +from unittest import TestCase + +from constants import Basins +from earthdiagnostics.ocean.siasiesiv import Siasiesiv +from mock import Mock + + +class TestSiasiesiv(TestCase): + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.mask = Mock() + self.psi = Siasiesiv(self.data_manager, '20000101', 1, 1, Basins.Global, self.mask) + + def test_str(self): + self.assertEquals(str(self.psi), 'Siasiesiv Startdate: 20000101 Member: 1 Chunk: 1 Basin: Global_Ocean') -- GitLab From d057f86a64e5b0a2c44e534b102c8ccaba1977a8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 26 Aug 2016 16:26:56 +0200 Subject: [PATCH 180/268] Added more tests. Minor bug fixed on verticalmean --- earthdiagnostics/ocean/verticalmean.py | 6 +++- earthdiagnostics/ocean/verticalmeanmeters.py | 4 +++ test/unit/__init__.py | 2 ++ test/unit/test_verticalmean.py | 38 ++++++++++++++++++++ test/unit/test_verticalmeanmeters.py | 38 ++++++++++++++++++++ 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 test/unit/test_verticalmean.py create mode 100644 test/unit/test_verticalmeanmeters.py diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 9398842..3c5300c 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -44,6 +44,10 @@ class VerticalMean(Diagnostic): self.required_vars = [variable] self.generated_vars = [variable + 'vmean'] + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.box == other.box and self.variable == other.variable + def __str__(self): return 'Vertical mean Startdate: {0} Member: {1} Chunk: {2} Variable: {3} ' \ 'Box: {4}'.format(self.startdate, self.member, self.chunk, self.variable, self.box) @@ -66,7 +70,7 @@ class VerticalMean(Diagnostic): raise Exception('You must specify between one and three parameters for the vertical mean') variable = options[1] - box = Box(True) + box = Box() if num_options >= 2: box.min_depth = float(options[2]) if num_options >= 2: diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 911bc1f..77ec989 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -43,6 +43,10 @@ class VerticalMeanMeters(Diagnostic): self.required_vars = [variable] self.generated_vars = [variable + 'vmean'] + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.box == other.box and self.variable == other.variable + def __str__(self): return 'Vertical mean meters Startdate: {0} Member: {1} Chunk: {2} Variable: {3} ' \ 'Box: {4}'.format(self.startdate, self.member, self.chunk, self.variable, self.box) diff --git a/test/unit/__init__.py b/test/unit/__init__.py index f751ed5..af1dea0 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -20,3 +20,5 @@ from test_mixedlayerheatcontent import TestMixedLayerHeatContent from test_mixedlayersaltcontent import TestMixedLayerSaltContent from test_moc import TestMoc from test_siasiesiv import TestSiasiesiv +from test_verticalmean import TestVericalMean +from test_verticalmeanmeters import TestVerticalMeanMeters diff --git a/test/unit/test_verticalmean.py b/test/unit/test_verticalmean.py new file mode 100644 index 0000000..e653d02 --- /dev/null +++ b/test/unit/test_verticalmean.py @@ -0,0 +1,38 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from earthdiagnostics.ocean.verticalmean import VerticalMean +from mock import Mock + + +class TestVericalMean(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.box = Box() + self.box.min_depth = 0 + self.box.max_depth = 100 + + self.mixed = VerticalMean(self.data_manager, '20000101', 1, 1, 'var', self.box) + + def test_generate_jobs(self): + jobs = VerticalMean.generate_jobs(self.diags, ['psi', 'var', '0', '100']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], VerticalMean(self.data_manager, '20010101', 0, 0, 'var', self.box)) + self.assertEqual(jobs[1], VerticalMean(self.data_manager, '20010101', 0, 1, 'var', self.box)) + + with self.assertRaises(Exception): + VerticalMean.generate_jobs(self.diags, ['psi']) + + with self.assertRaises(Exception): + VerticalMean.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.mixed), 'Vertical mean Startdate: 20000101 Member: 1 Chunk: 1 Variable: var ' + 'Box: 0-100') diff --git a/test/unit/test_verticalmeanmeters.py b/test/unit/test_verticalmeanmeters.py new file mode 100644 index 0000000..8447c03 --- /dev/null +++ b/test/unit/test_verticalmeanmeters.py @@ -0,0 +1,38 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from earthdiagnostics.ocean.verticalmeanmeters import VerticalMeanMeters +from mock import Mock + + +class TestVerticalMeanMeters(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.box = Box(True) + self.box.min_depth = 0 + self.box.max_depth = 100 + + self.mixed = VerticalMeanMeters(self.data_manager, '20000101', 1, 1, 'var', self.box) + + def test_generate_jobs(self): + jobs = VerticalMeanMeters.generate_jobs(self.diags, ['psi', 'var', '0', '100']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], VerticalMeanMeters(self.data_manager, '20010101', 0, 0, 'var', self.box)) + self.assertEqual(jobs[1], VerticalMeanMeters(self.data_manager, '20010101', 0, 1, 'var', self.box)) + + with self.assertRaises(Exception): + VerticalMeanMeters.generate_jobs(self.diags, ['psi']) + + with self.assertRaises(Exception): + VerticalMeanMeters.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.mixed), 'Vertical mean meters Startdate: 20000101 Member: 1 Chunk: 1 Variable: var ' + 'Box: 0m-100m') -- GitLab From be3f4008b6cd741ce0ea15e79c7626a569a66de1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 26 Aug 2016 16:31:29 +0200 Subject: [PATCH 181/268] Improved coverage for verticalmean and verticalmeanmeters. Also fixed small bug on both --- earthdiagnostics/ocean/verticalmean.py | 2 +- earthdiagnostics/ocean/verticalmeanmeters.py | 2 +- test/unit/test_verticalmean.py | 12 ++++++++++++ test/unit/test_verticalmeanmeters.py | 12 ++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 3c5300c..1d48383 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -73,7 +73,7 @@ class VerticalMean(Diagnostic): box = Box() if num_options >= 2: box.min_depth = float(options[2]) - if num_options >= 2: + if num_options >= 3: box.max_depth = float(options[3]) job_list = list() diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index 77ec989..adc7e3f 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -71,7 +71,7 @@ class VerticalMeanMeters(Diagnostic): box = Box(True) if num_options >= 2: box.min_depth = float(options[2]) - if num_options >= 2: + if num_options >= 3: box.max_depth = float(options[3]) job_list = list() diff --git a/test/unit/test_verticalmean.py b/test/unit/test_verticalmean.py index e653d02..d55b033 100644 --- a/test/unit/test_verticalmean.py +++ b/test/unit/test_verticalmean.py @@ -27,6 +27,18 @@ class TestVericalMean(TestCase): self.assertEqual(jobs[0], VerticalMean(self.data_manager, '20010101', 0, 0, 'var', self.box)) self.assertEqual(jobs[1], VerticalMean(self.data_manager, '20010101', 0, 1, 'var', self.box)) + jobs = VerticalMean.generate_jobs(self.diags, ['psi', 'var', '0']) + box = Box() + box.min_depth = 0 + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], VerticalMean(self.data_manager, '20010101', 0, 0, 'var', box)) + self.assertEqual(jobs[1], VerticalMean(self.data_manager, '20010101', 0, 1, 'var', box)) + + jobs = VerticalMean.generate_jobs(self.diags, ['psi', 'var']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], VerticalMean(self.data_manager, '20010101', 0, 0, 'var', Box())) + self.assertEqual(jobs[1], VerticalMean(self.data_manager, '20010101', 0, 1, 'var', Box())) + with self.assertRaises(Exception): VerticalMean.generate_jobs(self.diags, ['psi']) diff --git a/test/unit/test_verticalmeanmeters.py b/test/unit/test_verticalmeanmeters.py index 8447c03..076f1b2 100644 --- a/test/unit/test_verticalmeanmeters.py +++ b/test/unit/test_verticalmeanmeters.py @@ -27,6 +27,18 @@ class TestVerticalMeanMeters(TestCase): self.assertEqual(jobs[0], VerticalMeanMeters(self.data_manager, '20010101', 0, 0, 'var', self.box)) self.assertEqual(jobs[1], VerticalMeanMeters(self.data_manager, '20010101', 0, 1, 'var', self.box)) + jobs = VerticalMeanMeters.generate_jobs(self.diags, ['psi', 'var', '0']) + box = Box(True) + box.min_depth = 0 + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], VerticalMeanMeters(self.data_manager, '20010101', 0, 0, 'var', box)) + self.assertEqual(jobs[1], VerticalMeanMeters(self.data_manager, '20010101', 0, 1, 'var', box)) + + jobs = VerticalMeanMeters.generate_jobs(self.diags, ['psi', 'var']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], VerticalMeanMeters(self.data_manager, '20010101', 0, 0, 'var', Box(True))) + self.assertEqual(jobs[1], VerticalMeanMeters(self.data_manager, '20010101', 0, 1, 'var', Box(True))) + with self.assertRaises(Exception): VerticalMeanMeters.generate_jobs(self.diags, ['psi']) -- GitLab From bba3b1d203cf904a65cc061ae593afd1916ad3bf Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 26 Aug 2016 16:48:53 +0200 Subject: [PATCH 182/268] More tests --- earthdiagnostics/general/monthlymean.py | 9 +++-- earthdiagnostics/general/rewrite.py | 8 +++-- earthdiagnostics/ocean/interpolate.py | 3 +- test/unit/__init__.py | 4 ++- test/unit/test_monthlymean.py | 44 +++++++++++++++++++++++++ test/unit/test_rewrite.py | 39 ++++++++++++++++++++++ test/unit/test_verticalmean.py | 2 +- 7 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 test/unit/test_monthlymean.py create mode 100644 test/unit/test_rewrite.py diff --git a/earthdiagnostics/general/monthlymean.py b/earthdiagnostics/general/monthlymean.py index a9d771a..70523df 100644 --- a/earthdiagnostics/general/monthlymean.py +++ b/earthdiagnostics/general/monthlymean.py @@ -32,7 +32,7 @@ class MonthlyMean(Diagnostic): alias = 'monmean' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, variable, domain, frequency): + def __init__(self, data_manager, startdate, member, chunk, domain, variable, frequency): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member @@ -45,6 +45,10 @@ class MonthlyMean(Diagnostic): return 'Calculate monthly mean Startdate: {0} Member: {1} Chunk: {2} ' \ 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.domain == other.domain and self.variable == other.variable and self.frequency == other.frequency + @classmethod def generate_jobs(cls, diags, options): """ @@ -70,8 +74,7 @@ class MonthlyMean(Diagnostic): job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(MonthlyMean(diags.data_manager, startdate, member, chunk, - variable, domain, frequency)) + job_list.append(MonthlyMean(diags.data_manager, startdate, member, chunk, domain, variable, frequency)) return job_list def compute(self): diff --git a/earthdiagnostics/general/rewrite.py b/earthdiagnostics/general/rewrite.py index 6833b8a..5425927 100644 --- a/earthdiagnostics/general/rewrite.py +++ b/earthdiagnostics/general/rewrite.py @@ -28,7 +28,7 @@ class Rewrite(Diagnostic): alias = 'rewrite' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, variable, domain): + def __init__(self, data_manager, startdate, member, chunk, domain, variable): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member @@ -40,6 +40,10 @@ class Rewrite(Diagnostic): return 'Rewrites output Startdate: {0} Member: {1} Chunk: {2} ' \ 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.domain == other.domain and self.variable == other.variable + @classmethod def generate_jobs(cls, diags, options): """ @@ -60,7 +64,7 @@ class Rewrite(Diagnostic): domain = options[2] job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(Rewrite(diags.data_manager, startdate, member, chunk, variable, domain)) + job_list.append(Rewrite(diags.data_manager, startdate, member, chunk, domain, variable)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 4f67602..cbb4d2c 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -54,7 +54,8 @@ class Interpolate(Diagnostic): def __eq__(self, other): return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ - self.model_version == other.model_version and self.domain == other.domain and self.variable == other.variable + self.model_version == other.model_version and self.domain == other.domain and \ + self.variable == other.variable def __str__(self): return 'Interpolate Startdate: {0} Member: {1} Chunk: {2} ' \ diff --git a/test/unit/__init__.py b/test/unit/__init__.py index af1dea0..1b0573f 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -20,5 +20,7 @@ from test_mixedlayerheatcontent import TestMixedLayerHeatContent from test_mixedlayersaltcontent import TestMixedLayerSaltContent from test_moc import TestMoc from test_siasiesiv import TestSiasiesiv -from test_verticalmean import TestVericalMean +from test_verticalmean import TestVerticalMean from test_verticalmeanmeters import TestVerticalMeanMeters +from test_monthlymean import TestMonthlyMean +from test_rewrite import TestRewrite diff --git a/test/unit/test_monthlymean.py b/test/unit/test_monthlymean.py new file mode 100644 index 0000000..edfbbea --- /dev/null +++ b/test/unit/test_monthlymean.py @@ -0,0 +1,44 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from earthdiagnostics.general.monthlymean import MonthlyMean +from mock import Mock + + +class TestMonthlyMean(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.box = Box() + self.box.min_depth = 0 + self.box.max_depth = 100 + + self.mixed = MonthlyMean(self.data_manager, '20000101', 1, 1, 'domain', 'var', 'freq') + + def test_generate_jobs(self): + + jobs = MonthlyMean.generate_jobs(self.diags, ['psi', 'var', 'domain']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], MonthlyMean(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'day')) + self.assertEqual(jobs[1], MonthlyMean(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'day')) + + jobs = MonthlyMean.generate_jobs(self.diags, ['psi', 'var', 'domain', 'freq']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], MonthlyMean(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'freq')) + self.assertEqual(jobs[1], MonthlyMean(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'freq')) + + with self.assertRaises(Exception): + MonthlyMean.generate_jobs(self.diags, ['psi']) + + with self.assertRaises(Exception): + MonthlyMean.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.mixed), 'Calculate monthly mean Startdate: 20000101 Member: 1 Chunk: 1 ' + 'Variable: domain:var') diff --git a/test/unit/test_rewrite.py b/test/unit/test_rewrite.py new file mode 100644 index 0000000..bf15f2f --- /dev/null +++ b/test/unit/test_rewrite.py @@ -0,0 +1,39 @@ +# coding=utf-8 +from unittest import TestCase + +from box import Box +from earthdiagnostics.general.rewrite import Rewrite +from mock import Mock + + +class TestRewrite(TestCase): + + def setUp(self): + self.data_manager = Mock() + + self.diags = Mock() + self.diags.model_version = 'model_version' + self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + + self.box = Box() + self.box.min_depth = 0 + self.box.max_depth = 100 + + self.mixed = Rewrite(self.data_manager, '20000101', 1, 1, 'domain', 'var') + + def test_generate_jobs(self): + + jobs = Rewrite.generate_jobs(self.diags, ['psi', 'var', 'domain']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], Rewrite(self.data_manager, '20010101', 0, 0, 'domain', 'var')) + self.assertEqual(jobs[1], Rewrite(self.data_manager, '20010101', 0, 1, 'domain', 'var')) + + with self.assertRaises(Exception): + Rewrite.generate_jobs(self.diags, ['psi']) + + with self.assertRaises(Exception): + Rewrite.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) + + def test_str(self): + self.assertEquals(str(self.mixed), 'Rewrites output Startdate: 20000101 Member: 1 Chunk: 1 ' + 'Variable: domain:var') diff --git a/test/unit/test_verticalmean.py b/test/unit/test_verticalmean.py index d55b033..abddd4b 100644 --- a/test/unit/test_verticalmean.py +++ b/test/unit/test_verticalmean.py @@ -6,7 +6,7 @@ from earthdiagnostics.ocean.verticalmean import VerticalMean from mock import Mock -class TestVericalMean(TestCase): +class TestVerticalMean(TestCase): def setUp(self): self.data_manager = Mock() -- GitLab From 7dfb40e4cd9b31119d86012f507f399478dac477 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 29 Aug 2016 11:17:24 +0200 Subject: [PATCH 183/268] Added test for __repr__ in Diagnostic --- test/unit/test_diagnostic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/unit/test_diagnostic.py b/test/unit/test_diagnostic.py index 3804844..117e8e2 100644 --- a/test/unit/test_diagnostic.py +++ b/test/unit/test_diagnostic.py @@ -43,4 +43,6 @@ class TestDiagnostic(TestCase): def test_str(self): self.assertEquals('Developer must override base class __str__ method', str(self.diagnostic)) + def test_repr(self): + self.assertEquals(self.diagnostic.__repr__(), str(self.diagnostic)) -- GitLab From d1157ac83a15767a9e3d2c1777fe06e387d05c2d Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 30 Aug 2016 17:38:04 +0200 Subject: [PATCH 184/268] First version of setup.py --- VERSION | 2 +- setup.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 setup.py diff --git a/VERSION b/VERSION index 09fb39d..1129dfd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b5 +3.0.0b7 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..c096a5b --- /dev/null +++ b/setup.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# coding=utf-8 + +from os import path +from setuptools import setup +from setuptools import find_packages + +here = path.abspath(path.dirname(__file__)) + +# Get the version number from the relevant file +with open(path.join(here, 'VERSION')) as f: + version = f.read().strip() + +setup( + name='earthdiagnostics', + license='GNU GPL v3', + platforms=['GNU/Linux Debian'], + version=version, + description='EarthDiagnostics', + author='BSC-CNS Earth Sciences Department', + author_email='javier.vegas@bsc.es', + url='http://www.bsc.es/projects/earthscience/autosubmit/', + keywords=['climate', 'weather', 'diagnostic'], + install_requires=['numpy', 'netCDF4', 'autosubmit', 'cdo', 'pygrib', 'nco', 'cfunits>=1.1.4', ], + packages=find_packages(), + include_package_data=True, + package_data={'earthdiagnostics': [ + 'earthdiagnostics/conversions.csv', + 'earthdiagnostics/cmor_table.csv', + 'earthdiagnostics/diags.conf', + 'README', + 'VERSION', + 'EarthDiagnostics.pdf' + ] + }, +) -- GitLab From 719757a58ca636cc8be97fbb0db9b521d7b06d2b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 30 Aug 2016 18:05:16 +0200 Subject: [PATCH 185/268] Adapted code to work with cfunits 1.1.4 --- earthdiagnostics/datamanager.py | 43 +++++++++++++++++++++------------ earthdiagnostics/diags.conf | 5 ++-- earthdiagnostics/utils.py | 2 +- test/unit/__init__.py | 2 +- test/unit/test_data_manager.py | 34 +++++++++++++++++++++++++- 5 files changed, 66 insertions(+), 20 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 5a43c2b..dc14e70 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -5,13 +5,12 @@ import shutil import threading import uuid import pygrib -from cf_units import Unit +from cfunits import Units from datetime import datetime import netCDF4 import numpy as np import os -import stat from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day, add_months, \ date2str @@ -186,6 +185,7 @@ class DataManager(object): mes2 = grib_handler.readline() nfrp = mes2.analDate - mes1.analDate nfrp = int(nfrp.total_seconds() / 3600) + self.nfrp = nfrp grib_handler.close() prev_gribfile = os.path.join(self.scratch_dir, @@ -892,15 +892,31 @@ class DataManager(object): if cmor_var.units: if 'units' in var_handler.ncattrs(): + if var_handler.units == 'PSU': + var_handler.units = 'psu' + if var_handler.units == 'C' and cmor_var.units == 'K': + var_handler.units = 'deg_C' if cmor_var.units != var_handler.units: - new_unit = Unit(cmor_var.units) - old_unit = Unit(var_handler.units) - var_handler[:] = new_unit.convert(var_handler[:], old_unit, inplace=True) - - if 'valid_min' in var_handler.ncattrs(): - var_handler.valid_min = new_unit.convert(float(var_handler.valid_min), old_unit) - if 'valid_max' in var_handler.ncattrs(): - var_handler.valid_max = new_unit.convert(float(var_handler.valid_max), old_unit) + try: + new_unit = Units(cmor_var.units) + old_unit = Units(var_handler.units) + + var_handler[:] = Units.conform(var_handler[:], old_unit, new_unit, inplace=True) + + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = Units.conform(float(var_handler.valid_min), old_unit, new_unit, + inplace=True) + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = Units.conform(float(var_handler.valid_max), old_unit, new_unit, + inplace=True) + except ValueError: + factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, + cmor_var.units) + var_handler[:] = var_handler[:] * factor + offset + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = float(var_handler.valid_min) * factor + offset + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = float(var_handler.valid_max) * factor + offset var_handler.units = cmor_var.units handler.sync() @@ -944,8 +960,6 @@ class DataManager(object): Utils.rename_variables(filetosend, variables, False, True) Utils.move_file(filetosend, filepath) - st = os.stat(filepath) - os.chmod(filepath, st.st_mode | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) self._create_link(domain, filepath, frequency, var) def _create_link(self, domain, filepath, frequency, var): @@ -959,7 +973,7 @@ class DataManager(object): else: variable_folder = '{0}_f{1}h'.format(var, self.nfrp) - link_path = os.path.join(self.data_dir, self.expid, freq_str, domain.lower(), variable_folder) + link_path = os.path.join(self.data_dir, self.expid, freq_str, variable_folder) if not os.path.exists(link_path): # This can be a race condition @@ -1206,8 +1220,7 @@ class UnitConversion(object): conversion = cls._dict_conversions[(unit, new_unit)] return conversion.factor, conversion.offset elif (new_unit, unit) in cls._dict_conversions: - conversion = cls._dict_conversions[(unit, new_unit)] + conversion = cls._dict_conversions[(new_unit, unit)] return 1 / conversion.factor, -conversion.offset else: return None, None - diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 2407c20..75de6f1 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -7,7 +7,7 @@ DATA_DIR = /esnas/exp/ecearth/ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below) -DIAGS = 3dsal +DIAGS = rewrite,tas,atmos # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -19,7 +19,7 @@ RESTORE_MESHES = False [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = True +FORCE = False # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True @@ -39,6 +39,7 @@ INSTITUTE = BSC MODEL = EC-EARTH # Model version MODEL_VERSION =Ec3.2_O1L75 +NFRP = 6 # For those who use Autosubmit, this no need documentation # For those who not, EXPID is the unique identifier of the experiment. diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 515c61d..4ef7fd7 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -141,7 +141,7 @@ class Utils(object): while hash_original != hash_destiny: if retrials == 0: raise Exception('Can not move {0} to {1}'.format(source, destiny)) - shutil.copy(source, destiny) + shutil.copyfile(source, destiny) hash_destiny = Utils.get_file_hash(destiny) os.remove(source) diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 1b0573f..ea91cd6 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -1,5 +1,5 @@ # coding=utf-8 -from test_data_manager import TestDataManager, TestVariable +from test_data_manager import TestDataManager, TestVariable, TestConversion from test_constants import TestBasin, TestBasins from test_experiment_manager import TestExperimentManager from test_box import TestBox diff --git a/test/unit/test_data_manager.py b/test/unit/test_data_manager.py index 074b628..6a1b3a6 100644 --- a/test/unit/test_data_manager.py +++ b/test/unit/test_data_manager.py @@ -2,7 +2,7 @@ from unittest import TestCase -from earthdiagnostics.datamanager import DataManager, Variable +from earthdiagnostics.datamanager import DataManager, Variable, UnitConversion from experimentmanager import ExperimentManager from datetime import date @@ -49,3 +49,35 @@ class TestVariable(TestCase): Variable._dict_variables['var'] = variable self.assertIs(Variable.get_variable('var'), variable) self.assertIsNone(Variable.get_variable('novar')) + + +class TestConversion(TestCase): + + def test__init(self): + conversion = UnitConversion('km', 'm', 1000, 0) + self.assertEqual(conversion.source, 'km') + self.assertEqual(conversion.destiny, 'm') + self.assertEqual(conversion.factor, 1000) + self.assertEqual(conversion.offset, 0) + + def test_add_conversion(self): + UnitConversion._dict_conversions = dict() + conversion = UnitConversion('km', 'm', 1000, 0) + UnitConversion.add_conversion(conversion) + self.assertIs(UnitConversion._dict_conversions[('km', 'm')], conversion) + UnitConversion._dict_conversions = dict() + + def test_get_factor_offset(self): + UnitConversion._dict_conversions = dict() + conversion = UnitConversion('km', 'm', 1000, 0) + UnitConversion.add_conversion(conversion) + self.assertEqual(UnitConversion.get_conversion_factor_offset('km', 'm'), (1000, 0)) + self.assertEqual(UnitConversion.get_conversion_factor_offset('m', 'km'), (1 / 1000.0, 0)) + self.assertEqual(UnitConversion.get_conversion_factor_offset('1e3 m', 'km'), (1, 0)) + self.assertEqual(UnitConversion.get_conversion_factor_offset('10^3 m', 'km'), (1, 0)) + self.assertEqual(UnitConversion.get_conversion_factor_offset('km', '1e3 m'), (1, 0)) + self.assertEqual(UnitConversion.get_conversion_factor_offset('km', '10^3 m'), (1, 0)) + self.assertEqual(UnitConversion.get_conversion_factor_offset('m', 'm'), (1, 0)) + self.assertEqual(UnitConversion.get_conversion_factor_offset('m²', 'km'), (None, None)) + + UnitConversion._dict_conversions = dict() -- GitLab From a54b8e6e6161196cb45feb434d613a894d12a47a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 1 Sep 2016 15:37:15 +0200 Subject: [PATCH 186/268] Refactored configuration. Now atmos variables and levels to CMORize are selected in conf file --- earthdiagnostics/config.py | 216 ++++++++++++++ earthdiagnostics/datamanager.py | 413 ++++++++++---------------- earthdiagnostics/diags.conf | 9 +- earthdiagnostics/diags.py | 136 ++------- earthdiagnostics/experimentmanager.py | 112 ------- setup.py | 2 +- test/unit/__init__.py | 3 +- test/unit/test_data_manager.py | 40 ++- test/unit/test_experiment_manager.py | 68 ++--- 9 files changed, 458 insertions(+), 541 deletions(-) create mode 100644 earthdiagnostics/config.py delete mode 100644 earthdiagnostics/experimentmanager.py diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py new file mode 100644 index 0000000..4d010a3 --- /dev/null +++ b/earthdiagnostics/config.py @@ -0,0 +1,216 @@ +# coding=utf-8 +import os + +from autosubmit.config.log import Log +from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date + +from earthdiagnostics.parser import Parser + + +class Config(object): + + def __init__(self, path): + parser = Parser() + parser.optionxform = str + parser.read(path) + + # Read diags config + self.scratch_dir = parser.get_option('DIAGNOSTICS', 'SCRATCH_DIR') + self.data_dir = parser.get_option('DIAGNOSTICS', 'DATA_DIR') + self.con_files = parser.get_option('DIAGNOSTICS', 'CON_FILES') + self.diags = parser.get_option('DIAGNOSTICS', 'DIAGS').lower() + self.frequency = parser.get_option('DIAGNOSTICS', 'FREQUENCY') + self.cdftools_path = parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') + self.max_cores = parser.get_int_option('DIAGNOSTICS', 'MAX_CORES', 100000) + self.restore_meshes = parser.get_bool_option('DIAGNOSTICS', 'RESTORE_MESHES', False) + + # Read experiment config + self.experiment = ExperimentConfig(parser) + + # Read aliases + self._aliases = dict() + if parser.has_section('ALIAS'): + for option in parser.options('ALIAS'): + self._aliases[option.lower()] = parser.get_option('ALIAS', option).lower().split() + Log.debug('Preparing command list') + commands = self.diags.split() + self._real_commands = list() + for command in commands: + if command in self._aliases: + added_commands = self._aliases[command] + Log.info('Changing alias {0} for {1}', command, ' '.join(added_commands)) + for add_command in added_commands: + self._real_commands.append(add_command) + else: + self._real_commands.append(command) + Log.debug('Command list ready ') + + self.scratch_dir = os.path.join(self.scratch_dir, 'diags', self.experiment.expid) + + self.cmor = CMORConfig(parser) + + def get_commands(self): + return self._real_commands + + +class CMORConfig(object): + + def __init__(self, parser): + self.force = parser.get_bool_option('CMOR', 'FORCE', False) + self.ocean = parser.get_bool_option('CMOR', 'OCEAN_FILES', True) + self.atmosphere = parser.get_bool_option('CMOR', 'ATMOSPHERE_FILES', True) + self.associated_experiment = parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', 'to be filled') + self.associated_model = parser.get_option('CMOR', 'ASSOCIATED_MODEL', 'to be filled') + self.initialization_description = parser.get_option('CMOR', 'INITIALIZATION_DESCRIPTION', 'to be filled') + self.initialization_method = parser.get_option('CMOR', 'INITIALIZATION_METHOD', '1') + self.physics_description = parser.get_option('CMOR', 'PHYSICS_DESCRIPTION', 'to be filled') + self.physics_version = parser.get_option('CMOR', 'PHYSICS_VERSION', '1') + self.source = parser.get_option('CMOR', 'SOURCE', 'to be filled') + self.add_name = parser.get_bool_option('CMOR', 'ADD_NAME') + self.add_startdate = parser.get_bool_option('CMOR', 'ADD_STARTDATE') + + self._var_hourly = self._parse_variables(parser.get_option('CMOR', 'ATMOS_HOURLY_VARS', '')) + self._var_daily = self._parse_variables(parser.get_option('CMOR', 'ATMOS_DAILY_VARS', '')) + self._var_monthly = self._parse_variables(parser.get_option('CMOR', 'ATMOS_MONTHLY_VARS', '')) + + def _parse_variables(self, raw_string): + variables = dict() + if raw_string: + splitted = raw_string.split(',') + for var_section in splitted: + splitted_var = var_section.split(':') + if len(splitted_var) == 1: + levels = None + else: + levels = ','.join(map(str, CMORConfig._parse_levels(splitted_var[1:]))) + variables[int(splitted_var[0])] = levels + return variables + + @staticmethod + def _parse_levels(levels_splitted): + if len(levels_splitted) == 1: + return map(int, levels_splitted[0].split('-')) + start = int(levels_splitted[0]) + end = int(levels_splitted[1]) + if len(levels_splitted) == 3: + step = int(levels_splitted[2]) + else: + step = 1 + return range(start, end, step) + + +class ExperimentConfig(object): + """ + Encapsulates all chunk related tasks + + :param parser: parser for the config file + :type parser: Parser + """ + + def __init__(self, parser): + self.institute = parser.get_option('EXPERIMENT', 'INSTITUTE') + self.expid = parser.get_option('EXPERIMENT', 'EXPID') + self.experiment_name = parser.get_option('EXPERIMENT', 'NAME', self.expid) + + members = list() + for member in parser.get_option('EXPERIMENT', 'MEMBERS').split(): + members.append(int(member)) + + member_digits = parser.get_int_option('EXPERIMENT', 'MEMBER_DIGITS', 1) + startdates = parser.get_option('EXPERIMENT', 'STARTDATES').split() + chunk_size = parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') + chunks = parser.get_int_option('EXPERIMENT', 'CHUNKS') + calendar = parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') + self.model = parser.get_option('EXPERIMENT', 'MODEL') + self.nfrp = parser.get_int_option('EXPERIMENT', 'NFRP') + self.model_version = parser.get_option('EXPERIMENT', 'MODEL_VERSION') + + self.startdates = startdates + self.members = members + self.num_chunks = chunks + self.chunk_size = chunk_size + self.member_digits = member_digits + self.calendar = calendar + + def get_chunk_list(self): + """ + Return a list with all the chunks + :return: List containing tuples of startdate, member and chunk + :rtype: tuple[str, int, int] + """ + chunk_list = list() + for startdate in self.startdates: + for member in self.members: + for chunk in range(1, self.num_chunks + 1): + chunk_list.append((startdate, member, chunk)) + return chunk_list + + def get_member_list(self): + """ + Return a list with all the members + :return: List containing tuples of startdate and member + :rtype: tuple[str, int, int] + """ + member_list = list() + for startdate in self.startdates: + for member in self.members: + member_list.append((startdate, member)) + return member_list + + def get_year_chunks(self, startdate, year): + """ + Get the list of chunks containing timesteps from the given year + :param startdate: startdate to use + :type startdate: str + :param year: reference year + :type year: int + :return: list of chunks containing data from the given year + :rtype: list[int] + """ + date = parse_date(startdate) + chunks = list() + for chunk in range(1, self.num_chunks + 1): + chunk_start = chunk_start_date(date, chunk, self.chunk_size, 'month', self.calendar) + if chunk_start.year > year: + break + elif chunk_start.year == year or chunk_end_date(chunk_start, self.chunk_size, 'month', + self.calendar).year == year: + chunks.append(chunk) + + return chunks + + def get_full_years(self, startdate): + """ + Returns the list of full years that are in the given startdate + :param startdate: startdate to use + :type startdate: str + :return: list of full years + :rtype: list[int] + """ + chunks_per_year = 12 / self.chunk_size + date = parse_date(startdate) + first_january = 0 + first_year = date.year + if date.month != 1: + month = date.month + first_year += 1 + while month + self.chunk_size < 12: + month += self.chunk_size + first_january += 1 + + years = list() + for chunk in range(first_january, self.num_chunks - chunks_per_year, chunks_per_year): + years.append(first_year) + first_year += 1 + return years + + def get_member_str(self, member): + """ + Returns the member name for a given member number. + :param member: member's number + :type member: int + :return: member's name + :rtype: str + """ + return 'fc{0}'.format(str(member).zfill(self.member_digits)) + diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index dc14e70..ddcc8ca 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -23,53 +23,17 @@ class DataManager(object): """ Class to manage the data repositories - :param exp_manager: - :type exp_manager: ExperimentManager - :param institution: CMOR's institution name - :type institution: str - :param model: CMOR's model name - :type model: str - :param expid: experiment identifier - :type expid: str - :param datafolder: Folder containing the data - :type datafolder: str - :param frequency: default frequency - :type frequency: str - :param experiment_name: CMOR's experiment name - :type experiment_name: str - :param scratch_dir: path to scratch folder - :type scratch_dir: str - :param nfrp: sample frequency - :type nfrp: int - :param calendar: experiment's calendar - :type calendar: str + :param config: + :type config: Config """ - def __init__(self, exp_manager, institution, model, expid, datafolder, frequency, experiment_name, - scratch_dir, nfrp, calendar='standard'): - self.initialization_method = 1 - self.initialization_description = 'to be filled' - self.physics_version = 1 - self.physics_description = 'to be filled' - self.associated_model = 'to be filled' - self.source = 'to be filled' - self.associated_experiment = 'to be filled' - self.institution = institution - self.model = model - self.expid = expid - self.data_dir = datafolder - self.frequency = frequency - self.experiment_name = experiment_name - self.add_startdate = True - self.add_name = True - self.calendar = calendar - self.scratch_dir = scratch_dir - self.nfrp = nfrp - self.exp_manager = exp_manager + def __init__(self, config): + self.config = config + self.experiment = config.experiment Variable.load_variables() UnitConversion.load_conversions() # noinspection PyPep8Naming - def prepare_CMOR_files(self, force_rebuild, ocean, atmosphere): + def prepare_CMOR_files(self): """ Prepares the data to be used by the diagnostic. @@ -78,36 +42,30 @@ class DataManager(object): If CMOR data is available but packed, the procedure will unpack it. - :param atmosphere: activates atmosphere files cmorization - :type atmosphere: bool - :param ocean: activates ocean files cmorization - :type ocean: bool - :param force_rebuild: if True, forces the creation of the CMOR files - :type force_rebuild: bool :return: """ # Check if cmorized and convert if not created = False errors = list() - for startdate, member in self.exp_manager.get_member_list(): - member_str = self.exp_manager.get_member_str(member) - if force_rebuild or not self._is_cmorized(startdate, member): + for startdate, member in self.experiment.get_member_list(): + member_str = self.experiment.get_member_str(member) + if self.config.cmor.force or not self._is_cmorized(startdate, member): created = True Log.info('CMORizing startdate {0} member {1}', startdate, member_str) - if ocean: + if self.config.cmor.ocean: errors += self._unpack_ocean_files('MMO', startdate, member) errors += self._unpack_ocean_files('diags', startdate, member) - if not atmosphere: + if not self.config.cmor.atmosphere: continue - grb_path = os.path.join(self.data_dir, self.expid, 'original_files', startdate, + grb_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, member_str, 'outputs', '*.grb') gribfiles = glob.glob(grb_path) if len(gribfiles) == 0: tar_files = glob.glob( - os.path.join(self.data_dir, self.expid, 'original_files', startdate, member_str, 'outputs', - 'MMA*')) + os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, + member_str, 'outputs', 'MMA*')) tar_files.sort() count = 1 for tarfile in tar_files: @@ -124,8 +82,8 @@ class DataManager(object): Log.error('File {0} could not be unzipped.', error) return - for startdate, member in self.exp_manager.get_member_list(): - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles') + for startdate, member in self.experiment.get_member_list(): + member_path = os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles') Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) filepaths = glob.glob(os.path.join(member_path, '*.gz')) @@ -136,8 +94,8 @@ class DataManager(object): self._unpack_cmorfiles(filepaths, member_path) def _unpack_ocean_files(self, prefix, startdate, member): - tar_folder = os.path.join(self.data_dir, self.expid, 'original_files', startdate, - self.exp_manager.get_member_str(member), 'outputs', '{0}*'.format(prefix)) + tar_folder = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, + self.experiment.get_member_str(member), 'outputs', '{0}*'.format(prefix)) tar_files = glob.glob(tar_folder) tar_files.sort() errors = list() @@ -150,59 +108,41 @@ class DataManager(object): return errors def _get_grib_filename(self, grid, month): - return 'ICM{0}{1}+{2}.grb'.format(grid, self.expid, date2str(month)[:-2]) + return 'ICM{0}{1}+{2}.grb'.format(grid, self.experiment.expid, date2str(month)[:-2]) def _cmorize_grib(self, startdate, member): count = 1 nfrp = None chunk_start = parse_date(startdate) - member_str = self.exp_manager.get_member_str(member) - data_folder = os.path.join(self.data_dir, self.expid, 'original_files', startdate, member_str, 'outputs') + member_str = self.experiment.get_member_str(member) + data_folder = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, + member_str, 'outputs') while os.path.exists(os.path.join(data_folder, self._get_grib_filename('GG', chunk_start))): - chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') Log.info('CMORizing chunk {0}-{1}', date2str(chunk_start), date2str(chunk_end)) for grid in ('SH', 'GG'): Log.info('Processing {0} variables', grid) - for month in range(0, self.exp_manager.chunk_size): + for month in range(0, self.experiment.chunk_size): current_month = add_months(chunk_start, month, 'standard') original_gribfile = os.path.join(data_folder, self._get_grib_filename(grid, current_month)) Log.info('Processing month {1}', grid, date2str(current_month)) - gribfile = os.path.join(self.scratch_dir, os.path.basename(original_gribfile)) + gribfile = os.path.join(self.config.scratch_dir, os.path.basename(original_gribfile)) if not os.path.isfile(gribfile): Log.info('Copying file...', grid, date2str(current_month)) shutil.copy(original_gribfile, gribfile) if nfrp is None: - Log.info('Getting timestep...') - grib_handler = pygrib.open(gribfile) - mes1 = grib_handler.message(1) - mes2 = grib_handler.readline() - while mes2['name'] != mes1['name']: - mes2 = grib_handler.readline() - nfrp = mes2.analDate - mes1.analDate - nfrp = int(nfrp.total_seconds() / 3600) - self.nfrp = nfrp - grib_handler.close() - - prev_gribfile = os.path.join(self.scratch_dir, + nfrp = self._get_nfrp(gribfile) + + prev_gribfile = os.path.join(self.config.scratch_dir, self._get_grib_filename(grid, add_months(current_month, -1, 'standard'))) if os.path.exists(prev_gribfile): - Log.info('Merging data from different files...') - fd = open('rules_files', 'w') - fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(current_month)) - fd.close() - # get first timestep for each month from previous file (if possible) - if os.path.exists('ICM'): - os.remove('ICM') - Utils.execute_shell_command('grib_filter -o ICM rules_files ' - '{0} {1}'.format(grid, os.path.basename(prev_gribfile), gribfile)) - os.remove('rules_files') - os.remove(prev_gribfile) + self._merge_grib_files(current_month, gribfile, grid, prev_gribfile) full_file = 'ICM' else: full_file = gribfile @@ -220,7 +160,7 @@ class DataManager(object): output='{0}_228.128.nc'.format(gribfile)) if full_file == 'ICM': os.remove('ICM') - next_gribfile = os.path.join(self.scratch_dir, + next_gribfile = os.path.join(self.config.scratch_dir, self._get_grib_filename(grid, add_months(current_month, 1, 'standard'))) @@ -229,9 +169,9 @@ class DataManager(object): cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') - self._ungrib_6_hourly_vars(cdo_reftime, gribfile, current_month.month) - self._ungrib_daily_vars(cdo_reftime, gribfile, current_month.month, nfrp) - self._ungrib_monthly_files(cdo_reftime, gribfile, current_month.month, nfrp) + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, 'hour') + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, 'day') + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, 'mon') for splited_file in glob.glob('{0}_*.128.nc'.format(gribfile)): os.remove(splited_file) @@ -242,147 +182,97 @@ class DataManager(object): self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1m') self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1d') self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '6hr') - chunk_start = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') + chunk_start = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') @staticmethod - def _ungrib_6_hourly_vars(cdo_reftime, gribfile, month): - Log.info('Preparing 6-hourly variables') - var_codes = (129, 130, 131, 132, 151, 167, 168, 164, 165, 166, 129) - levels = ','.join(map(str, range(30000, 90000, 5000))) - for param in var_codes: - if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, param)): + def _merge_grib_files(current_month, gribfile, grid, prev_gribfile): + Log.info('Merging data from different files...') + fd = open('rules_files', 'w') + fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(current_month)) + fd.close() + # get first timestep for each month from previous file (if possible) + if os.path.exists('ICM'): + os.remove('ICM') + Utils.execute_shell_command('grib_filter -o ICM rules_files ' + '{0} {1}'.format(grid, os.path.basename(prev_gribfile), gribfile)) + os.remove('rules_files') + os.remove(prev_gribfile) + + def _get_nfrp(self, gribfile): + Log.info('Getting timestep...') + grib_handler = pygrib.open(gribfile) + mes1 = grib_handler.message(1) + mes2 = grib_handler.readline() + while mes2['name'] != mes1['name']: + mes2 = grib_handler.readline() + nfrp = mes2.analDate - mes1.analDate + nfrp = int(nfrp.total_seconds() / 3600) + self.nfrp = nfrp + grib_handler.close() + return nfrp + + def _ungrib_vars(self, cdo_reftime, gribfile, month, frequency): + Log.info('Preparing {0} variables'.format(frequency)) + var_codes = self.config.cmor.variables(frequency) + for var_code in var_codes: + if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, var_code)): continue new_units = None - if param == 129: - # geopotential - new_units = "m" - cdo_operator = "-divc,9.81 -sellevel,{1} -selmon,{0}".format(month, levels) - elif param == 129: - # upper air temperature - new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, levels) - elif param in (131, 132): - # upper air wind - new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, levels) - else: - # default, plain monthly mean - cdo_operator = "-selmon,{0}".format(month) - Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.nc ' - '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - h_var_file = '{0}_{1}_6hr.nc'.format(gribfile, param) - if new_units: - handler = Utils.openCdf(h_var_file) - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: - var.units = new_units - break - handler.close() - - @staticmethod - def _ungrib_daily_vars(cdo_reftime, gribfile, month, nfrp): - Log.info('Preparing daily variables') - var_codes = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) - for param in var_codes: - if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, param)): - continue - new_units = None - if param in (169, 177, 179): - # radiation - new_units = "W m-2" - cdo_operator = "-divc,{0} -daymean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param == 228: - # precipitation - new_units = "kg m-2 -s" - cdo_operator = "-mulc,1000 -divc,{0} -daymean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param == 201: - # maximum - cdo_operator = "-daymax -selmon,{1} -shifttime,-{0}hours".format(int(nfrp), month) - elif param == 202: - # minmimum - cdo_operator = "-daymin -selmon,{1} -shifttime,-{0}hours".format(int(nfrp), month) - elif param == 130: - # 850 hPa - cdo_operator = "-daymean -sellevel,85000 -selmon,{0}".format(month) - else: - # default, plain daily mean - cdo_operator = "-daymean -selmon,{0}".format(month) + cdo_operator = '-selmon, {0}'.format(month) - Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.nc ' - '{2}_{3}_1d.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - - daily_variable_file = '{0}_{1}_1d.nc'.format(gribfile, param) - if new_units: - handler = Utils.openCdf(daily_variable_file) - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: - var.units = new_units - break - handler.close() + if frequency == 'mon': + if var_code == 201: + cdo_operator = "-monmean -daymax {0}".format(cdo_operator) + elif var_code == 202: + cdo_operator = "-monmean -daymax {0}".format(cdo_operator) + else: + cdo_operator = "-monmean {0} ".format(cdo_operator) + elif frequency == 'day': + if var_code == 201: + cdo_operator = "-daymax {0} ".format(cdo_operator) + elif var_code == 202: + cdo_operator = "-daymin {0} ".format(cdo_operator) + else: + cdo_operator = "-daymean {0} ".format(cdo_operator) - @staticmethod - def _ungrib_monthly_files(cdo_reftime, gribfile, month, nfrp): - Log.info('Preparing monthly variables') + if var_code in (144, 146, 147, 169, 175, 176, 177, 179, 180, 181, 182, 201, 202, 205, 212, 228): + cdo_operator = '{0} -shifttime,-{1}hours'.format(cdo_operator, self.nfrp) - var_codes = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, - 177, 175, 212, 141, 180, 181, 179, 168, 243, 129, 130, 131, 132, 133) - for param in var_codes: - if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, param)): - continue - new_units = None - if param in (146, 147, 176, 169, 177, 175, 179, 212): - # radiation/heat + if var_code == 129: + # geopotential + new_units = "m" + cdo_operator = "-divc,9.81 {0}".format(cdo_operator) + elif var_code in (146, 147, 169, 175, 176, 177, 179, 212): + # radiation new_units = "W m-2" - cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param in (180, 181): + cdo_operator = "-divc,{0} {1}".format(self.nfrp * 3600, cdo_operator) + elif var_code in (180, 181): # momentum flux new_units = "N m-2" - cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param in (144, 228, 205, 182): + cdo_operator = "-divc,{0} {1}".format(self.nfrp * 3600, cdo_operator) + elif var_code in (144, 182, 205, 228): # precipitation/evaporation/runoff new_units = "kg m-2 s-1" - cdo_operator = "-mulc,1000 -divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param == 201: - # mean daily maximum - cdo_operator = "-monmean -daymax -selmon,{1} " \ - "-shifttime,-{0}hours".format(nfrp, month) - elif param == 202: - # mean daily minmimum - cdo_operator = "-monmean -daymin -selmon,{1} " \ - "-shifttime,-{0}hours".format(nfrp, month) - elif param in (130, 131, 132, 133): - # upper-air - cdo_operator = "-monmean -sellevel,5000,20000,50000,85000 " \ - "-selmon,{0}".format(month) - elif param == 129: - # upper-air geopotential - new_units = "m" - cdo_operator = "-divc,9.81 -timmean -sellevel,5000,20000,50000,85000 " \ - "-selmon,{0}".format(month) - else: - # default, plain monthly mean - cdo_operator = "-monmean -selmon,{0}".format(month) + cdo_operator = "-mulc,1000 -divc,{0}".format(self.nfrp * 3600) - Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' + levels = self.config.cmor.get_levels(frequency, var_code) + if levels: + cdo_operator = "{0} -sellevel,{1}".format(cdo_operator, levels) + + Utils.execute_shell_command('cdo -t ecmwf setreftime,{0}' '{1} {2}_{3}.128.nc ' - '{2}_{3}_1m.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - handler = Utils.openCdf('{0}_{1}_1m.nc'.format(gribfile, param)) + '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, + gribfile, var_code)) + h_var_file = '{0}_{1}_6hr.nc'.format(gribfile, var_code) if new_units: + handler = Utils.openCdf(h_var_file) for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: + if 'code' in var.ncattrs() and var.code == var_code: var.units = new_units break + handler.close() + var_name = None for key in handler.variables.keys(): if key + '_2' in handler.variables and key not in handler.dimensions: @@ -390,13 +280,13 @@ class DataManager(object): handler.close() if var_name is not None: - Utils.nco.ncks(input='{0}_{1}_1m.nc'.format(gribfile, param), - output='{0}_{1}_1m.nc'.format(gribfile, param), + Utils.nco.ncks(input='{0}_{1}_1m.nc'.format(gribfile, var_code), + output='{0}_{1}_1m.nc'.format(gribfile, var_code), options='-O -v {0}'.format(var_name)) def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, grid, frequency): merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) - files = glob.glob(os.path.join(self.scratch_dir, + files = glob.glob(os.path.join(self.config.scratch_dir, '{0}_*_{1}.nc'.format(self._get_grib_filename(grid, chunk_start), frequency))) for first_file in files: shutil.move(first_file, merged_file) @@ -409,6 +299,7 @@ class DataManager(object): self._cmorize_nc_file(merged_file, member, startdate) def _unpack_cmorfiles(self, filepaths, member_path): + cmor = self.config.cmor threads = list() numthreads = Utils.available_cpu_count() for numthread in range(0, numthreads): @@ -426,27 +317,27 @@ class DataManager(object): t.start() for t in threads: t.join() - if self.experiment_name != self.model: - bad_path = os.path.join(member_path, self.institution, self.model, self.model) + if cmor.experiment_name != cmor.model: + bad_path = os.path.join(member_path, cmor.institution, cmor.model, cmor.model) for (dirpath, dirnames, filenames) in os.walk(bad_path, False): for filename in filenames: filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_output_'.format(self.model), - '_{0}_{1}_'.format(self.model, self.experiment_name)) + good = filepath.replace('_{0}_output_'.format(cmor.model), + '_{0}_{1}_'.format(cmor.model, cmor.experiment_name)) - good = good.replace('/{0}/{0}'.format(self.model), - '/{0}/{1}'.format(self.model, - self.experiment_name)) + good = good.replace('/{0}/{0}'.format(cmor.model), + '/{0}/{1}'.format(cmor.model, + cmor.experiment_name)) Utils.move_file(filepath, good) os.rmdir(dirpath) - good_dir = os.path.join(member_path, self.institution, self.model, self.experiment_name) + good_dir = os.path.join(member_path, cmor.institution, cmor.model, cmor.experiment_name) for sdate in os.listdir(good_dir): for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): for filename in filenames: filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_{1}_r'.format(self.model, self.experiment_name, sdate), - '_{0}_{1}_{2}_r'.format(self.model, self.experiment_name, sdate)) + good = filepath.replace('_{0}_{1}_r'.format(cmor.model, cmor.experiment_name, sdate), + '_{0}_{1}_{2}_r'.format(cmor.model, cmor.experiment_name, sdate)) if good != filepath: Log.info('Moving {0} to {1}'.format(filename, good)) Utils.move_file(filepath, good) @@ -454,7 +345,7 @@ class DataManager(object): def _unpack_tar(self, tarfile, startdate, member): Log.info('Unpacking {0}', tarfile) - scratch_dir = os.path.join(self.scratch_dir, 'CMOR') + scratch_dir = os.path.join(self.config.scratch_dir, 'CMOR') if os.path.exists(scratch_dir): shutil.rmtree(scratch_dir) @@ -495,7 +386,7 @@ class DataManager(object): Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filename, temp]) shutil.move(temp, filename) file_parts = os.path.basename(filename).split('_') - if self.expid in [file_parts[1], file_parts[2]]: + if self.experiment.expid in [file_parts[1], file_parts[2]]: frequency = 'm' else: frequency = file_parts[1][1].lower() @@ -582,10 +473,11 @@ class DataManager(object): else: region = var_cmor.basin.fullname - if file_parts[0] == self.expid or file_parts[0].startswith('ORCA') or file_parts[0] in ('MMA', 'MMO'): + if file_parts[0] == self.experiment.expid or file_parts[0].startswith('ORCA') or \ + file_parts[0] in ('MMA', 'MMO'): # Model output date_str = '{0}-{1}'.format(file_parts[2][0:6], file_parts[3][0:6]) - elif file_parts[1] == self.expid: + elif file_parts[1] == self.experiment.expid: # Files generated by the old version of the diagnostics date_str = '{0}-{1}'.format(file_parts[4][0:6], file_parts[5][0:6]) else: @@ -642,32 +534,33 @@ class DataManager(object): var[lt] = leadtime[lt].days def _add_common_attributes(self, frequency, handler, member, startdate): - handler.associated_experiment = self.associated_experiment - handler.batch = '{0}{1}'.format(self.institution, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) + cmor = self.config.cmor + handler.associated_experiment = cmor.associated_experiment + handler.batch = '{0}{1}'.format(cmor.institution, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ 'Javier Vegas-Regidor, javier.vegas@bsc.es ' handler.Conventions = 'CF-1.6' handler.creation_date = datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)') - handler.experiment_id = self.experiment_name + handler.experiment_id = cmor.experiment_name handler.forecast_reference_time = parse_date(startdate).strftime('%Y-%m-%d(T%H:%M:%SZ)') if frequency == 'd': handler.frequency = 'day' elif frequency == 'm': handler.frequency = 'mon' - handler.institute_id = self.institution - handler.institution = self.institution - handler.initialization_method = self.initialization_method - handler.initialization_description = self.initialization_description - handler.physics_version = self.physics_version - handler.physics_description = self.physics_description - handler.model_id = self.model - handler.associated_model = self.associated_model + handler.institute_id = cmor.institution + handler.institution = cmor.institution + handler.initialization_method = cmor.initialization_method + handler.initialization_description = cmor.initialization_description + handler.physics_version = cmor.physics_version + handler.physics_description = cmor.physics_description + handler.model_id = cmor.model + handler.associated_model = cmor.associated_model handler.project_id = 'SPECS' handler.realization = str(member + 1) - handler.source = self.source + handler.source = cmor.source handler.startdate = 'S{0}'.format(startdate) handler.tracking_id = str(uuid.uuid1()) - handler.title = "{0} model output prepared for SPECS {1}".format(self.model, self.experiment_name) + handler.title = "{0} model output prepared for SPECS {1}".format(cmor.model, cmor.experiment_name) @staticmethod def _unzip(files): @@ -712,7 +605,7 @@ class DataManager(object): """ if not frequency: - frequency = self.frequency + frequency = self.config.frequency domain_abbreviation = self.domain_abbreviation(domain, frequency) @@ -720,8 +613,8 @@ class DataManager(object): member_plus = str(member + 1) member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) - chunk_start = chunk_start_date(start, chunk, self.exp_manager.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') + chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') if box: @@ -733,8 +626,9 @@ class DataManager(object): var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) filepath = os.path.join(var_path, '{0}_{1}_{3}_{4}_S{5}_r{6}i1p1_' - '{7}-{8}.nc'.format(var, domain_abbreviation, frequency, self.model, - self.experiment_name, startdate, member_plus, + '{7}-{8}.nc'.format(var, domain_abbreviation, frequency, + self.config.cmor.model, + self.config.cmor.experiment_name, startdate, member_plus, "{0:04}{1:02}".format(chunk_start.year, chunk_start.month), "{0:04}{1:02}".format(chunk_end.year, @@ -752,8 +646,8 @@ class DataManager(object): :return: path to the startdate's CMOR folder :rtype: str """ - return os.path.join(self.data_dir, self.expid, 'cmorfiles', self.institution, self.model, - self.experiment_name, 'S' + startdate) + return os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles', self.config.cmor.institution, + self.config.cmor.model, self.config.cmor.experiment_name, 'S' + startdate) def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, rename_var=None, frequency=None, year=None, date_str=None): @@ -801,7 +695,7 @@ class DataManager(object): Utils.rename_variable(filetosend, original_var, var) if not frequency: - frequency = self.frequency + frequency = self.config.frequency domain_abreviattion = self.domain_abbreviation(domain, frequency) start = parse_date(startdate) @@ -809,8 +703,8 @@ class DataManager(object): member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) if chunk is not None: - chunk_start = chunk_start_date(start, chunk, self.exp_manager.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') + chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, @@ -831,8 +725,9 @@ class DataManager(object): var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' - '{6}.nc'.format(var, domain_abreviattion, self.model, - self.experiment_name, startdate, member_plus, time_bound)) + '{6}.nc'.format(var, domain_abreviattion, self.config.cmor.model, + self.config.cmor.experiment_name, + startdate, member_plus, time_bound)) if region: Utils.convert2netcdf4(filetosend) @@ -973,7 +868,7 @@ class DataManager(object): else: variable_folder = '{0}_f{1}h'.format(var, self.nfrp) - link_path = os.path.join(self.data_dir, self.expid, freq_str, variable_folder) + link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) if not os.path.exists(link_path): # This can be a race condition @@ -1035,7 +930,7 @@ class DataManager(object): :rtype: str """ chunk_files = list() - for chunk in self.exp_manager.get_year_chunks(startdate, year): + for chunk in self.experiment.get_year_chunks(startdate, year): chunk_files.append(self.get_file(domain, var, startdate, member, chunk, grid=grid, box=box)) if len(chunk_files) > 1: diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 75de6f1..baf396f 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -19,11 +19,14 @@ RESTORE_MESHES = False [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = False +FORCE = True # If true, CMORizes ocean files. Default = True -OCEAN_FILES = True +OCEAN_FILES = False # If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = True +ATMOS_HOURLY_VARS = 129:30000:90000:5000, 130, 131:30000:90000:5000, 132:30000:90000:5000, 151, 167, 168, 164, 165, 166 +ATMOS_DAILY_VARS = 167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130:85000 +ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, 177, 175, 212, 141, 180, 181, 179, 168, 243, 129:5000-20000-50000-85000, 130:5000-20000-50000-85000, 131:5000-20000-50000-85000, 132:5000-20000-50000-85000, 133:5000-20000-50000-85000 # The next bunch of parameters are used to provide metadata for the CMOR files # ASSOCIATED_EXPERIMENT = # INITIALIZATION_METHOD = 1 @@ -48,7 +51,7 @@ NFRP = 6 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment -EXPID = a09i +EXPID = a045 STARTDATES = 19900101 MEMBERS = 0 MEMBER_DIGITS = 1 diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 70fb608..d356755 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -11,16 +11,15 @@ import operator import os from autosubmit.date.chunk_date_lib import * +from config import Config from datamanager import DataManager from earthdiagnostics import cdftools from earthdiagnostics.utils import TempFile from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.ocean import * from earthdiagnostics.general import * -from experimentmanager import ExperimentManager from ocean import ConvectionSites, Gyres, Psi, MaxMoc, AreaMoc, Moc, VerticalMean, VerticalMeanMeters, Interpolate, \ AverageSection, CutSection, MixedLayerSaltContent, Siasiesiv -from parser import Parser from utils import Utils @@ -33,10 +32,10 @@ class Diags(object): """ def __init__(self, config_file): Log.debug('Initialising Diags') - self._read_config(config_file) + self.config = Config(config_file) - TempFile.scratch_folder = self.scratch_dir - cdftools.path = self.cdftools_path + TempFile.scratch_folder = self.config.scratch_dir + cdftools.path = self.config.cdftools_path self._create_dic_variables() self.time = dict() Log.debug('Diags ready') @@ -57,9 +56,9 @@ class Diags(object): Run the diagnostics """ Log.debug('Using netCDF version {0}', netCDF4.getlibversion()) - if not os.path.exists(self.scratch_dir): - os.makedirs(self.scratch_dir) - os.chdir(self.scratch_dir) + if not os.path.exists(self.config.scratch_dir): + os.makedirs(self.config.scratch_dir) + os.chdir(self.config.scratch_dir) self._prepare_mesh_files() @@ -83,13 +82,13 @@ class Diags(object): Diagnostic.register(Rewrite) parse_date('20000101') - - self.data_manager.prepare_CMOR_files(self.CMOR_force, self.CMOR_ocean, self.CMOR_atmosphere) + self.data_manager = DataManager(self.config) + self.data_manager.prepare_CMOR_files() # Run diagnostics Log.info('Running diagnostics') list_jobs = Queue.Queue() - for fulldiag in self._get_commands(): + for fulldiag in self.config.get_commands(): Log.info("Adding {0} to diagnostic list", fulldiag) diag_options = fulldiag.split(',') @@ -103,7 +102,7 @@ class Diags(object): time = datetime.datetime.now() Log.info("Starting to compute at {0}", time) - num_threads = min(Utils.available_cpu_count(), self.max_cores) + num_threads = min(Utils.available_cpu_count(), self.config.max_cores) Log.info('Using {0} threads', num_threads) threads = list() for num_thread in range(0, num_threads): @@ -134,8 +133,8 @@ class Diags(object): def clean(self): Log.info('Removing scratch folder...') - if os.path.exists(self.scratch_dir): - shutil.rmtree(self.scratch_dir) + if os.path.exists(self.config.scratch_dir): + shutil.rmtree(self.config.scratch_dir) Log.result('Scratch folder removed') def _run_jobs(self, queue, numthread): @@ -179,40 +178,29 @@ class Diags(object): Log.error('Job {0} could not be run', job) return - def _get_commands(self): - Log.debug('Preparing command list') - commands = self.diags.split() - real_commands = list() - for command in commands: - if command in self._aliases: - added_commands = self._aliases[command] - Log.info('Changing alias {0} for {1}', command, ' '.join(added_commands)) - for add_command in added_commands: - real_commands.append(add_command) - else: - real_commands.append(command) - Log.debug('Command list ready ') - return real_commands - def _prepare_mesh_files(self): Log.info('Copying mesh files') - self._copy_file(os.path.join(self.con_files, 'mesh_mask_nemo.{0}.nc'.format(self.model_version)), 'mesh_hgr.nc', - self.restore_meshes) + con_files = self.config.con_files + model_version = self.config.experiment.model_version + restore_meshes = self.config.restore_meshes + + self._copy_file(os.path.join(con_files, 'mesh_mask_nemo.{0}.nc'.format(model_version)), 'mesh_hgr.nc', + restore_meshes) self._link_file('mesh_hgr.nc', 'mesh_zgr.nc') self._link_file('mesh_hgr.nc', 'mask.nc') - self._copy_file(os.path.join(self.con_files, 'new_maskglo.{0}.nc'.format(self.model_version)), 'new_maskglo.nc', - self.restore_meshes) - self._copy_file(os.path.join(self.con_files, 'mask.regions.{0}.nc'.format(self.model_version)), - 'mask_regions.nc', self.restore_meshes) - self._copy_file(os.path.join(self.con_files, 'mask.regions.3d.{0}.nc'.format(self.model_version)), - 'mask_regions.3d.nc', self.restore_meshes) + self._copy_file(os.path.join(con_files, 'new_maskglo.{0}.nc'.format(model_version)), 'new_maskglo.nc', + restore_meshes) + self._copy_file(os.path.join(con_files, 'mask.regions.{0}.nc'.format(model_version)), + 'mask_regions.nc', restore_meshes) + self._copy_file(os.path.join(con_files, 'mask.regions.3d.{0}.nc'.format(model_version)), + 'mask_regions.3d.nc', restore_meshes) Log.result('Mesh files ready!') def _copy_file(self, source, destiny, force): if not os.path.exists(source): - Log.user_warning('File {0} is not available for {1}', destiny, self.model_version) + Log.user_warning('File {0} is not available for {1}', destiny, self.config.experiment.model_version) return if not force and os.path.exists(destiny): @@ -227,7 +215,7 @@ class Diags(object): def _link_file(self, source, destiny): if not os.path.exists(source): - Log.user_warning('File {0} is not available for {1}', destiny, self.model_version) + Log.user_warning('File {0} is not available for {1}', destiny, self.config.experiment.model_version) return if os.path.lexists(destiny): @@ -236,76 +224,6 @@ class Diags(object): os.symlink(source, destiny) Log.info('File {0} ready', destiny) - def _read_config(self, config_file): - self.parser = Parser() - self.parser.optionxform = str - self.parser.read(config_file) - - # Read diags config - self.scratch_dir = self.parser.get_option('DIAGNOSTICS', 'SCRATCH_DIR') - self.data_dir = self.parser.get_option('DIAGNOSTICS', 'DATA_DIR') - self.con_files = self.parser.get_option('DIAGNOSTICS', 'CON_FILES') - self.diags = self.parser.get_option('DIAGNOSTICS', 'DIAGS').lower() - self.frequency = self.parser.get_option('DIAGNOSTICS', 'FREQUENCY') - self.cdftools_path = self.parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') - self.max_cores = self.parser.get_int_option('DIAGNOSTICS', 'MAX_CORES', 100000) - self.restore_meshes = self.parser.get_bool_option('DIAGNOSTICS', 'RESTORE_MESHES', False) - - # Read experiment config - self.institute = self.parser.get_option('EXPERIMENT', 'INSTITUTE') - self.expid = self.parser.get_option('EXPERIMENT', 'EXPID') - self.experiment_name = self.parser.get_option('EXPERIMENT', 'NAME', self.expid) - - members = list() - for member in self.parser.get_option('EXPERIMENT', 'MEMBERS').split(): - members.append(int(member)) - - member_digits = self.parser.get_int_option('EXPERIMENT', 'MEMBER_DIGITS', 1) - startdates = self.parser.get_option('EXPERIMENT', 'STARTDATES').split() - chunk_size = self.parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') - chunks = self.parser.get_int_option('EXPERIMENT', 'CHUNKS') - cal = self.parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') - - self.exp_manager = ExperimentManager(startdates, members, chunks, chunk_size, member_digits, cal) - - self.model = self.parser.get_option('EXPERIMENT', 'MODEL') - self.nfrp = self.parser.get_int_option('EXPERIMENT', 'NFRP') - self.model_version = self.parser.get_option('EXPERIMENT', 'MODEL_VERSION') - - self.add_name = self.parser.get_bool_option('CMOR', 'ADD_NAME') - self.add_startdate = self.parser.get_bool_option('CMOR', 'ADD_STARTDATE') - - # Read aliases - self._aliases = dict() - if self.parser.has_section('ALIAS'): - for option in self.parser.options('ALIAS'): - self._aliases[option.lower()] = self.parser.get_option('ALIAS', option).lower().split() - - self.scratch_dir = os.path.join(self.scratch_dir, 'diags', self.expid) - if not os.path.exists(self.scratch_dir): - os.makedirs(self.scratch_dir) - os.chdir(self.scratch_dir) - - self.data_manager = DataManager(self.exp_manager, self.institute, self.model, self.expid, self.data_dir, - self.frequency, self.experiment_name, self.scratch_dir, self.nfrp) - - self.data_manager.add_startdate = self.add_startdate - self.data_manager.add_name = self.add_name - - self.CMOR_force = self.parser.get_bool_option('CMOR', 'FORCE', False) - self.CMOR_ocean = self.parser.get_bool_option('CMOR', 'OCEAN_FILES', True) - self.CMOR_atmosphere = self.parser.get_bool_option('CMOR', 'ATMOSPHERE_FILES', True) - self.data_manager.associated_experiment = self.parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', - 'to be filled') - self.data_manager.associated_model = self.parser.get_option('CMOR', 'ASSOCIATED_MODEL', 'to be filled') - self.data_manager.initialization_description = self.parser.get_option('CMOR', 'INITIALIZATION_DESCRIPTION', - 'to be filled') - self.data_manager.initialization_method = self.parser.get_option('CMOR', 'INITIALIZATION_METHOD', - '1') - self.data_manager.physics_description = self.parser.get_option('CMOR', 'PHYSICS_DESCRIPTION', 'to be filled') - self.data_manager.physics_version = self.parser.get_option('CMOR', 'PHYSICS_VERSION', '1') - self.data_manager.source = self.parser.get_option('CMOR', 'SOURCE', 'to be filled') - def main(): """ diff --git a/earthdiagnostics/experimentmanager.py b/earthdiagnostics/experimentmanager.py deleted file mode 100644 index c79ccf6..0000000 --- a/earthdiagnostics/experimentmanager.py +++ /dev/null @@ -1,112 +0,0 @@ -# coding=utf-8 -from autosubmit.date.chunk_date_lib import chunk_start_date, chunk_end_date -from autosubmit.date.chunk_date_lib import parse_date - - -class ExperimentManager(object): - """ - Encapsulates all chunk related tasks - - :param startdates: startdates to run - :type startdates: list[str] - :param members: members to run - :type members: list[int] - :param num_chunks: chunks to run - :type num_chunks: int - :param chunk_size: length of the chunks in months - :type chunk_size: int - :param member_digits: minimum number of digits to use in the member name - :type member_digits: int - :param calendar: experiment's calendar - :type calendar: str - """ - - def __init__(self, startdates, members, num_chunks, chunk_size, member_digits, calendar='standard'): - self.startdates = startdates - self.members = members - self.num_chunks = num_chunks - self.chunk_size = chunk_size - self.member_digits = member_digits - self.calendar = calendar - - def get_chunk_list(self): - """ - Return a list with all the chunks - :return: List containing tuples of startdate, member and chunk - :rtype: tuple[str, int, int] - """ - chunk_list = list() - for startdate in self.startdates: - for member in self.members: - for chunk in range(1, self.num_chunks + 1): - chunk_list.append((startdate, member, chunk)) - return chunk_list - - def get_member_list(self): - """ - Return a list with all the members - :return: List containing tuples of startdate and member - :rtype: tuple[str, int, int] - """ - member_list = list() - for startdate in self.startdates: - for member in self.members: - member_list.append((startdate, member)) - return member_list - - def get_year_chunks(self, startdate, year): - """ - Get the list of chunks containing timesteps from the given year - :param startdate: startdate to use - :type startdate: str - :param year: reference year - :type year: int - :return: list of chunks containing data from the given year - :rtype: list[int] - """ - date = parse_date(startdate) - chunks = list() - for chunk in range(1, self.num_chunks + 1): - chunk_start = chunk_start_date(date, chunk, self.chunk_size, 'month', self.calendar) - if chunk_start.year > year: - break - elif chunk_start.year == year or chunk_end_date(chunk_start, self.chunk_size, 'month', - self.calendar).year == year: - chunks.append(chunk) - - return chunks - - def get_full_years(self, startdate): - """ - Returns the list of full years that are in the given startdate - :param startdate: startdate to use - :type startdate: str - :return: list of full years - :rtype: list[int] - """ - chunks_per_year = 12 / self.chunk_size - date = parse_date(startdate) - first_january = 0 - first_year = date.year - if date.month != 1: - month = date.month - first_year += 1 - while month + self.chunk_size < 12: - month += self.chunk_size - first_january += 1 - - years = list() - for chunk in range(first_january, self.num_chunks - chunks_per_year, chunks_per_year): - years.append(first_year) - first_year += 1 - return years - - def get_member_str(self, member): - """ - Returns the member name for a given member number. - :param member: member's number - :type member: int - :return: member's name - :rtype: str - """ - return 'fc{0}'.format(str(member).zfill(self.member_digits)) diff --git a/setup.py b/setup.py index c096a5b..18b6f77 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ setup( author_email='javier.vegas@bsc.es', url='http://www.bsc.es/projects/earthscience/autosubmit/', keywords=['climate', 'weather', 'diagnostic'], - install_requires=['numpy', 'netCDF4', 'autosubmit', 'cdo', 'pygrib', 'nco', 'cfunits>=1.1.4', ], + install_requires=['numpy', 'netCDF4', 'autosubmit', 'cdo', 'pygrib', 'nco', 'cfunits>=1.1.4', 'coverage', ], packages=find_packages(), include_package_data=True, package_data={'earthdiagnostics': [ diff --git a/test/unit/__init__.py b/test/unit/__init__.py index ea91cd6..9f35180 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -1,7 +1,6 @@ # coding=utf-8 -from test_data_manager import TestDataManager, TestVariable, TestConversion +from test_data_manager import TestVariable, TestConversion from test_constants import TestBasin, TestBasins -from test_experiment_manager import TestExperimentManager from test_box import TestBox from test_diagnostic import TestDiagnostic from test_cdftools import TestCDFTools diff --git a/test/unit/test_data_manager.py b/test/unit/test_data_manager.py index 6a1b3a6..8a384fe 100644 --- a/test/unit/test_data_manager.py +++ b/test/unit/test_data_manager.py @@ -3,29 +3,27 @@ from unittest import TestCase from earthdiagnostics.datamanager import DataManager, Variable, UnitConversion -from experimentmanager import ExperimentManager -from datetime import date -class TestDataManager(TestCase): - def setUp(self): - self.data_manager = DataManager(ExperimentManager(['20000101'], [0], 5, 3, 3), 'institution', 'model', 'expid', - 'datafolder', 'mon', 'experiment', 'scratch', 6) - - def test_domain_abbreviation(self): - self.assertEquals('Omon', DataManager.domain_abbreviation('Ocean', 'mon')) - self.assertEquals('OImon', DataManager.domain_abbreviation('seaIce', 'mon')) - self.assertEquals('LImon', DataManager.domain_abbreviation('landIce', 'mon')) - self.assertEquals('Amon', DataManager.domain_abbreviation('atmos', 'mon')) - self.assertEquals('day', DataManager.domain_abbreviation('atmos', 'day')) - self.assertEquals('6hrPlev', DataManager.domain_abbreviation('atmos', '6hr')) - - def test_get_grib_filename(self): - self.assertEqual(self.data_manager._get_grib_filename('SH', date(2000, 1, 1)), 'ICMSHexpid+200001.grb') - - def test_get_startdate_path(self): - self.assertEqual(self.data_manager.get_startdate_path('20000101'), - 'datafolder/expid/cmorfiles/institution/model/experiment/S20000101') +# class TestDataManager(TestCase): +# def setUp(self): +# self.data_manager = DataManager(ExperimentManager(['20000101'], [0], 5, 3, 3), 'institution', 'model', 'expid', +# 'datafolder', 'mon', 'experiment', 'scratch', 6) +# +# def test_domain_abbreviation(self): +# self.assertEquals('Omon', DataManager.domain_abbreviation('Ocean', 'mon')) +# self.assertEquals('OImon', DataManager.domain_abbreviation('seaIce', 'mon')) +# self.assertEquals('LImon', DataManager.domain_abbreviation('landIce', 'mon')) +# self.assertEquals('Amon', DataManager.domain_abbreviation('atmos', 'mon')) +# self.assertEquals('day', DataManager.domain_abbreviation('atmos', 'day')) +# self.assertEquals('6hrPlev', DataManager.domain_abbreviation('atmos', '6hr')) +# +# def test_get_grib_filename(self): +# self.assertEqual(self.data_manager._get_grib_filename('SH', date(2000, 1, 1)), 'ICMSHexpid+200001.grb') +# +# def test_get_startdate_path(self): +# self.assertEqual(self.data_manager.get_startdate_path('20000101'), +# 'datafolder/expid/cmorfiles/institution/model/experiment/S20000101') class TestVariable(TestCase): diff --git a/test/unit/test_experiment_manager.py b/test/unit/test_experiment_manager.py index 0c1f4e1..3dce31f 100644 --- a/test/unit/test_experiment_manager.py +++ b/test/unit/test_experiment_manager.py @@ -1,37 +1,37 @@ # coding=utf-8 from unittest import TestCase -from earthdiagnostics.experimentmanager import ExperimentManager - - -class TestExperimentManager(TestCase): - def setUp(self): - self.experiment_manager = ExperimentManager(['20000101', '20000201'], [0, 1], 5, 3, 3) - - def test_get_full_years(self): - self.assertEquals([2000], self.experiment_manager.get_full_years('20000101')) - self.assertEquals(list(), self.experiment_manager.get_full_years('20000201')) - - def test_get_member_str(self): - self.assertEquals('fc000', self.experiment_manager.get_member_str(0)) - self.assertEquals('fc001', self.experiment_manager.get_member_str(1)) - - def test_get_member_list(self): - self.assertEquals([('20000101', 0), ('20000101', 1), ('20000201', 0), ('20000201', 1)], - self.experiment_manager.get_member_list()) - - def test_get_year_chunks(self): - self.assertEquals([1, 2, 3, 4], self.experiment_manager.get_year_chunks('20000101', 2000)) - self.assertEquals([4, 5], self.experiment_manager.get_year_chunks('20000201', 2001)) - self.assertEquals(list(), self.experiment_manager.get_year_chunks('20000201', 2003)) - - def test_get_chunk_list(self): - self.assertEquals([('20000101', 0, 1), ('20000101', 0, 2), ('20000101', 0, 3), ('20000101', 0, 4), - ('20000101', 0, 5), - ('20000101', 1, 1), ('20000101', 1, 2), ('20000101', 1, 3), ('20000101', 1, 4), - ('20000101', 1, 5), - ('20000201', 0, 1), ('20000201', 0, 2), ('20000201', 0, 3), ('20000201', 0, 4), - ('20000201', 0, 5), - ('20000201', 1, 1), ('20000201', 1, 2), ('20000201', 1, 3), ('20000201', 1, 4), - ('20000201', 1, 5)], - self.experiment_manager.get_chunk_list()) +from earthdiagnostics.experimentconfig import ExperimentConfig + + +# class TestExperimentManager(TestCase): +# def setUp(self): +# self.experiment_manager = ExperimentManager(['20000101', '20000201'], [0, 1], 5, 3, 3) +# +# def test_get_full_years(self): +# self.assertEquals([2000], self.experiment_manager.get_full_years('20000101')) +# self.assertEquals(list(), self.experiment_manager.get_full_years('20000201')) +# +# def test_get_member_str(self): +# self.assertEquals('fc000', self.experiment_manager.get_member_str(0)) +# self.assertEquals('fc001', self.experiment_manager.get_member_str(1)) +# +# def test_get_member_list(self): +# self.assertEquals([('20000101', 0), ('20000101', 1), ('20000201', 0), ('20000201', 1)], +# self.experiment_manager.get_member_list()) +# +# def test_get_year_chunks(self): +# self.assertEquals([1, 2, 3, 4], self.experiment_manager.get_year_chunks('20000101', 2000)) +# self.assertEquals([4, 5], self.experiment_manager.get_year_chunks('20000201', 2001)) +# self.assertEquals(list(), self.experiment_manager.get_year_chunks('20000201', 2003)) +# +# def test_get_chunk_list(self): +# self.assertEquals([('20000101', 0, 1), ('20000101', 0, 2), ('20000101', 0, 3), ('20000101', 0, 4), +# ('20000101', 0, 5), +# ('20000101', 1, 1), ('20000101', 1, 2), ('20000101', 1, 3), ('20000101', 1, 4), +# ('20000101', 1, 5), +# ('20000201', 0, 1), ('20000201', 0, 2), ('20000201', 0, 3), ('20000201', 0, 4), +# ('20000201', 0, 5), +# ('20000201', 1, 1), ('20000201', 1, 2), ('20000201', 1, 3), ('20000201', 1, 4), +# ('20000201', 1, 5)], +# self.experiment_manager.get_chunk_list()) -- GitLab From df691d4f9a9ba8c61273df24dad1ab99af94e40b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 1 Sep 2016 17:38:22 +0200 Subject: [PATCH 187/268] Fixed some errors introduced in previous commit --- earthdiagnostics/config.py | 41 ++++++++++++++-- earthdiagnostics/datamanager.py | 83 ++++++++++++++++++--------------- earthdiagnostics/diags.conf | 16 +++---- 3 files changed, 91 insertions(+), 49 deletions(-) diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index 4d010a3..ba8c3f0 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -7,7 +7,13 @@ from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_e from earthdiagnostics.parser import Parser -class Config(object): +class Config(object): + """ + Class to read and manage the configuration + + :param path: path to the conf file + :type path: str + """ def __init__(self, path): parser = Parser() @@ -16,16 +22,28 @@ class Config(object): # Read diags config self.scratch_dir = parser.get_option('DIAGNOSTICS', 'SCRATCH_DIR') + "Scratch folder path" self.data_dir = parser.get_option('DIAGNOSTICS', 'DATA_DIR') + "Root data folder path" self.con_files = parser.get_option('DIAGNOSTICS', 'CON_FILES') - self.diags = parser.get_option('DIAGNOSTICS', 'DIAGS').lower() + "Mask and meshes folder path" + self._diags = parser.get_option('DIAGNOSTICS', 'DIAGS').lower() self.frequency = parser.get_option('DIAGNOSTICS', 'FREQUENCY') + "Default data frequency to be used by the diagnostics" self.cdftools_path = parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') + "Path to CDFTOOLS executables" self.max_cores = parser.get_int_option('DIAGNOSTICS', 'MAX_CORES', 100000) + "Maximum number of cores to use" self.restore_meshes = parser.get_bool_option('DIAGNOSTICS', 'RESTORE_MESHES', False) + "If True, forces the tool to copy all the mesh and mask files for the model, regardless of existence" # Read experiment config self.experiment = ExperimentConfig(parser) + """ + Configuration related to the experiment + + :rtype: ExperimentConfig + """ # Read aliases self._aliases = dict() @@ -33,7 +51,7 @@ class Config(object): for option in parser.options('ALIAS'): self._aliases[option.lower()] = parser.get_option('ALIAS', option).lower().split() Log.debug('Preparing command list') - commands = self.diags.split() + commands = self._diags.split() self._real_commands = list() for command in commands: if command in self._aliases: @@ -50,6 +68,11 @@ class Config(object): self.cmor = CMORConfig(parser) def get_commands(self): + """ + Returns the list of commands after replacing the alias + :return: full list of commands + :rtype: list(str) + """ return self._real_commands @@ -98,6 +121,18 @@ class CMORConfig(object): step = 1 return range(start, end, step) + def get_variables(self, frequency): + if frequency in ('hour', 'hourly') or frequency[1:] == 'hr': + return self._var_hourly + elif frequency in ('day', 'daily', '1d'): + return self._var_daily + elif frequency in ('month', 'monthly', 'mon', '1m'): + return self._var_monthly + raise Exception('Frequency not recognized: {0}'.format(frequency)) + + def get_levels(self, frequency, variable): + return self.get_variables(frequency)[variable] + class ExperimentConfig(object): """ diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index ddcc8ca..2c93104 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -118,7 +118,8 @@ class DataManager(object): data_folder = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, member_str, 'outputs') - while os.path.exists(os.path.join(data_folder, self._get_grib_filename('GG', chunk_start))): + while os.path.exists(os.path.join(data_folder, self._get_grib_filename('GG', chunk_start))) or \ + os.path.exists(os.path.join(data_folder, self._get_grib_filename('SH', chunk_start))): chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') @@ -126,6 +127,9 @@ class DataManager(object): for grid in ('SH', 'GG'): Log.info('Processing {0} variables', grid) + if not os.path.exists(os.path.join(data_folder, self._get_grib_filename(grid, chunk_start))): + continue + for month in range(0, self.experiment.chunk_size): current_month = add_months(chunk_start, month, 'standard') original_gribfile = os.path.join(data_folder, self._get_grib_filename(grid, current_month)) @@ -169,9 +173,9 @@ class DataManager(object): cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, 'hour') - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, 'day') - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, 'mon') + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '{0}hr'.format(nfrp)) + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1d') + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1m') for splited_file in glob.glob('{0}_*.128.nc'.format(gribfile)): os.remove(splited_file) @@ -181,7 +185,7 @@ class DataManager(object): self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1m') self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1d') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '6hr') + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '{0}hr'.format(nfrp)) chunk_start = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') @staticmethod @@ -213,13 +217,13 @@ class DataManager(object): def _ungrib_vars(self, cdo_reftime, gribfile, month, frequency): Log.info('Preparing {0} variables'.format(frequency)) - var_codes = self.config.cmor.variables(frequency) + var_codes = self.config.cmor.get_variables(frequency) for var_code in var_codes: if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, var_code)): continue new_units = None - cdo_operator = '-selmon, {0}'.format(month) + cdo_operator = '-selmon,{0}'.format(month) if frequency == 'mon': if var_code == 201: @@ -260,25 +264,25 @@ class DataManager(object): if levels: cdo_operator = "{0} -sellevel,{1}".format(cdo_operator, levels) - Utils.execute_shell_command('cdo -t ecmwf setreftime,{0}' + Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' '{1} {2}_{3}.128.nc ' - '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, - gribfile, var_code)) - h_var_file = '{0}_{1}_6hr.nc'.format(gribfile, var_code) + '{2}_{3}_{4}.nc'.format(cdo_reftime, cdo_operator, + gribfile, var_code, frequency)) + h_var_file = '{0}_{1}_{2}.nc'.format(gribfile, var_code, frequency) + + handler = Utils.openCdf(h_var_file) if new_units: - handler = Utils.openCdf(h_var_file) for var in handler.variables.values(): if 'code' in var.ncattrs() and var.code == var_code: var.units = new_units break - handler.close() var_name = None for key in handler.variables.keys(): if key + '_2' in handler.variables and key not in handler.dimensions: var_name = key - handler.close() + if var_name is not None: Utils.nco.ncks(input='{0}_{1}_1m.nc'.format(gribfile, var_code), output='{0}_{1}_1m.nc'.format(gribfile, var_code), @@ -292,9 +296,10 @@ class DataManager(object): shutil.move(first_file, merged_file) current_month = add_months(chunk_start, 1, 'standard') while current_month < chunk_end: - month_file = first_file.replace('_{0}_'.format(parse_date(chunk_start)[:-2]), - '_{0}_'.format(parse_date(current_month)[:-2])) + month_file = first_file.replace('+{0}.grb'.format(date2str(chunk_start)[:-2]), + '+{0}.grb'.format(date2str(current_month)[:-2])) Utils.concat_variables(month_file, merged_file, True) + current_month = add_months(current_month, 1, 'standard') self._cmorize_nc_file(merged_file, member, startdate) @@ -317,27 +322,28 @@ class DataManager(object): t.start() for t in threads: t.join() - if cmor.experiment_name != cmor.model: - bad_path = os.path.join(member_path, cmor.institution, cmor.model, cmor.model) + if self.experiment.experiment_name != self.experiment.model: + bad_path = os.path.join(member_path, self.experiment.institute, self.experiment.model, + self.experiment.model) for (dirpath, dirnames, filenames) in os.walk(bad_path, False): for filename in filenames: filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_output_'.format(cmor.model), - '_{0}_{1}_'.format(cmor.model, cmor.experiment_name)) + good = filepath.replace('_{0}_output_'.format(self.experiment.model), + '_{0}_{1}_'.format(self.experiment.model, self.experiment.experiment_name)) - good = good.replace('/{0}/{0}'.format(cmor.model), - '/{0}/{1}'.format(cmor.model, - cmor.experiment_name)) + good = good.replace('/{0}/{0}'.format(self.experiment.model), + '/{0}/{1}'.format(self.experiment.model, + self.experiment.experiment_name)) Utils.move_file(filepath, good) os.rmdir(dirpath) - good_dir = os.path.join(member_path, cmor.institution, cmor.model, cmor.experiment_name) + good_dir = os.path.join(member_path, self.experiment.institute, self.experiment.model, self.experiment.experiment_name) for sdate in os.listdir(good_dir): for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): for filename in filenames: filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_{1}_r'.format(cmor.model, cmor.experiment_name, sdate), - '_{0}_{1}_{2}_r'.format(cmor.model, cmor.experiment_name, sdate)) + good = filepath.replace('_{0}_{1}_r'.format(self.experiment.model, self.experiment.experiment_name, sdate), + '_{0}_{1}_{2}_r'.format(self.experiment.model, self.experiment.experiment_name, sdate)) if good != filepath: Log.info('Moving {0} to {1}'.format(filename, good)) Utils.move_file(filepath, good) @@ -535,32 +541,33 @@ class DataManager(object): def _add_common_attributes(self, frequency, handler, member, startdate): cmor = self.config.cmor + experiment = self.config.experiment handler.associated_experiment = cmor.associated_experiment - handler.batch = '{0}{1}'.format(cmor.institution, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) + handler.batch = '{0}{1}'.format(experiment.institute, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ 'Javier Vegas-Regidor, javier.vegas@bsc.es ' handler.Conventions = 'CF-1.6' handler.creation_date = datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)') - handler.experiment_id = cmor.experiment_name + handler.experiment_id = experiment.experiment_name handler.forecast_reference_time = parse_date(startdate).strftime('%Y-%m-%d(T%H:%M:%SZ)') if frequency == 'd': handler.frequency = 'day' elif frequency == 'm': handler.frequency = 'mon' - handler.institute_id = cmor.institution - handler.institution = cmor.institution + handler.institute_id = experiment.institute + handler.institution = experiment.institute handler.initialization_method = cmor.initialization_method handler.initialization_description = cmor.initialization_description handler.physics_version = cmor.physics_version handler.physics_description = cmor.physics_description - handler.model_id = cmor.model + handler.model_id = experiment.model handler.associated_model = cmor.associated_model handler.project_id = 'SPECS' handler.realization = str(member + 1) handler.source = cmor.source handler.startdate = 'S{0}'.format(startdate) handler.tracking_id = str(uuid.uuid1()) - handler.title = "{0} model output prepared for SPECS {1}".format(cmor.model, cmor.experiment_name) + handler.title = "{0} model output prepared for SPECS {1}".format(experiment.model, experiment.experiment_name) @staticmethod def _unzip(files): @@ -627,8 +634,8 @@ class DataManager(object): filepath = os.path.join(var_path, '{0}_{1}_{3}_{4}_S{5}_r{6}i1p1_' '{7}-{8}.nc'.format(var, domain_abbreviation, frequency, - self.config.cmor.model, - self.config.cmor.experiment_name, startdate, member_plus, + self.experiment.model, + self.experiment.experiment_name, startdate, member_plus, "{0:04}{1:02}".format(chunk_start.year, chunk_start.month), "{0:04}{1:02}".format(chunk_end.year, @@ -646,8 +653,8 @@ class DataManager(object): :return: path to the startdate's CMOR folder :rtype: str """ - return os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles', self.config.cmor.institution, - self.config.cmor.model, self.config.cmor.experiment_name, 'S' + startdate) + return os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles', self.experiment.institute, + self.experiment.model, self.experiment.experiment_name, 'S' + startdate) def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, rename_var=None, frequency=None, year=None, date_str=None): @@ -725,8 +732,8 @@ class DataManager(object): var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' - '{6}.nc'.format(var, domain_abreviattion, self.config.cmor.model, - self.config.cmor.experiment_name, + '{6}.nc'.format(var, domain_abreviattion, self.experiment.model, + self.experiment.experiment_name, startdate, member_plus, time_bound)) if region: diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index baf396f..ce3bd46 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -7,7 +7,7 @@ DATA_DIR = /esnas/exp/ecearth/ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below) -DIAGS = rewrite,tas,atmos +DIAGS = # Frequency of the data you want to use FREQUENCY = mon # Path to CDFTOOLS binaries @@ -24,9 +24,9 @@ FORCE = True OCEAN_FILES = False # If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = True -ATMOS_HOURLY_VARS = 129:30000:90000:5000, 130, 131:30000:90000:5000, 132:30000:90000:5000, 151, 167, 168, 164, 165, 166 -ATMOS_DAILY_VARS = 167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130:85000 -ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, 177, 175, 212, 141, 180, 181, 179, 168, 243, 129:5000-20000-50000-85000, 130:5000-20000-50000-85000, 131:5000-20000-50000-85000, 132:5000-20000-50000-85000, 133:5000-20000-50000-85000 +ATMOS_HOURLY_VARS = +ATMOS_DAILY_VARS = 130:18-22-26-28-30, 131:18-22-26-28-30, 132:18-22-26-28-30 +ATMOS_MONTHLY_VARS = # The next bunch of parameters are used to provide metadata for the CMOR files # ASSOCIATED_EXPERIMENT = # INITIALIZATION_METHOD = 1 @@ -41,7 +41,7 @@ ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, INSTITUTE = BSC MODEL = EC-EARTH # Model version -MODEL_VERSION =Ec3.2_O1L75 +MODEL_VERSION =Ec3.1_O1L75 NFRP = 6 # For those who use Autosubmit, this no need documentation @@ -52,11 +52,11 @@ NFRP = 6 # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment EXPID = a045 -STARTDATES = 19900101 +STARTDATES = 20300101 MEMBERS = 0 MEMBER_DIGITS = 1 -CHUNK_SIZE = 1 -CHUNKS = 12 +CHUNK_SIZE = 4 +CHUNKS = 1 # CHUNKS = 1 -- GitLab From 50da688b6b9b8fa7a84a76e99dc5ad4c38b5ab80 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 2 Sep 2016 09:44:56 +0200 Subject: [PATCH 188/268] Fixed NFRP retrieval from GRIB --- earthdiagnostics/datamanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 2c93104..dc4b719 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -207,7 +207,7 @@ class DataManager(object): grib_handler = pygrib.open(gribfile) mes1 = grib_handler.message(1) mes2 = grib_handler.readline() - while mes2['name'] != mes1['name']: + while mes2.analDate == mes1.analDate: mes2 = grib_handler.readline() nfrp = mes2.analDate - mes1.analDate nfrp = int(nfrp.total_seconds() / 3600) -- GitLab From acf9b56e6b1fcad355da275b1d860f15ae857425 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 5 Sep 2016 11:29:13 +0200 Subject: [PATCH 189/268] Fixed error in frequency and improved concat_variables --- earthdiagnostics/datamanager.py | 5 ++--- earthdiagnostics/diags.conf | 10 +++++----- earthdiagnostics/utils.py | 13 ++++++++++++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index dc4b719..4dad00f 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -224,15 +224,14 @@ class DataManager(object): new_units = None cdo_operator = '-selmon,{0}'.format(month) - - if frequency == 'mon': + if frequency in ('month', 'monthly', 'mon', '1m'): if var_code == 201: cdo_operator = "-monmean -daymax {0}".format(cdo_operator) elif var_code == 202: cdo_operator = "-monmean -daymax {0}".format(cdo_operator) else: cdo_operator = "-monmean {0} ".format(cdo_operator) - elif frequency == 'day': + elif frequency in ('day', 'daily', '1d'): if var_code == 201: cdo_operator = "-daymax {0} ".format(cdo_operator) elif var_code == 202: diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index ce3bd46..ba0736f 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -24,9 +24,9 @@ FORCE = True OCEAN_FILES = False # If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = True -ATMOS_HOURLY_VARS = -ATMOS_DAILY_VARS = 130:18-22-26-28-30, 131:18-22-26-28-30, 132:18-22-26-28-30 -ATMOS_MONTHLY_VARS = +ATMOS_HOURLY_VARS = 129:30000:90000:5000, 130, 131:30000:90000:5000, 132:30000:90000:5000, 151, 167, 168, 164, 165, 166 +ATMOS_DAILY_VARS = 167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130:85000 +ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, 177, 175, 212, 141, 180, 181, 179, 168, 243, 129:5000-20000-50000-85000, 130:5000-20000-50000-85000, 131:5000-20000-50000-85000, 132:5000-20000-50000-85000, 133:5000-20000-50000-85000 # The next bunch of parameters are used to provide metadata for the CMOR files # ASSOCIATED_EXPERIMENT = # INITIALIZATION_METHOD = 1 @@ -51,11 +51,11 @@ NFRP = 6 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment -EXPID = a045 +EXPID = a032 STARTDATES = 20300101 MEMBERS = 0 MEMBER_DIGITS = 1 -CHUNK_SIZE = 4 +CHUNK_SIZE = 12 CHUNKS = 1 # CHUNKS = 1 diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 4ef7fd7..caa0205 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -326,8 +326,19 @@ class Utils(object): if os.path.exists(destiny): handler_total = Utils.openCdf(destiny) handler_variable = Utils.openCdf(source) + concatenated = dict() for var in handler_variable.variables: - Utils.copy_variable(handler_variable, handler_total, var, add_dimensions=True) + if var not in handler_total.variables: + Utils.copy_variable(handler_variable, handler_total, var, add_dimensions=True) + else: + variable = handler_variable.variables[var] + if 'time' not in variable.dimensions: + continue + concatenated[var] = np.concatenate((handler_total.variables[var][:], variable[:]), + axis=variable.dimensions.index('time')) + + for var, array in concatenated.iteritems(): + handler_total.variables[var][:] = array handler_total.close() handler_variable.close() if remove_source: -- GitLab From 6911ecfdfdfc81383e7430d8e83f6269846e04d8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 5 Sep 2016 12:06:38 +0200 Subject: [PATCH 190/268] Improved comments at conf file and all paths will be now properly expanded --- earthdiagnostics/config.py | 9 +++++---- earthdiagnostics/diags.conf | 28 ++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index ba8c3f0..3fcb6e5 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -5,6 +5,7 @@ from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date from earthdiagnostics.parser import Parser +from utils import Utils class Config(object): @@ -21,16 +22,16 @@ class Config(object): parser.read(path) # Read diags config - self.scratch_dir = parser.get_option('DIAGNOSTICS', 'SCRATCH_DIR') + self.scratch_dir = Utils.expand_path(parser.get_option('DIAGNOSTICS', 'SCRATCH_DIR')) "Scratch folder path" - self.data_dir = parser.get_option('DIAGNOSTICS', 'DATA_DIR') + self.data_dir = Utils.expand_path(parser.get_option('DIAGNOSTICS', 'DATA_DIR')) "Root data folder path" - self.con_files = parser.get_option('DIAGNOSTICS', 'CON_FILES') + self.con_files = Utils.expand_path(parser.get_option('DIAGNOSTICS', 'CON_FILES')) "Mask and meshes folder path" self._diags = parser.get_option('DIAGNOSTICS', 'DIAGS').lower() self.frequency = parser.get_option('DIAGNOSTICS', 'FREQUENCY') "Default data frequency to be used by the diagnostics" - self.cdftools_path = parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH') + self.cdftools_path = Utils.expand_path(parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH')) "Path to CDFTOOLS executables" self.max_cores = parser.get_int_option('DIAGNOSTICS', 'MAX_CORES', 100000) "Maximum number of cores to use" diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index ba0736f..3c9c832 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -1,17 +1,19 @@ [DIAGNOSTICS] # Path to the folder where you want to create the temporary files -SCRATCH_DIR = /scratch/Earth/jvegas +SCRATCH_DIR = /scratch/Earth/$USER # Root path for the cmorized data to use DATA_DIR = /esnas/exp/ecearth/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or -# an alias defined in the ALIAS section (see more below) +# an alias defined in the ALIAS section (see more below). If you are using the diagnpostics just to CMORize, leave it +# empty DIAGS = -# Frequency of the data you want to use +# Frequency of the data you want to use by default. Some diagnostics (i.e. monmean always stores result at monthly +# and has a parameter to specify input's frequency) FREQUENCY = mon # Path to CDFTOOLS binaries -CDFTOOLS_PATH = /home/Earth/jvegas/CDFTOOLS_CMOR/bin +CDFTOOLS_PATH = ~jvegas/CDFTOOLS_CMOR/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) @@ -19,14 +21,28 @@ RESTORE_MESHES = False [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = True +FORCE = False # If true, CMORizes ocean files. Default = True OCEAN_FILES = False # If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = True + +# Variables to be CMORized from the grib atmospheric files, separated by comma. +# You can also specify the levels to extract using the following syntax +# VARIABLE_CODE, VARIABLE_CODE:LEVEL, VARIABLE_CODE:LEVEL1-LEVEL2, VARIABLE_CODE:MIN_LEVEL:MAX_LEVEL:STEP +# Examples: +# Variable with code 129 at level 30000: 129:30000 +# Variable with code 129 at levels 30000, 40000 and 60000: 129:30000-40000-60000 +# Variable with code 129 at levels between 30000 and 600000 with 10000 intervals: +# 129:30000:60000:10000 equivalent to 129:30000-40000-50000-60000 + +# Hourly vars ATMOS_HOURLY_VARS = 129:30000:90000:5000, 130, 131:30000:90000:5000, 132:30000:90000:5000, 151, 167, 168, 164, 165, 166 +# Daily vars ATMOS_DAILY_VARS = 167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130:85000 +# Monthly vars ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, 177, 175, 212, 141, 180, 181, 179, 168, 243, 129:5000-20000-50000-85000, 130:5000-20000-50000-85000, 131:5000-20000-50000-85000, 132:5000-20000-50000-85000, 133:5000-20000-50000-85000 + # The next bunch of parameters are used to provide metadata for the CMOR files # ASSOCIATED_EXPERIMENT = # INITIALIZATION_METHOD = 1 @@ -63,7 +79,7 @@ CHUNKS = 1 # This ALIAS section is a bit different # Inside this, you can provide alias for frequent diagnostics calls. -# By default, there are some of the diagnostics available at the previos version. +# By default, there are some of the diagnostics available at the previous version. # You can define an alias for one or more diagnostic calls [ALIAS] -- GitLab From c48c8f72d7aaada7d7a90dad72b654e522a435c2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 5 Sep 2016 12:46:58 +0200 Subject: [PATCH 191/268] Cleaning code to comply with style guide --- earthdiagnostics/config.py | 11 +++---- earthdiagnostics/datamanager.py | 43 +++++++++++++++------------- earthdiagnostics/diags.conf | 16 ++++++----- launch_diags.sh | 3 +- setup.py | 4 +++ test.py | 3 ++ test/unit/test_experiment_manager.py | 1 - 7 files changed, 47 insertions(+), 34 deletions(-) diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index 3fcb6e5..edde99c 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -93,11 +93,12 @@ class CMORConfig(object): self.add_name = parser.get_bool_option('CMOR', 'ADD_NAME') self.add_startdate = parser.get_bool_option('CMOR', 'ADD_STARTDATE') - self._var_hourly = self._parse_variables(parser.get_option('CMOR', 'ATMOS_HOURLY_VARS', '')) - self._var_daily = self._parse_variables(parser.get_option('CMOR', 'ATMOS_DAILY_VARS', '')) - self._var_monthly = self._parse_variables(parser.get_option('CMOR', 'ATMOS_MONTHLY_VARS', '')) + self._var_hourly = CMORConfig._parse_variables(parser.get_option('CMOR', 'ATMOS_HOURLY_VARS', '')) + self._var_daily = CMORConfig._parse_variables(parser.get_option('CMOR', 'ATMOS_DAILY_VARS', '')) + self._var_monthly = CMORConfig._parse_variables(parser.get_option('CMOR', 'ATMOS_MONTHLY_VARS', '')) - def _parse_variables(self, raw_string): + @staticmethod + def _parse_variables(raw_string): variables = dict() if raw_string: splitted = raw_string.split(',') @@ -158,7 +159,7 @@ class ExperimentConfig(object): chunks = parser.get_int_option('EXPERIMENT', 'CHUNKS') calendar = parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') self.model = parser.get_option('EXPERIMENT', 'MODEL') - self.nfrp = parser.get_int_option('EXPERIMENT', 'NFRP') + self.atmos_timestep = parser.get_int_option('EXPERIMENT', 'ATMOS_TIMESTEP') self.model_version = parser.get_option('EXPERIMENT', 'MODEL_VERSION') self.startdates = startdates diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 4dad00f..222fcc2 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -112,14 +112,14 @@ class DataManager(object): def _cmorize_grib(self, startdate, member): count = 1 - nfrp = None + atmos_timestep = None chunk_start = parse_date(startdate) member_str = self.experiment.get_member_str(member) data_folder = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, member_str, 'outputs') while os.path.exists(os.path.join(data_folder, self._get_grib_filename('GG', chunk_start))) or \ - os.path.exists(os.path.join(data_folder, self._get_grib_filename('SH', chunk_start))): + os.path.exists(os.path.join(data_folder, self._get_grib_filename('SH', chunk_start))): chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') @@ -139,8 +139,8 @@ class DataManager(object): Log.info('Copying file...', grid, date2str(current_month)) shutil.copy(original_gribfile, gribfile) - if nfrp is None: - nfrp = self._get_nfrp(gribfile) + if atmos_timestep is None: + atmos_timestep = self._get_atmos_timestep(gribfile) prev_gribfile = os.path.join(self.config.scratch_dir, self._get_grib_filename(grid, @@ -173,7 +173,7 @@ class DataManager(object): cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '{0}hr'.format(nfrp)) + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '{0}hr'.format(atmos_timestep)) self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1d') self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1m') @@ -185,7 +185,8 @@ class DataManager(object): self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1m') self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1d') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '{0}hr'.format(nfrp)) + self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, + '{0}hr'.format(atmos_timestep)) chunk_start = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') @staticmethod @@ -202,18 +203,18 @@ class DataManager(object): os.remove('rules_files') os.remove(prev_gribfile) - def _get_nfrp(self, gribfile): + def _get_atmos_timestep(self, gribfile): Log.info('Getting timestep...') grib_handler = pygrib.open(gribfile) mes1 = grib_handler.message(1) mes2 = grib_handler.readline() while mes2.analDate == mes1.analDate: mes2 = grib_handler.readline() - nfrp = mes2.analDate - mes1.analDate - nfrp = int(nfrp.total_seconds() / 3600) - self.nfrp = nfrp + atmos_timestep = mes2.analDate - mes1.analDate + atmos_timestep = int(atmos_timestep.total_seconds() / 3600) + self.atmos_timestep = atmos_timestep grib_handler.close() - return nfrp + return atmos_timestep def _ungrib_vars(self, cdo_reftime, gribfile, month, frequency): Log.info('Preparing {0} variables'.format(frequency)) @@ -240,7 +241,7 @@ class DataManager(object): cdo_operator = "-daymean {0} ".format(cdo_operator) if var_code in (144, 146, 147, 169, 175, 176, 177, 179, 180, 181, 182, 201, 202, 205, 212, 228): - cdo_operator = '{0} -shifttime,-{1}hours'.format(cdo_operator, self.nfrp) + cdo_operator = '{0} -shifttime,-{1}hours'.format(cdo_operator, self.atmos_timestep) if var_code == 129: # geopotential @@ -249,15 +250,15 @@ class DataManager(object): elif var_code in (146, 147, 169, 175, 176, 177, 179, 212): # radiation new_units = "W m-2" - cdo_operator = "-divc,{0} {1}".format(self.nfrp * 3600, cdo_operator) + cdo_operator = "-divc,{0} {1}".format(self.atmos_timestep * 3600, cdo_operator) elif var_code in (180, 181): # momentum flux new_units = "N m-2" - cdo_operator = "-divc,{0} {1}".format(self.nfrp * 3600, cdo_operator) + cdo_operator = "-divc,{0} {1}".format(self.atmos_timestep * 3600, cdo_operator) elif var_code in (144, 182, 205, 228): # precipitation/evaporation/runoff new_units = "kg m-2 s-1" - cdo_operator = "-mulc,1000 -divc,{0}".format(self.nfrp * 3600) + cdo_operator = "-mulc,1000 -divc,{0}".format(self.atmos_timestep * 3600) levels = self.config.cmor.get_levels(frequency, var_code) if levels: @@ -303,7 +304,6 @@ class DataManager(object): self._cmorize_nc_file(merged_file, member, startdate) def _unpack_cmorfiles(self, filepaths, member_path): - cmor = self.config.cmor threads = list() numthreads = Utils.available_cpu_count() for numthread in range(0, numthreads): @@ -336,13 +336,16 @@ class DataManager(object): Utils.move_file(filepath, good) os.rmdir(dirpath) - good_dir = os.path.join(member_path, self.experiment.institute, self.experiment.model, self.experiment.experiment_name) + good_dir = os.path.join(member_path, self.experiment.institute, self.experiment.model, + self.experiment.experiment_name) for sdate in os.listdir(good_dir): for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): for filename in filenames: filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_{1}_r'.format(self.experiment.model, self.experiment.experiment_name, sdate), - '_{0}_{1}_{2}_r'.format(self.experiment.model, self.experiment.experiment_name, sdate)) + good = filepath.replace('_{0}_{1}_r'.format(self.experiment.model, + self.experiment.experiment_name, sdate), + '_{0}_{1}_{2}_r'.format(self.experiment.model, + self.experiment.experiment_name, sdate)) if good != filepath: Log.info('Moving {0} to {1}'.format(filename, good)) Utils.move_file(filepath, good) @@ -872,7 +875,7 @@ class DataManager(object): if domain in ['ocean', 'seaIce']: variable_folder = '{0}_f6h'.format(var) else: - variable_folder = '{0}_f{1}h'.format(var, self.nfrp) + variable_folder = '{0}_f{1}h'.format(var, self.atmos_timestep) link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 3c9c832..6ee50be 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -56,14 +56,17 @@ ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, # Experiments parameters as defined in CMOR standard INSTITUTE = BSC MODEL = EC-EARTH -# Model version -MODEL_VERSION =Ec3.1_O1L75 -NFRP = 6 +# Model version: Available versions +MODEL_VERSION =Ec3.0_O1L46 +# Atmos output timestep in hours +ATMOS_TIMESTEP = 6 -# For those who use Autosubmit, this no need documentation -# For those who not, EXPID is the unique identifier of the experiment. +# For those who use Autosubmit, this will be easy +# EXPID is the unique identifier of the experiment. # STARTDATES is the list of start dates -# MEMBERS is the list of members of your experiment +# MEMBERS is the list of members of your experiment (only the numbers, the fc will be added by the tool) +# MEMBER_DIGITS is the minimum number of digits to use for the member name: if 1 the name for member 0 will be fc0, +# if 2, fc00 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment @@ -76,7 +79,6 @@ CHUNKS = 1 # CHUNKS = 1 - # This ALIAS section is a bit different # Inside this, you can provide alias for frequent diagnostics calls. # By default, there are some of the diagnostics available at the previous version. diff --git a/launch_diags.sh b/launch_diags.sh index 94ec71f..9dfa14a 100755 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -9,6 +9,7 @@ set -xv PATH_TO_DIAGNOSTICS=~/pyCharm/ocean_diagnostics PATH_TO_VIRTUALENV=/home/Earth/jvegas/virtualenvs/diags/bin +PATH_TO_CONF_FILE=diags.conf module purge module load NCO/4.5.4-foss-2015a @@ -19,4 +20,4 @@ source ${PATH_TO_VIRTUALENV}/activate export PYTHONPATH=${PATH_TO_DIAGNOSTICS}:${PYTHONPATH} cd ${PATH_TO_DIAGNOSTICS}/earthdiagnostics/ -./diags.py -lc DEBUG +./diags.py -lc DEBUG -f ${PATH_TO_CONF_FILE} diff --git a/setup.py b/setup.py index 18b6f77..44071e3 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,8 @@ #!/usr/bin/env python # coding=utf-8 +""" +Installation script for EarthDiagnostics package +""" from os import path from setuptools import setup @@ -28,6 +31,7 @@ setup( 'earthdiagnostics/conversions.csv', 'earthdiagnostics/cmor_table.csv', 'earthdiagnostics/diags.conf', + 'cdftoolspython.so' 'README', 'VERSION', 'EarthDiagnostics.pdf' diff --git a/test.py b/test.py index bed5d23..ff30995 100644 --- a/test.py +++ b/test.py @@ -1,4 +1,7 @@ # coding=utf-8 +""" +Script to run the tests for EarthDiagnostics and generate the code coverage report +""" import coverage import unittest import os diff --git a/test/unit/test_experiment_manager.py b/test/unit/test_experiment_manager.py index 3dce31f..773a545 100644 --- a/test/unit/test_experiment_manager.py +++ b/test/unit/test_experiment_manager.py @@ -1,7 +1,6 @@ # coding=utf-8 from unittest import TestCase -from earthdiagnostics.experimentconfig import ExperimentConfig # class TestExperimentManager(TestCase): -- GitLab From 9dc9bcd6cf97efb6774ab9d61ac0590233f5e750 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 5 Sep 2016 17:48:41 +0200 Subject: [PATCH 192/268] Improved doc --- doc/source/codedoc/earthdiagnostics.rst | 31 ++++--- doc/source/codedoc/general.rst | 14 ++++ doc/source/codedoc/main.rst | 1 + doc/source/codedoc/ocean.rst | 18 ++++ doc/source/diagnostic_list.rst | 86 ++++++++++++++++++++ doc/source/errors.rst | 17 ++-- doc/source/index.rst | 1 + doc/source/tips.rst | 3 +- doc/source/tutorial.rst | 51 ++++++++---- earthdiagnostics/diags.conf | 2 +- earthdiagnostics/{diags.py => earthdiags.py} | 6 +- earthdiagnostics/ocean/heatcontent.py | 2 +- launch_diags.sh | 6 +- setup.py | 2 +- 14 files changed, 195 insertions(+), 45 deletions(-) create mode 100644 doc/source/codedoc/general.rst create mode 100644 doc/source/diagnostic_list.rst rename earthdiagnostics/{diags.py => earthdiags.py} (98%) diff --git a/doc/source/codedoc/earthdiagnostics.rst b/doc/source/codedoc/earthdiagnostics.rst index 997c4c7..f4cefa7 100644 --- a/doc/source/codedoc/earthdiagnostics.rst +++ b/doc/source/codedoc/earthdiagnostics.rst @@ -8,16 +8,23 @@ earthdiagnostics.box :inherited-members: :members: -earthdiagnostics.constants --------------------------- -.. automodule:: earthdiagnostics.constants +earthdiagnostics.cdftools +------------------------- +.. automodule:: earthdiagnostics.cdftools :show-inheritance: :inherited-members: :members: -earthdiagnostics.cdftools -------------------------- -.. automodule:: earthdiagnostics.cdftools +earthdiagnostics.config +----------------------- +.. automodule:: earthdiagnostics.config + :show-inheritance: + :inherited-members: + :members: + +earthdiagnostics.constants +-------------------------- +.. automodule:: earthdiagnostics.constants :show-inheritance: :inherited-members: :members: @@ -37,16 +44,16 @@ earthdiagnostics.diagnostic :inherited-members: :members: -earthdiagnostics.diags ----------------------- -.. automodule:: earthdiagnostics.diags +earthdiagnostics.earthdiags +--------------------------- +.. automodule:: earthdiagnostics.earthdiags :show-inheritance: :inherited-members: :members: -earthdiagnostics.experimentmanager ----------------------------------- -.. automodule:: earthdiagnostics.experimentmanager +earthdiagnostics.parser +----------------------- +.. automodule:: earthdiagnostics.parser :show-inheritance: :inherited-members: :members: diff --git a/doc/source/codedoc/general.rst b/doc/source/codedoc/general.rst new file mode 100644 index 0000000..99200a0 --- /dev/null +++ b/doc/source/codedoc/general.rst @@ -0,0 +1,14 @@ +earthdiagnostics.general +======================== + +earthdiagnostics.general.monthlymean +------------------------------------ +.. automodule:: earthdiagnostics.general.monthlymean + :show-inheritance: + :members: + +earthdiagnostics.ocean.rewrite +------------------------------ +.. automodule:: earthdiagnostics.general.rewrite + :show-inheritance: + :members: diff --git a/doc/source/codedoc/main.rst b/doc/source/codedoc/main.rst index 8755b7d..1607284 100644 --- a/doc/source/codedoc/main.rst +++ b/doc/source/codedoc/main.rst @@ -6,4 +6,5 @@ Module documentation :titlesonly: earthdiagnostics + general ocean \ No newline at end of file diff --git a/doc/source/codedoc/ocean.rst b/doc/source/codedoc/ocean.rst index 9370d77..49d48c6 100644 --- a/doc/source/codedoc/ocean.rst +++ b/doc/source/codedoc/ocean.rst @@ -31,6 +31,18 @@ earthdiagnostics.ocean.gyres :show-inheritance: :members: +earthdiagnostics.ocean.heatcontent +---------------------------------- +.. automodule:: earthdiagnostics.ocean.heatcontent + :show-inheritance: + :members: + +earthdiagnostics.ocean.heatcontentlayer +--------------------------------------- +.. automodule:: earthdiagnostics.ocean.heatcontentlayer + :show-inheritance: + :members: + earthdiagnostics.ocean.interpolate ---------------------------------- .. automodule:: earthdiagnostics.ocean.interpolate @@ -43,6 +55,12 @@ earthdiagnostics.ocean.maxmoc :show-inheritance: :members: +earthdiagnostics.ocean.mixedlayerheatcontent +-------------------------------------------- +.. automodule:: earthdiagnostics.ocean.mixedlayerheatcontent + :show-inheritance: + :members: + earthdiagnostics.ocean.mixedlayersaltcontent -------------------------------------------- .. automodule:: earthdiagnostics.ocean.mixedlayersaltcontent diff --git a/doc/source/diagnostic_list.rst b/doc/source/diagnostic_list.rst new file mode 100644 index 0000000..c29d910 --- /dev/null +++ b/doc/source/diagnostic_list.rst @@ -0,0 +1,86 @@ +Diagnostic list +=============== + +In this section you have a list of the available diagnostics, with a small description of each one and a link to +the full documentation. To see what options are available for each diagnostic, see generate_jobs' documentation. + +Remember that diagnostics are specified separated by spaces while options are given separated by commas: + +.. code-block:: ini + + DIAGS = diag1 diag2,option1,option2 diag3 + + +General +------- + +- monmean: + Calculates the monthly mean of the given variable. + See :class:`~earthdiagnostics.general.monthlymean.MonthlyMean` + +- rewrite: + Just rewrites the CMOR output of a given variable. Useful to correct metadata or variable units. + See :class:`~earthdiagnostics.general.rewrite.Rewrite` + +Ocean +----- +- areamoc: + Compute an Atlantic MOC index. See :class:`~earthdiagnostics.ocean.areamoc.AreaMoc` + +- averagesection: + Compute an average of a given zone. The variable MUST be in a regular grid + See :class:`~earthdiagnostics.ocean.averagesection.AverageSection` + +- convectionsites: + Compute the intensity of convection in the four main convection sites. + See :class:`~earthdiagnostics.ocean.convectionsites.ConvectionSites` + +- cutsection: + Cuts a meridional or zonal section. See :class:`~earthdiagnostics.ocean.cutsection.CutSection` + +- gyres: + Compute the intensity of the subtropical and subpolar gyres. See :class:`~earthdiagnostics.ocean.gyres.Gyres` + +- heatcontent: + Compute the total ocean heat content. See :class:`~earthdiagnostics.ocean.heatcontent.HeatContent` + +- heatcontentlayer: + Point-wise Ocean Heat Content in a specified ocean thickness. + See :class:`~earthdiagnostics.ocean.heatcontentlayer.HeatContentLayer` + +- interpolate: + 3-dimensional conservative interpolation to the regular atmospheric grid. + It can also be used for 2D (i,j) variables. See :class:`~earthdiagnostics.ocean.interpolate.Interpolate` + +- maxmoc: + Compute an Atlantic MOC index by finding the maximum of the annual mean meridional overturning in a + latitude / depth region See :class:`~earthdiagnostics.ocean.maxmoc.MaxMoc` + +- mixedlayerheatcontent: + Compute mixed layer heat content. + See :class:`~earthdiagnostics.ocean.mixedlayerheatcontent.MixedLayerHeatContent` + +- mixedlayersaltcontent: + Compute mixed layer salt content. See + :class:`~earthdiagnostics.ocean.mixedlayersaltcontent.MixedLayerSaltContent` + +- moc: + Compute the MOC for oceanic basins. See :class:`~earthdiagnostics.ocean.moc.Moc` + +- psi: + Compute the barotropic stream function. See :class:`~earthdiagnostics.ocean.psi.Psi` + +- siasiesiv: + Compute the sea ice extent , area and volume in both hemispheres or a specified region. + See :class:`~earthdiagnostics.ocean.siasiesiv.Siasiesiv` + +- verticalmean: + Chooses vertical level in ocean, or vertically averages between 2 or more ocean levels. + See :class:`~earthdiagnostics.ocean.verticalmean.VerticalMean` + +- verticalmeanmeters: + Averages vertically any given variable. + See :class:`~earthdiagnostics.ocean.verticalmeanmeters.VerticalMeanMeters` + + + diff --git a/doc/source/errors.rst b/doc/source/errors.rst index c47c9e4..d71948c 100644 --- a/doc/source/errors.rst +++ b/doc/source/errors.rst @@ -7,9 +7,9 @@ good issue reports. Remember: a good issue report reduces the time required to s .. hint:: - Please, read carefully yhe error messsage. Most times the error message will point you to the problem's source and - sometimes even give you a hint of how to solve it by yourself. And if this it not the case or you find it obscure, - even if it was helpful, please contact the developers so it can be improved in further versions + Please, read carefully the error message. Most times the error message will point you to the problem's source and + sometimes even give you a hint of how to solve it by yourself. And if this it not the case or if you find it + obscure, even if it was helpful, please contact the developers so it can be improved in further versions Try this simple steps BEFORE reporting an issue @@ -25,9 +25,14 @@ it's fine that's all. If you experienced the same problem again, go to the GitLab portal and look into the open issues ( https://earth.bsc.es/gitlab/es/ocean_diagnostics/issues ). If you find your issue or a very similar one, use it to report your problems. If you can not find an open one that suites your problem, create a new one and explain what is -happening to you. - -In any case, it will be very useful if you can attach your diags.conf and log.txt files. +happening to you. In any case, it will be very useful if you can attach your diags.conf and log.txt files and specify +the machine you were using. After that, it's just a matter of waiting for the developers to do their work and answering the questions that they may have. Please, be patient. + +.. caution:: + + Of course, there is a third option: you keep experiencing an error that appears randomly on some executions but you + are not able to reproduce it in a consistent manner. Report it and attach as much logs and configuration files as + you have, along with the date and time of the errors. \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst index 4516651..c7858dc 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -10,6 +10,7 @@ Welcome to Earth Diagnostics's documentation! :maxdepth: 3 tutorial + diagnostic_list tips errors developers diff --git a/doc/source/tips.rst b/doc/source/tips.rst index 6883a11..0cd7de9 100644 --- a/doc/source/tips.rst +++ b/doc/source/tips.rst @@ -5,7 +5,7 @@ Working with ORCA1 ------------------ If you plan to run diagnostics for ORCA1 resolution, be aware that your workstation will be more than capable to run -them. At this resolution, memory and time consumption is low enough to allow you keep using the machine while running, +them. At this resolution, memory and CPU consumption is low enough to allow you keep using the machine while running, specially if you reserve a pair of cores for other uses. Configuring core usage @@ -22,3 +22,4 @@ NEMO files Unlike the bash version of the ocean diagnostics, this program keeps the NEMO files in the scratch folder so you can launch different configurations for the same experiment with reduced start time. You will need to remove the experiment's folder in the scratch directory at the end of the experiment to avoid wasting resources. + diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 2fb78b5..136c7bc 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -6,12 +6,12 @@ From now on this tutorial will guide you through all the process from installati .. Hint:: If you have any problem with this tutorial, please report it to so it can be corrected. - A lof of people will benefit from it and you will be mentioned here. + A lof of people will benefit from it. Installation ------------ -For now, you only have an option: dowload the diagnostics directly from BSC-ES's Gitlab: +For now, you only have one option: download the diagnostics directly from BSC-ES's Gitlab: .. code-block:: sh @@ -21,30 +21,47 @@ You will also need * CDO version 1.6.9 (other versions could work, but this is the one we use) * NCO version 4.5.4 or newer -* Python 2.7 or newer (but no 3.x) with Autosubmit, CDO and NCO packages -* Acces to CDFTOOLS_3.0 executables for BSC-ES. At this point, those are located at /home/Earth/jvegas/CDFTOOLS_CMOR/bin. +* Python 2.7 or newer (but no 3.x) with Autosubmit, CDO and NCO packages, among others. A virtual environment with all requisites fullfilled is available at /shared/earth/ClimatePrediction/EarthDiagnostics +* Access to CDFTOOLS_3.0 executables for BSC-ES. At this point, those are located at /shared/earth/ClimatePrediction/CDFTOOLS_CMOR/bin. -Call the diags with -h option to see if everything is ready: +Creating a config file +---------------------- -.. code-block:: sh +Go to the folder where you installed the EarthDiagnostics. You will see a folder called earthdiagnostics, +and, inside it, a diags.conf file that can be used as a model for your config file. Create a copy of it wherever it +suites you. - ${PATH_TO_REPOSITORY}/earthdiagnostics.diags.py -h +Now open your brand new copy with your preferred text editor. The file contains commentaries explaining each +one of its options, so read it carefully and edit whatever you need. Don't worry about DIAGS option, we will +talk about it next. -Creating a config file ----------------------- +After this, you need to choose the diagnostics you want to run. For a simple test, it's recommended to use the monmean +diagnostic to compute monthly means from daily data. We recommend it because it can be used with any variable, the user +has to provide parameters but they are quite intuitive and it's relatively fast to compute. If your experiment does not +have daily data, you can use any other diagnostic. Check next section for a list of available diagnostics and choose +whichever suits you better. From now on, we will assume that you are going to run the monmean diagnostic. -If you go into the earthdiagnostics folder in the git repository, you will see a diags.conf that can be used as a model -for your config file. It contains commentaries explaining what represents each one of its parameters, so please read it -carefully. +.. hint:: -Once you have configured your experiment you can execute any diagnostic by calling this command (substitute the -variables for the real paths before launching, please) + For old Ocean Diagnostics users: you can use most of the old names as aliases to launch one or multiple diagnostics. + Check the ALIAS section on the diags.conf to see which ones are available. + +First, choose a variable that has daily data. Then replace the DIAGS option with the next one where $VARIABLE represents the +variable's name and $DOMAIN its domain (atmos, ocean, seaice, landice...) .. code-block:: sh - ${PATH_TO_REPOSITORY}/earthdiagnostics.diags.py ${PATH_TO_MY_CONF_FILE} + DIAGS = monmean,$VARIABLE,$DOMAIN + +Prepare the run script +---------------------- + +Once you have configured your experiment you can execute any diagnostic with the provided launch_diags.sh script. +Create a copy and change the variables PATH_TO_CONF_FILE and PATH_TO_DIAGNOSTICS so they point to your conf file and +installation folder. + +Now, execute the script (or submit it to bsceslogin01, it has the correct header) and... that's it! +You will find your results directly on the storage and a folder for the temp files in the scratch named after the EXPID. -And... that's it. You will find your results inside CMOR's folder tree and a folder for the temp files in the scratch. -This folder is named after the EXPID. diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 6ee50be..110a9de 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -13,7 +13,7 @@ DIAGS = # and has a parameter to specify input's frequency) FREQUENCY = mon # Path to CDFTOOLS binaries -CDFTOOLS_PATH = ~jvegas/CDFTOOLS_CMOR/bin +CDFTOOLS_PATH = /shared/earth/ClimatePrediction/CDFTOOLS_CMOR/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/earthdiags.py similarity index 98% rename from earthdiagnostics/diags.py rename to earthdiagnostics/earthdiags.py index d356755..60969b9 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/earthdiags.py @@ -23,7 +23,7 @@ from ocean import ConvectionSites, Gyres, Psi, MaxMoc, AreaMoc, Moc, VerticalMea from utils import Utils -class Diags(object): +class EarthDiags(object): """ Launcher class for the diagnostics @@ -107,7 +107,7 @@ class Diags(object): threads = list() for num_thread in range(0, num_threads): self.time[num_thread] = dict() - t = threading.Thread(target=Diags._run_jobs, args=(self, list_jobs, num_thread)) + t = threading.Thread(target=EarthDiags._run_jobs, args=(self, list_jobs, num_thread)) threads.append(t) t.start() @@ -261,7 +261,7 @@ def main(): if args.logfilepath: Log.set_file(Utils.expand_path(args.logfilepath)) - diags = Diags(Utils.expand_path(args.configfile)) + diags = EarthDiags(Utils.expand_path(args.configfile)) if args.clean: diags.clean() else: diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index 963e282..2319a18 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -12,7 +12,7 @@ from earthdiagnostics.box import Box class HeatContent(Diagnostic): """ - Compute the total ocean heat extent + Compute the total ocean heat content :original author: Virginie Guemas :contributor: Javier Vegas-Regidor diff --git a/launch_diags.sh b/launch_diags.sh index 9dfa14a..cd1c013 100755 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -7,9 +7,9 @@ set -xv -PATH_TO_DIAGNOSTICS=~/pyCharm/ocean_diagnostics -PATH_TO_VIRTUALENV=/home/Earth/jvegas/virtualenvs/diags/bin PATH_TO_CONF_FILE=diags.conf +PATH_TO_DIAGNOSTICS=~/pyCharm/ocean_diagnostics +PATH_TO_VIRTUALENV=/shared/earth/ClimatePrediction/EarthDiagnostics/bin module purge module load NCO/4.5.4-foss-2015a @@ -20,4 +20,4 @@ source ${PATH_TO_VIRTUALENV}/activate export PYTHONPATH=${PATH_TO_DIAGNOSTICS}:${PYTHONPATH} cd ${PATH_TO_DIAGNOSTICS}/earthdiagnostics/ -./diags.py -lc DEBUG -f ${PATH_TO_CONF_FILE} +./earthdiags.py -lc DEBUG -f ${PATH_TO_CONF_FILE} diff --git a/setup.py b/setup.py index 44071e3..a377169 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ setup( author_email='javier.vegas@bsc.es', url='http://www.bsc.es/projects/earthscience/autosubmit/', keywords=['climate', 'weather', 'diagnostic'], - install_requires=['numpy', 'netCDF4', 'autosubmit', 'cdo', 'pygrib', 'nco', 'cfunits>=1.1.4', 'coverage', ], + install_requires=['numpy', 'netCDF4', 'autosubmit', 'cdo', 'pygrib', 'nco', 'cfunits>=1.1.4', 'coverage', 'pyproj'], packages=find_packages(), include_package_data=True, package_data={'earthdiagnostics': [ -- GitLab From a87231ecd859c539fa29ad16f85b890639242342 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 5 Sep 2016 17:51:18 +0200 Subject: [PATCH 193/268] Bumped version and updated pdf documentation --- EarthDiagnostics.pdf | Bin 201103 -> 232539 bytes VERSION | 2 +- doc/source/conf.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index bea81421cda1ed54adb9e6aa4bdfbb2d5d77dc82..3f451ec071c0ccdd9d5c6746921328348459bedc 100644 GIT binary patch delta 193391 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

<#RF4lp8~WjrLi+dx#jpKwR?md*bM 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 z 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

Y3|(N+h4=h@~JK9;^jiyK90uj-GLoW#G=AD%uh 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 Date: Mon, 12 Sep 2016 13:15:35 +0200 Subject: [PATCH 194/268] Fixed mixed timestep when cmorizing atmosphere from grib_files. Started preparation of launcher and installation --- bin/earthdiags | 22 +++++++ earthdiagnostics/datamanager.py | 16 ++--- earthdiagnostics/diags.conf | 12 ++-- earthdiagnostics/earthdiags.py | 108 ++++++++++++++++++++------------ earthdiagnostics/utils.py | 11 ++++ setup.py | 4 +- 6 files changed, 116 insertions(+), 57 deletions(-) create mode 100644 bin/earthdiags diff --git a/bin/earthdiags b/bin/earthdiags new file mode 100644 index 0000000..95f9c27 --- /dev/null +++ b/bin/earthdiags @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +"""Script for launching Earth Diagnostics""" +import os +import sys + +scriptdir = os.path.abspath(os.path.dirname(sys.argv[0])) +assert sys.path[0] == scriptdir +sys.path[0] = os.path.normpath(os.path.join(scriptdir, os.pardir)) + +# noinspection PyUnresolvedReferences +from earthdiagnostics.earthdiags import EarthDiags + + +# noinspection PyProtectedMember +def main(): + if not EarthDiags.parse_args(): + os._exit(1) + os._exit(0) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 222fcc2..286a3d3 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -146,7 +146,7 @@ class DataManager(object): self._get_grib_filename(grid, add_months(current_month, -1, 'standard'))) if os.path.exists(prev_gribfile): - self._merge_grib_files(current_month, gribfile, grid, prev_gribfile) + self._merge_grib_files(current_month, prev_gribfile, gribfile) full_file = 'ICM' else: full_file = gribfile @@ -162,9 +162,8 @@ class DataManager(object): Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' '{0}_{{142,143}}.128.nc'.format(gribfile), output='{0}_228.128.nc'.format(gribfile)) - if full_file == 'ICM': - os.remove('ICM') - next_gribfile = os.path.join(self.config.scratch_dir, + Utils.remove_file('ICM') + next_gribfile = os.path.join(data_folder, self._get_grib_filename(grid, add_months(current_month, 1, 'standard'))) @@ -180,7 +179,7 @@ class DataManager(object): for splited_file in glob.glob('{0}_*.128.nc'.format(gribfile)): os.remove(splited_file) - Log.result('Month {0} finished', date2str(current_month)) + Log.result('Month {0}, {1} variables finished', date2str(current_month), grid) count += 1 self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1m') @@ -190,7 +189,7 @@ class DataManager(object): chunk_start = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') @staticmethod - def _merge_grib_files(current_month, gribfile, grid, prev_gribfile): + def _merge_grib_files(current_month, prev_gribfile, gribfile): Log.info('Merging data from different files...') fd = open('rules_files', 'w') fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(current_month)) @@ -199,9 +198,10 @@ class DataManager(object): if os.path.exists('ICM'): os.remove('ICM') Utils.execute_shell_command('grib_filter -o ICM rules_files ' - '{0} {1}'.format(grid, os.path.basename(prev_gribfile), gribfile)) + '{0} {1}'.format(os.path.basename(prev_gribfile), + os.path.basename(gribfile))) os.remove('rules_files') - os.remove(prev_gribfile) + Utils.remove_file(prev_gribfile) def _get_atmos_timestep(self, gribfile): Log.info('Getting timestep...') diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 110a9de..862fe84 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -21,7 +21,7 @@ RESTORE_MESHES = False [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = False +FORCE = True # If true, CMORizes ocean files. Default = True OCEAN_FILES = False # If true, CMORizes atmosphere files. Default = True @@ -57,7 +57,7 @@ ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, INSTITUTE = BSC MODEL = EC-EARTH # Model version: Available versions -MODEL_VERSION =Ec3.0_O1L46 +MODEL_VERSION =Ec3.2_O1L75 # Atmos output timestep in hours ATMOS_TIMESTEP = 6 @@ -70,12 +70,12 @@ ATMOS_TIMESTEP = 6 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment -EXPID = a032 -STARTDATES = 20300101 +EXPID = a09i +STARTDATES = 19900101 MEMBERS = 0 MEMBER_DIGITS = 1 -CHUNK_SIZE = 12 -CHUNKS = 1 +CHUNK_SIZE = 1 +CHUNKS = 12 # CHUNKS = 1 diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 60969b9..74f4ed0 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -5,6 +5,7 @@ import Queue import argparse import shutil import threading +import pkg_resources import netCDF4 import operator @@ -30,6 +31,21 @@ class EarthDiags(object): :param config_file: path to the configuration file :type config_file: str """ + # Get the version number from the relevant file. If not, from autosubmit package + scriptdir = os.path.abspath(os.path.dirname(__file__)) + + if not os.path.exists(os.path.join(scriptdir, 'VERSION')): + scriptdir = os.path.join(scriptdir, os.path.pardir) + + version_path = os.path.join(scriptdir, 'VERSION') + readme_path = os.path.join(scriptdir, 'README') + changes_path = os.path.join(scriptdir, 'CHANGELOG') + if os.path.isfile(version_path): + with open(version_path) as f: + autosubmit_version = f.read().strip() + else: + autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version + def __init__(self, config_file): Log.debug('Initialising Diags') self.config = Config(config_file) @@ -40,6 +56,56 @@ class EarthDiags(object): self.time = dict() Log.debug('Diags ready') + @staticmethod + def parse_args(): + """ + Entry point for the Earth Diagnostics. For more detailed documentation, use -h option + """ + try: + parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') + parser.add_argument('-v', '--version', action='version', version='3.0.0b8', + help="returns Earth Diagnostics's version number and exit") + parser.add_argument('--doc', action='store_true', + help="opens documentation and exits") + parser.add_argument('--clean', action='store_true', + help="clean the scratch folder and exits") + parser.add_argument('-lf', '--logfile', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', + 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), + default='DEBUG', type=str, + help="sets file's log level.") + parser.add_argument('-lc', '--logconsole', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', + 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), + default='INFO', type=str, + help="sets console's log level") + + parser.add_argument('-log', '--logfilepath', default=None, type=str) + + parser.add_argument('-f', '--configfile', default='diags.conf', type=str) + + args = parser.parse_args() + if args.doc: + Log.info('Opening documentation...') + Utils.execute_shell_command(('xdg-open', os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', + 'EarthDiagnostics.pdf'))) + Log.result('Documentation opened!') + return True + Log.set_console_level(args.logconsole) + Log.set_file_level(args.logfile) + if args.logfilepath: + Log.set_file(Utils.expand_path(args.logfilepath)) + + diags = EarthDiags(Utils.expand_path(args.configfile)) + if args.clean: + diags.clean() + else: + diags.run() + TempFile.clean() + + except Exception as e: + from traceback import format_exc + Log.critical('Unhandled exception on EarthDiagnostics: {0}\n{1}', e, format_exc(10)) + return False + def _create_dic_variables(self): self.dic_variables = dict() self.dic_variables['x'] = 'i' @@ -226,47 +292,7 @@ class EarthDiags(object): def main(): - """ - Entry point for the Earth Diagnostics. For more detailed documentation, use -h option - """ - parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') - parser.add_argument('-v', '--version', action='version', version='3.0.0b3', - help="returns Earth Diagnostics's version number and exit") - parser.add_argument('--doc', action='store_true', - help="opens documentation and exits") - parser.add_argument('--clean', action='store_true', - help="clean the scratch folder and exits") - parser.add_argument('-lf', '--logfile', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', - 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), - default='DEBUG', type=str, - help="sets file's log level.") - parser.add_argument('-lc', '--logconsole', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', - 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), - default='INFO', type=str, - help="sets console's log level") - - parser.add_argument('-log', '--logfilepath', default=None, type=str) - - parser.add_argument('-f', '--configfile', default='diags.conf', type=str) - - args = parser.parse_args() - if args.doc: - Log.info('Opening documentation...') - Utils.execute_shell_command(('xdg-open', os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', - 'EarthDiagnostics.pdf'))) - Log.result('Documentation opened!') - return - Log.set_console_level(args.logconsole) - Log.set_file_level(args.logfile) - if args.logfilepath: - Log.set_file(Utils.expand_path(args.logfilepath)) - - diags = EarthDiags(Utils.expand_path(args.configfile)) - if args.clean: - diags.clean() - else: - diags.run() - TempFile.clean() + EarthDiags.parse_args() if __name__ == "__main__": diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index caa0205..9229cfc 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -145,6 +145,17 @@ class Utils(object): hash_destiny = Utils.get_file_hash(destiny) os.remove(source) + @staticmethod + def remove_file(path): + """ + Removes a file, checking before if its exists + + :param path: path to file + :type path: str + """ + if os.path.isfile(path): + os.remove(path) + @staticmethod def get_file_hash(filepath): """ diff --git a/setup.py b/setup.py index a377169..db83c49 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,6 @@ setup( 'README', 'VERSION', 'EarthDiagnostics.pdf' - ] - }, + ]}, + scripts=['bin/earthdiags'] ) -- GitLab From f6de9e91bba13ec3af1daf283660cfb40907a7a9 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 14:59:49 +0200 Subject: [PATCH 195/268] Finished launch script --- bin/earthdiags | 6 +++++- earthdiagnostics/diags.conf => diags.conf | 0 earthdiagnostics/earthdiags.py | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) rename earthdiagnostics/diags.conf => diags.conf (100%) diff --git a/bin/earthdiags b/bin/earthdiags index 95f9c27..3895867 100644 --- a/bin/earthdiags +++ b/bin/earthdiags @@ -1,4 +1,5 @@ #!/usr/bin/env python +# coding=utf-8 """Script for launching Earth Diagnostics""" import os @@ -14,9 +15,12 @@ from earthdiagnostics.earthdiags import EarthDiags # noinspection PyProtectedMember def main(): + """ + Entry point for the Earth Diagnostics + """ if not EarthDiags.parse_args(): os._exit(1) os._exit(0) if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/earthdiagnostics/diags.conf b/diags.conf similarity index 100% rename from earthdiagnostics/diags.conf rename to diags.conf diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 74f4ed0..d30f1ca 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -100,6 +100,7 @@ class EarthDiags(object): else: diags.run() TempFile.clean() + return True except Exception as e: from traceback import format_exc -- GitLab From b09e57fd56149c532f338493e2dca45434c5a21e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 15:13:56 +0200 Subject: [PATCH 196/268] Changed location of cdftoolspython.so --- .../cdftoolspython.so | Bin earthdiagnostics/ocean/siasiesiv.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename cdftoolspython.so => earthdiagnostics/cdftoolspython.so (100%) diff --git a/cdftoolspython.so b/earthdiagnostics/cdftoolspython.so similarity index 100% rename from cdftoolspython.so rename to earthdiagnostics/cdftoolspython.so diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 7f36ff0..5636f50 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -4,7 +4,7 @@ import os from earthdiagnostics.constants import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile -import cdftoolspython +import earthdiagnostics.cdftoolspython import numpy as np -- GitLab From e431d31a0bb578054772bb1c929b066e59017f69 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 15:28:07 +0200 Subject: [PATCH 197/268] Added ocean timestep configuration --- diags.conf | 4 +++- earthdiagnostics/config.py | 1 + earthdiagnostics/datamanager.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/diags.conf b/diags.conf index 862fe84..d5375ef 100644 --- a/diags.conf +++ b/diags.conf @@ -58,8 +58,10 @@ INSTITUTE = BSC MODEL = EC-EARTH # Model version: Available versions MODEL_VERSION =Ec3.2_O1L75 -# Atmos output timestep in hours +# Atmospheric output timestep in hours ATMOS_TIMESTEP = 6 +# Ocean output timestep in hours +OCEAN_TIMESTEP = 6 # For those who use Autosubmit, this will be easy # EXPID is the unique identifier of the experiment. diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index edde99c..aa499ae 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -160,6 +160,7 @@ class ExperimentConfig(object): calendar = parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') self.model = parser.get_option('EXPERIMENT', 'MODEL') self.atmos_timestep = parser.get_int_option('EXPERIMENT', 'ATMOS_TIMESTEP') + self.ocean_timestep = parser.get_int_option('EXPERIMENT', 'OCEAN_TIMESTEP') self.model_version = parser.get_option('EXPERIMENT', 'MODEL_VERSION') self.startdates = startdates diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 286a3d3..272bd9d 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -873,7 +873,7 @@ class DataManager(object): freq_str = 'monthly_mean' if domain in ['ocean', 'seaIce']: - variable_folder = '{0}_f6h'.format(var) + variable_folder = '{0}_f{0}h'.format(var, self.experiment.ocean_timestep) else: variable_folder = '{0}_f{1}h'.format(var, self.atmos_timestep) -- GitLab From 082bd85e2fee3392c1ec2c6afad04215a4a4d51c Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 15:38:03 +0200 Subject: [PATCH 198/268] Testing manifest file --- MANIFEST.in | 6 ++++++ earthdiagnostics/earthdiags.py | 4 ++++ setup.py | 9 --------- 3 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..ebd38d5 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,6 @@ +include earthdiagnostics/*.csv +include earthdiagnostics/*.so +include diags.conf +include README +include VERSION +include EarthDiagnostics.pdf \ No newline at end of file diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index d30f1ca..464c774 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -40,12 +40,16 @@ class EarthDiags(object): version_path = os.path.join(scriptdir, 'VERSION') readme_path = os.path.join(scriptdir, 'README') changes_path = os.path.join(scriptdir, 'CHANGELOG') + documentation_path = os.path.join(scriptdir, 'EarthDiagnostics.pdf') if os.path.isfile(version_path): with open(version_path) as f: autosubmit_version = f.read().strip() else: autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version + if not os.path.isfile(documentation_path): + autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version + def __init__(self, config_file): Log.debug('Initialising Diags') self.config = Config(config_file) diff --git a/setup.py b/setup.py index db83c49..17f4b07 100644 --- a/setup.py +++ b/setup.py @@ -27,14 +27,5 @@ setup( install_requires=['numpy', 'netCDF4', 'autosubmit', 'cdo', 'pygrib', 'nco', 'cfunits>=1.1.4', 'coverage', 'pyproj'], packages=find_packages(), include_package_data=True, - package_data={'earthdiagnostics': [ - 'earthdiagnostics/conversions.csv', - 'earthdiagnostics/cmor_table.csv', - 'earthdiagnostics/diags.conf', - 'cdftoolspython.so' - 'README', - 'VERSION', - 'EarthDiagnostics.pdf' - ]}, scripts=['bin/earthdiags'] ) -- GitLab From a3beb0d673441ab098699c9a96b4359fb6fffecd Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 15:41:25 +0200 Subject: [PATCH 199/268] Fixed --doc command --- earthdiagnostics/earthdiags.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 464c774..cdcb093 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -89,8 +89,10 @@ class EarthDiags(object): args = parser.parse_args() if args.doc: Log.info('Opening documentation...') - Utils.execute_shell_command(('xdg-open', os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', - 'EarthDiagnostics.pdf'))) + doc_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'EarthDiagnostics.pdf') + if not os.path.isfile(doc_path): + doc_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'EarthDiagnostics.pdf') + Utils.execute_shell_command(('xdg-open', doc_path)) Log.result('Documentation opened!') return True Log.set_console_level(args.logconsole) -- GitLab From b1f11f1737b4e7e70c77138914fcd5fad69bd3f8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 15:44:08 +0200 Subject: [PATCH 200/268] Fixed pdf location --- MANIFEST.in | 2 +- .../EarthDiagnostics.pdf | Bin earthdiagnostics/earthdiags.py | 7 +------ 3 files changed, 2 insertions(+), 7 deletions(-) rename EarthDiagnostics.pdf => earthdiagnostics/EarthDiagnostics.pdf (100%) diff --git a/MANIFEST.in b/MANIFEST.in index ebd38d5..d3fa2e0 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,4 +3,4 @@ include earthdiagnostics/*.so include diags.conf include README include VERSION -include EarthDiagnostics.pdf \ No newline at end of file +include earthdiagnostics/EarthDiagnostics.pdf \ No newline at end of file diff --git a/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf similarity index 100% rename from EarthDiagnostics.pdf rename to earthdiagnostics/EarthDiagnostics.pdf diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index cdcb093..9850860 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -44,11 +44,8 @@ class EarthDiags(object): if os.path.isfile(version_path): with open(version_path) as f: autosubmit_version = f.read().strip() - else: - autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version + else: autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version - if not os.path.isfile(documentation_path): - autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version def __init__(self, config_file): Log.debug('Initialising Diags') @@ -90,8 +87,6 @@ class EarthDiags(object): if args.doc: Log.info('Opening documentation...') doc_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'EarthDiagnostics.pdf') - if not os.path.isfile(doc_path): - doc_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'EarthDiagnostics.pdf') Utils.execute_shell_command(('xdg-open', doc_path)) Log.result('Documentation opened!') return True -- GitLab From e185c8456b3fa0a8762e73c4781fcf5e7a4517b1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 16:05:37 +0200 Subject: [PATCH 201/268] Automatic correction of domain capitalization. Added grid parameter to monthlymean diagnostic --- earthdiagnostics/datamanager.py | 11 +++++++++++ earthdiagnostics/general/monthlymean.py | 23 ++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 272bd9d..27a1919 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -616,6 +616,7 @@ class DataManager(object): if not frequency: frequency = self.config.frequency + domain = DataManager.correct_domain(domain) domain_abbreviation = self.domain_abbreviation(domain, frequency) start = parse_date(startdate) @@ -705,6 +706,7 @@ class DataManager(object): if not frequency: frequency = self.config.frequency + domain = DataManager.correct_domain(domain) domain_abreviattion = self.domain_abbreviation(domain, frequency) start = parse_date(startdate) @@ -866,6 +868,15 @@ class DataManager(object): Utils.move_file(filetosend, filepath) self._create_link(domain, filepath, frequency, var) + @staticmethod + def correct_domain(domain): + domain = domain.lower() + if domain == 'seaice': + return 'seaIce' + elif domain == 'landice': + return 'landIce' + return domain + def _create_link(self, domain, filepath, frequency, var): if frequency in ('d', 'daily', 'day'): freq_str = 'daily_mean' diff --git a/earthdiagnostics/general/monthlymean.py b/earthdiagnostics/general/monthlymean.py index 70523df..8ca4479 100644 --- a/earthdiagnostics/general/monthlymean.py +++ b/earthdiagnostics/general/monthlymean.py @@ -27,12 +27,14 @@ class MonthlyMean(Diagnostic): :type domain: str :param frequency: original frequency :type frequency: str + :param grid: original data grid + :type grid: str """ alias = 'monmean' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, domain, variable, frequency): + def __init__(self, data_manager, startdate, member, chunk, domain, variable, frequency, grid): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member @@ -40,6 +42,7 @@ class MonthlyMean(Diagnostic): self.variable = variable self.domain = domain self.frequency = frequency + self.grid = grid def __str__(self): return 'Calculate monthly mean Startdate: {0} Member: {1} Chunk: {2} ' \ @@ -47,7 +50,8 @@ class MonthlyMean(Diagnostic): def __eq__(self, other): return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ - self.domain == other.domain and self.variable == other.variable and self.frequency == other.frequency + self.domain == other.domain and self.variable == other.variable and self.frequency == other.frequency and \ + self.grid == other.grid @classmethod def generate_jobs(cls, diags, options): @@ -56,7 +60,7 @@ class MonthlyMean(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: variable, domain, frequency=day + :param options: variable, domain, frequency=day, grid='' :type options: list[str] :return: """ @@ -64,17 +68,22 @@ class MonthlyMean(Diagnostic): if num_options < 2: raise Exception('You must specify the variable and domain to average monthly') if num_options > 3: - raise Exception('You must specify between 2 and 3 parameters for the monthly mean diagnostic') + raise Exception('You must specify between 2 and 4 parameters for the monthly mean diagnostic') variable = options[1] domain = options[2] if num_options >= 3: frequency = options[3] else: frequency = 'day' + if num_options >= 4: + grid = options[4] + else: + grid = '' job_list = list() for startdate, member, chunk in diags.exp_manager.get_chunk_list(): - job_list.append(MonthlyMean(diags.data_manager, startdate, member, chunk, domain, variable, frequency)) + job_list.append(MonthlyMean(diags.data_manager, startdate, member, chunk, domain, variable, + frequency, grid)) return job_list def compute(self): @@ -83,10 +92,10 @@ class MonthlyMean(Diagnostic): """ temp = TempFile.get() variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk, - frequency=self.frequency) + frequency=self.frequency, grid=self.grid) Utils.cdo.monmean(input=variable_file, output=temp, options='-O') os.remove(variable_file) self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, - frequency='mon') + frequency='mon', grid=self.grid) -- GitLab From 6ad32b45cfd04e1a92507e78a7410f00b13e4f5b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 16:13:44 +0200 Subject: [PATCH 202/268] Added grid to link folder --- earthdiagnostics/datamanager.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 27a1919..e9d1744 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -866,10 +866,17 @@ class DataManager(object): Utils.rename_variables(filetosend, variables, False, True) Utils.move_file(filetosend, filepath) - self._create_link(domain, filepath, frequency, var) + self._create_link(domain, filepath, frequency, var, grid) @staticmethod def correct_domain(domain): + """ + Corrects domain capitalization + :param domain: domain name + :type domain: str + :return: domain with correct capitalization + :rtype: str + """ domain = domain.lower() if domain == 'seaice': return 'seaIce' @@ -877,12 +884,15 @@ class DataManager(object): return 'landIce' return domain - def _create_link(self, domain, filepath, frequency, var): + def _create_link(self, domain, filepath, frequency, var, grid): if frequency in ('d', 'daily', 'day'): freq_str = 'daily_mean' else: freq_str = 'monthly_mean' + if grid: + var = '{0}-{1}'.format(var, grid) + if domain in ['ocean', 'seaIce']: variable_folder = '{0}_f{0}h'.format(var, self.experiment.ocean_timestep) else: -- GitLab From 387c48e23ace97995b9b287d8aff43e3f264be5d Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 12 Sep 2016 16:27:57 +0200 Subject: [PATCH 203/268] Bumped version and updated doc --- VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/EarthDiagnostics.pdf | Bin 232539 -> 233001 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 6783f3b..9e0b71d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b8 +3.0.0b9 diff --git a/doc/source/conf.py b/doc/source/conf.py index 9d6fca1..fe23e77 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b8' +release = '3.0.0b9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index 3f451ec071c0ccdd9d5c6746921328348459bedc..a2a74c07e770c5d7c09da5f312f28c322030dd0d 100644 GIT binary patch delta 97703 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

`e(aTpb_*l7W>M`=DZ{9BS`^d}<|*t;N(V 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

gE!Bb>e_)6D2S!OXvGc-(@M6*pt^<#6v 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 AbpQYW delta 96949 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

ij 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 F{|8BlL~Q^7 -- GitLab From 044896d98c1c500ebcf8e1d0010eac6204647fcd Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 14 Sep 2016 10:01:33 +0200 Subject: [PATCH 204/268] Fixed error on diagnostic creation --- earthdiagnostics/earthdiags.py | 4 ++-- earthdiagnostics/general/monthlymean.py | 2 +- earthdiagnostics/general/rewrite.py | 2 +- earthdiagnostics/ocean/areamoc.py | 2 +- earthdiagnostics/ocean/averagesection.py | 2 +- earthdiagnostics/ocean/convectionsites.py | 2 +- earthdiagnostics/ocean/cutsection.py | 2 +- earthdiagnostics/ocean/gyres.py | 2 +- earthdiagnostics/ocean/heatcontent.py | 2 +- earthdiagnostics/ocean/heatcontentlayer.py | 2 +- earthdiagnostics/ocean/interpolate.py | 5 +++-- earthdiagnostics/ocean/maxmoc.py | 2 +- earthdiagnostics/ocean/mixedlayerheatcontent.py | 2 +- earthdiagnostics/ocean/mixedlayersaltcontent.py | 2 +- earthdiagnostics/ocean/moc.py | 2 +- earthdiagnostics/ocean/psi.py | 2 +- earthdiagnostics/ocean/siasiesiv.py | 2 +- earthdiagnostics/ocean/verticalmean.py | 2 +- earthdiagnostics/ocean/verticalmeanmeters.py | 2 +- test/unit/test_areamoc.py | 2 +- test/unit/test_averagesection.py | 2 +- test/unit/test_convectionsites.py | 2 +- test/unit/test_cutsection.py | 2 +- test/unit/test_gyres.py | 2 +- test/unit/test_heatcontent.py | 2 +- test/unit/test_heatcontentlayer.py | 2 +- test/unit/test_interpolate.py | 2 +- test/unit/test_maxmoc.py | 4 ++-- test/unit/test_mixedlayerheatcontent.py | 2 +- test/unit/test_mixedlayersaltcontent.py | 2 +- test/unit/test_moc.py | 2 +- test/unit/test_monthlymean.py | 17 +++++++++++------ test/unit/test_psi.py | 2 +- test/unit/test_rewrite.py | 2 +- test/unit/test_siasiesiv.py | 2 +- test/unit/test_verticalmean.py | 2 +- test/unit/test_verticalmeanmeters.py | 2 +- 37 files changed, 51 insertions(+), 45 deletions(-) diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 9850860..d7bbdda 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -44,8 +44,8 @@ class EarthDiags(object): if os.path.isfile(version_path): with open(version_path) as f: autosubmit_version = f.read().strip() - else: autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version - + else: + autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version def __init__(self, config_file): Log.debug('Initialising Diags') diff --git a/earthdiagnostics/general/monthlymean.py b/earthdiagnostics/general/monthlymean.py index 8ca4479..c787d5a 100644 --- a/earthdiagnostics/general/monthlymean.py +++ b/earthdiagnostics/general/monthlymean.py @@ -81,7 +81,7 @@ class MonthlyMean(Diagnostic): grid = '' job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(MonthlyMean(diags.data_manager, startdate, member, chunk, domain, variable, frequency, grid)) return job_list diff --git a/earthdiagnostics/general/rewrite.py b/earthdiagnostics/general/rewrite.py index 5425927..77a6fe9 100644 --- a/earthdiagnostics/general/rewrite.py +++ b/earthdiagnostics/general/rewrite.py @@ -63,7 +63,7 @@ class Rewrite(Diagnostic): variable = options[1] domain = options[2] job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(Rewrite(diags.data_manager, startdate, member, chunk, domain, variable)) return job_list diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 7e0c93d..7ea6f1b 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -81,7 +81,7 @@ class AreaMoc(Diagnostic): basin = Basins.Global job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(AreaMoc(diags.data_manager, startdate, member, chunk, basin, box)) return job_list diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 56d01c4..1ac8f8e 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -80,7 +80,7 @@ class AverageSection(Diagnostic): domain = 'ocean' job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(AverageSection(diags.data_manager, startdate, member, chunk, domain, variable, box)) return job_list diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 43e6fa5..8c49dd0 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -61,7 +61,7 @@ class ConvectionSites(Diagnostic): if len(options) > 1: raise Exception('The convection sites diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(ConvectionSites(diags.data_manager, startdate, member, chunk, diags.model_version)) return job_list diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index bf62c53..03a3fdb 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -83,7 +83,7 @@ class CutSection(Diagnostic): domain = 'ocean' job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(CutSection(diags.data_manager, startdate, member, chunk, domain, variable, zonal, value)) return job_list diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 6624569..0fefb93 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -62,7 +62,7 @@ class Gyres(Diagnostic): if len(options) > 1: raise Exception('The gyres diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(Gyres(diags.data_manager, startdate, member, chunk, diags.model_version)) return job_list diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index 2319a18..a00e9f9 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -81,7 +81,7 @@ class HeatContent(Diagnostic): box.min_depth = int(options[3]) box.max_depth = int(options[4]) job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(HeatContent(diags.data_manager, startdate, member, chunk, basin, mixed_layer, box)) return job_list diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 459ca56..c9921fe 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -148,7 +148,7 @@ class HeatContentLayer(Diagnostic): max_level += 1 weight = weight[:, min_level:max_level, :] - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(HeatContentLayer(diags.data_manager, startdate, member, chunk, box, weight, min_level, max_level)) return job_list diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index cbb4d2c..b526da8 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -84,9 +84,10 @@ class Interpolate(Diagnostic): domain = 'ocean' job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append( - Interpolate(diags.data_manager, startdate, member, chunk, domain, variable, diags.model_version)) + Interpolate(diags.data_manager, startdate, member, chunk, domain, variable, + diags.config.experiment.model_version)) return job_list def compute(self): diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 6b70bc3..2b91345 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -83,7 +83,7 @@ class MaxMoc(Diagnostic): job_list = list() for startdate in diags.startdates: for member in diags.members: - years = diags.exp_manager.get_full_years(startdate) + years = diags.config.experiment.get_full_years(startdate) if len(years) == 0: Log.user_warning('No complete years are available with the given configuration. ' 'MaxMoc can not be computed') diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index f967e5f..e5b43c4 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -58,7 +58,7 @@ class MixedLayerHeatContent(Diagnostic): if len(options) > 1: raise Exception('The mixed layer ocean heat content diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(MixedLayerHeatContent(diags.data_manager, startdate, member, chunk)) return job_list diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 915c38c..9c53bb4 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -56,7 +56,7 @@ class MixedLayerSaltContent(Diagnostic): if len(options) > 1: raise Exception('The mixed layer salt content diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(MixedLayerSaltContent(diags.data_manager, startdate, member, chunk)) return job_list diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index 76ff9ec..29040a7 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -59,7 +59,7 @@ class Moc(Diagnostic): if len(options) > 1: raise Exception('The MOC diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(Moc(diags.data_manager, startdate, member, chunk)) return job_list diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index f40d9e4..bd7356f 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -55,7 +55,7 @@ class Psi(Diagnostic): if len(options) > 1: raise Exception('The PSI diagnostic has no options') job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(Psi(diags.data_manager, startdate, member, chunk)) return job_list diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index 5636f50..e1b4645 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -73,7 +73,7 @@ class Siasiesiv(Diagnostic): mask = Utils.get_mask(basin) job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(Siasiesiv(diags.data_manager, startdate, member, chunk, basin, mask)) mesh_handler = Utils.openCdf('mesh_hgr.nc') Siasiesiv.e1t = np.asfortranarray(mesh_handler.variables['e1t'][0, :]) diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 1d48383..0af7ec8 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -77,7 +77,7 @@ class VerticalMean(Diagnostic): box.max_depth = float(options[3]) job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(VerticalMean(diags.data_manager, startdate, member, chunk, variable, box)) return job_list diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index adc7e3f..d5a7a5f 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -75,7 +75,7 @@ class VerticalMeanMeters(Diagnostic): box.max_depth = float(options[3]) job_list = list() - for startdate, member, chunk in diags.exp_manager.get_chunk_list(): + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(VerticalMeanMeters(diags.data_manager, startdate, member, chunk, variable, box)) return job_list diff --git a/test/unit/test_areamoc.py b/test/unit/test_areamoc.py index 6992604..f9894d8 100644 --- a/test/unit/test_areamoc.py +++ b/test/unit/test_areamoc.py @@ -19,7 +19,7 @@ class TestAreaMoc(TestCase): self.box.min_depth = 0 self.box.max_depth = 0 - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.psi = AreaMoc(self.data_manager, '20000101', 1, 1, Basins.Antarctic, self.box) def test_generate_jobs(self): diff --git a/test/unit/test_averagesection.py b/test/unit/test_averagesection.py index 3707fa2..982ec6c 100644 --- a/test/unit/test_averagesection.py +++ b/test/unit/test_averagesection.py @@ -18,7 +18,7 @@ class TestAverageSection(TestCase): self.box.min_lon = 0 self.box.max_lon = 0 - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.psi = AverageSection(self.data_manager, '20000101', 1, 1, 'domain', 'var', self.box) def test_generate_jobs(self): diff --git a/test/unit/test_convectionsites.py b/test/unit/test_convectionsites.py index 282dcd9..b6a7e54 100644 --- a/test/unit/test_convectionsites.py +++ b/test/unit/test_convectionsites.py @@ -11,7 +11,7 @@ class TestConvectionSites(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.psi = ConvectionSites(self.data_manager, '20000101', 1, 1, 'model_version') diff --git a/test/unit/test_cutsection.py b/test/unit/test_cutsection.py index cf91f1e..a808ef3 100644 --- a/test/unit/test_cutsection.py +++ b/test/unit/test_cutsection.py @@ -18,7 +18,7 @@ class TestCutSection(TestCase): self.box.min_lon = 0 self.box.max_lon = 0 - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.psi = CutSection(self.data_manager, '20000101', 1, 1, 'domain', 'var', True, 0) def test_generate_jobs(self): diff --git a/test/unit/test_gyres.py b/test/unit/test_gyres.py index ded1acd..77f3987 100644 --- a/test/unit/test_gyres.py +++ b/test/unit/test_gyres.py @@ -12,7 +12,7 @@ class TestGyres(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.gyres = Gyres(self.data_manager, '20000101', 1, 1, 'model_version') diff --git a/test/unit/test_heatcontent.py b/test/unit/test_heatcontent.py index 1e3d3eb..682c995 100644 --- a/test/unit/test_heatcontent.py +++ b/test/unit/test_heatcontent.py @@ -14,7 +14,7 @@ class TestHeatContent(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.box = Box(True) self.box.min_depth = 0 diff --git a/test/unit/test_heatcontentlayer.py b/test/unit/test_heatcontentlayer.py index 7d8b4d4..a14b76b 100644 --- a/test/unit/test_heatcontentlayer.py +++ b/test/unit/test_heatcontentlayer.py @@ -12,7 +12,7 @@ class TestHeatContentLayer(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.weight = Mock() diff --git a/test/unit/test_interpolate.py b/test/unit/test_interpolate.py index cfddaa5..8cf8222 100644 --- a/test/unit/test_interpolate.py +++ b/test/unit/test_interpolate.py @@ -12,7 +12,7 @@ class TestInterpolate(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.interpolate = Interpolate(self.data_manager, '20000101', 1, 1, 'domain', 'var', 'model_version') diff --git a/test/unit/test_maxmoc.py b/test/unit/test_maxmoc.py index e812290..618b14e 100644 --- a/test/unit/test_maxmoc.py +++ b/test/unit/test_maxmoc.py @@ -25,7 +25,7 @@ class TestMaxMoc(TestCase): self.diags.model_version = 'model_version' self.diags.startdates = ('20010101',) self.diags.members = (0,) - self.diags.exp_manager.get_full_years.return_value = (2000, 2001) + self.diags.config.experiment.get_full_years.return_value = (2000, 2001) jobs = MaxMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0']) self.assertEqual(len(jobs), 2) @@ -37,7 +37,7 @@ class TestMaxMoc(TestCase): self.assertEqual(jobs[0], MaxMoc(self.data_manager, '20010101', 0, 2000, Basins.Atlantic, self.box)) self.assertEqual(jobs[1], MaxMoc(self.data_manager, '20010101', 0, 2001, Basins.Atlantic, self.box)) - self.diags.exp_manager.get_full_years.return_value = list() + self.diags.config.experiment.get_full_years.return_value = list() jobs = MaxMoc.generate_jobs(self.diags, ['psi', '0', '0', '0', '0']) self.assertEqual(len(jobs), 0) diff --git a/test/unit/test_mixedlayerheatcontent.py b/test/unit/test_mixedlayerheatcontent.py index 35809b0..bf7bff9 100644 --- a/test/unit/test_mixedlayerheatcontent.py +++ b/test/unit/test_mixedlayerheatcontent.py @@ -12,7 +12,7 @@ class TestMixedLayerHeatContent(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.mixed = MixedLayerHeatContent(self.data_manager, '20000101', 1, 1) diff --git a/test/unit/test_mixedlayersaltcontent.py b/test/unit/test_mixedlayersaltcontent.py index 2f89929..38074f0 100644 --- a/test/unit/test_mixedlayersaltcontent.py +++ b/test/unit/test_mixedlayersaltcontent.py @@ -12,7 +12,7 @@ class TestMixedLayerSaltContent(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.mixed = MixedLayerSaltContent(self.data_manager, '20000101', 1, 1) diff --git a/test/unit/test_moc.py b/test/unit/test_moc.py index fb081f9..1a14303 100644 --- a/test/unit/test_moc.py +++ b/test/unit/test_moc.py @@ -12,7 +12,7 @@ class TestMoc(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.mixed = Moc(self.data_manager, '20000101', 1, 1) diff --git a/test/unit/test_monthlymean.py b/test/unit/test_monthlymean.py index edfbbea..d098198 100644 --- a/test/unit/test_monthlymean.py +++ b/test/unit/test_monthlymean.py @@ -13,25 +13,30 @@ class TestMonthlyMean(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.box = Box() self.box.min_depth = 0 self.box.max_depth = 100 - self.mixed = MonthlyMean(self.data_manager, '20000101', 1, 1, 'domain', 'var', 'freq') + self.mixed = MonthlyMean(self.data_manager, '20000101', 1, 1, 'domain', 'var', 'freq', '') def test_generate_jobs(self): jobs = MonthlyMean.generate_jobs(self.diags, ['psi', 'var', 'domain']) self.assertEqual(len(jobs), 2) - self.assertEqual(jobs[0], MonthlyMean(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'day')) - self.assertEqual(jobs[1], MonthlyMean(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'day')) + self.assertEqual(jobs[0], MonthlyMean(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'day', '')) + self.assertEqual(jobs[1], MonthlyMean(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'day', '')) jobs = MonthlyMean.generate_jobs(self.diags, ['psi', 'var', 'domain', 'freq']) self.assertEqual(len(jobs), 2) - self.assertEqual(jobs[0], MonthlyMean(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'freq')) - self.assertEqual(jobs[1], MonthlyMean(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'freq')) + self.assertEqual(jobs[0], MonthlyMean(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'freq', '')) + self.assertEqual(jobs[1], MonthlyMean(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'freq', '')) + + jobs = MonthlyMean.generate_jobs(self.diags, ['psi', 'var', 'domain', 'freq', 'grid']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], MonthlyMean(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'freq', 'grid')) + self.assertEqual(jobs[1], MonthlyMean(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'freq', 'grid')) with self.assertRaises(Exception): MonthlyMean.generate_jobs(self.diags, ['psi']) diff --git a/test/unit/test_psi.py b/test/unit/test_psi.py index fe53231..3099fa8 100644 --- a/test/unit/test_psi.py +++ b/test/unit/test_psi.py @@ -9,7 +9,7 @@ class TestPsi(TestCase): def setUp(self): self.data_manager = Mock() self.diags = Mock() - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.psi = Psi(self.data_manager, '20000101', 1, 1) def test_generate_jobs(self): diff --git a/test/unit/test_rewrite.py b/test/unit/test_rewrite.py index bf15f2f..606f812 100644 --- a/test/unit/test_rewrite.py +++ b/test/unit/test_rewrite.py @@ -13,7 +13,7 @@ class TestRewrite(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.box = Box() self.box.min_depth = 0 diff --git a/test/unit/test_siasiesiv.py b/test/unit/test_siasiesiv.py index 6dcfc37..2e8278f 100644 --- a/test/unit/test_siasiesiv.py +++ b/test/unit/test_siasiesiv.py @@ -12,7 +12,7 @@ class TestSiasiesiv(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.mask = Mock() self.psi = Siasiesiv(self.data_manager, '20000101', 1, 1, Basins.Global, self.mask) diff --git a/test/unit/test_verticalmean.py b/test/unit/test_verticalmean.py index abddd4b..4eefacf 100644 --- a/test/unit/test_verticalmean.py +++ b/test/unit/test_verticalmean.py @@ -13,7 +13,7 @@ class TestVerticalMean(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.box = Box() self.box.min_depth = 0 diff --git a/test/unit/test_verticalmeanmeters.py b/test/unit/test_verticalmeanmeters.py index 076f1b2..b0836c9 100644 --- a/test/unit/test_verticalmeanmeters.py +++ b/test/unit/test_verticalmeanmeters.py @@ -13,7 +13,7 @@ class TestVerticalMeanMeters(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' - self.diags.exp_manager.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) self.box = Box(True) self.box.min_depth = 0 -- GitLab From cddce0a7a1a1d01ada9901405ae080a3947ff8bc Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 14 Sep 2016 10:33:29 +0200 Subject: [PATCH 205/268] Updated config to check multiple paths for data --- diags.conf | 6 +++--- earthdiagnostics/config.py | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/diags.conf b/diags.conf index d5375ef..af8d3e5 100644 --- a/diags.conf +++ b/diags.conf @@ -2,15 +2,15 @@ # Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/$USER # Root path for the cmorized data to use -DATA_DIR = /esnas/exp/ecearth/ +DATA_DIR = /esnas/exp/ecearth/:/esarchive/exp/ecearth/:/esnas/exp/nemo/:/esarchive/exp/nemo/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below). If you are using the diagnpostics just to CMORize, leave it # empty DIAGS = -# Frequency of the data you want to use by default. Some diagnostics (i.e. monmean always stores result at monthly -# and has a parameter to specify input's frequency) +# Frequency of the data you want to use by default. Some diagnostics do not use this value: i.e. monmean always stores +# its results at monthly frequency (obvious) and has a parameter to specify input's frequency. FREQUENCY = mon # Path to CDFTOOLS binaries CDFTOOLS_PATH = /shared/earth/ClimatePrediction/CDFTOOLS_CMOR/bin diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index aa499ae..e21d5b0 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -46,6 +46,16 @@ class Config(object): :rtype: ExperimentConfig """ + data_folders = self.data_dir.split(':') + self.data_dir = None + for data_folder in data_folders: + if os.path.isdir(os.path.join(data_folder, self.experiment.expid)): + self.data_dir = data_folder + break + + if not self.data_dir: + raise Exception('Can not find model data') + # Read aliases self._aliases = dict() if parser.has_section('ALIAS'): -- GitLab From 2acba4de144825e155d67b92405db138532e3288 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 14 Sep 2016 11:21:45 +0200 Subject: [PATCH 206/268] Fixed name for links folder. Added default value of 6 for ocean and atmos timesteps --- earthdiagnostics/config.py | 4 ++-- earthdiagnostics/datamanager.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index e21d5b0..d885a15 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -169,8 +169,8 @@ class ExperimentConfig(object): chunks = parser.get_int_option('EXPERIMENT', 'CHUNKS') calendar = parser.get_option('EXPERIMENT', 'CALENDAR', 'standard') self.model = parser.get_option('EXPERIMENT', 'MODEL') - self.atmos_timestep = parser.get_int_option('EXPERIMENT', 'ATMOS_TIMESTEP') - self.ocean_timestep = parser.get_int_option('EXPERIMENT', 'OCEAN_TIMESTEP') + self.atmos_timestep = parser.get_int_option('EXPERIMENT', 'ATMOS_TIMESTEP', 6) + self.ocean_timestep = parser.get_int_option('EXPERIMENT', 'OCEAN_TIMESTEP', 6) self.model_version = parser.get_option('EXPERIMENT', 'MODEL_VERSION') self.startdates = startdates diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index e9d1744..d69f6d8 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -894,7 +894,7 @@ class DataManager(object): var = '{0}-{1}'.format(var, grid) if domain in ['ocean', 'seaIce']: - variable_folder = '{0}_f{0}h'.format(var, self.experiment.ocean_timestep) + variable_folder = '{0}_f{1}h'.format(var, self.experiment.ocean_timestep) else: variable_folder = '{0}_f{1}h'.format(var, self.atmos_timestep) -- GitLab From fea36a1651e4825310745152dcb41747dd0cab23 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 14 Sep 2016 13:17:35 +0200 Subject: [PATCH 207/268] Make a more robust rename variabls to avoid netCDF library errors --- earthdiagnostics/earthdiags.py | 9 +++- earthdiagnostics/utils.py | 96 ++++++++++++++++++++++++++++++---- launch_diags.sh | 5 +- 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index d7bbdda..45d2d45 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -56,6 +56,8 @@ class EarthDiags(object): self._create_dic_variables() self.time = dict() Log.debug('Diags ready') + Log.info('Running diags for experiment {0}, startdates {1}, members {2}', self.config.experiment.expid, + self.config.experiment.startdates, self.config.experiment.members) @staticmethod def parse_args(): @@ -95,7 +97,12 @@ class EarthDiags(object): if args.logfilepath: Log.set_file(Utils.expand_path(args.logfilepath)) - diags = EarthDiags(Utils.expand_path(args.configfile)) + config_file_path = Utils.expand_path(args.configfile) + if not os.path.isfile(config_file_path): + Log.critical('Configuration file {0} can not be found', config_file_path) + return False + + diags = EarthDiags(config_file_path) if args.clean: diags.clean() else: diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 9229cfc..20171ed 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -101,6 +101,16 @@ class Utils(object): """ handler = Utils.openCdf(filepath) + original_names = set(handler.variables.keys()).union(handler.dimensions.keys()) + if not any((True for x in dic_names.keys() if x in original_names)): + handler.close() + return + handler.close() + + temp = TempFile.get() + shutil.copyfile(filepath, temp) + + handler = Utils.openCdf(temp) for old_name, new_name in dic_names.items(): if old_name in handler.variables: if new_name not in handler.variables: @@ -116,6 +126,22 @@ class Utils(object): handler.sync() handler.close() + try: + Utils.execute_shell_command(['ncdump', '-h', temp]) + except Utils.ExecutionError: + original_handler = Utils.openCdf(filepath) + new_handler = Utils.openCdf(temp, 'w') + for attribute in original_handler.ncattrs(): + setattr(new_handler, attribute, getattr(original_handler, attribute)) + + for dimension in original_handler.dimensions.keys(): + Utils.copy_dimension(original_handler, new_handler, dimension, new_names=dic_names) + for variable in original_handler.variables.keys(): + Utils.copy_variable(original_handler, new_handler, variable, new_names=dic_names) + original_handler.close() + new_handler.close() + + Utils.move_file(temp, filepath) @staticmethod def move_file(source, destiny): @@ -198,7 +224,7 @@ class Utils(object): Log.log.log(log_level, line) output.append(line) if process.returncode != 0: - raise Exception('Error executing {0}\n Return code: {1}', ' '.join(command), process.returncode) + raise Utils.ExecutionError('Error executing {0}\n Return code: {1}', ' '.join(command), process.returncode) return output _cpu_count = None @@ -284,7 +310,7 @@ class Utils(object): return netCDF4.num2date(nctime, units=units, calendar=cal_temps) @staticmethod - def copy_variable(source, destiny, variable, must_exist=True, add_dimensions=False): + def copy_variable(source, destiny, variable, must_exist=True, add_dimensions=False, new_names=None): """ Copies the given variable from source to destiny @@ -306,23 +332,61 @@ class Utils(object): return if variable in destiny.variables.keys(): return - if not set(source.variables[variable].dimensions).issubset(destiny.dimensions): + + if not new_names: + new_names = dict() + + if variable in new_names: + new_name = new_names[variable] + else: + new_name = variable + translated_dimensions = Utils._translate(source.variables[variable].dimensions, new_names) + if not set(translated_dimensions).issubset(destiny.dimensions): if not add_dimensions: raise Exception('Variable {0} can not be added because dimensions does not match'.format(variable)) for dimension in source.variables[variable].dimensions: - if dimension in destiny.dimensions: - continue - destiny.createDimension(dimension, source.dimensions[dimension].size) - if dimension in source.variables: - Utils.copy_variable(source, destiny, dimension) + Utils.copy_dimension(source, destiny, dimension, new_names, new_names) if variable in destiny.variables.keys(): # Just in case the variable we are copying match a dimension name return original_var = source.variables[variable] - new_var = destiny.createVariable(variable, original_var.datatype, original_var.dimensions) + new_var = destiny.createVariable(new_name, original_var.datatype, translated_dimensions) new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) new_var[:] = original_var[:] + @staticmethod + def copy_dimension(source, destiny, dimension, must_exist=True, new_names=None): + """ + Copies the given dimension from source to destiny, including dimension variables if present + + :param source: origin file + :type source: netCDF4.Dataset + :param destiny: destiny file + :type destiny: netCDF4.Dataset + :param dimension: variable to copy + :type dimension: str + :param must_exist: if false, does not raise an error uf variable does not exist + :type must_exist: bool + + :return: + """ + if not must_exist and dimension not in source.dimensions.keys(): + return + if not new_names: + new_names = dict() + if dimension in new_names: + new_name = new_names[dimension] + else: + new_name = dimension + if new_name in destiny.dimensions.keys(): + return + if not new_name: + new_name = dimension + destiny.createDimension(new_name, source.dimensions[dimension].size) + if dimension in source.variables: + Utils.copy_variable(source, destiny, dimension, new_names=new_names) + + @staticmethod def concat_variables(source, destiny, remove_source=False): """ @@ -371,6 +435,19 @@ class Utils(object): """ return os.path.expandvars(os.path.expanduser(path)) + class ExecutionError(Exception): + pass + + @classmethod + def _translate(cls, dimensions, new_names): + translated = list() + for dim in dimensions: + if dim in new_names: + translated.append(new_names[dim]) + else: + translated.append(dim) + return translated + class TempFile(object): """ @@ -432,3 +509,4 @@ class TempFile(object): TempFile.files = list() + diff --git a/launch_diags.sh b/launch_diags.sh index cd1c013..8e0374c 100755 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -1,14 +1,15 @@ #!/usr/bin/env bash #SBATCH -n 1 +#SBATCH -w gustafson #SBATCH --time 72:00:00 #SBATCH --error=job.%J.err #SBATCH --output=job.%J.out set -xv -PATH_TO_CONF_FILE=diags.conf -PATH_TO_DIAGNOSTICS=~/pyCharm/ocean_diagnostics +PATH_TO_CONF_FILE=~/earthdiagnostics/diags.conf +PATH_TO_DIAGNOSTICS=~/earthdiagnostics PATH_TO_VIRTUALENV=/shared/earth/ClimatePrediction/EarthDiagnostics/bin module purge -- GitLab From a1b1238765d0965ab3f8a345b96dd9fde508617f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 14 Sep 2016 16:37:32 +0200 Subject: [PATCH 208/268] Fixed interpolation and added more options to diagnostic --- earthdiagnostics/config.py | 4 +-- earthdiagnostics/ocean/interpolate.py | 41 +++++++++++++++++---------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index d885a15..012ea50 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -28,7 +28,7 @@ class Config(object): "Root data folder path" self.con_files = Utils.expand_path(parser.get_option('DIAGNOSTICS', 'CON_FILES')) "Mask and meshes folder path" - self._diags = parser.get_option('DIAGNOSTICS', 'DIAGS').lower() + self._diags = parser.get_option('DIAGNOSTICS', 'DIAGS') self.frequency = parser.get_option('DIAGNOSTICS', 'FREQUENCY') "Default data frequency to be used by the diagnostics" self.cdftools_path = Utils.expand_path(parser.get_option('DIAGNOSTICS', 'CDFTOOLS_PATH')) @@ -65,7 +65,7 @@ class Config(object): commands = self._diags.split() self._real_commands = list() for command in commands: - if command in self._aliases: + if command.lower() in self._aliases: added_commands = self._aliases[command] Log.info('Changing alias {0} for {1}', command, ' '.join(added_commands)) for add_command in added_commands: diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index b526da8..91e624d 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -40,7 +40,8 @@ class Interpolate(Diagnostic): lock = threading.Lock() - def __init__(self, data_manager, startdate, member, chunk, domain, variable, model_version): + def __init__(self, data_manager, startdate, member, chunk, domain, variable, target_grid, model_version, + invert_lat): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member @@ -51,6 +52,8 @@ class Interpolate(Diagnostic): self.required_vars = [variable] self.generated_vars = [variable] self.tempTemplate = '' + self.grid = target_grid + self.invert_latitude = invert_lat def __eq__(self, other): return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ @@ -68,26 +71,31 @@ class Interpolate(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: variable, domain=ocean + :param options: target_grid, variable, domain=ocean :type options: list[str] :return: """ num_options = len(options) - 1 - if num_options < 1: - raise Exception('You must specify the variable to average vertically') - if num_options > 2: - raise Exception('You must specify between 1 and 2 parameters for the interpolation diagnostic') - variable = options[1] - if num_options >= 2: - domain = options[2] + if num_options < 2: + raise Exception('You must specify the grid and variable to interpolate') + if num_options > 4: + raise Exception('You must specify between 2 and 4 parameters for the interpolation diagnostic') + target_grid = options[1] + variable = options[2] + if num_options >= 3: + domain = options[3] else: domain = 'ocean' + if num_options >= 4: + invert_lat = bool(options[4].lower()) + else: + invert_lat = False job_list = list() for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append( - Interpolate(diags.data_manager, startdate, member, chunk, domain, variable, - diags.config.experiment.model_version)) + Interpolate(diags.data_manager, startdate, member, chunk, domain, variable, target_grid, + diags.config.experiment.model_version, invert_lat)) return job_list def compute(self): @@ -95,6 +103,7 @@ class Interpolate(Diagnostic): Runs the diagnostic """ variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + Utils.rename_variables(variable_file, {'i':'x', 'j':'y'}, must_exist=False, rename_dimension=True) cdo = Utils.cdo nco = Utils.nco handler = Utils.openCdf(variable_file) @@ -130,13 +139,14 @@ class Interpolate(Diagnostic): temp2 = TempFile.get() cdo.setgrid('t106grid', input=temp, output=temp2) os.remove(temp) - if self.model_version[6:9] == '025': - cdo.invertlatdata(input=temp2, output=temp2) + if self.invert_latitude: + cdo.invertlatdata(input=temp2, output=temp) + shutil.move(temp, temp2) if not has_levels: nco.ncks(input=temp2, output=temp2, options='-O -v {0},lat,lon,time'.format(self.variable)) self.data_manager.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, - grid='regular') + grid=self.grid) def _get_level_file(self, lev): if not self.tempTemplate: @@ -156,7 +166,8 @@ class Interpolate(Diagnostic): scrip_use_in = open(namelist_file, 'w') scrip_use_in.writelines("&remap_inputs\n") scrip_use_in.writelines(" remap_wgt = '/esnas/autosubmit/con_files/" - "weigths/{0}/rmp_{0}_to_regular_lev{1}.nc'\n".format(self.model_version, lev + 1)) + "weigths/{0}/rmp_{0}_to_{1}_lev{2}.nc'\n".format(self.model_version, self.grid, + lev + 1)) scrip_use_in.writelines(" infile = '{0}'\n".format(temp)) scrip_use_in.writelines(" invertlat = FALSE\n") scrip_use_in.writelines(" var = '{0}'\n".format(self.variable)) -- GitLab From 3a01d904560bd407d70e10596fd0fc90443e2b6d Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 14 Sep 2016 16:53:30 +0200 Subject: [PATCH 209/268] Removed ncdump logging when renaming variables --- earthdiagnostics/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 20171ed..7e20311 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -127,7 +127,7 @@ class Utils(object): handler.close() try: - Utils.execute_shell_command(['ncdump', '-h', temp]) + Utils.execute_shell_command(['ncdump', '-h', temp], log_level=Log.NO_LOG) except Utils.ExecutionError: original_handler = Utils.openCdf(filepath) new_handler = Utils.openCdf(temp, 'w') -- GitLab From 9ab97a4c1319e4244b79433210ed8f9d0a49d777 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 15 Sep 2016 10:27:49 +0200 Subject: [PATCH 210/268] Added code to move old files to another folder --- earthdiagnostics/datamanager.py | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index d69f6d8..75cff37 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,6 +1,7 @@ # coding: utf-8 import csv import glob +import re import shutil import threading import uuid @@ -29,6 +30,7 @@ class DataManager(object): def __init__(self, config): self.config = config self.experiment = config.experiment + self._checked_vars = list() Variable.load_variables() UnitConversion.load_conversions() @@ -496,7 +498,7 @@ class DataManager(object): self.send_file(temp, var_cmor.domain, var_cmor.short_name, startdate, member, frequency=frequency, rename_var=variable, date_str=date_str, - region=region) + region=region, move_older=True) @staticmethod def _update_time_variables(handler, startdate): @@ -660,7 +662,7 @@ class DataManager(object): self.experiment.model, self.experiment.experiment_name, 'S' + startdate) def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, - rename_var=None, frequency=None, year=None, date_str=None): + rename_var=None, frequency=None, year=None, date_str=None, move_older=False): """ Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge with already existing ones as needed @@ -866,7 +868,7 @@ class DataManager(object): Utils.rename_variables(filetosend, variables, False, True) Utils.move_file(filetosend, filepath) - self._create_link(domain, filepath, frequency, var, grid) + self._create_link(domain, filepath, frequency, var, grid, move_older) @staticmethod def correct_domain(domain): @@ -884,7 +886,7 @@ class DataManager(object): return 'landIce' return domain - def _create_link(self, domain, filepath, frequency, var, grid): + def _create_link(self, domain, filepath, frequency, var, grid, move_older): if frequency in ('d', 'daily', 'day'): freq_str = 'daily_mean' else: @@ -907,6 +909,24 @@ class DataManager(object): os.makedirs(link_path) except Exception: pass + elif move_older: + if link_path not in self._checked_vars: + old_path = link_path + '_old' + regex = re.compile(var + '_[0-9]{6,8}\.nc') + for filename in os.listdir(link_path): + if regex.match(filename): + if not os.path.exists(old_path): + # This can be a race condition + # noinspection PyBroadException + try: + os.makedirs(old_path) + except Exception: + pass + Utils.move_file(os.path.join(link_path, filename), + os.path.join(old_path, filename)) + self._checked_vars.append(link_path) + + link_path = os.path.join(link_path, os.path.basename(filepath)) if os.path.lexists(link_path): @@ -989,9 +1009,9 @@ class DataManager(object): return temp2 def _is_cmorized(self, startdate, member): - if not os.path.exists(self.get_startdate_path(startdate)): - return False startdate_path = self.get_startdate_path(startdate) + if not os.path.exists(startdate_path): + return False for freq in os.listdir(startdate_path): freq_path = os.path.join(startdate_path, freq) for domain in os.listdir(freq_path): -- GitLab From 446b1f2972a7be819426f6b7e84b2d36b9353d33 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 15 Sep 2016 11:34:38 +0200 Subject: [PATCH 211/268] Updated tests --- earthdiagnostics/general/monthlymean.py | 2 +- earthdiagnostics/ocean/interpolate.py | 7 ++++-- earthdiagnostics/utils.py | 5 +++++ test/unit/test_areamoc.py | 4 ++-- test/unit/test_averagesection.py | 2 +- test/unit/test_cutsection.py | 2 +- test/unit/test_heatcontent.py | 4 ++-- test/unit/test_heatcontentlayer.py | 2 +- test/unit/test_interpolate.py | 30 ++++++++++++++++++------- test/unit/test_maxmoc.py | 4 ++-- test/unit/test_monthlymean.py | 2 +- test/unit/test_rewrite.py | 2 +- test/unit/test_siasiesiv.py | 2 +- test/unit/test_utils.py | 29 +++++++++++++++--------- test/unit/test_verticalmean.py | 2 +- test/unit/test_verticalmeanmeters.py | 2 +- 16 files changed, 66 insertions(+), 35 deletions(-) diff --git a/earthdiagnostics/general/monthlymean.py b/earthdiagnostics/general/monthlymean.py index c787d5a..cc74adc 100644 --- a/earthdiagnostics/general/monthlymean.py +++ b/earthdiagnostics/general/monthlymean.py @@ -67,7 +67,7 @@ class MonthlyMean(Diagnostic): num_options = len(options) - 1 if num_options < 2: raise Exception('You must specify the variable and domain to average monthly') - if num_options > 3: + if num_options > 4: raise Exception('You must specify between 2 and 4 parameters for the monthly mean diagnostic') variable = options[1] domain = options[2] diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 91e624d..257c213 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -58,11 +58,14 @@ class Interpolate(Diagnostic): def __eq__(self, other): return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ self.model_version == other.model_version and self.domain == other.domain and \ - self.variable == other.variable + self.variable == other.variable and self.grid == other.grid and \ + self.invert_latitude == other.invert_latitude def __str__(self): return 'Interpolate Startdate: {0} Member: {1} Chunk: {2} ' \ - 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + 'Variable: {3}:{4} Target grid: {5} Invert lat: {6} ' \ + 'Model: {7}' .format(self.startdate, self.member, self.chunk, self.domain, self.variable, self.grid, + self.invert_latitude, self.model_version) @classmethod def generate_jobs(cls, diags, options): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 7e20311..ebcbd0d 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -99,11 +99,16 @@ class Utils(object): :param rename_dimension: if True, also rename dimensions with the same name :type rename_dimension: bool """ + for old, new in dic_names.iteritems(): + if old == new: + raise ValueError('{0} original name is the same as the new') handler = Utils.openCdf(filepath) original_names = set(handler.variables.keys()).union(handler.dimensions.keys()) if not any((True for x in dic_names.keys() if x in original_names)): handler.close() + if must_exist: + raise Exception("Variables {0} does not exist in file {1}".format(','.join(dic_names.keys()), filepath)) return handler.close() diff --git a/test/unit/test_areamoc.py b/test/unit/test_areamoc.py index f9894d8..f4ddf69 100644 --- a/test/unit/test_areamoc.py +++ b/test/unit/test_areamoc.py @@ -1,8 +1,8 @@ # coding=utf-8 from unittest import TestCase -from box import Box -from constants import Basins +from earthdiagnostics.box import Box +from earthdiagnostics.constants import Basins from earthdiagnostics.ocean.areamoc import AreaMoc from mock import Mock diff --git a/test/unit/test_averagesection.py b/test/unit/test_averagesection.py index 982ec6c..e9b4816 100644 --- a/test/unit/test_averagesection.py +++ b/test/unit/test_averagesection.py @@ -1,7 +1,7 @@ # coding=utf-8 from unittest import TestCase -from box import Box +from earthdiagnostics.box import Box from earthdiagnostics.ocean.averagesection import AverageSection from mock import Mock diff --git a/test/unit/test_cutsection.py b/test/unit/test_cutsection.py index a808ef3..060c4a4 100644 --- a/test/unit/test_cutsection.py +++ b/test/unit/test_cutsection.py @@ -1,7 +1,7 @@ # coding=utf-8 from unittest import TestCase -from box import Box +from earthdiagnostics.box import Box from earthdiagnostics.ocean.cutsection import CutSection from mock import Mock diff --git a/test/unit/test_heatcontent.py b/test/unit/test_heatcontent.py index 682c995..32c6900 100644 --- a/test/unit/test_heatcontent.py +++ b/test/unit/test_heatcontent.py @@ -1,8 +1,8 @@ # coding=utf-8 from unittest import TestCase -from box import Box -from constants import Basins +from earthdiagnostics.box import Box +from earthdiagnostics.constants import Basins from earthdiagnostics.ocean.heatcontent import HeatContent from mock import Mock diff --git a/test/unit/test_heatcontentlayer.py b/test/unit/test_heatcontentlayer.py index a14b76b..60b6dd8 100644 --- a/test/unit/test_heatcontentlayer.py +++ b/test/unit/test_heatcontentlayer.py @@ -1,6 +1,6 @@ # coding=utf-8 from unittest import TestCase -from box import Box +from earthdiagnostics.box import Box from earthdiagnostics.ocean.heatcontentlayer import HeatContentLayer from mock import Mock diff --git a/test/unit/test_interpolate.py b/test/unit/test_interpolate.py index 8cf8222..9a092cf 100644 --- a/test/unit/test_interpolate.py +++ b/test/unit/test_interpolate.py @@ -13,19 +13,32 @@ class TestInterpolate(TestCase): self.diags = Mock() self.diags.model_version = 'model_version' self.diags.config.experiment.get_chunk_list.return_value = (('20010101', 0, 0), ('20010101', 0, 1)) + self.diags.config.experiment.model_version = 'model_version' - self.interpolate = Interpolate(self.data_manager, '20000101', 1, 1, 'domain', 'var', 'model_version') + self.interpolate = Interpolate(self.data_manager, '20000101', 1, 1, 'domain', 'var', 'grid', 'model_version', + False) def test_generate_jobs(self): - jobs = Interpolate.generate_jobs(self.diags, ['interp', 'var']) + jobs = Interpolate.generate_jobs(self.diags, ['interp', 'grid', 'var']) self.assertEqual(len(jobs), 2) - self.assertEqual(jobs[0], Interpolate(self.data_manager, '20010101', 0, 0, 'ocean', 'var', 'model_version')) - self.assertEqual(jobs[1], Interpolate(self.data_manager, '20010101', 0, 1, 'ocean', 'var', 'model_version')) + self.assertEqual(jobs[0], Interpolate(self.data_manager, '20010101', 0, 0, 'ocean', 'var', 'grid', + 'model_version', False)) + self.assertEqual(jobs[1], Interpolate(self.data_manager, '20010101', 0, 1, 'ocean', 'var', 'grid', + 'model_version', False)) - jobs = Interpolate.generate_jobs(self.diags, ['interp', 'var', 'domain']) + jobs = Interpolate.generate_jobs(self.diags, ['interp', 'grid', 'var', 'domain']) self.assertEqual(len(jobs), 2) - self.assertEqual(jobs[0], Interpolate(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'model_version')) - self.assertEqual(jobs[1], Interpolate(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'model_version')) + self.assertEqual(jobs[0], Interpolate(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'grid', + 'model_version', False)) + self.assertEqual(jobs[1], Interpolate(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'grid', + 'model_version', False)) + + jobs = Interpolate.generate_jobs(self.diags, ['interp', 'grid', 'var', 'domain', 'true']) + self.assertEqual(len(jobs), 2) + self.assertEqual(jobs[0], Interpolate(self.data_manager, '20010101', 0, 0, 'domain', 'var', 'grid', + 'model_version', True)) + self.assertEqual(jobs[1], Interpolate(self.data_manager, '20010101', 0, 1, 'domain', 'var', 'grid', + 'model_version', True)) with self.assertRaises(Exception): Interpolate.generate_jobs(self.diags, ['interp']) @@ -35,4 +48,5 @@ class TestInterpolate(TestCase): def test_str(self): self.assertEquals(str(self.interpolate), 'Interpolate Startdate: 20000101 Member: 1 Chunk: 1 ' - 'Variable: domain:var') + 'Variable: domain:var Target grid: grid Invert lat: False ' + 'Model: model_version') diff --git a/test/unit/test_maxmoc.py b/test/unit/test_maxmoc.py index 618b14e..f31c582 100644 --- a/test/unit/test_maxmoc.py +++ b/test/unit/test_maxmoc.py @@ -1,8 +1,8 @@ # coding=utf-8 from unittest import TestCase -from box import Box -from constants import Basins +from earthdiagnostics.box import Box +from earthdiagnostics.constants import Basins from earthdiagnostics.ocean.maxmoc import MaxMoc from mock import Mock diff --git a/test/unit/test_monthlymean.py b/test/unit/test_monthlymean.py index d098198..6694908 100644 --- a/test/unit/test_monthlymean.py +++ b/test/unit/test_monthlymean.py @@ -1,7 +1,7 @@ # coding=utf-8 from unittest import TestCase -from box import Box +from earthdiagnostics.box import Box from earthdiagnostics.general.monthlymean import MonthlyMean from mock import Mock diff --git a/test/unit/test_rewrite.py b/test/unit/test_rewrite.py index 606f812..dfc8277 100644 --- a/test/unit/test_rewrite.py +++ b/test/unit/test_rewrite.py @@ -1,7 +1,7 @@ # coding=utf-8 from unittest import TestCase -from box import Box +from earthdiagnostics.box import Box from earthdiagnostics.general.rewrite import Rewrite from mock import Mock diff --git a/test/unit/test_siasiesiv.py b/test/unit/test_siasiesiv.py index 2e8278f..2ed2842 100644 --- a/test/unit/test_siasiesiv.py +++ b/test/unit/test_siasiesiv.py @@ -1,7 +1,7 @@ # coding=utf-8 from unittest import TestCase -from constants import Basins +from earthdiagnostics.constants import Basins from earthdiagnostics.ocean.siasiesiv import Siasiesiv from mock import Mock diff --git a/test/unit/test_utils.py b/test/unit/test_utils.py index 2ae94e3..0810ede 100644 --- a/test/unit/test_utils.py +++ b/test/unit/test_utils.py @@ -65,18 +65,27 @@ class TestUtils(TestCase): mock_handler.variables['old'] = mock.Mock() mock_handler.variables['old_var'] = mock.Mock() mock_handler.dimensions['old'] = mock.Mock() + mock_handler.ncattrs.return_value = 'attribute' + mock_handler.attribute = 'value' with mock.patch('earthdiagnostics.utils.Utils.openCdf') as opencdf_mock: - opencdf_mock.return_value = mock_handler - Utils.rename_variables('file', {'old': 'old_var'}) - Utils.rename_variables('file', {'old': 'new'}, False, True) - Utils.rename_variables('file', {'new': 'new'}, False) - Utils.rename_variables('file', {'old_var': 'new'}, False, True) - - with self.assertRaises(Exception): - Utils.rename_variables('file', {'new': 'new'}) - with self.assertRaises(Exception): - Utils.rename_variables('file', {'old_var': 'new'}, rename_dimension=True) + with mock.patch('shutil.copyfile'): + with mock.patch('earthdiagnostics.utils.Utils.move_file'): + opencdf_mock.return_value = mock_handler + Utils.rename_variables('file', {'old': 'old_var'}) + Utils.rename_variables('file', {'old2': 'new'}, False) + Utils.rename_variables('file', {'old2': 'new', 'old': 'new'}, False) + Utils.rename_variables('file', {'old': 'new'}, False, True) + Utils.rename_variables('file', {'old_var': 'new'}, False, True) + + with self.assertRaises(ValueError): + Utils.rename_variables('file', {'new': 'new'}) + with self.assertRaises(Exception): + Utils.rename_variables('file', {'old2': 'new'}) + with self.assertRaises(Exception): + Utils.rename_variables('file', {'old2': 'new', 'old': 'new'}) + with self.assertRaises(Exception): + Utils.rename_variables('file', {'old_var': 'new'}, rename_dimension=True) def test_convert2netcdf4(self): mock_handler = mock.Mock() diff --git a/test/unit/test_verticalmean.py b/test/unit/test_verticalmean.py index 4eefacf..dc2d32a 100644 --- a/test/unit/test_verticalmean.py +++ b/test/unit/test_verticalmean.py @@ -1,7 +1,7 @@ # coding=utf-8 from unittest import TestCase -from box import Box +from earthdiagnostics.box import Box from earthdiagnostics.ocean.verticalmean import VerticalMean from mock import Mock diff --git a/test/unit/test_verticalmeanmeters.py b/test/unit/test_verticalmeanmeters.py index b0836c9..20599cd 100644 --- a/test/unit/test_verticalmeanmeters.py +++ b/test/unit/test_verticalmeanmeters.py @@ -1,7 +1,7 @@ # coding=utf-8 from unittest import TestCase -from box import Box +from earthdiagnostics.box import Box from earthdiagnostics.ocean.verticalmeanmeters import VerticalMeanMeters from mock import Mock -- GitLab From d7caeb89062ec132db60c09cf74d7d87efe690fa Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 15 Sep 2016 17:24:32 +0200 Subject: [PATCH 212/268] Fixed bug on move_file when using relative paths for destiny --- earthdiagnostics/utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index ebcbd0d..52bdf51 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -158,12 +158,13 @@ class Utils(object): :param destiny: path to destiny :type destiny: str """ - if not os.path.exists(os.path.dirname(destiny)): + dirname_path = os.path.dirname(destiny) + if dirname_path and not os.path.exists(dirname_path): try: - os.makedirs(os.path.dirname(destiny)) + os.makedirs(dirname_path) except OSError as ex: # This can be due to a race condition. If directory already exists, we don have to do nothing - if not os.path.exists(os.path.dirname(destiny)): + if not os.path.exists(dirname_path): raise ex hash_destiny = None hash_original = Utils.get_file_hash(source) -- GitLab From 57bcc20a5d52163f93c8d5b9367a28b0d495d537 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 15 Sep 2016 17:43:18 +0200 Subject: [PATCH 213/268] Reformated code to comply with style guide --- bin/earthdiags | 2 +- earthdiagnostics/datamanager.py | 2 -- earthdiagnostics/ocean/interpolate.py | 2 +- earthdiagnostics/ocean/siasiesiv.py | 2 +- earthdiagnostics/utils.py | 11 ++++---- test.py | 1 + test/unit/test_data_manager.py | 23 +---------------- test/unit/test_experiment_manager.py | 36 --------------------------- 8 files changed, 10 insertions(+), 69 deletions(-) delete mode 100644 test/unit/test_experiment_manager.py diff --git a/bin/earthdiags b/bin/earthdiags index 3895867..6ac2607 100644 --- a/bin/earthdiags +++ b/bin/earthdiags @@ -9,7 +9,7 @@ scriptdir = os.path.abspath(os.path.dirname(sys.argv[0])) assert sys.path[0] == scriptdir sys.path[0] = os.path.normpath(os.path.join(scriptdir, os.pardir)) -# noinspection PyUnresolvedReferences +# noinspection PyUnresolvedReferences,PyPep8 from earthdiagnostics.earthdiags import EarthDiags diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 75cff37..997cf23 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -926,8 +926,6 @@ class DataManager(object): os.path.join(old_path, filename)) self._checked_vars.append(link_path) - - link_path = os.path.join(link_path, os.path.basename(filepath)) if os.path.lexists(link_path): os.remove(link_path) diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 257c213..b7cb998 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -106,7 +106,7 @@ class Interpolate(Diagnostic): Runs the diagnostic """ variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) - Utils.rename_variables(variable_file, {'i':'x', 'j':'y'}, must_exist=False, rename_dimension=True) + Utils.rename_variables(variable_file, {'i': 'x', 'j': 'y'}, must_exist=False, rename_dimension=True) cdo = Utils.cdo nco = Utils.nco handler = Utils.openCdf(variable_file) diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index e1b4645..cd263de 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -4,7 +4,7 @@ import os from earthdiagnostics.constants import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile -import earthdiagnostics.cdftoolspython +import earthdiagnostics.cdftoolspython as cdftoolspython import numpy as np diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 52bdf51..849a496 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -331,7 +331,8 @@ class Utils(object): :type variable: str :param must_exist: if false, does not raise an error uf variable does not exist :type must_exist: bool - + :param new_names: dictionary containing variables to rename and new name as key-value pairs + :type new_names: dict :return: """ if not must_exist and variable not in source.variables.keys(): @@ -351,7 +352,7 @@ class Utils(object): if not add_dimensions: raise Exception('Variable {0} can not be added because dimensions does not match'.format(variable)) for dimension in source.variables[variable].dimensions: - Utils.copy_dimension(source, destiny, dimension, new_names, new_names) + Utils.copy_dimension(source, destiny, dimension, must_exist, new_names) if variable in destiny.variables.keys(): # Just in case the variable we are copying match a dimension name return @@ -365,6 +366,8 @@ class Utils(object): """ Copies the given dimension from source to destiny, including dimension variables if present + :param new_names: dictionary containing variables to rename and new name as key-value pairs + :type new_names: dict :param source: origin file :type source: netCDF4.Dataset :param destiny: destiny file @@ -392,7 +395,6 @@ class Utils(object): if dimension in source.variables: Utils.copy_variable(source, destiny, dimension, new_names=new_names) - @staticmethod def concat_variables(source, destiny, remove_source=False): """ @@ -513,6 +515,3 @@ class TempFile(object): if os.path.exists(temp_file): os.remove(temp_file) TempFile.files = list() - - - diff --git a/test.py b/test.py index ff30995..a6785ec 100644 --- a/test.py +++ b/test.py @@ -9,6 +9,7 @@ cov = coverage.Coverage() cov.set_option("run:branch", True) cov.start() +# noinspection PyPep8 import test.unit suite = unittest.TestLoader().loadTestsFromModule(test.unit) diff --git a/test/unit/test_data_manager.py b/test/unit/test_data_manager.py index 8a384fe..0b5d2ab 100644 --- a/test/unit/test_data_manager.py +++ b/test/unit/test_data_manager.py @@ -2,28 +2,7 @@ from unittest import TestCase -from earthdiagnostics.datamanager import DataManager, Variable, UnitConversion - - -# class TestDataManager(TestCase): -# def setUp(self): -# self.data_manager = DataManager(ExperimentManager(['20000101'], [0], 5, 3, 3), 'institution', 'model', 'expid', -# 'datafolder', 'mon', 'experiment', 'scratch', 6) -# -# def test_domain_abbreviation(self): -# self.assertEquals('Omon', DataManager.domain_abbreviation('Ocean', 'mon')) -# self.assertEquals('OImon', DataManager.domain_abbreviation('seaIce', 'mon')) -# self.assertEquals('LImon', DataManager.domain_abbreviation('landIce', 'mon')) -# self.assertEquals('Amon', DataManager.domain_abbreviation('atmos', 'mon')) -# self.assertEquals('day', DataManager.domain_abbreviation('atmos', 'day')) -# self.assertEquals('6hrPlev', DataManager.domain_abbreviation('atmos', '6hr')) -# -# def test_get_grib_filename(self): -# self.assertEqual(self.data_manager._get_grib_filename('SH', date(2000, 1, 1)), 'ICMSHexpid+200001.grb') -# -# def test_get_startdate_path(self): -# self.assertEqual(self.data_manager.get_startdate_path('20000101'), -# 'datafolder/expid/cmorfiles/institution/model/experiment/S20000101') +from earthdiagnostics.datamanager import Variable, UnitConversion class TestVariable(TestCase): diff --git a/test/unit/test_experiment_manager.py b/test/unit/test_experiment_manager.py deleted file mode 100644 index 773a545..0000000 --- a/test/unit/test_experiment_manager.py +++ /dev/null @@ -1,36 +0,0 @@ -# coding=utf-8 - -from unittest import TestCase - - -# class TestExperimentManager(TestCase): -# def setUp(self): -# self.experiment_manager = ExperimentManager(['20000101', '20000201'], [0, 1], 5, 3, 3) -# -# def test_get_full_years(self): -# self.assertEquals([2000], self.experiment_manager.get_full_years('20000101')) -# self.assertEquals(list(), self.experiment_manager.get_full_years('20000201')) -# -# def test_get_member_str(self): -# self.assertEquals('fc000', self.experiment_manager.get_member_str(0)) -# self.assertEquals('fc001', self.experiment_manager.get_member_str(1)) -# -# def test_get_member_list(self): -# self.assertEquals([('20000101', 0), ('20000101', 1), ('20000201', 0), ('20000201', 1)], -# self.experiment_manager.get_member_list()) -# -# def test_get_year_chunks(self): -# self.assertEquals([1, 2, 3, 4], self.experiment_manager.get_year_chunks('20000101', 2000)) -# self.assertEquals([4, 5], self.experiment_manager.get_year_chunks('20000201', 2001)) -# self.assertEquals(list(), self.experiment_manager.get_year_chunks('20000201', 2003)) -# -# def test_get_chunk_list(self): -# self.assertEquals([('20000101', 0, 1), ('20000101', 0, 2), ('20000101', 0, 3), ('20000101', 0, 4), -# ('20000101', 0, 5), -# ('20000101', 1, 1), ('20000101', 1, 2), ('20000101', 1, 3), ('20000101', 1, 4), -# ('20000101', 1, 5), -# ('20000201', 0, 1), ('20000201', 0, 2), ('20000201', 0, 3), ('20000201', 0, 4), -# ('20000201', 0, 5), -# ('20000201', 1, 1), ('20000201', 1, 2), ('20000201', 1, 3), ('20000201', 1, 4), -# ('20000201', 1, 5)], -# self.experiment_manager.get_chunk_list()) -- GitLab From 42c5a926c5be636634b60f4435d512a1594e312c Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 15 Sep 2016 18:23:49 +0200 Subject: [PATCH 214/268] Added relink diagnostic --- earthdiagnostics/datamanager.py | 260 ++++++++++++++++----------- earthdiagnostics/earthdiags.py | 79 ++++---- earthdiagnostics/general/__init__.py | 1 + earthdiagnostics/general/relink.py | 74 ++++++++ earthdiagnostics/general/rewrite.py | 4 +- 5 files changed, 277 insertions(+), 141 deletions(-) create mode 100644 earthdiagnostics/general/relink.py diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 997cf23..20f1d04 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -214,7 +214,7 @@ class DataManager(object): mes2 = grib_handler.readline() atmos_timestep = mes2.analDate - mes1.analDate atmos_timestep = int(atmos_timestep.total_seconds() / 3600) - self.atmos_timestep = atmos_timestep + self.experiment.atmos_timestep = atmos_timestep grib_handler.close() return atmos_timestep @@ -629,8 +629,7 @@ class DataManager(object): chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') - if box: - var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() + var = self._get_final_var_name(box, var) if grid: var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) @@ -698,8 +697,7 @@ class DataManager(object): """ original_var = var cmor_var = Variable.get_variable(var) - if box: - var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() + var = self._get_final_var_name(box, var) if rename_var: Utils.rename_variable(filetosend, rename_var, var) @@ -709,80 +707,10 @@ class DataManager(object): if not frequency: frequency = self.config.frequency domain = DataManager.correct_domain(domain) - domain_abreviattion = self.domain_abbreviation(domain, frequency) - - start = parse_date(startdate) - member_plus = str(member + 1) - member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) - - if chunk is not None: - chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') - - time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, - chunk_end.month) - - elif year is not None: - if frequency is not 'yr': - raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') - time_bound = str(year) - elif date_str is not None: - time_bound = date_str - else: - raise ValueError('Chunk and year can not be None at the same time') - - if grid: - var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) - else: - var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) - - filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' - '{6}.nc'.format(var, domain_abreviattion, self.experiment.model, - self.experiment.experiment_name, - startdate, member_plus, time_bound)) + filepath = self._get_file_path(chunk, date_str, domain, frequency, grid, member, startdate, var, year) if region: - Utils.convert2netcdf4(filetosend) - if not os.path.exists(filepath): - - handler = Utils.openCdf(filetosend) - handler.createDimension('region') - var_region = handler.createVariable('region', str, 'region') - var_region[0] = region - - original_var = handler.variables[var] - new_var = handler.createVariable('new_var', original_var.datatype, - original_var.dimensions + ('region',)) - new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) - value = original_var[:] - new_var[..., 0] = value - handler.close() - - Utils.nco.ncks(input=filetosend, output=filetosend, options='-O -x -v {0}'.format(var)) - Utils.rename_variable(filetosend, 'new_var', var) - else: - - temp = TempFile.get() - shutil.copyfile(filepath, temp) - Utils.nco.ncks(input=temp, output=temp, options='-O --mk_rec_dmn region') - handler = Utils.openCdf(temp) - handler_send = Utils.openCdf(filetosend) - value = handler_send.variables[var][:] - var_region = handler.variables['region'] - basin_index = np.where(var_region[:] == region) - if len(basin_index[0]) == 0: - var_region[var_region.shape[0]] = region - basin_index = var_region.shape[0] - 1 - - else: - basin_index = basin_index[0][0] - - handler.variables[var][..., basin_index] = value - handler.close() - handler_send.close() - Utils.move_file(temp, filetosend) - Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') + self._prepare_region(filepath, filetosend, region, var) temp = TempFile.get() Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) @@ -799,33 +727,7 @@ class DataManager(object): handler.table_id = 'Table {0} (December 2013)'.format(self.domain_abbreviation(cmor_var.domain, frequency)) if cmor_var.units: - if 'units' in var_handler.ncattrs(): - if var_handler.units == 'PSU': - var_handler.units = 'psu' - if var_handler.units == 'C' and cmor_var.units == 'K': - var_handler.units = 'deg_C' - if cmor_var.units != var_handler.units: - try: - new_unit = Units(cmor_var.units) - old_unit = Units(var_handler.units) - - var_handler[:] = Units.conform(var_handler[:], old_unit, new_unit, inplace=True) - - if 'valid_min' in var_handler.ncattrs(): - var_handler.valid_min = Units.conform(float(var_handler.valid_min), old_unit, new_unit, - inplace=True) - if 'valid_max' in var_handler.ncattrs(): - var_handler.valid_max = Units.conform(float(var_handler.valid_max), old_unit, new_unit, - inplace=True) - except ValueError: - factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, - cmor_var.units) - var_handler[:] = var_handler[:] * factor + offset - if 'valid_min' in var_handler.ncattrs(): - var_handler.valid_min = float(var_handler.valid_min) * factor + offset - if 'valid_max' in var_handler.ncattrs(): - var_handler.valid_max = float(var_handler.valid_max) * factor + offset - var_handler.units = cmor_var.units + self._fix_units(cmor_var, var_handler) handler.sync() if 'lev' in handler.variables: @@ -870,6 +772,154 @@ class DataManager(object): Utils.move_file(filetosend, filepath) self._create_link(domain, filepath, frequency, var, grid, move_older) + @staticmethod + def _fix_units(cmor_var, var_handler): + if 'units' in var_handler.ncattrs(): + if var_handler.units == 'PSU': + var_handler.units = 'psu' + if var_handler.units == 'C' and cmor_var.units == 'K': + var_handler.units = 'deg_C' + if cmor_var.units != var_handler.units: + try: + new_unit = Units(cmor_var.units) + old_unit = Units(var_handler.units) + + var_handler[:] = Units.conform(var_handler[:], old_unit, new_unit, inplace=True) + + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = Units.conform(float(var_handler.valid_min), old_unit, new_unit, + inplace=True) + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = Units.conform(float(var_handler.valid_max), old_unit, new_unit, + inplace=True) + except ValueError: + factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, + cmor_var.units) + var_handler[:] = var_handler[:] * factor + offset + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = float(var_handler.valid_min) * factor + offset + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = float(var_handler.valid_max) * factor + offset + var_handler.units = cmor_var.units + + @staticmethod + def _prepare_region(filepath, filetosend, region, var): + Utils.convert2netcdf4(filetosend) + if not os.path.exists(filepath): + + handler = Utils.openCdf(filetosend) + handler.createDimension('region') + var_region = handler.createVariable('region', str, 'region') + var_region[0] = region + + original_var = handler.variables[var] + new_var = handler.createVariable('new_var', original_var.datatype, + original_var.dimensions + ('region',)) + new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) + value = original_var[:] + new_var[..., 0] = value + handler.close() + + Utils.nco.ncks(input=filetosend, output=filetosend, options='-O -x -v {0}'.format(var)) + Utils.rename_variable(filetosend, 'new_var', var) + else: + + temp = TempFile.get() + shutil.copyfile(filepath, temp) + Utils.nco.ncks(input=temp, output=temp, options='-O --mk_rec_dmn region') + handler = Utils.openCdf(temp) + handler_send = Utils.openCdf(filetosend) + value = handler_send.variables[var][:] + var_region = handler.variables['region'] + basin_index = np.where(var_region[:] == region) + if len(basin_index[0]) == 0: + var_region[var_region.shape[0]] = region + basin_index = var_region.shape[0] - 1 + + else: + basin_index = basin_index[0][0] + + handler.variables[var][..., basin_index] = value + handler.close() + handler_send.close() + Utils.move_file(temp, filetosend) + Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') + + def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, + frequency=None, year=None, date_str=None, move_older=False): + """ + Creates the link of a given file from the CMOR repository. + + :param date_str: + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int + :param region: specifies the region represented by the file. If it is defined, the data will be appended to the + CMOR repository as a new region in the file or will overwrite if region was already present + :type region: str + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ + var = self._get_final_var_name(box, var) + + if not frequency: + frequency = self.config.frequency + domain = DataManager.correct_domain(domain) + filepath = self._get_file_path(chunk, date_str, domain, frequency, grid, member, startdate, var, year) + + self._create_link(domain, filepath, frequency, var, grid, move_older) + + def _get_file_path(self, chunk, date_str, domain, frequency, grid, member, startdate, var, year): + domain_abreviattion = self.domain_abbreviation(domain, frequency) + start = parse_date(startdate) + member_plus = str(member + 1) + member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) + if chunk is not None: + chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + + time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, + chunk_end.month) + + elif year is not None: + if frequency is not 'yr': + raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') + time_bound = str(year) + elif date_str is not None: + time_bound = date_str + else: + raise ValueError('Chunk and year can not be None at the same time') + if grid: + var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) + else: + var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) + filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' + '{6}.nc'.format(var, domain_abreviattion, self.experiment.model, + self.experiment.experiment_name, + startdate, member_plus, time_bound)) + return filepath + + def _get_final_var_name(self, box, var): + if box: + var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() + return var + @staticmethod def correct_domain(domain): """ @@ -898,7 +948,7 @@ class DataManager(object): if domain in ['ocean', 'seaIce']: variable_folder = '{0}_f{1}h'.format(var, self.experiment.ocean_timestep) else: - variable_folder = '{0}_f{1}h'.format(var, self.atmos_timestep) + variable_folder = '{0}_f{1}h'.format(var, self.experiment.atmos_timestep) link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 45d2d45..2d2b96c 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -137,24 +137,7 @@ class EarthDiags(object): self._prepare_mesh_files() - Diagnostic.register(MixedLayerSaltContent) - Diagnostic.register(Siasiesiv) - Diagnostic.register(VerticalMean) - Diagnostic.register(VerticalMeanMeters) - Diagnostic.register(Interpolate) - Diagnostic.register(Moc) - Diagnostic.register(AreaMoc) - Diagnostic.register(MaxMoc) - Diagnostic.register(Psi) - Diagnostic.register(Gyres) - Diagnostic.register(ConvectionSites) - Diagnostic.register(CutSection) - Diagnostic.register(AverageSection) - Diagnostic.register(MixedLayerHeatContent) - Diagnostic.register(HeatContentLayer) - Diagnostic.register(HeatContent) - Diagnostic.register(MonthlyMean) - Diagnostic.register(Rewrite) + self._register_diagnostics() parse_date('20000101') self.data_manager = DataManager(self.config) @@ -162,25 +145,15 @@ class EarthDiags(object): # Run diagnostics Log.info('Running diagnostics') - list_jobs = Queue.Queue() - for fulldiag in self.config.get_commands(): - Log.info("Adding {0} to diagnostic list", fulldiag) - diag_options = fulldiag.split(',') - - diag_class = Diagnostic.get_diagnostic(diag_options[0]) - if diag_class: - for job in diag_class.generate_jobs(self, diag_options): - list_jobs.put(job) - continue - else: - Log.error('{0} is not an available diagnostic', diag_options[0]) + list_jobs = self.prepare_job_list() time = datetime.datetime.now() Log.info("Starting to compute at {0}", time) num_threads = min(Utils.available_cpu_count(), self.config.max_cores) - Log.info('Using {0} threads', num_threads) + self.threads = num_threads + Log.info('Using {0} threads', self.threads) threads = list() - for num_thread in range(0, num_threads): + for num_thread in range(0, self.threads): self.time[num_thread] = dict() t = threading.Thread(target=EarthDiags._run_jobs, args=(self, list_jobs, num_thread)) threads.append(t) @@ -193,19 +166,57 @@ class EarthDiags(object): Log.result("Diagnostics finished at {0}", finsih_time) Log.result("Time ellapsed: {0}\n", finsih_time - time) + self.print_stats() + + def print_stats(self): Log.info('Time consumed by each diagnostic class') Log.info('--------------------------------------') total = dict() - for num_thread in range(0, num_threads): + for num_thread in range(0, self.threads): for key, value in self.time[num_thread].items(): if key in total: total[key] += value else: total[key] = value - for diag, time in sorted(total.items(), key=operator.itemgetter(1)): Log.info('{0:23} {1:}', diag.__name__, time) + def prepare_job_list(self): + list_jobs = Queue.Queue() + for fulldiag in self.config.get_commands(): + Log.info("Adding {0} to diagnostic list", fulldiag) + diag_options = fulldiag.split(',') + + diag_class = Diagnostic.get_diagnostic(diag_options[0]) + if diag_class: + for job in diag_class.generate_jobs(self, diag_options): + list_jobs.put(job) + continue + else: + Log.error('{0} is not an available diagnostic', diag_options[0]) + return list_jobs + + def _register_diagnostics(self): + Diagnostic.register(MixedLayerSaltContent) + Diagnostic.register(Siasiesiv) + Diagnostic.register(VerticalMean) + Diagnostic.register(VerticalMeanMeters) + Diagnostic.register(Interpolate) + Diagnostic.register(Moc) + Diagnostic.register(AreaMoc) + Diagnostic.register(MaxMoc) + Diagnostic.register(Psi) + Diagnostic.register(Gyres) + Diagnostic.register(ConvectionSites) + Diagnostic.register(CutSection) + Diagnostic.register(AverageSection) + Diagnostic.register(MixedLayerHeatContent) + Diagnostic.register(HeatContentLayer) + Diagnostic.register(HeatContent) + Diagnostic.register(MonthlyMean) + Diagnostic.register(Rewrite) + Diagnostic.register(Relink) + def clean(self): Log.info('Removing scratch folder...') if os.path.exists(self.config.scratch_dir): diff --git a/earthdiagnostics/general/__init__.py b/earthdiagnostics/general/__init__.py index d934d63..c53fb33 100644 --- a/earthdiagnostics/general/__init__.py +++ b/earthdiagnostics/general/__init__.py @@ -1,3 +1,4 @@ # coding=utf-8 from earthdiagnostics.general.monthlymean import MonthlyMean from earthdiagnostics.general.rewrite import Rewrite +from earthdiagnostics.general.relink import Relink diff --git a/earthdiagnostics/general/relink.py b/earthdiagnostics/general/relink.py new file mode 100644 index 0000000..74d5c1c --- /dev/null +++ b/earthdiagnostics/general/relink.py @@ -0,0 +1,74 @@ +# coding=utf-8 +from earthdiagnostics.diagnostic import Diagnostic + + +class Relink(Diagnostic): + """ + Recreates the links for the variable specified + + :original author: Javier Vegas-Regidor + + :created: September 2016 + + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: str + """ + + alias = 'relink' + "Diagnostic alias for the configuration file" + + def __init__(self, data_manager, startdate, member, chunk, domain, variable): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + + def __str__(self): + return 'Relink output Startdate: {0} Member: {1} Chunk: {2} ' \ + 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.domain == other.domain and self.variable == other.variable + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, domain + :type options: list[str] + :return: + """ + num_options = len(options) - 1 + if num_options < 2: + raise Exception('You must specify the variable and domain to link') + if num_options > 2: + raise Exception('You must specify 2 parameters for the relink diagnostic') + variable = options[1] + domain = options[2] + job_list = list() + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): + job_list.append(Relink(diags.data_manager, startdate, member, chunk, domain, variable)) + return job_list + + def compute(self): + """ + Runs the diagnostic + """ + self.data_manager.link_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + diff --git a/earthdiagnostics/general/rewrite.py b/earthdiagnostics/general/rewrite.py index 77a6fe9..952cb6d 100644 --- a/earthdiagnostics/general/rewrite.py +++ b/earthdiagnostics/general/rewrite.py @@ -51,13 +51,13 @@ class Rewrite(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: variable, domain, frequency=day + :param options: variable, domain :type options: list[str] :return: """ num_options = len(options) - 1 if num_options < 2: - raise Exception('You must specify the variable and domain to average monthly') + raise Exception('You must specify the variable and domain to rewrite') if num_options > 2: raise Exception('You must specify 2 parameters for the rewrite diagnostic') variable = options[1] -- GitLab From 57839b42c4315e11af0d1988748eaf286411eee4 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 15 Sep 2016 18:42:47 +0200 Subject: [PATCH 215/268] Added exception when trying to link a file that does not exists --- earthdiagnostics/datamanager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 20f1d04..80324fb 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -881,7 +881,6 @@ class DataManager(object): frequency = self.config.frequency domain = DataManager.correct_domain(domain) filepath = self._get_file_path(chunk, date_str, domain, frequency, grid, member, startdate, var, year) - self._create_link(domain, filepath, frequency, var, grid, move_older) def _get_file_path(self, chunk, date_str, domain, frequency, grid, member, startdate, var, year): @@ -979,6 +978,8 @@ class DataManager(object): link_path = os.path.join(link_path, os.path.basename(filepath)) if os.path.lexists(link_path): os.remove(link_path) + if not os.path.exists(filepath): + raise ValueError('Original file {0} does not exists') os.symlink(filepath, link_path) @staticmethod -- GitLab From 1d05884519871f4ff7098658272a98dbe4bfc831 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 16 Sep 2016 12:37:16 +0200 Subject: [PATCH 216/268] Extracted CMORization to its own class --- diags.conf | 2 +- doc/source/codedoc/earthdiagnostics.rst | 14 + earthdiagnostics/cmorizer.py | 477 ++++++++++++++++++++ earthdiagnostics/datamanager.py | 575 ++---------------------- earthdiagnostics/earthdiags.py | 13 +- earthdiagnostics/utils.py | 18 + earthdiagnostics/variable.py | 59 +++ test/unit/__init__.py | 3 +- test/unit/test_data_manager.py | 26 +- test/unit/test_variable.py | 26 ++ 10 files changed, 633 insertions(+), 580 deletions(-) create mode 100644 earthdiagnostics/cmorizer.py create mode 100644 earthdiagnostics/variable.py create mode 100644 test/unit/test_variable.py diff --git a/diags.conf b/diags.conf index af8d3e5..3b6bfc2 100644 --- a/diags.conf +++ b/diags.conf @@ -23,7 +23,7 @@ RESTORE_MESHES = False # If true, recreates CMOR files regardless of presence. Default = False FORCE = True # If true, CMORizes ocean files. Default = True -OCEAN_FILES = False +OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = True diff --git a/doc/source/codedoc/earthdiagnostics.rst b/doc/source/codedoc/earthdiagnostics.rst index f4cefa7..9c35e00 100644 --- a/doc/source/codedoc/earthdiagnostics.rst +++ b/doc/source/codedoc/earthdiagnostics.rst @@ -15,6 +15,13 @@ earthdiagnostics.cdftools :inherited-members: :members: +earthdiagnostics.cmorizer +------------------------- +.. automodule:: earthdiagnostics.cmorizer + :show-inheritance: + :inherited-members: + :members: + earthdiagnostics.config ----------------------- .. automodule:: earthdiagnostics.config @@ -64,3 +71,10 @@ earthdiagnostics.utils :show-inheritance: :inherited-members: :members: + +earthdiagnostics.variable +------------------------- +.. automodule:: earthdiagnostics.variable + :show-inheritance: + :inherited-members: + :members: diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py new file mode 100644 index 0000000..acb89df --- /dev/null +++ b/earthdiagnostics/cmorizer.py @@ -0,0 +1,477 @@ +# coding=utf-8 +import glob +import shutil +import uuid + +import netCDF4 +import os +from datetime import datetime + +import pygrib +from autosubmit.config.log import Log +from autosubmit.date.chunk_date_lib import parse_date, chunk_end_date, previous_day, date2str, add_months + +from earthdiagnostics.variable import Variable +from earthdiagnostics.utils import TempFile, Utils + + +class Cmorizer(object): + + def __init__(self, data_manager, startdate, member): + self.data_manager = data_manager + self.startdate = startdate + self.member = member + self.config = data_manager.config + self.experiment = self.config.experiment + self.cmor = self.config.cmor + self.member_str = self.experiment.get_member_str(member) + self.original_files_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', + self.startdate, self.member_str, 'outputs') + + def cmorize_ocean(self): + if not self.cmor.ocean: + return + self._unpack_ocean_files('MMO') + self._unpack_ocean_files('diags') + + def _unpack_ocean_files(self, prefix): + tar_folder = os.path.join(self.original_files_path, '{0}*'.format(prefix)) + tar_files = glob.glob(tar_folder) + tar_files.sort() + errors = list() + count = 1 + for tarfile in tar_files: + Log.info('Unpacking oceanic file {0}/{1}'.format(count, len(tar_files))) + self._unpack_tar(tarfile) + Log.result('Oceanic file {0}/{1} finished'.format(count, len(tar_files))) + count += 1 + return errors + + def _unpack_tar(self, tarfile): + Log.info('Unpacking {0}', tarfile) + + scratch_dir = os.path.join(self.config.scratch_dir, 'CMOR') + + if os.path.exists(scratch_dir): + shutil.rmtree(scratch_dir) + os.makedirs(scratch_dir) + Utils.untar((tarfile,), scratch_dir) + errors = Utils.unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) + + if os.path.basename(tarfile).startswith('MMA'): + temp = TempFile.get() + for filename in glob.glob(os.path.join(scratch_dir, 'MMA_*_SH_*.nc')): + Utils.cdo.sp2gpl(options='-O', input=filename, output=temp) + shutil.move(temp, filename) + + sh_files = glob.glob(os.path.join(scratch_dir, 'MMA_*_SH_*.nc')) + Utils.cdo.mergetime(input=sh_files, output=os.path.join(scratch_dir, 'sh.nc')) + + gg_files = glob.glob(os.path.join(scratch_dir, 'MMA_*_GG_*.nc')) + Utils.cdo.mergetime(input=gg_files, output=os.path.join(scratch_dir, 'gg.nc')) + + for filename in sh_files + gg_files: + os.remove(filename) + + Utils.nco.ncks(input=os.path.join(scratch_dir, 'sh.nc'), + output=os.path.join(scratch_dir, 'gg.nc'), options='-A') + os.remove(os.path.join(scratch_dir, 'sh.nc')) + + tar_startdate = tarfile[0:-4].split('_')[5].split('-') + new_name = 'MMA_1m_{0[0]}_{0[1]}.nc'.format(tar_startdate) + shutil.move(os.path.join(scratch_dir, 'gg.nc'), os.path.join(scratch_dir, new_name)) + + for filename in glob.glob(os.path.join(scratch_dir, '*.nc')): + self._cmorize_nc_file(filename) + return errors + + def cmorize_atmos(self): + if not self.cmor.atmosphere: + return + + grb_path = os.path.join(self.original_files_path, '*.grb') + gribfiles = glob.glob(grb_path) + if len(gribfiles) == 0: + tar_files = glob.glob( + os.path.join(self.original_files_path, 'MMA*')) + tar_files.sort() + count = 1 + for tarfile in tar_files: + Log.info('Unpacking atmospheric file {0}/{1}'.format(count, len(tar_files))) + self._unpack_tar(tarfile) + Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) + count += 1 + else: + self._cmorize_grib() + + def _cmorize_grib(self): + count = 1 + atmos_timestep = None + chunk_start = parse_date(self.startdate) + + while os.path.exists(os.path.join(self.original_files_path, self._get_grib_filename('GG', chunk_start))) or \ + os.path.exists(os.path.join(self.original_files_path, self._get_grib_filename('SH', chunk_start))): + + chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + Log.info('CMORizing chunk {0}-{1}', date2str(chunk_start), date2str(chunk_end)) + for grid in ('SH', 'GG'): + Log.info('Processing {0} variables', grid) + + if not os.path.exists(os.path.join(self.original_files_path, + self._get_grib_filename(grid, chunk_start))): + continue + + for month in range(0, self.experiment.chunk_size): + current_month = add_months(chunk_start, month, 'standard') + original_gribfile = os.path.join(self.original_files_path, + self._get_grib_filename(grid, current_month)) + Log.info('Processing month {1}', grid, date2str(current_month)) + gribfile = os.path.join(self.config.scratch_dir, os.path.basename(original_gribfile)) + if not os.path.isfile(gribfile): + Log.info('Copying file...', grid, date2str(current_month)) + shutil.copy(original_gribfile, gribfile) + + if atmos_timestep is None: + atmos_timestep = self._get_atmos_timestep(gribfile) + + prev_gribfile = os.path.join(self.config.scratch_dir, + self._get_grib_filename(grid, + add_months(current_month, -1, 'standard'))) + if os.path.exists(prev_gribfile): + self._merge_grib_files(current_month, prev_gribfile, gribfile) + full_file = 'ICM' + else: + full_file = gribfile + + Log.info('Unpacking... ') + # remap on regular Gauss grid + if grid == 'SH': + Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_', + options='-f nc4') + else: + Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R -f nc4') + # total precipitation (remove negative values) + Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' + '{0}_{{142,143}}.128.nc'.format(gribfile), + output='{0}_228.128.nc'.format(gribfile)) + Utils.remove_file('ICM') + next_gribfile = os.path.join(self.original_files_path, + self._get_grib_filename(grid, + add_months(current_month, 1, 'standard'))) + + if not os.path.exists(next_gribfile): + os.remove(gribfile) + + cdo_reftime = parse_date(self.startdate).strftime('%Y-%m-%d,00:00') + + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '{0}hr'.format(atmos_timestep)) + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1d') + self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1m') + + for splited_file in glob.glob('{0}_*.128.nc'.format(gribfile)): + os.remove(splited_file) + + Log.result('Month {0}, {1} variables finished', date2str(current_month), grid) + count += 1 + + self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, '1m') + self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, '1d') + self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, + '{0}hr'.format(atmos_timestep)) + chunk_start = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') + + def _get_grib_filename(self, grid, month): + return 'ICM{0}{1}+{2}.grb'.format(grid, self.experiment.expid, date2str(month)[:-2]) + + def _get_atmos_timestep(self, gribfile): + Log.info('Getting timestep...') + grib_handler = pygrib.open(gribfile) + mes1 = grib_handler.message(1) + mes2 = grib_handler.readline() + while mes2.analDate == mes1.analDate: + mes2 = grib_handler.readline() + atmos_timestep = mes2.analDate - mes1.analDate + atmos_timestep = int(atmos_timestep.total_seconds() / 3600) + self.experiment.atmos_timestep = atmos_timestep + grib_handler.close() + return atmos_timestep + + def _cmorize_nc_file(self, filename): + Log.info('Processing file {0}', filename) + temp = TempFile.get() + Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filename, temp]) + shutil.move(temp, filename) + file_parts = os.path.basename(filename).split('_') + if self.experiment.expid in [file_parts[1], file_parts[2]]: + frequency = 'm' + else: + frequency = file_parts[1][1].lower() + variables = dict() + variables['time_counter'] = 'time' + variables['time_counter_bnds'] = 'time_bnds' + variables['tbnds'] = 'bnds' + variables['nav_lat'] = 'lat' + variables['nav_lon'] = 'lon' + variables['x'] = 'i' + variables['y'] = 'j' + Utils.rename_variables(filename, variables, False, True) + handler = Utils.openCdf(filename) + self._add_common_attributes(frequency, handler) + self._update_time_variables(handler) + handler.sync() + temp = TempFile.get() + Log.info('Splitting file {0}', filename) + for variable in handler.variables.keys(): + if variable in ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', + 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', + 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', + 'time_counter_bounds', 'ncatice', + 'nav_lat_grid_V', 'nav_lat_grid_U', 'nav_lat_grid_T', + 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T', + 'depth', 'depth_2', 'depth_3', 'depth_4', + 'mlev', 'hyai', 'hybi', 'hyam', 'hybm'): + continue + self.extract_variable(filename, handler, frequency, temp, variable) + Log.result('File {0} cmorized!', filename) + handler.close() + os.remove(filename) + + def extract_variable(self, file_path, handler, frequency, temp, variable): + """ + Extracts a variable from a file and creates the CMOR file + + :param file_path: path to the file + :type file_path: str + :param handler: netCDF4 handler for the file + :type handler: netCDF$.Dataset + :param frequency: variable's frequency + :type frequency: str + :param temp: temporal file to use + :type temp: str + :param variable: variable's name + :type variable: str + """ + file_parts = os.path.basename(file_path).split('_') + var_cmor = Variable.get_variable(variable) + if var_cmor is None: + return + if frequency == 'd': + frequency = 'day' + elif frequency == 'm': + frequency = 'mon' + elif frequency == 'h': + frequency = '6hr' + else: + raise Exception('Frequency {0} not supported'.format(frequency)) + Utils.nco.ncks(input=file_path, output=temp, options='-v {0}'.format(variable)) + if var_cmor.domain == 'ocean': + Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev', + 'depth': 'lev'}, False, True) + elif var_cmor.domain in ('land', 'landIce'): + Utils.rename_variables(temp, {'depth': 'sdepth', 'depth_2': 'sdepth', 'depth_3': 'sdepth', + 'depth_4': 'sdepth'}, False, True) + elif var_cmor.domain == 'atmos': + Utils.rename_variables(temp, {'depth': 'plev'}, False, True) + + handler_cmor = Utils.openCdf(temp) + Utils.copy_variable(handler, handler_cmor, 'lon', False) + Utils.copy_variable(handler, handler_cmor, 'lat', False) + if 'time' in handler_cmor.dimensions.keys(): + Utils.copy_variable(handler, handler_cmor, 'leadtime', False) + handler_cmor.close() + + if var_cmor.basin is None: + region = None + else: + region = var_cmor.basin.fullname + + if file_parts[0] == self.experiment.expid or file_parts[0].startswith('ORCA') or \ + file_parts[0] in ('MMA', 'MMO'): + # Model output + date_str = '{0}-{1}'.format(file_parts[2][0:6], file_parts[3][0:6]) + elif file_parts[1] == self.experiment.expid: + # Files generated by the old version of the diagnostics + date_str = '{0}-{1}'.format(file_parts[4][0:6], file_parts[5][0:6]) + else: + Log.error('Variable {0} can not be cmorized. Original filename does not match a recognized pattern', + var_cmor.short_name) + return + + self.data_manager.send_file(temp, var_cmor.domain, var_cmor.short_name, self.startdate, self.member, + frequency=frequency, rename_var=variable, date_str=date_str, region=region, + move_older=True) + + @staticmethod + def _merge_grib_files(current_month, prev_gribfile, gribfile): + Log.info('Merging data from different files...') + fd = open('rules_files', 'w') + fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(current_month)) + fd.close() + # get first timestep for each month from previous file (if possible) + if os.path.exists('ICM'): + os.remove('ICM') + Utils.execute_shell_command('grib_filter -o ICM rules_files ' + '{0} {1}'.format(os.path.basename(prev_gribfile), + os.path.basename(gribfile))) + os.remove('rules_files') + Utils.remove_file(prev_gribfile) + + def _ungrib_vars(self, cdo_reftime, gribfile, month, frequency): + Log.info('Preparing {0} variables'.format(frequency)) + var_codes = self.config.cmor.get_variables(frequency) + for var_code in var_codes: + if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, var_code)): + continue + new_units = None + + cdo_operator = '-selmon,{0}'.format(month) + if frequency in ('month', 'monthly', 'mon', '1m'): + if var_code == 201: + cdo_operator = "-monmean -daymax {0}".format(cdo_operator) + elif var_code == 202: + cdo_operator = "-monmean -daymax {0}".format(cdo_operator) + else: + cdo_operator = "-monmean {0} ".format(cdo_operator) + elif frequency in ('day', 'daily', '1d'): + if var_code == 201: + cdo_operator = "-daymax {0} ".format(cdo_operator) + elif var_code == 202: + cdo_operator = "-daymin {0} ".format(cdo_operator) + else: + cdo_operator = "-daymean {0} ".format(cdo_operator) + + if var_code in (144, 146, 147, 169, 175, 176, 177, 179, 180, 181, 182, 201, 202, 205, 212, 228): + cdo_operator = '{0} -shifttime,-{1}hours'.format(cdo_operator, self.experiment.atmos_timestep) + + if var_code == 129: + # geopotential + new_units = "m" + cdo_operator = "-divc,9.81 {0}".format(cdo_operator) + elif var_code in (146, 147, 169, 175, 176, 177, 179, 212): + # radiation + new_units = "W m-2" + cdo_operator = "-divc,{0} {1}".format(self.experiment.atmos_timestep * 3600, cdo_operator) + elif var_code in (180, 181): + # momentum flux + new_units = "N m-2" + cdo_operator = "-divc,{0} {1}".format(self.experiment.atmos_timestep * 3600, cdo_operator) + elif var_code in (144, 182, 205, 228): + # precipitation/evaporation/runoff + new_units = "kg m-2 s-1" + cdo_operator = "-mulc,1000 -divc,{0}".format(self.experiment.atmos_timestep * 3600) + + levels = self.config.cmor.get_levels(frequency, var_code) + if levels: + cdo_operator = "{0} -sellevel,{1}".format(cdo_operator, levels) + + Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.nc ' + '{2}_{3}_{4}.nc'.format(cdo_reftime, cdo_operator, + gribfile, var_code, frequency)) + h_var_file = '{0}_{1}_{2}.nc'.format(gribfile, var_code, frequency) + + handler = Utils.openCdf(h_var_file) + if new_units: + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == var_code: + var.units = new_units + break + + var_name = None + for key in handler.variables.keys(): + if key + '_2' in handler.variables and key not in handler.dimensions: + var_name = key + handler.close() + + if var_name is not None: + Utils.nco.ncks(input='{0}_{1}_1m.nc'.format(gribfile, var_code), + output='{0}_{1}_1m.nc'.format(gribfile, var_code), + options='-O -v {0}'.format(var_name)) + + def _merge_and_cmorize_atmos(self, chunk_start, chunk_end, grid, frequency): + merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) + files = glob.glob(os.path.join(self.config.scratch_dir, + '{0}_*_{1}.nc'.format(self._get_grib_filename(grid, chunk_start), frequency))) + for first_file in files: + shutil.move(first_file, merged_file) + current_month = add_months(chunk_start, 1, 'standard') + while current_month < chunk_end: + month_file = first_file.replace('+{0}.grb'.format(date2str(chunk_start)[:-2]), + '+{0}.grb'.format(date2str(current_month)[:-2])) + Utils.concat_variables(month_file, merged_file, True) + current_month = add_months(current_month, 1, 'standard') + + self._cmorize_nc_file(merged_file) + + def _update_time_variables(self, handler): + time_var = handler.variables['time'] + times = Utils.get_datetime_from_netcdf(handler) + if type(times[0]) is not datetime: + for x in range(0, times.shape[0]): + # noinspection PyProtectedMember + times[x] = times[x]._to_real_datetime() + time_var[:] = netCDF4.date2num(times, 'days since 1850-01-01', 'standard') + if 'axis_nbounds' in handler.dimensions: + handler.renameDimension('axis_nbounds', 'bnds') + + if 'time_counter_bounds' in handler.variables: + handler.renameVariable('time_counter_bounds', 'time_bnds') + handler.sync() + if 'time_bnds' in handler.variables: + time_bounds_var = handler.variables['time_bnds'] + time_var.bounds = "time_bnds" + + time_bounds = Utils.get_datetime_from_netcdf(handler, 'time_bnds') + if type(time_bounds[0, 0]) is not datetime: + for x in range(0, time_bounds.shape[0]): + for y in range(0, time_bounds.shape[1]): + # noinspection PyProtectedMember + time_bounds[x, y] = time_bounds[x, y]._to_real_datetime() + time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') + time_var.units = 'days since 1850-01-01' + time_var.time_origin = "1850-01-01" + time_var.calendar = 'standard' + time_var.long_name = "Verification time of the forecast" + time_var.standard_name = "time" + time_var.axis = "T" + if 'leadtime' in handler.variables: + var = handler.variables['leadtime'] + else: + var = handler.createVariable('leadtime', float, 'time') + var.units = "days" + var.long_name = "Time elapsed since the start of the forecast" + var.standard_name = "forecast_period" + leadtime = (Utils.get_datetime_from_netcdf(handler) - parse_date(self.startdate)) + for lt in range(0, leadtime.shape[0]): + var[lt] = leadtime[lt].days + + def _add_common_attributes(self, frequency, handler): + cmor = self.config.cmor + experiment = self.config.experiment + handler.associated_experiment = cmor.associated_experiment + handler.batch = '{0}{1}'.format(experiment.institute, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) + handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ + 'Javier Vegas-Regidor, javier.vegas@bsc.es ' + handler.Conventions = 'CF-1.6' + handler.creation_date = datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)') + handler.experiment_id = experiment.experiment_name + handler.forecast_reference_time = parse_date(self.startdate).strftime('%Y-%m-%d(T%H:%M:%SZ)') + if frequency == 'd': + handler.frequency = 'day' + elif frequency == 'm': + handler.frequency = 'mon' + handler.institute_id = experiment.institute + handler.institution = experiment.institute + handler.initialization_method = cmor.initialization_method + handler.initialization_description = cmor.initialization_description + handler.physics_version = cmor.physics_version + handler.physics_description = cmor.physics_description + handler.model_id = experiment.model + handler.associated_model = cmor.associated_model + handler.project_id = 'SPECS' + handler.realization = str(self.member + 1) + handler.source = cmor.source + handler.startdate = 'S{0}'.format(self.startdate) + handler.tracking_id = str(uuid.uuid1()) + handler.title = "{0} model output prepared for SPECS {1}".format(experiment.model, experiment.experiment_name) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 80324fb..278090a 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,23 +1,20 @@ # coding: utf-8 import csv import glob -import re import shutil import threading -import uuid -import pygrib -from cfunits import Units from datetime import datetime -import netCDF4 import numpy as np import os +import re from autosubmit.config.log import Log -from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day, add_months, \ - date2str +from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day +from cfunits import Units -from earthdiagnostics.constants import Basins +from earthdiagnostics.cmorizer import Cmorizer from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Variable class DataManager(object): @@ -53,31 +50,14 @@ class DataManager(object): member_str = self.experiment.get_member_str(member) if self.config.cmor.force or not self._is_cmorized(startdate, member): created = True - Log.info('CMORizing startdate {0} member {1}', startdate, member_str) - if self.config.cmor.ocean: - errors += self._unpack_ocean_files('MMO', startdate, member) - errors += self._unpack_ocean_files('diags', startdate, member) + start_time = datetime.now() + Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) - if not self.config.cmor.atmosphere: - continue - grb_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, - member_str, 'outputs', '*.grb') - gribfiles = glob.glob(grb_path) - if len(gribfiles) == 0: - - tar_files = glob.glob( - os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, - member_str, 'outputs', 'MMA*')) - tar_files.sort() - count = 1 - for tarfile in tar_files: - Log.info('Unpacking atmospheric file {0}/{1}'.format(count, len(tar_files))) - errors += self._unpack_tar(tarfile, startdate, member) - Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) - count += 1 - else: - self._cmorize_grib(startdate, member) - Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str) + cmorizer = Cmorizer(self, startdate, member) + cmorizer.cmorize_ocean() + cmorizer.cmorize_atmos() + Log.result('CMORized startdate {0} member {1}! Ti\n\n', startdate, member_str, + datetime.now() - start_time) if created: for error in errors: @@ -95,221 +75,11 @@ class DataManager(object): self._unpack_cmorfiles(filepaths, member_path) - def _unpack_ocean_files(self, prefix, startdate, member): - tar_folder = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, - self.experiment.get_member_str(member), 'outputs', '{0}*'.format(prefix)) - tar_files = glob.glob(tar_folder) - tar_files.sort() - errors = list() - count = 1 - for tarfile in tar_files: - Log.info('Unpacking oceanic file {0}/{1}'.format(count, len(tar_files))) - errors += self._unpack_tar(tarfile, startdate, member) - Log.result('Oceanic file {0}/{1} finished'.format(count, len(tar_files))) - count += 1 - return errors - - def _get_grib_filename(self, grid, month): - return 'ICM{0}{1}+{2}.grb'.format(grid, self.experiment.expid, date2str(month)[:-2]) - - def _cmorize_grib(self, startdate, member): - count = 1 - atmos_timestep = None - chunk_start = parse_date(startdate) - member_str = self.experiment.get_member_str(member) - data_folder = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', startdate, - member_str, 'outputs') - - while os.path.exists(os.path.join(data_folder, self._get_grib_filename('GG', chunk_start))) or \ - os.path.exists(os.path.join(data_folder, self._get_grib_filename('SH', chunk_start))): - - chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') - Log.info('CMORizing chunk {0}-{1}', date2str(chunk_start), date2str(chunk_end)) - for grid in ('SH', 'GG'): - Log.info('Processing {0} variables', grid) - - if not os.path.exists(os.path.join(data_folder, self._get_grib_filename(grid, chunk_start))): - continue - - for month in range(0, self.experiment.chunk_size): - current_month = add_months(chunk_start, month, 'standard') - original_gribfile = os.path.join(data_folder, self._get_grib_filename(grid, current_month)) - Log.info('Processing month {1}', grid, date2str(current_month)) - gribfile = os.path.join(self.config.scratch_dir, os.path.basename(original_gribfile)) - if not os.path.isfile(gribfile): - Log.info('Copying file...', grid, date2str(current_month)) - shutil.copy(original_gribfile, gribfile) - - if atmos_timestep is None: - atmos_timestep = self._get_atmos_timestep(gribfile) - - prev_gribfile = os.path.join(self.config.scratch_dir, - self._get_grib_filename(grid, - add_months(current_month, -1, 'standard'))) - if os.path.exists(prev_gribfile): - self._merge_grib_files(current_month, prev_gribfile, gribfile) - full_file = 'ICM' - else: - full_file = gribfile - - Log.info('Unpacking... ') - # remap on regular Gauss grid - if grid == 'SH': - Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_', - options='-f nc4') - else: - Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R -f nc4') - # total precipitation (remove negative values) - Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' - '{0}_{{142,143}}.128.nc'.format(gribfile), - output='{0}_228.128.nc'.format(gribfile)) - Utils.remove_file('ICM') - next_gribfile = os.path.join(data_folder, - self._get_grib_filename(grid, - add_months(current_month, 1, 'standard'))) - - if not os.path.exists(next_gribfile): - os.remove(gribfile) - - cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') - - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '{0}hr'.format(atmos_timestep)) - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1d') - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1m') - - for splited_file in glob.glob('{0}_*.128.nc'.format(gribfile)): - os.remove(splited_file) - - Log.result('Month {0}, {1} variables finished', date2str(current_month), grid) - count += 1 - - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1m') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, '1d') - self._merge_and_cmorize_atmos(startdate, member, chunk_start, chunk_end, grid, - '{0}hr'.format(atmos_timestep)) - chunk_start = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') - - @staticmethod - def _merge_grib_files(current_month, prev_gribfile, gribfile): - Log.info('Merging data from different files...') - fd = open('rules_files', 'w') - fd.write('if (dataDate >= {0.year}{0.month:02}01) {{ write ; }}\n'.format(current_month)) - fd.close() - # get first timestep for each month from previous file (if possible) - if os.path.exists('ICM'): - os.remove('ICM') - Utils.execute_shell_command('grib_filter -o ICM rules_files ' - '{0} {1}'.format(os.path.basename(prev_gribfile), - os.path.basename(gribfile))) - os.remove('rules_files') - Utils.remove_file(prev_gribfile) - - def _get_atmos_timestep(self, gribfile): - Log.info('Getting timestep...') - grib_handler = pygrib.open(gribfile) - mes1 = grib_handler.message(1) - mes2 = grib_handler.readline() - while mes2.analDate == mes1.analDate: - mes2 = grib_handler.readline() - atmos_timestep = mes2.analDate - mes1.analDate - atmos_timestep = int(atmos_timestep.total_seconds() / 3600) - self.experiment.atmos_timestep = atmos_timestep - grib_handler.close() - return atmos_timestep - - def _ungrib_vars(self, cdo_reftime, gribfile, month, frequency): - Log.info('Preparing {0} variables'.format(frequency)) - var_codes = self.config.cmor.get_variables(frequency) - for var_code in var_codes: - if not os.path.exists('{0}_{1}.128.nc'.format(gribfile, var_code)): - continue - new_units = None - - cdo_operator = '-selmon,{0}'.format(month) - if frequency in ('month', 'monthly', 'mon', '1m'): - if var_code == 201: - cdo_operator = "-monmean -daymax {0}".format(cdo_operator) - elif var_code == 202: - cdo_operator = "-monmean -daymax {0}".format(cdo_operator) - else: - cdo_operator = "-monmean {0} ".format(cdo_operator) - elif frequency in ('day', 'daily', '1d'): - if var_code == 201: - cdo_operator = "-daymax {0} ".format(cdo_operator) - elif var_code == 202: - cdo_operator = "-daymin {0} ".format(cdo_operator) - else: - cdo_operator = "-daymean {0} ".format(cdo_operator) - - if var_code in (144, 146, 147, 169, 175, 176, 177, 179, 180, 181, 182, 201, 202, 205, 212, 228): - cdo_operator = '{0} -shifttime,-{1}hours'.format(cdo_operator, self.atmos_timestep) - - if var_code == 129: - # geopotential - new_units = "m" - cdo_operator = "-divc,9.81 {0}".format(cdo_operator) - elif var_code in (146, 147, 169, 175, 176, 177, 179, 212): - # radiation - new_units = "W m-2" - cdo_operator = "-divc,{0} {1}".format(self.atmos_timestep * 3600, cdo_operator) - elif var_code in (180, 181): - # momentum flux - new_units = "N m-2" - cdo_operator = "-divc,{0} {1}".format(self.atmos_timestep * 3600, cdo_operator) - elif var_code in (144, 182, 205, 228): - # precipitation/evaporation/runoff - new_units = "kg m-2 s-1" - cdo_operator = "-mulc,1000 -divc,{0}".format(self.atmos_timestep * 3600) - - levels = self.config.cmor.get_levels(frequency, var_code) - if levels: - cdo_operator = "{0} -sellevel,{1}".format(cdo_operator, levels) - - Utils.execute_shell_command('cdo -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.nc ' - '{2}_{3}_{4}.nc'.format(cdo_reftime, cdo_operator, - gribfile, var_code, frequency)) - h_var_file = '{0}_{1}_{2}.nc'.format(gribfile, var_code, frequency) - - handler = Utils.openCdf(h_var_file) - if new_units: - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == var_code: - var.units = new_units - break - - var_name = None - for key in handler.variables.keys(): - if key + '_2' in handler.variables and key not in handler.dimensions: - var_name = key - handler.close() - - if var_name is not None: - Utils.nco.ncks(input='{0}_{1}_1m.nc'.format(gribfile, var_code), - output='{0}_{1}_1m.nc'.format(gribfile, var_code), - options='-O -v {0}'.format(var_name)) - - def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, grid, frequency): - merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) - files = glob.glob(os.path.join(self.config.scratch_dir, - '{0}_*_{1}.nc'.format(self._get_grib_filename(grid, chunk_start), frequency))) - for first_file in files: - shutil.move(first_file, merged_file) - current_month = add_months(chunk_start, 1, 'standard') - while current_month < chunk_end: - month_file = first_file.replace('+{0}.grb'.format(date2str(chunk_start)[:-2]), - '+{0}.grb'.format(date2str(current_month)[:-2])) - Utils.concat_variables(month_file, merged_file, True) - current_month = add_months(current_month, 1, 'standard') - - self._cmorize_nc_file(merged_file, member, startdate) - def _unpack_cmorfiles(self, filepaths, member_path): threads = list() numthreads = Utils.available_cpu_count() for numthread in range(0, numthreads): - t = threading.Thread(target=DataManager._unzip, + t = threading.Thread(target=Utils.unzip, args=([filepaths[numthread::numthreads]])) threads.append(t) t.start() @@ -317,7 +87,7 @@ class DataManager(object): t.join() filepaths = glob.glob(os.path.join(member_path, '*.tar')).sort() for numthread in range(0, numthreads): - t = threading.Thread(target=DataManager._untar, + t = threading.Thread(target=Utils.untar, args=(filepaths[numthread::numthreads], member_path)) threads.append(t) t.start() @@ -352,245 +122,6 @@ class DataManager(object): Log.info('Moving {0} to {1}'.format(filename, good)) Utils.move_file(filepath, good) - def _unpack_tar(self, tarfile, startdate, member): - Log.info('Unpacking {0}', tarfile) - - scratch_dir = os.path.join(self.config.scratch_dir, 'CMOR') - - if os.path.exists(scratch_dir): - shutil.rmtree(scratch_dir) - os.makedirs(scratch_dir) - self._untar((tarfile,), scratch_dir) - errors = self._unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) - - if os.path.basename(tarfile).startswith('MMA'): - temp = TempFile.get() - for filename in glob.glob(os.path.join(scratch_dir, 'MMA_*_SH_*.nc')): - Utils.cdo.sp2gpl(options='-O', input=filename, output=temp) - shutil.move(temp, filename) - - sh_files = glob.glob(os.path.join(scratch_dir, 'MMA_*_SH_*.nc')) - Utils.cdo.mergetime(input=sh_files, output=os.path.join(scratch_dir, 'sh.nc')) - - gg_files = glob.glob(os.path.join(scratch_dir, 'MMA_*_GG_*.nc')) - Utils.cdo.mergetime(input=gg_files, output=os.path.join(scratch_dir, 'gg.nc')) - - for filename in sh_files + gg_files: - os.remove(filename) - - Utils.nco.ncks(input=os.path.join(scratch_dir, 'sh.nc'), - output=os.path.join(scratch_dir, 'gg.nc'), options='-A') - os.remove(os.path.join(scratch_dir, 'sh.nc')) - - tar_startdate = tarfile[0:-4].split('_')[5].split('-') - new_name = 'MMA_1m_{0[0]}_{0[1]}.nc'.format(tar_startdate) - shutil.move(os.path.join(scratch_dir, 'gg.nc'), os.path.join(scratch_dir, new_name)) - - for filename in glob.glob(os.path.join(scratch_dir, '*.nc')): - self._cmorize_nc_file(filename, member, startdate) - return errors - - def _cmorize_nc_file(self, filename, member, startdate): - Log.info('Processing file {0}', filename) - temp = TempFile.get() - Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filename, temp]) - shutil.move(temp, filename) - file_parts = os.path.basename(filename).split('_') - if self.experiment.expid in [file_parts[1], file_parts[2]]: - frequency = 'm' - else: - frequency = file_parts[1][1].lower() - variables = dict() - variables['time_counter'] = 'time' - variables['time_counter_bnds'] = 'time_bnds' - variables['tbnds'] = 'bnds' - variables['nav_lat'] = 'lat' - variables['nav_lon'] = 'lon' - variables['x'] = 'i' - variables['y'] = 'j' - Utils.rename_variables(filename, variables, False, True) - handler = Utils.openCdf(filename) - self._add_common_attributes(frequency, handler, member, startdate) - self._update_time_variables(handler, startdate) - handler.sync() - temp = TempFile.get() - Log.info('Splitting file {0}', filename) - for variable in handler.variables.keys(): - if variable in ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', - 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', - 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', - 'time_counter_bounds', 'ncatice', - 'nav_lat_grid_V', 'nav_lat_grid_U', 'nav_lat_grid_T', - 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T', - 'depth', 'depth_2', 'depth_3', 'depth_4', - 'mlev', 'hyai', 'hybi', 'hyam', 'hybm'): - continue - self.extract_variable(filename, handler, frequency, member, startdate, temp, variable) - Log.result('File {0} cmorized!', filename) - handler.close() - os.remove(filename) - - def extract_variable(self, file_path, handler, frequency, member, startdate, temp, variable): - """ - Extracts a variable from a file and creates the CMOR file - - :param file_path: path to the file - :type file_path: str - :param handler: netCDF4 handler for the file - :type handler: netCDF$.Dataset - :param frequency: variable's frequency - :type frequency: str - :param member: member - :type member: int - :param startdate: startdate - :type startdate: str - :param temp: temporal file to use - :type temp: str - :param variable: variable's name - :type variable: str - """ - file_parts = os.path.basename(file_path).split('_') - var_cmor = Variable.get_variable(variable) - if var_cmor is None: - return - if frequency == 'd': - frequency = 'day' - elif frequency == 'm': - frequency = 'mon' - elif frequency == 'h': - frequency = '6hr' - else: - raise Exception('Frequency {0} not supported'.format(frequency)) - Utils.nco.ncks(input=file_path, output=temp, options='-v {0}'.format(variable)) - if var_cmor.domain == 'ocean': - Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev', - 'depth': 'lev'}, False, True) - elif var_cmor.domain in ('land', 'landIce'): - Utils.rename_variables(temp, {'depth': 'sdepth', 'depth_2': 'sdepth', 'depth_3': 'sdepth', - 'depth_4': 'sdepth'}, False, True) - elif var_cmor.domain == 'atmos': - Utils.rename_variables(temp, {'depth': 'plev'}, False, True) - - handler_cmor = Utils.openCdf(temp) - Utils.copy_variable(handler, handler_cmor, 'lon', False) - Utils.copy_variable(handler, handler_cmor, 'lat', False) - if 'time' in handler_cmor.dimensions.keys(): - Utils.copy_variable(handler, handler_cmor, 'leadtime', False) - handler_cmor.close() - - if var_cmor.basin is None: - region = None - else: - region = var_cmor.basin.fullname - - if file_parts[0] == self.experiment.expid or file_parts[0].startswith('ORCA') or \ - file_parts[0] in ('MMA', 'MMO'): - # Model output - date_str = '{0}-{1}'.format(file_parts[2][0:6], file_parts[3][0:6]) - elif file_parts[1] == self.experiment.expid: - # Files generated by the old version of the diagnostics - date_str = '{0}-{1}'.format(file_parts[4][0:6], file_parts[5][0:6]) - else: - Log.error('Variable {0} can not be cmorized. Original filename does not match a recognized pattern', - var_cmor.short_name) - return - - self.send_file(temp, var_cmor.domain, var_cmor.short_name, startdate, member, - frequency=frequency, rename_var=variable, - date_str=date_str, - region=region, move_older=True) - - @staticmethod - def _update_time_variables(handler, startdate): - time_var = handler.variables['time'] - times = Utils.get_datetime_from_netcdf(handler) - if type(times[0]) is not datetime: - for x in range(0, times.shape[0]): - # noinspection PyProtectedMember - times[x] = times[x]._to_real_datetime() - time_var[:] = netCDF4.date2num(times, 'days since 1850-01-01', 'standard') - if 'axis_nbounds' in handler.dimensions: - handler.renameDimension('axis_nbounds', 'bnds') - - if 'time_counter_bounds' in handler.variables: - handler.renameVariable('time_counter_bounds', 'time_bnds') - handler.sync() - if 'time_bnds' in handler.variables: - time_bounds_var = handler.variables['time_bnds'] - time_var.bounds = "time_bnds" - - time_bounds = Utils.get_datetime_from_netcdf(handler, 'time_bnds') - if type(time_bounds[0, 0]) is not datetime: - for x in range(0, time_bounds.shape[0]): - for y in range(0, time_bounds.shape[1]): - # noinspection PyProtectedMember - time_bounds[x, y] = time_bounds[x, y]._to_real_datetime() - time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') - time_var.units = 'days since 1850-01-01' - time_var.time_origin = "1850-01-01" - time_var.calendar = 'standard' - time_var.long_name = "Verification time of the forecast" - time_var.standard_name = "time" - time_var.axis = "T" - if 'leadtime' in handler.variables: - var = handler.variables['leadtime'] - else: - var = handler.createVariable('leadtime', float, 'time') - var.units = "days" - var.long_name = "Time elapsed since the start of the forecast" - var.standard_name = "forecast_period" - leadtime = (Utils.get_datetime_from_netcdf(handler) - parse_date(startdate)) - for lt in range(0, leadtime.shape[0]): - var[lt] = leadtime[lt].days - - def _add_common_attributes(self, frequency, handler, member, startdate): - cmor = self.config.cmor - experiment = self.config.experiment - handler.associated_experiment = cmor.associated_experiment - handler.batch = '{0}{1}'.format(experiment.institute, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) - handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ - 'Javier Vegas-Regidor, javier.vegas@bsc.es ' - handler.Conventions = 'CF-1.6' - handler.creation_date = datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)') - handler.experiment_id = experiment.experiment_name - handler.forecast_reference_time = parse_date(startdate).strftime('%Y-%m-%d(T%H:%M:%SZ)') - if frequency == 'd': - handler.frequency = 'day' - elif frequency == 'm': - handler.frequency = 'mon' - handler.institute_id = experiment.institute - handler.institution = experiment.institute - handler.initialization_method = cmor.initialization_method - handler.initialization_description = cmor.initialization_description - handler.physics_version = cmor.physics_version - handler.physics_description = cmor.physics_description - handler.model_id = experiment.model - handler.associated_model = cmor.associated_model - handler.project_id = 'SPECS' - handler.realization = str(member + 1) - handler.source = cmor.source - handler.startdate = 'S{0}'.format(startdate) - handler.tracking_id = str(uuid.uuid1()) - handler.title = "{0} model output prepared for SPECS {1}".format(experiment.model, experiment.experiment_name) - - @staticmethod - def _unzip(files): - errors = list() - for filepath in files: - Log.debug('Unzipping {0}', filepath) - try: - Utils.execute_shell_command('gunzip {0}'.format(filepath)) - except Exception as ex: - Log.error('Can not unzip {0}: {1}', filepath, ex) - errors.append(filepath) - return errors - - @staticmethod - def _untar(files, member_path): - for filepath in files: - Log.debug('Unpacking {0}', filepath) - Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) - def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy @@ -619,7 +150,7 @@ class DataManager(object): frequency = self.config.frequency domain = DataManager.correct_domain(domain) - domain_abbreviation = self.domain_abbreviation(domain, frequency) + domain_abbreviation = self.get_domain_abbreviation(domain, frequency) start = parse_date(startdate) member_plus = str(member + 1) @@ -666,7 +197,10 @@ class DataManager(object): Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge with already existing ones as needed - :param date_str: + :param move_older: if true, moves files following older conventions that may be found on the links folder + :type move_older: bool + :param date_str: exact date_str to use in the cmorized file + :type: str :param year: if frequency is yearly, this parameter is used to give the corresponding year :type year: int :param rename_var: if exists, the given variable will be renamed to the one given by var @@ -724,7 +258,7 @@ class DataManager(object): var_handler.short_name = cmor_var.short_name var_type = var_handler.dtype handler.modeling_realm = cmor_var.domain - handler.table_id = 'Table {0} (December 2013)'.format(self.domain_abbreviation(cmor_var.domain, frequency)) + handler.table_id = 'Table {0} (December 2013)'.format(self.get_domain_abbreviation(cmor_var.domain, frequency)) if cmor_var.units: self._fix_units(cmor_var, var_handler) @@ -853,9 +387,6 @@ class DataManager(object): :param date_str: :param year: if frequency is yearly, this parameter is used to give the corresponding year :type year: int - :param region: specifies the region represented by the file. If it is defined, the data will be appended to the - CMOR repository as a new region in the file or will overwrite if region was already present - :type region: str :param domain: CMOR domain :type domain: str :param var: variable name @@ -884,7 +415,7 @@ class DataManager(object): self._create_link(domain, filepath, frequency, var, grid, move_older) def _get_file_path(self, chunk, date_str, domain, frequency, grid, member, startdate, var, year): - domain_abreviattion = self.domain_abbreviation(domain, frequency) + domain_abreviattion = self.get_domain_abbreviation(domain, frequency) start = parse_date(startdate) member_plus = str(member + 1) member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) @@ -896,14 +427,14 @@ class DataManager(object): time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, chunk_end.month) - elif year is not None: + elif year: if frequency is not 'yr': raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') time_bound = str(year) - elif date_str is not None: + elif date_str: time_bound = date_str else: - raise ValueError('Chunk and year can not be None at the same time') + raise ValueError('Chunk, year and date_str can not be None at the same time') if grid: var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) else: @@ -914,7 +445,8 @@ class DataManager(object): startdate, member_plus, time_bound)) return filepath - def _get_final_var_name(self, box, var): + @staticmethod + def _get_final_var_name(box, var): if box: var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() return var @@ -983,7 +515,7 @@ class DataManager(object): os.symlink(filepath, link_path) @staticmethod - def domain_abbreviation(domain, frequency): + def get_domain_abbreviation(domain, frequency): """ Returns the table name for a domain-frequency pair :param domain: variable's domain @@ -1072,59 +604,6 @@ class DataManager(object): return False -class Variable(object): - """ - Class to characterize a CMOR variable. It also contains the static method to make the match between thje original - name and the standard name. Requires cmor_table.csv to work. - """ - _dict_variables = None - - def __init__(self, line): - self.short_name = line[1].strip() - self.standard_name = line[2].strip() - self.long_name = line[3].strip() - self.domain = line[4].strip() - self.basin = Basins.parse(line[5]) - self.units = line[6].strip() - self.valid_min = line[7].strip() - self.valid_max = line[8].strip() - - @classmethod - def get_variable(cls, original_name): - """ - Returns the cmor variable instance given a variable name - - :param original_name: original variable's name - :type original_name: str - :return: CMOR variable - :rtype: Variable - """ - try: - return cls._dict_variables[original_name.lower()] - except KeyError: - Log.warning('Variable {0} is not defined in the CMOR table. Please add it'.format(original_name)) - return None - - @classmethod - def load_variables(cls): - """ - Loads the cmor_table.csv and creates the variables dictionary - """ - Variable._dict_variables = dict() - with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'cmor_table.csv'), 'rb') as csvfile: - reader = csv.reader(csvfile, dialect='excel') - for line in reader: - if line[0] == 'Variable': - continue - - var = Variable(line) - if not var.short_name: - continue - for old_name in line[0].split(':'): - Variable._dict_variables[old_name] = var - Variable._dict_variables[var.short_name] = var - - class UnitConversion(object): """ Class to manage unit conversions diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 2d2b96c..ee0d76d 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -159,13 +159,13 @@ class EarthDiags(object): threads.append(t) t.start() - list_jobs.join() + for t in threads: + t.join() TempFile.clean() - finsih_time = datetime.datetime.now() - Log.result("Diagnostics finished at {0}", finsih_time) - Log.result("Time ellapsed: {0}\n", finsih_time - time) - + finish_time = datetime.datetime.now() + Log.result("Diagnostics finished at {0}", finish_time) + Log.result("Time ellapsed: {0}\n", finish_time - time) self.print_stats() def print_stats(self): @@ -196,7 +196,8 @@ class EarthDiags(object): Log.error('{0} is not an available diagnostic', diag_options[0]) return list_jobs - def _register_diagnostics(self): + @staticmethod + def _register_diagnostics(): Diagnostic.register(MixedLayerSaltContent) Diagnostic.register(Siasiesiv) Diagnostic.register(VerticalMean) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 849a496..39993b8 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -456,6 +456,24 @@ class Utils(object): translated.append(dim) return translated + @staticmethod + def untar(files, member_path): + for filepath in files: + Log.debug('Unpacking {0}', filepath) + Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) + + @staticmethod + def unzip(files): + for filepath in files: + Log.debug('Unzipping {0}', filepath) + try: + Utils.execute_shell_command('gunzip {0}'.format(filepath)) + except Exception as ex: + raise Utils.UnzipException('Can not unzip {0}: {1}'.format(filepath, ex)) + + class UnzipException(Exception): + pass + class TempFile(object): """ diff --git a/earthdiagnostics/variable.py b/earthdiagnostics/variable.py new file mode 100644 index 0000000..642b048 --- /dev/null +++ b/earthdiagnostics/variable.py @@ -0,0 +1,59 @@ +import csv + +import os +from autosubmit.config.log import Log + +from earthdiagnostics.constants import Basins + + +class Variable(object): + """ + Class to characterize a CMOR variable. It also contains the static method to make the match between thje original + name and the standard name. Requires cmor_table.csv to work. + """ + _dict_variables = None + + def __init__(self, line): + self.short_name = line[1].strip() + self.standard_name = line[2].strip() + self.long_name = line[3].strip() + self.domain = line[4].strip() + self.basin = Basins.parse(line[5]) + self.units = line[6].strip() + self.valid_min = line[7].strip() + self.valid_max = line[8].strip() + + @classmethod + def get_variable(cls, original_name): + """ + Returns the cmor variable instance given a variable name + + :param original_name: original variable's name + :type original_name: str + :return: CMOR variable + :rtype: Variable + """ + try: + return cls._dict_variables[original_name.lower()] + except KeyError: + Log.warning('Variable {0} is not defined in the CMOR table. Please add it'.format(original_name)) + return None + + @classmethod + def load_variables(cls): + """ + Loads the cmor_table.csv and creates the variables dictionary + """ + Variable._dict_variables = dict() + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'cmor_table.csv'), 'rb') as csvfile: + reader = csv.reader(csvfile, dialect='excel') + for line in reader: + if line[0] == 'Variable': + continue + + var = Variable(line) + if not var.short_name: + continue + for old_name in line[0].split(':'): + Variable._dict_variables[old_name] = var + Variable._dict_variables[var.short_name] = var diff --git a/test/unit/__init__.py b/test/unit/__init__.py index 9f35180..7a15d90 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -1,5 +1,6 @@ # coding=utf-8 -from test_data_manager import TestVariable, TestConversion +from test_data_manager import TestConversion +from test.unit.test_variable import TestVariable from test_constants import TestBasin, TestBasins from test_box import TestBox from test_diagnostic import TestDiagnostic diff --git a/test/unit/test_data_manager.py b/test/unit/test_data_manager.py index 0b5d2ab..6bdc84b 100644 --- a/test/unit/test_data_manager.py +++ b/test/unit/test_data_manager.py @@ -2,30 +2,8 @@ from unittest import TestCase -from earthdiagnostics.datamanager import Variable, UnitConversion - - -class TestVariable(TestCase): - - def test__init__(self): - variable = Variable('alias:alias2,name,standard_name,long_name,domain,basin,units,' - 'valid_min,valid_max'.split(',')) - self.assertEqual(variable.short_name, 'name') - self.assertEqual(variable.standard_name, 'standard_name') - self.assertEqual(variable.long_name, 'long_name') - self.assertEqual(variable.domain, 'domain') - self.assertEqual(variable.basin, None) - self.assertEqual(variable.units, 'units') - self.assertEqual(variable.valid_min, 'valid_min') - self.assertEqual(variable.valid_max, 'valid_max') - - def test_get_variable(self): - Variable._dict_variables = dict() - variable = Variable('alias:alias2,name,standard_name,long_name,domain,basin,units,valid_min,' - 'valid_max'.split(',')) - Variable._dict_variables['var'] = variable - self.assertIs(Variable.get_variable('var'), variable) - self.assertIsNone(Variable.get_variable('novar')) + +from earthdiagnostics.datamanager import UnitConversion class TestConversion(TestCase): diff --git a/test/unit/test_variable.py b/test/unit/test_variable.py new file mode 100644 index 0000000..6b3bc79 --- /dev/null +++ b/test/unit/test_variable.py @@ -0,0 +1,26 @@ +from unittest import TestCase + +from earthdiagnostics.variable import Variable + + +class TestVariable(TestCase): + + def test__init__(self): + variable = Variable('alias:alias2,name,standard_name,long_name,domain,basin,units,' + 'valid_min,valid_max'.split(',')) + self.assertEqual(variable.short_name, 'name') + self.assertEqual(variable.standard_name, 'standard_name') + self.assertEqual(variable.long_name, 'long_name') + self.assertEqual(variable.domain, 'domain') + self.assertEqual(variable.basin, None) + self.assertEqual(variable.units, 'units') + self.assertEqual(variable.valid_min, 'valid_min') + self.assertEqual(variable.valid_max, 'valid_max') + + def test_get_variable(self): + Variable._dict_variables = dict() + variable = Variable('alias:alias2,name,standard_name,long_name,domain,basin,units,valid_min,' + 'valid_max'.split(',')) + Variable._dict_variables['var'] = variable + self.assertIs(Variable.get_variable('var'), variable) + self.assertIsNone(Variable.get_variable('novar')) \ No newline at end of file -- GitLab From 1974f7a5a6e887d7c64c07e4486e20c5e86fee3b Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 16 Sep 2016 14:59:04 +0200 Subject: [PATCH 217/268] Changed path for the moved files when move_old is active when linking. Added move_old option to relink diagnostic --- earthdiagnostics/datamanager.py | 50 +++++++++++++++++------------- earthdiagnostics/general/relink.py | 25 ++++++++++----- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 278090a..4b55c02 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -30,6 +30,7 @@ class DataManager(object): self._checked_vars = list() Variable.load_variables() UnitConversion.load_conversions() + self.lock = threading.Lock() # noinspection PyPep8Naming def prepare_CMOR_files(self): @@ -192,13 +193,13 @@ class DataManager(object): self.experiment.model, self.experiment.experiment_name, 'S' + startdate) def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, - rename_var=None, frequency=None, year=None, date_str=None, move_older=False): + rename_var=None, frequency=None, year=None, date_str=None, move_old=False): """ Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge with already existing ones as needed - :param move_older: if true, moves files following older conventions that may be found on the links folder - :type move_older: bool + :param move_old: if true, moves files following older conventions that may be found on the links folder + :type move_old: bool :param date_str: exact date_str to use in the cmorized file :type: str :param year: if frequency is yearly, this parameter is used to give the corresponding year @@ -304,7 +305,7 @@ class DataManager(object): Utils.rename_variables(filetosend, variables, False, True) Utils.move_file(filetosend, filepath) - self._create_link(domain, filepath, frequency, var, grid, move_older) + self._create_link(domain, filepath, frequency, var, grid, move_old) @staticmethod def _fix_units(cmor_var, var_handler): @@ -380,7 +381,7 @@ class DataManager(object): Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, - frequency=None, year=None, date_str=None, move_older=False): + frequency=None, year=None, date_str=None, move_old=False): """ Creates the link of a given file from the CMOR repository. @@ -412,7 +413,7 @@ class DataManager(object): frequency = self.config.frequency domain = DataManager.correct_domain(domain) filepath = self._get_file_path(chunk, date_str, domain, frequency, grid, member, startdate, var, year) - self._create_link(domain, filepath, frequency, var, grid, move_older) + self._create_link(domain, filepath, frequency, var, grid, move_old) def _get_file_path(self, chunk, date_str, domain, frequency, grid, member, startdate, var, year): domain_abreviattion = self.get_domain_abbreviation(domain, frequency) @@ -467,7 +468,7 @@ class DataManager(object): return 'landIce' return domain - def _create_link(self, domain, filepath, frequency, var, grid, move_older): + def _create_link(self, domain, filepath, frequency, var, grid, move_old): if frequency in ('d', 'daily', 'day'): freq_str = 'daily_mean' else: @@ -490,22 +491,26 @@ class DataManager(object): os.makedirs(link_path) except Exception: pass - elif move_older: - if link_path not in self._checked_vars: - old_path = link_path + '_old' - regex = re.compile(var + '_[0-9]{6,8}\.nc') - for filename in os.listdir(link_path): - if regex.match(filename): - if not os.path.exists(old_path): - # This can be a race condition - # noinspection PyBroadException - try: - os.makedirs(old_path) - except Exception: - pass - Utils.move_file(os.path.join(link_path, filename), - os.path.join(old_path, filename)) + elif move_old: + if self.lock.acquire(False): + if link_path not in self._checked_vars: self._checked_vars.append(link_path) + self.lock.release() + old_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, + 'old_{0}_f{1}h'.format(var, self.experiment.atmos_timestep)) + regex = re.compile(var + '_[0-9]{6,8}\.nc') + for filename in os.listdir(link_path): + if regex.match(filename): + if not os.path.exists(old_path): + # This can be a race condition + # noinspection PyBroadException + try: + os.makedirs(old_path) + except Exception: + pass + Utils.move_file(os.path.join(link_path, filename), + os.path.join(old_path, filename)) + link_path = os.path.join(link_path, os.path.basename(filepath)) if os.path.lexists(link_path): @@ -697,3 +702,4 @@ class UnitConversion(object): return 1 / conversion.factor, -conversion.offset else: return None, None + diff --git a/earthdiagnostics/general/relink.py b/earthdiagnostics/general/relink.py index 74d5c1c..c9b04c8 100644 --- a/earthdiagnostics/general/relink.py +++ b/earthdiagnostics/general/relink.py @@ -22,22 +22,26 @@ class Relink(Diagnostic): :type variable: str :param domain: variable's domain :type domain: str + :param move_old: if true, looks for files following the old convention and moves to avoid collisions + :type move_old: bool """ alias = 'relink' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, domain, variable): + def __init__(self, data_manager, startdate, member, chunk, domain, variable, move_old): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.variable = variable self.domain = domain + self.move_old = move_old def __str__(self): - return 'Relink output Startdate: {0} Member: {1} Chunk: {2} ' \ - 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + return 'Relink output Startdate: {0} Member: {1} Chunk: {2} Move old: {5} ' \ + 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable, + self.move_old) def __eq__(self, other): return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ @@ -50,25 +54,30 @@ class Relink(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: variable, domain + :param options: variable, domain, move_old=False :type options: list[str] :return: """ num_options = len(options) - 1 if num_options < 2: raise Exception('You must specify the variable and domain to link') - if num_options > 2: - raise Exception('You must specify 2 parameters for the relink diagnostic') + if num_options > 3: + raise Exception('You must between 2 and 3 parameters for the relink diagnostic') variable = options[1] domain = options[2] + if num_options >= 3: + move_old = bool(options[3].lower()) + else: + move_old = True job_list = list() for startdate, member, chunk in diags.config.experiment.get_chunk_list(): - job_list.append(Relink(diags.data_manager, startdate, member, chunk, domain, variable)) + job_list.append(Relink(diags.data_manager, startdate, member, chunk, domain, variable, move_old)) return job_list def compute(self): """ Runs the diagnostic """ - self.data_manager.link_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + self.data_manager.link_file(self.domain, self.variable, self.startdate, self.member, self.chunk, + move_old=self.move_old) -- GitLab From 3c02f66e5ed9a7ee1bc7c1317bafe7f9545e2374 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 16 Sep 2016 15:38:55 +0200 Subject: [PATCH 218/268] Updated doc and bumped version to v3.0.0b10 --- VERSION | 2 +- doc/source/codedoc/general.rst | 6 ++++++ doc/source/conf.py | 2 +- doc/source/diagnostic_list.rst | 4 ++++ earthdiagnostics/EarthDiagnostics.pdf | Bin 233001 -> 240758 bytes earthdiagnostics/datamanager.py | 1 - test/unit/test_variable.py | 2 +- 7 files changed, 13 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 9e0b71d..bb86ca5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b9 +3.0.0b10 diff --git a/doc/source/codedoc/general.rst b/doc/source/codedoc/general.rst index 99200a0..a64c615 100644 --- a/doc/source/codedoc/general.rst +++ b/doc/source/codedoc/general.rst @@ -7,6 +7,12 @@ earthdiagnostics.general.monthlymean :show-inheritance: :members: +earthdiagnostics.ocean.relink +----------------------------- +.. automodule:: earthdiagnostics.general.relink + :show-inheritance: + :members: + earthdiagnostics.ocean.rewrite ------------------------------ .. automodule:: earthdiagnostics.general.rewrite diff --git a/doc/source/conf.py b/doc/source/conf.py index fe23e77..f8a9a12 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b9' +release = '3.0.0b10' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/diagnostic_list.rst b/doc/source/diagnostic_list.rst index c29d910..e75b31f 100644 --- a/doc/source/diagnostic_list.rst +++ b/doc/source/diagnostic_list.rst @@ -18,6 +18,10 @@ General Calculates the monthly mean of the given variable. See :class:`~earthdiagnostics.general.monthlymean.MonthlyMean` +- relink: + Regenerates the links created in the monthly_mean, daily_mean, folders. + See :class:`~earthdiagnostics.general.relink.Relink` + - rewrite: Just rewrites the CMOR output of a given variable. Useful to correct metadata or variable units. See :class:`~earthdiagnostics.general.rewrite.Rewrite` diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index a2a74c07e770c5d7c09da5f312f28c322030dd0d..0f4c4084aaf17ac2997cd85ad045f8db8021821a 100644 GIT binary patch delta 154109 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 K1g;tBQ2saLPU&?3 delta 146688 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 Date: Tue, 20 Sep 2016 15:34:43 +0200 Subject: [PATCH 219/268] Modifications to make it work with CDFTOOLS module --- diags.conf | 2 +- earthdiagnostics/cdftools.py | 4 ++-- earthdiagnostics/config.py | 2 +- earthdiagnostics/datamanager.py | 4 +++- launch_diags.sh | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/diags.conf b/diags.conf index 3b6bfc2..bacc31e 100644 --- a/diags.conf +++ b/diags.conf @@ -13,7 +13,7 @@ DIAGS = # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. FREQUENCY = mon # Path to CDFTOOLS binaries -CDFTOOLS_PATH = /shared/earth/ClimatePrediction/CDFTOOLS_CMOR/bin +CDFTOOLS_PATH = # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) diff --git a/earthdiagnostics/cdftools.py b/earthdiagnostics/cdftools.py index 5db174b..baa5623 100644 --- a/earthdiagnostics/cdftools.py +++ b/earthdiagnostics/cdftools.py @@ -31,8 +31,9 @@ class CDFTools(object): :param log_level: log level at which the output of the cdftool command will be added :type log_level: int """ + line = [os.path.join(self.path, command)] - if not os.path.exists(line[0]): + if self.path and not os.path.exists(line[0]): raise ValueError('Error executing {0}\n Command does not exist in {1}', command, self.path) if input: @@ -63,4 +64,3 @@ class CDFTools(object): raise Exception('Error executing {0}\n Output file not created', ' '.join(line)) return shell_output - diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index 012ea50..a5f53a4 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -66,7 +66,7 @@ class Config(object): self._real_commands = list() for command in commands: if command.lower() in self._aliases: - added_commands = self._aliases[command] + added_commands = self._aliases[command.lower()] Log.info('Changing alias {0} for {1}', command, ' '.join(added_commands)) for add_command in added_commands: self._real_commands.append(add_command) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 9dd5051..db8be9c 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -259,7 +259,8 @@ class DataManager(object): var_handler.short_name = cmor_var.short_name var_type = var_handler.dtype handler.modeling_realm = cmor_var.domain - handler.table_id = 'Table {0} (December 2013)'.format(self.get_domain_abbreviation(cmor_var.domain, frequency)) + handler.table_id = 'Table {0} (December 2013)'.format(self.get_domain_abbreviation(cmor_var.domain, + frequency)) if cmor_var.units: self._fix_units(cmor_var, var_handler) @@ -385,6 +386,7 @@ class DataManager(object): """ Creates the link of a given file from the CMOR repository. + :param move_old: :param date_str: :param year: if frequency is yearly, this parameter is used to give the corresponding year :type year: int diff --git a/launch_diags.sh b/launch_diags.sh index 8e0374c..561d2df 100755 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -15,7 +15,7 @@ PATH_TO_VIRTUALENV=/shared/earth/ClimatePrediction/EarthDiagnostics/bin module purge module load NCO/4.5.4-foss-2015a module load CDO/1.6.9-foss-2015a -module load netCDF-Fortran/4.2-foss-2015a +module load CDFTOOLS/3.0a1-foss-2015a source ${PATH_TO_VIRTUALENV}/activate -- GitLab From 94e0a537387522e12d5b61471e100d51dd9de01a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 23 Sep 2016 12:45:25 +0200 Subject: [PATCH 220/268] Updated files management to improve management of online-cmorized experiments. Updated cmor table --- diags.conf | 13 ++-- earthdiagnostics/cmor_table.csv | 66 ++++++++++++++----- earthdiagnostics/cmorizer.py | 15 ++++- earthdiagnostics/datamanager.py | 108 +++++++++++--------------------- earthdiagnostics/earthdiags.py | 101 +++++++++++++++-------------- earthdiagnostics/utils.py | 11 ++-- earthdiagnostics/variable.py | 4 +- 7 files changed, 163 insertions(+), 155 deletions(-) diff --git a/diags.conf b/diags.conf index bacc31e..0e8be14 100644 --- a/diags.conf +++ b/diags.conf @@ -25,7 +25,7 @@ FORCE = True # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True -ATMOSPHERE_FILES = True +ATMOSPHERE_FILES = False # Variables to be CMORized from the grib atmospheric files, separated by comma. # You can also specify the levels to extract using the following syntax @@ -57,7 +57,7 @@ ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, INSTITUTE = BSC MODEL = EC-EARTH # Model version: Available versions -MODEL_VERSION =Ec3.2_O1L75 +MODEL_VERSION =Ec3.1_O25L75 # Atmospheric output timestep in hours ATMOS_TIMESTEP = 6 # Ocean output timestep in hours @@ -71,13 +71,12 @@ OCEAN_TIMESTEP = 6 # if 2, fc00 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment - -EXPID = a09i -STARTDATES = 19900101 +EXPID = m04v +STARTDATES = 19600101 MEMBERS = 0 MEMBER_DIGITS = 1 -CHUNK_SIZE = 1 -CHUNKS = 12 +CHUNK_SIZE = 12 +CHUNKS = 50 # CHUNKS = 1 diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 89c0b84..ceef0fa 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -40,7 +40,7 @@ sohtipc,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,oc sohtpac,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Pac,,, sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward ocean heat transport due to advection ,ocean,,,, sophteiv,hfbasinba,northward_ocean_heat_transport_due_to_bolus_advection,Northward ocean heat transport due to bolus advection ,ocean,,,, -qt_oce:sohefldo,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,, +qt_oce:sohefldo:qt,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,, slhf,hfls,surface_upward_latent_heat_flux,Surface upward latent heat flux,atmos,,,, sshf,hfss,surface_upward_sensible_heat_flux,Surface upward sensible heat flux,atmos,,,, sophtove,htovovrt,northward_ocean_heat_transport_due_to_overturning,Northward ocean heat transport due to overturning ,ocean,,,, @@ -111,11 +111,11 @@ swvl2,mrlsl2,moisture_content_of_soil_layer_2, Water content of soil layer 2,lan swvl3,mrlsl3,moisture_content_of_soil_layer_3, Water content of soil layer 3,land,,,, swvl4,mrlsl4,moisture_content_of_soil_layer_4, Water content of soil layer 4,land,,,, ro,mrro,runoff_flux,Total runoff,atmos,,,, -tp,pr,precipitation_flux,Precipitation,atmos,,,, +tp:precip,pr,precipitation_flux,Precipitation,atmos,,,, cp,prc,convective_precipitation_flux,Convective precipitation,atmos,,,, lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos,,,, isnowpre,prsn,snowfall_flux,Surface snowfall rate into the sea ice portion of the grid cell,seaIce,,,, -sf,prsn,snowfall_flux,Snowfall flux,atmos,,,, +sf:snowpre,prsn,snowfall_flux,Snowfall flux,atmos,,,, tcwv,prw,atmosphere_water_vapor_content,Water vapor path,atmos,,,, msl,psl,air_pressure_at_sea_level,Sea level pressure,atmos,,,, qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,Non-solar heat flux at ice surface: sum over categories,seaIce,,,, @@ -134,13 +134,13 @@ saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrate es,sbl,surface_snow_and_ice_sublimation_flux,Surface snow and ice sublimation flux,landIce,,,, sosalflx,sfs,salt_flux_surface,Surface salt flux,ocean,,,, si,si,solar_insolation,Solar insolation,atmos,,,, -siarean,siarean,sea_ice_area,Total area of sea ice in the northern hemisphere,seaIce,,10^6 km2,, -siareas,siareas,sea_ice_area,Total area of sea ice in the southern hemisphere,seaIce,,10^6 km2,, +NArea,siarean,sea_ice_area,Total area of sea ice in the northern hemisphere,seaIce,,10^6 km2,, +SArea,siareas,sea_ice_area,Total area of sea ice in the southern hemisphere,seaIce,,10^6 km2,, iiceconc:siconc:soicecov:ileadfra:ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce,,%,, iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,,,, ibgarea,sicga,sea_ice_content,Global mean sea ice content,seaIce,,,, -siextentn,siextentn,sea_ice_extent,Total area of all northern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,, -siextents,siextents,sea_ice_extent,Total area of all southern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,, +NExnsidc,siextentn,sea_ice_extent,Total area of all northern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,, +SExnsidc,siextents,sea_ice_extent,Total area of all southern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,, iiceprod,sigr,ice_production,Ice production,seaIce,,,, iiceheco,siheco,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea ice heat content,seaIce,,,, ibgsaltco,sisaltcga,global mean ice salt content,Global mean ice salt content,seaIce,,,, @@ -152,8 +152,8 @@ iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce,,,, iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce,,,, iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce,,,, ibgvoltot,sivolga,sea_ice_volume,Global mean sea ice volume,seaIce,,,, -sivoln,sivoln,sea_ice_volume,Total volume of sea ice in the northern hemisphere,seaIce,,10^3 km3,, -sivols,sivols,sea_ice_volume,Total volume of sea ice in the southern hemisphere,seaIce,,10^3 km3,, +sivoln:NVolume,sivoln,sea_ice_volume,Total volume of sea ice in the northern hemisphere,seaIce,,10^3 km3,, +sivols:SVolume,sivols,sea_ice_volume,Total volume of sea ice in the southern hemisphere,seaIce,,10^3 km3,, sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea ice volume per gridcell area unit,seaIce,,,, sostatl,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, sostind,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, @@ -177,13 +177,13 @@ smlt,snm,surface_snow_melt_flux,Surface snow melt,landIce,,,, isnowthi,snthic,surface_snow_thickness,Surface snow thickness,seaIce,,,, sbgvoltot,snvolga,snow_volume,Global mean snow volume,seaIce,,,, snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow volume per gridcell area unit,seaIce,,,, -vosaline,so,sea_water_salinity,Sea water salinity,ocean,,psu,, +vosaline:mean_3Dsosaline,so,sea_water_salinity,Sea water salinity,ocean,,psu,, scsaltot,soga,sea_water_salinity,Global mean sea water salinity ,ocean,,psu,, hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic northward ocean heat transport,ocean,,,, soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,Eddy induced vel. coeff. at w-point,ocean,,,, soleahtw,soleahtw,lateral_eddy_diffusivity,Lateral eddy diffusivity,ocean,,,, somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (turbocline),ocean,,,, -sosaline:isssalin,sos,sea_surface_salinity,Sea surface salinity ,ocean,,psu,, +sosaline:isssalin:mean_sosaline,sos,sea_surface_salinity,Sea surface salinity ,ocean,,psu,, sothedep,sothedep,thermocline_depth,Thermocline depth (max dt/dz),ocean,,,, src,src,skin_reservoir_content,Skin reservoir content,land,,,, zosrfatl,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Atl,,, @@ -208,11 +208,10 @@ nsss,tauv,surface_downward_northward_stress,Surface downward northward wind stre vtau_ice:iocestrv:iicestrv,strairy,surface_downward_y_stress,Y-Component of Atmospheric Stress On Sea Ice,seaIce,,N m-2,, sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface downward y stress ,ocean,,,, d2m,tdps,dew_point_temperature,2m dewpoint temperature,atmos,,K,, -votemper,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,,, +votemper:mean_3Dsosstsst,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,,, sctemtot,thetaoga,sea_water_potential_temperature,Global average sea water potential temperature ,ocean,,K,, iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of melt at upper surface of sea ice,seaIce,,,, -sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,, -sstk,tos,sea_surface_temperature,Sea surface temperature ,atmos,,K,, +sosstsst:sstk:mean_sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,, tossq,tossq,square_of_sea_surface_temperature,Square of sea surface temperature ,ocean,,K2,, zotematl,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Atl,K,, zotemglo,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Glob,K,, @@ -246,15 +245,50 @@ sobarstf,vsftbarot,ocean_barotropic_volume_streamfunction,Ocean barotropic volum zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Atl,,, zomsfglo,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Glob,,, zomsfind,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Ind,,, -zomsfipc,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,IndPac,,, +zomsfipc:zomsfinp,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,IndPac,,, zomsfpac,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Pac,,, zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction_due_to_bolus_advection,Ocean meridional overturning volume streamfunction due to bolus advection ,ocean,,,, w,wa,vertical_velocity,Vertical velocity,atmos,,,, z,zg,geopotential_height,Geopotential height,atmos,,,, vovecrtz,zo,sea_water_z_velocity,Sea water z velocity,ocean,,,, -sossheigh:sossheig,zos,sea_surface_height_above_geoid,Sea surface height above geoid ,ocean,,,, +sossheigh:sossheig:mean_sossheig,zos,sea_surface_height_above_geoid,Sea surface height above geoid ,ocean,,,, scsshtot,zosga,global_average_sea_level_change,Global average sea level change ,ocean,,,, scsshste,zossga,global_average_steric_sea_level_change,Global average steric sea level change ,ocean,,,, zossq,zossq,square_of_sea_surface_height_above_geoid,Square of sea surface height above geoid ,ocean,,,, scsshtst,zostoga,snthic,Global average thermosteric sea level change ,ocean,,,, heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,Joules,, +transix,transix,sea_ice_x_transport,X-Component of Sea Ice Mass Transport,seaIce,,kg s-1,, +transiy,transiy,sea_ice_y_transport,Y-Component of Sea Ice Mass Transport,seaIce,,kg s-1,, +windsp,sfcWind,wind_speed,Near-Surface Wind Speed,atmos,,,, +vsfsit,vsfsit,virtual_salt_flux_into_sea_water_due_to_sea_ice_thermodynamics,Virtual Salt Flux into Sea Water due to Sea Ice Thermodynamics ,ocean,,,, +sfdsi,sfdsi,downward_sea_ice_basal_salt_flux,Downward Sea Ice Basal Salt Flux,ocean,,,, +hfsithermds,hfsithermds,heat_flux_into_sea_water_due_to_sea_ice_thermodynamics,Heat Flux into Sea Water due to Sea Ice Thermodynamics ,ocean,,,, +u2o,uosq,square_of_sea_water_x_velocity,Square of Sea Water X Velocity ,ocean,,,, +v2o,vosq,square_of_sea_water_y_velocity,Square of Sea Water Y Velocity ,ocean,,,, +vozomatr,umo,ocean_mass_x_transport,Ocean Mass X Transport ,ocean,,,, +vomematr,vmo,ocean_mass_y_transport,Ocean Mass Y Transport ,ocean,,,, +sozohetr,hfx,ocean_heat_x_transport,Ocean Heat X Transport ,ocean,,,, +somehetr,hfy,ocean_heat_y_transport,Ocean Heat Y Transport ,ocean,,,, +uto,uothetao,product_of_xward_sea_water_velocity_and_temperature,Product of X-ward Sea Water Velocity and Temperature,ocean,,,, +vto,vothetao,product_of_yward_sea_water_velocity_and_temperature,Product of Y-ward Sea Water Velocity and Temperature,ocean,,,, +uso,uoso,product_of_xward_sea_water_velocity_and_salinity,Product of X-ward Sea Water Velocity and Salinity,ocean,,,, +vso,voso,product_of_yward_sea_water_velocity_and_salinity,Product of Y-ward Sea Water Velocity and Salinity,ocean,,,, +wfo,wfo,water_flux_into_sea_water,Water Flux into Sea Water ,ocean,,,, +emp_oce,evsmpr,evap_minus_precip_over_sea_water,Evap minus Precip over ocean,ocean,,,, +emp_ice,evsmpr,evap_minus_precip_over_sea_ice,Evap minus Precip over ice,seaIce,,,, +qsr_oce,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net Downward Shortwave Radiation at Sea Water Surface ,ocean,,,, +qns_oce,rlds,surface_net_downward_longwave_flux,Surface Net Downward Longwave Radiation,ocean,,,, +qsr_ice,rsdssi,surface_downwelling_shortwave_flux_in_air,Downwelling Shortwave over Sea Ice,seaIce,,,, +qns_ice,rldssi,surface_downwelling_longwave_flux_in_air,Downwelling Long Wave over Sea Ice,seaIce,,,, +sfx,sfx,downward_salt_flux,Downward Salt Flux,ocean,,,, +taum,taum,surface_downward_stress_module,Surface Downward Stress Module,ocean,,,, +zfull,zfull,depth_below_geoid,Depth Below Geoid of Ocean Layer,ocean,,,, +zhalf,zhalf,depth_below_geoid,Depth Below Geoid of Ocean Layer,ocean,,,, +pbo,pbo,sea_water_pressure_at_sea_floor,Sea Water Pressure at Sea Floor,ocean,,,, +thkcello,thkcello,cell_thickness,Cell Thickness,ocean,,,, +ficeberg,ficeberg,water_flux_into_sea_water_from_icebergs,Water Flux into Sea Water From Icebergs ,ocean,,,, +rsdo,rsds,downwelling_shortwave_flux_in_sea_water,Downwelling Shortwave Radiation in Sea Water ,ocean,,,, +wo,wo,sea_water_upward_velocity,Sea Water Upward Velocity ,ocean,,,, +w2o,wosq,square_of_sea_water_upward_velocity,Square of Sea Water Upward Velocity ,ocean,,,, +difvho,difvho,ocean_vertical_heat_diffusivity,Ocean Vertical Heat Diffusivity,ocean,,,, +vovematr,wmo,upward_ocean_mass_transport,Upward Ocean Mass Transport ,ocean,,,, diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index acb89df..a7244ca 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -32,6 +32,7 @@ class Cmorizer(object): if not self.cmor.ocean: return self._unpack_ocean_files('MMO') + self._unpack_ocean_files('PPO') self._unpack_ocean_files('diags') def _unpack_ocean_files(self, prefix): @@ -205,6 +206,12 @@ class Cmorizer(object): file_parts = os.path.basename(filename).split('_') if self.experiment.expid in [file_parts[1], file_parts[2]]: frequency = 'm' + elif self.experiment.expid == file_parts[0]: + try: + parse_date(file_parts[1]) + frequency = 'm' + except ValueError: + frequency = file_parts[1][1].lower() else: frequency = file_parts[1][1].lower() variables = dict() @@ -300,7 +307,7 @@ class Cmorizer(object): self.data_manager.send_file(temp, var_cmor.domain, var_cmor.short_name, self.startdate, self.member, frequency=frequency, rename_var=variable, date_str=date_str, region=region, - move_older=True) + move_old=True) @staticmethod def _merge_grib_files(current_month, prev_gribfile, gribfile): @@ -421,6 +428,12 @@ class Cmorizer(object): if 'time_bnds' in handler.variables: time_bounds_var = handler.variables['time_bnds'] time_var.bounds = "time_bnds" + try: + units = time_bounds_var.units + except AttributeError: + # we suppose that if not units are present, they match the ones in the time variable + units = time_var.units + time_bounds_var.units = units time_bounds = Utils.get_datetime_from_netcdf(handler, 'time_bnds') if type(time_bounds[0, 0]) is not datetime: diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index db8be9c..6185d5f 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -31,6 +31,7 @@ class DataManager(object): Variable.load_variables() UnitConversion.load_conversions() self.lock = threading.Lock() + self.cmor_path = os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles') # noinspection PyPep8Naming def prepare_CMOR_files(self): @@ -45,83 +46,44 @@ class DataManager(object): :return: """ # Check if cmorized and convert if not - created = False - errors = list() - for startdate, member in self.experiment.get_member_list(): - member_str = self.experiment.get_member_str(member) - if self.config.cmor.force or not self._is_cmorized(startdate, member): - created = True - start_time = datetime.now() - Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) - - cmorizer = Cmorizer(self, startdate, member) - cmorizer.cmorize_ocean() - cmorizer.cmorize_atmos() - Log.result('CMORized startdate {0} member {1}! Ti\n\n', startdate, member_str, - datetime.now() - start_time) - - if created: - for error in errors: - Log.error('File {0} could not be unzipped.', error) - return for startdate, member in self.experiment.get_member_list(): - member_path = os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles') - Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) - - filepaths = glob.glob(os.path.join(member_path, '*.gz')) - if len(filepaths) == 0: + if not self.config.cmor.force and self._is_cmorized(startdate, member): continue + member_str = self.experiment.get_member_str(member) + if not self.config.cmor.force: + tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') + tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, + 'cmorfiles') + file_name = 'CMOR?_{0}_{1}_*.tar.gz'.format(self.experiment.expid, startdate, member_str) + filepaths = glob.glob(os.path.join(tar_path, file_name)) + filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) + if len(filepaths) > 0: + Log.info('Unzipping cmorized data...') + Utils.unzip(filepaths) + + file_name = 'CMOR?_{0}_{1}_*.tar'.format(self.experiment.expid, startdate, member_str) + filepaths = glob.glob(os.path.join(tar_path, file_name)) + filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) + if len(filepaths) > 0: + Log.info('Unpacking cmorized data...') + Utils.untar(filepaths, os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles')) + continue + else: + if not self._is_cmorized(startdate, member): + start_time = datetime.now() + Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) - self._unpack_cmorfiles(filepaths, member_path) - - def _unpack_cmorfiles(self, filepaths, member_path): - threads = list() - numthreads = Utils.available_cpu_count() - for numthread in range(0, numthreads): - t = threading.Thread(target=Utils.unzip, - args=([filepaths[numthread::numthreads]])) - threads.append(t) - t.start() - for t in threads: - t.join() - filepaths = glob.glob(os.path.join(member_path, '*.tar')).sort() - for numthread in range(0, numthreads): - t = threading.Thread(target=Utils.untar, - args=(filepaths[numthread::numthreads], member_path)) - threads.append(t) - t.start() - for t in threads: - t.join() - if self.experiment.experiment_name != self.experiment.model: - bad_path = os.path.join(member_path, self.experiment.institute, self.experiment.model, - self.experiment.model) - for (dirpath, dirnames, filenames) in os.walk(bad_path, False): - for filename in filenames: - filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_output_'.format(self.experiment.model), - '_{0}_{1}_'.format(self.experiment.model, self.experiment.experiment_name)) - - good = good.replace('/{0}/{0}'.format(self.experiment.model), - '/{0}/{1}'.format(self.experiment.model, - self.experiment.experiment_name)) - - Utils.move_file(filepath, good) - os.rmdir(dirpath) - good_dir = os.path.join(member_path, self.experiment.institute, self.experiment.model, - self.experiment.experiment_name) - for sdate in os.listdir(good_dir): - for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): - for filename in filenames: - filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_{1}_r'.format(self.experiment.model, - self.experiment.experiment_name, sdate), - '_{0}_{1}_{2}_r'.format(self.experiment.model, - self.experiment.experiment_name, sdate)) - if good != filepath: - Log.info('Moving {0} to {1}'.format(filename, good)) - Utils.move_file(filepath, good) + cmorizer = Cmorizer(self, startdate, member) + cmorizer.cmorize_ocean() + cmorizer.cmorize_atmos() + Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, + datetime.now() - start_time) def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ @@ -234,7 +196,7 @@ class DataManager(object): cmor_var = Variable.get_variable(var) var = self._get_final_var_name(box, var) - if rename_var: + if rename_var and rename_var != var: Utils.rename_variable(filetosend, rename_var, var) elif original_var != var: Utils.rename_variable(filetosend, original_var, var) diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index ee0d76d..a063b68 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -33,7 +33,6 @@ class EarthDiags(object): """ # Get the version number from the relevant file. If not, from autosubmit package scriptdir = os.path.abspath(os.path.dirname(__file__)) - if not os.path.exists(os.path.join(scriptdir, 'VERSION')): scriptdir = os.path.join(scriptdir, os.path.pardir) @@ -43,9 +42,9 @@ class EarthDiags(object): documentation_path = os.path.join(scriptdir, 'EarthDiagnostics.pdf') if os.path.isfile(version_path): with open(version_path) as f: - autosubmit_version = f.read().strip() + version = f.read().strip() else: - autosubmit_version = pkg_resources.require("earthdiagnostics")[0].version + version = pkg_resources.require("earthdiagnostics")[0].version def __init__(self, config_file): Log.debug('Initialising Diags') @@ -64,57 +63,57 @@ class EarthDiags(object): """ Entry point for the Earth Diagnostics. For more detailed documentation, use -h option """ - try: - parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') - parser.add_argument('-v', '--version', action='version', version='3.0.0b8', - help="returns Earth Diagnostics's version number and exit") - parser.add_argument('--doc', action='store_true', - help="opens documentation and exits") - parser.add_argument('--clean', action='store_true', - help="clean the scratch folder and exits") - parser.add_argument('-lf', '--logfile', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', - 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), - default='DEBUG', type=str, - help="sets file's log level.") - parser.add_argument('-lc', '--logconsole', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', - 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), - default='INFO', type=str, - help="sets console's log level") - - parser.add_argument('-log', '--logfilepath', default=None, type=str) - - parser.add_argument('-f', '--configfile', default='diags.conf', type=str) - - args = parser.parse_args() - if args.doc: - Log.info('Opening documentation...') - doc_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'EarthDiagnostics.pdf') - Utils.execute_shell_command(('xdg-open', doc_path)) - Log.result('Documentation opened!') - return True - Log.set_console_level(args.logconsole) - Log.set_file_level(args.logfile) - if args.logfilepath: - Log.set_file(Utils.expand_path(args.logfilepath)) - - config_file_path = Utils.expand_path(args.configfile) - if not os.path.isfile(config_file_path): - Log.critical('Configuration file {0} can not be found', config_file_path) - return False - - diags = EarthDiags(config_file_path) - if args.clean: - diags.clean() - else: - diags.run() - TempFile.clean() + # try: + parser = argparse.ArgumentParser(description='Main executable for Earth Diagnostics.') + parser.add_argument('-v', '--version', action='version', version=EarthDiags.version, + help="returns Earth Diagnostics's version number and exit") + parser.add_argument('--doc', action='store_true', + help="opens documentation and exits") + parser.add_argument('--clean', action='store_true', + help="clean the scratch folder and exits") + parser.add_argument('-lf', '--logfile', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', + 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), + default='DEBUG', type=str, + help="sets file's log level.") + parser.add_argument('-lc', '--logconsole', choices=('EVERYTHING', 'DEBUG', 'INFO', 'RESULT', 'USER_WARNING', + 'WARNING', 'ERROR', 'CRITICAL', 'NO_LOG'), + default='INFO', type=str, + help="sets console's log level") + + parser.add_argument('-log', '--logfilepath', default=None, type=str) + + parser.add_argument('-f', '--configfile', default='diags.conf', type=str) + + args = parser.parse_args() + if args.doc: + Log.info('Opening documentation...') + doc_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'EarthDiagnostics.pdf') + Utils.execute_shell_command(('xdg-open', doc_path)) + Log.result('Documentation opened!') return True - - except Exception as e: - from traceback import format_exc - Log.critical('Unhandled exception on EarthDiagnostics: {0}\n{1}', e, format_exc(10)) + Log.set_console_level(args.logconsole) + Log.set_file_level(args.logfile) + if args.logfilepath: + Log.set_file(Utils.expand_path(args.logfilepath)) + + config_file_path = Utils.expand_path(args.configfile) + if not os.path.isfile(config_file_path): + Log.critical('Configuration file {0} can not be found', config_file_path) return False + diags = EarthDiags(config_file_path) + if args.clean: + diags.clean() + else: + diags.run() + TempFile.clean() + return True + + # except Exception as e: + # from traceback import format_exc + # Log.critical('Unhandled exception on EarthDiagnostics: {0}\n{1}', e, format_exc(10)) + # return False + def _create_dic_variables(self): self.dic_variables = dict() self.dic_variables['x'] = 'i' diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 39993b8..8c5ff39 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -306,13 +306,14 @@ class Utils(object): :return: Datetime numpy array created from the values stored at the netCDF file :rtype: np.array """ - nctime = handler.variables[time_variable][:] # get values - units = handler.variables[time_variable].units # get unit "days since 1950-01-01T00:00:00Z" + var_time = handler.variables[time_variable] + nctime = var_time[:] # get values + units = var_time.units try: - cal_temps = handler.variables[time_variable].calendar - except AttributeError: # Attribute doesn't exist - cal_temps = u"gregorian" # or standard + cal_temps = var_time.calendar + except AttributeError: + cal_temps = u"standard" return netCDF4.num2date(nctime, units=units, calendar=cal_temps) @staticmethod diff --git a/earthdiagnostics/variable.py b/earthdiagnostics/variable.py index 642b048..0757486 100644 --- a/earthdiagnostics/variable.py +++ b/earthdiagnostics/variable.py @@ -55,5 +55,5 @@ class Variable(object): if not var.short_name: continue for old_name in line[0].split(':'): - Variable._dict_variables[old_name] = var - Variable._dict_variables[var.short_name] = var + Variable._dict_variables[old_name.lower()] = var + Variable._dict_variables[var.short_name.lower()] = var -- GitLab From 2d4a0dde3e1a7634fa7adcf6e8c8c560c90928e5 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 23 Sep 2016 13:15:46 +0200 Subject: [PATCH 221/268] Updated cmor_table --- earthdiagnostics/cmor_table.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index ceef0fa..33749a1 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -292,3 +292,4 @@ wo,wo,sea_water_upward_velocity,Sea Water Upward Velocity ,ocean,,,, w2o,wosq,square_of_sea_water_upward_velocity,Square of Sea Water Upward Velocity ,ocean,,,, difvho,difvho,ocean_vertical_heat_diffusivity,Ocean Vertical Heat Diffusivity,ocean,,,, vovematr,wmo,upward_ocean_mass_transport,Upward Ocean Mass Transport ,ocean,,,, +qtr_ice,qtr,shortwave_flux_transmitted_through_ice,Shortwave Flux Transmitted Through The Ice,seaIce,,,, -- GitLab From 2203a26b13c1f05282455837cfdd28ac73739ea2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 23 Sep 2016 16:50:07 +0200 Subject: [PATCH 222/268] Fixes for first integration within auto-ecearth --- VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/datamanager.py | 31 ++++++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index bb86ca5..f0198fa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b10 +3.0.0b11 diff --git a/doc/source/conf.py b/doc/source/conf.py index f8a9a12..35d7609 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b10' +release = '3.0.0b11' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6185d5f..50c35df 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -65,6 +65,9 @@ class DataManager(object): Log.info('Unzipping cmorized data...') Utils.unzip(filepaths) + if not os.path.exists(self.cmor_path): + os.mkdir(self.cmor_path) + file_name = 'CMOR?_{0}_{1}_*.tar'.format(self.experiment.expid, startdate, member_str) filepaths = glob.glob(os.path.join(tar_path, file_name)) filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) @@ -72,7 +75,8 @@ class DataManager(object): filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) if len(filepaths) > 0: Log.info('Unpacking cmorized data...') - Utils.untar(filepaths, os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles')) + Utils.untar(filepaths, self.cmor_path) + self._correct_paths(startdate) continue else: if not self._is_cmorized(startdate, member): @@ -85,6 +89,31 @@ class DataManager(object): Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, datetime.now() - start_time) + def _correct_paths(self, startdate): + bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) + if os.path.exists(bad_path): + Utils.execute_shell_command(['mv', bad_path, os.path.join(bad_path, '..', '..')]) + os.rmdir(os.path.join(self.cmor_path, 'output')) + + if self.experiment.experiment_name != self.experiment.model: + bad_path = os.path.join(self.cmor_path, self.experiment.institute, self.experiment.model, + self.experiment.model) + for (dirpath, dirnames, filenames) in os.walk(bad_path, False): + + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_output_'.format(self.experiment.model), + '_{0}_{1}_S{2}_'.format(self.experiment.model, + self.experiment.experiment_name, + startdate)) + + good = good.replace('/{0}/{0}'.format(self.experiment.model), + '/{0}/{1}'.format(self.experiment.model, + self.experiment.experiment_name)) + + Utils.move_file(filepath, good) + os.rmdir(dirpath) + def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy -- GitLab From bac882eae96557987213e1bde170645ee1733fb5 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 23 Sep 2016 16:51:13 +0200 Subject: [PATCH 223/268] Updated pdf --- earthdiagnostics/EarthDiagnostics.pdf | Bin 240758 -> 240809 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index 0f4c4084aaf17ac2997cd85ad045f8db8021821a..fa9f24d9b22f0879fdcf3a61b1571189f0da3c64 100644 GIT binary patch delta 43858 zcmZs?Q*b6sv^5;twrwX9+qRvFZ9cI%PwY%Gv2EM7ZJYmlPW>0>;;ZWF>gukpu38s+ zt-bc{=T)S#HKba0Y=G$e)^z0ubhYlrpcoL2`ygmP^$(ryzq6Ga5L+|5PA<^jp6M^o zFIWXop(QXiba&W6y|e)+ia&x+Z*p-YY-Lr~ZCbXWh@M#d zxfWR65gCM5SuR_mL|vQm%skyNZzU3LKc$#7j0Wd0(cB~o^8i}-WxBFak-8uae&&QI zWgO2NeSJJ34hvD7m8S_~u-YU(KxTEt*)r0wHr#Y1NRI z<$9iu#uBj5$L@@xf^`kbA%BsxQ=yy3E@n!8apXm%{C4`@aSazk zKpC6F;UvN9Rwi0O*FAF+p8N{ZfHLE3gNLWsnE27Z?~DupnWc=L00yCCP2V4l>xkh`SkiWsJsK!!_kX9q~jjmlla;huL4h)$4<0^xtjgn^LIyQ8w~t?U*kEB7#^Nl&^`(o^&S z4EVHghnqDNKA3n=cLz&+VkSGWckm)`O$k|u7YS~`s|^Yyxiws>2x>1^R6{nliYuHM zkDABfOZ1;;rmvrxFCUB5kDIome0O2ZC_r$in*nm z>A1@RvjY6FIGh;AF3$T17rRo?y%-t+byz7=dI*&Go^;@&BR8Pf-HZP^nK6H*YdZfy zRUF{{H%PJwB{moukpbWAu#QyEhk!1`e7-&$jqiIIjK#UG9hzO8NT?bXhlC=>@>WL8 z2fK|S%mk-F+Mtr9dOY(U&y%GP68TQ-;H2j`+ZG)*5FHD8Q2< z@`u%?`8<2Fd;flDi{m4dB)GIvhtG54i{ARC2Ox#s<^+z3W9QmL4bH87wwzs}akoq9 zF58wFNc#N?9(OQk8DUyI9{6<)6gk&#Q-IB{B@YdR(?qo~Tdm}$s1`y%CsCA{6lF$& zG-2>>YNk*QK)cI^0gp`pivnPfSjTHVRS*6WCs}IqZx0=O>cAJ7Q|i|nZ2r@ z{b7*t-Ier4hEDo$c{Qb!v8oJ3ptd$AC*wg^6UlGzj>x8Ui@*-KTW@A*WIAmXdq@mtK@mFPb>Eg{N7O37rZtD5Zs?scvJpO ztmXJ3mbqi&1{Li@Vx68!6Zx%Nk^eOG+{QXEl8~{|p*TZ^CdukqheaFlVH(RxzQ;1} z*bO1dKr*PMEKsW}b}=#zD&A0)X!RiJ*xsj6I1WD)DW*t;fS9FKOm@#R5I=^lrd$Ur zT;M7-tJtkNuC*b_m=}f*D5@oKP%oTH4u*lTz)*PDlF=FU+xVr;12K$#e) WO~Pm z(Tx_VpoSlI<6}Jq@()e7&A!KT^<^FG?G%cww3`X7B<{~}Aj|MIn4F>GvE8{U?AAXgKYVKdiKM0-q3Y=&QM1PFSk%ciK?l1Dwmkwdyy;F=U?@!chV zS|Wqn(|J9YBLKm4FH4b-lDQD?zUU@prp+p&7=JAT=G4QtXPI!^%F`i&c6Fzv&1S;q zAN}|xW!+9pyI_weK*W$65kYK}F&W~(9=^fXi@K2`9rW)k61=|{r)B%c7=hD|5)4G+ zFyp?!dHvcxJgj&YXPYA#|*{x8e{-ClLT{7J|giJS>-xVUZ(Kl!|m$0IE4lMMzI0!wA+lJUgsV3{b@gy`h7N2OTuC;ZXzw459*O z>Fj?uiN%{CZL_bhQtcStDEQyVZ!f7cBoW=^JbXi`?ifkv6(DyO)ZtY%WSDOi4PmF( zu)mrvMA!t&DaB0&+y%ogGCw25O09Xf zyt8eXz16;m#d@^|{`XNeSr1r%Y?MKl$wj6=3+4@ZshiRS7`zo!^A>62+z!ZiCEeZy z8)qPw#UZTW8vDS}3q9a!youuBMguUsLXq+}xjXg-e;&8z=F-*i{ zF8W5;7wMgz^7PlQC?>A7hnat9d{ph$Xmv(H2JLO((S%ex&licw`hNt&QP-X8qJ!kpuUe0JWlNDNwH;u$*B<=Hb()sm>YMvoEa z!qR>>r;APBvFEI&a#7mihwzEITjh^5<6|h<+@Z`viCRGJe(i3NDupI(cT}+IH)hs1 zK?I*kQVnt$lRIurZ415SDe=aSX2AdA-e+I{1|VJCwjUi&LPtFl3?6;K;I_)Y9&<>T zr2v4B#?1Ghc$Y)}v!6#Y98KM&{Llbg>C!Ph^=N%X)lguI{`MhN3$UM?k1%^e{YrM` zu!Lu%G*J5HpuUceqWl`~>bSkm(s!^V4hW#guB-7z|K<)+(GB|#Y;#vP7Yh^n|5*Wz zjG!6{jUk{wGa5>Nk3vGI$u>a(`z+9b5q5K+q(B|}bU=a~JS>kUf+BONI*l2H4oYw% zO71y9r&^vjuQ(%8B)ff(7F}83-1M>Dgm-0xWDeHF1z@uNS7n4iHwo^1C1Q1f@h4?%v{S`M19I{Xb>rj>XC2okT<{o+>y*xgd z=uOv291z(4B72gQWG_!jWqxTK!=Q=P9jix^f-owX)iKI8D2)y8$XoW2ZvjS2D+#*S z>myb6SdrhRw^Kdvw~ZV0()|s|%m=&FxQ#7BSqG&raddSx%d@!6#i2tN)14i)C7QHM zlE$CYgHj}8@nF{9Hq%~X8ap!7i?Ud&#q;3Cbj9+~5DPRLyYvY&~^P@2JO<7h&d&Ndq4l%(m~LHCZMtG#w?a z@VcCJWH`gsOeda4B8;PXH~0H0Z=?NR6VWzlj#I09(}O*6Ai}vyE#`Ah6_-kjJ*S<$ zySU&V-pmQ9h)Cr1uC?-{#(_g;XZnyL3_l=wFO(?YWy92IAlc5rDImV*53Ossg~etK2JWC1FEYmAo2mFn2?9sp168OY;-`dysruZ1Poj@vyBogQDwY*eEeT+%L% zefs7P#R5PVX9{gv@ekVcM<5{~wV?3UNw-kYRUrN)-zLnpb4VAe!!6SJ(YJaa!ZU+8 z`tcwvoi1iVr#%bVq9WYlFth2OS1RspHw7m7Y(oxr(g8|U46<<6Q=@^QWB_UKpj!x_ zG5-*aKUQr)p@#dQZ3)S9cc{J$S%PC%{8udkkH8Dcipq^$K19a&RCkQVU0<|yhYg=s za|mLnM!Iozk2nF8nq|?nRbt-({O6rnRg0fXeV9j<^)}i-tah>*8HcKDj(X+wipBxl zxkKH4v)ycAOp1NdfcsZH@TCrMwU_2S%v-krfU!_6?cGM95PGZTM8d z!bXj&Tc>`Y86b}lc(MFIt*~}}O6!{d$|0s*Q3uH~5G{sXE&6>@P&1s77)d9dx{j}e6Gj9 z>!0flYHzS*3$d>ot2gwZd9fwx9=xpMoNXZKxi|Vx#7po%n*wv1o!=rJA?(vk!ZG ze*@X8xv~s= z6IE^R3G)OZKs#|pP6QvQG&GuLzd-yjV%FoJHdca4GpZESe)^#y}C3IAdH-w+)Y zFai3nK?4vE29c`;&k8&V+5xq07zu6ygHZax5eEi_oq~yGH`s*lK|rK4NZli6r_AcG@wGQ?p>D`&V_rICf_z$M`T>!PuFxa0;LTY*4; z@&M;^K5Tl2tbp;9Sah{)GsNIwGsSYz*w20l1+yeGh76)GgC=|w)rjx|;2IemopZ5@ zUJ{|3fI+G_T_*8GXcKuWJXeM&1)7V~1$ztr?$8`xsoAC#|v@wtT7A1}6#Goq-PP z(<8682>+X^y{`sMWx8&1v+sX^z`4PbBvBS89x!!0=nR21i9|X9CCbKbXjLZ6){X?D zgKE$%TS__q6R84G;6{^me_7)=KVtwF9Ey_op}iDQHws*f*{N>?*t#Y{<64INYajo< zJ`zWTJ#}_2?pvs%okk_jtLYjkJD*^r{vpFOLXt9&3gHxwZbh8k;z`Wi| zHQ}HeXTq+p$%#pzMnq03DXRj&-k}6FYBGz43=wg)c%;QP;##}IB%FeMiUnja=h-)~ zs1x!DJ<>hS{W($!qIuVS<79jmu1u|{b}o3pJu7M zDbC1YiGxJ|)bs05Sa)vH3X|jpnf6-6w@A{IB1J#)%*#STgG5K_`L|HTbxY(ic5}!H z7BQY1Y!*5gES=J;3wi%-hD=8cpUoGe?<~V`sJ=@#l}jCgZ#v@z(bvowAr@Y;+4_Q3 zm6cNSZvC3s1s~8ALTBe>t{BR)m{UmubR@#|fuhwf$)w^0VsUI;s(}NY zx|=vN$=a+Hn}ppF?XF!QGnTF!`@L<}+a;N~Eo~nC@oPnSOx)>vEUL3SOUwm(W!E($ zqAuBi-3|sW829lGT}xjFp5jCI$Yy@kV1S$Tq1I{~u^1qD+`y&(oaJA8?1qtNsBq>RHbS%#p zWUy1|8fr3PB&}MfKSiQuts0m)bp$KxRYE+EXb1Z&Gh=P%B`>KFdxHN}9qRr%>NOQ5 zjMo?a)tp`@?6HvX^411^)EX5NA;^o>SCA0C`>6fea*9J#y;2!#t)$bgc7jd@z{ z>2%4Ud1B^Ve(FPBl+7xXu z225r8@*-hHZcAaq6^!T9LXwOAAVhA~%7aIH+)H8RQu z|1A8A!$+WG$baziex`*y*JQm@BMZLHOilMFG=ZXLsnUe|kAcAdEV*|w$#Sp?i+2kj zz?Lim@}?Y8pA+VF9@5mLG!yTPW=6#t|1TXmm^+%@nVk-B@{kB`rnI7>ug_Y=eWrpWSHrAW;Y!FWfROnz7 zQe})NVKnU&8S2rSWVjB$kF5$@Tp~XRwg^^))v=0uU^nB#qTj3;ld)wepbxZHElEBq-Hwp9VryYE z#j&Iy9p}cJU~>&IX-roGVDk^(z`bX6k=NZ(;f#u@fff^}6yEVn?)gngTOqr0Q7_$K z+GbSeNDyQ?&QzQ5$aw%(Aix(22`iy6tdeTxOrD`g4GykRhpQ6PI$8MdGtvPOgFHu@j`@0Q}w+=rqV4xih zzX;s4k4_L3`g&cKrqGl zU6}n@E_){Dn#i;S9OQj({C$K-L)`mUS#P0Px>>yyW0jACYlJd)e3X|E{lvp2o3cs6 z1J~8o{hol`?MuI}QW6bmK3Qmu7nz+m;9s70&sf@Kw7;t8Y2&P=M~g)OI2^ z5J?E(p9O(#NS%!zVc9eAVd^&k9Jp~#Sam*#&0A{4c82s5pg&o`2FNX?>Fv&lv?M@| zb6(JzHotxGTP-6lcuuJ_XlS|H5Yg6Rq8Z$C-JXVa<+qsOY|(t8PFIn|T$UbniVfO~ zHK;{WwIbXuH)}m$#;@c0_x*^M%+3W%)X1j!V2P!3q&Q7Sl9hpVDb!;XXk|+b!%CCu zy`mk7HW{iXz_>3^f{!m-0xXQ{5)~t){4(NZ)6{)OMZK_{D(eH)C<$l0`A4PLPb7X) z&={GpZ9Dj)KHZCC+VotDmE&MI+;pIo)JrRnH%iUAYfJf}W8UknE9pOGQmDO%7NK?^mQK6qw5_ zmv@8H&j!10;J>k<*UBPmTd%S3u)iY<4CBuapmoyC9#ZZSw8S+$g_fiQ1E9hd5wVv zy5)%wADXeJ^)=N1=wkZF5=gM}Y8*nqN3@-h+_8kRG&n8LX5pZnV5Pj=00?^m%0#BT zW@MtQXSo5rN`)Im5wK2?9$aTb*75>P_Y$We}91#6#fSvn(DyQk176iK|~Tb(8d|l z&^Dz!$8q=LKPB0#vxFXaZejR!b5^nhcBz8@!tJwDI}lL7rVZ2Fmy=Vj&_s_-5tOz8 zTn;EjG+(Orsj6+@QKTeg{jF^yTMAnS<+D>+jx~gFe1F9L+=Cc|Gr8iK{)Kwjg6oHj zqM9%ewGPS|Cp9V|La}Oy5Ml=bYeuxL(~n_M-|B0`rponXdg_=y)4o0fcMFhtcyN<5 z6n|u2B7CTyRPv^_I4!+StgqtRoyx=q{;s-G839U3+)#7~h%BpznV&MAR^Y-e*;RPH@-eU}YK zwkZ9pU=LL>w5Wjt=^kd$MxPnr5wz-(74WrWhy%<|(|`9IavXh|&KU#5Fkw7kA$~j}XvK?$14s@jr$z4Dzn= zuRuD~ph-Mc;iirroZ>Da?98J6J&IvBY!TWs$9u<2<5K4ThZ11rB4GjkpNVV{28blHZ z*}e7Ufz5%$1&U;7z~9yB^~qNBpA?9c>^tH`;Xo-6H<=8c;P7hkDkwjS-j{F%7ZPR4 zwX~7BHC0P?2U0fOFaWnSvEu+X_4Qtd@7w446}lbJ;Vk_tp$tO$-#&Ny_xlTwpl>`R ziiVL8SR(aZUN8TNfX5#^<3Uqgzq-O^5geJ#twC#t@TLL9@@zAQSqsolAL4pCC7tNfRAvlgam5^ACGmvSvMD6Fhk_>a@ZuWvZCok1iA`=Vhm*xx~VYbJV1ZlPXj zvikAmz{_C}d)e;25&*n}+oqu{c4@xn;?w(A@h(`~#~3fYTglfg^9m_vlt(c$a{bsu z`?}P_Vdq#*FBPe~fezaLxY~17|D(FkRoXxSVbBX%!1@_kTb44oRoeLLkJKqp#!!As?;dRGmP!%s-8VeI2aAI(OAF zsyq6s3I3&#mm6-@-9KO7U;Ac*({)32_GV}^CVUmLvVph#q@yy`=j&}Vf$lUC1#1!b z|1_31i!yA;X#lbsh0Wz4Bh`sn0=KGUy#`)TD1JA* zl&vNDm9|^*wBaO7M}d0rJR{Mt@ukj2!KTyxC_xw{-+(tiUIIICgzk--Cn*?EsTPw6 zWQ3ax&d#6`-Vm27gE<#HFe-G9f}-Z6<4F2_*pKb=<6?R0%jAei;IyJfrXi)#isHr; zxIf6#Bm+Jh$fsM%pU4p6i2}vEBI_-vZQRx0R;*KYubN9+6fu*%2&7DScTf2E>U5A+ zA-!fI1OQ`dUl&|4K^}W?)VRTwsp3I?)~TR?{I`(E0OD<9{Sk5!ZIQ`-6PRBkKHTkR zIyWigg%vIW1LPEFAQ%FD>3kED(HjP?7W@slvltlSZ2TdI9#d9L1xka`NcE?_R!FXc zX6OE7E)9lf!^=LK_ z(K6kwol2*1HZ3PBtAKG_)J zHy08FH_pUBXN2DBd`Y@-6(&m-NXbvIZK&}aAXEeqdRAmjN(-+My4dJaBUM}ia4Am= zoB_2`sG?ZnKVp8PtbY2>%N3bOq`dN>v}hawUQKg%^Q&3}_LII7=4&i^&y&fBQZYfE z$~yI`oC)o`3;g~(?J+!}{AkDt{N82nQ41J3BLotAyJ+X%93$pC@<_B_+$fxRSksuD zEXx?1Sq2u&AMcc}r6lBw+RTvCU>9+b?0_@p68cfA-N@ASt#H&qdL+Csb)m;B%t#W} zsZ?rsxa}&Q;bM>n?##1WCUnF+C0d9&87^c0?;E<_Y5^S(q=uN2tzB3Veo0aB6AH58 z_fEE@V1c%`!iusmN-ykRzasKg*W>&EP4jBL)KfSQ&vmN3LIK#0 z<@2v2CkWc}Q>p1vW;E2LfS_^zm3p?b!cfdMu6}p6Z;r-818@>%t^>l5C%a@~2_N6$y^~9*X z7dlS1rZO1RhUFj<;fdeff3wc50Nr4v7|A_o%kC~xQgy^e|q? z@BO1grXeAmM0q?CIaeDrWSmLGJ3v|OX3Tl0ciQmA29V>t6_8#VfA&`^1@N!z*+hmD zx}`~@d89Hfpl$D8;jR1{f2)AGk5BnF8A{8lHz?jZ)#1~gck#V>T7~3FLu4!)rLFkE z925Cf`d`mrF_MNW`|7EPPOPj{%HKhJ;_*8Pn>s081*8kJTEr6H6Gb(0lgLL_#ErnT&da0F0U!T9lsS~bzb%@^pp$9A z;JW9t~EM7l6uAATM(a`^Jl)o<-F7CA=8U9=<45UiEe?Q;poM3DKv56<>rGdB`lW3^03I&*qu@=>pgrF+jG6s9(^etW%rrgN<3_+#8hexvP6>)5;V4!6l6*<)4H28h*xc z)WUBi{=f9Ov<0Z9{K4V>Spv_4Hw`{&3XwQ^I#;Ju=`OM2d=npL6I17 zJb+Xkfd^!0(^P{LRt(9#Y9@2fMBzF+N_~n8J7ZGW#KgK1C?kyA`QlI~3YIxU4EQ-z zi8N)X5aJXn90*#bp)fhbI}t;+cGXrx`s*3Lg{QvBZ|qqE+9z> zBjogom>Vexq~no)GO7FTcgxI;(KWjd@##vNUpzaL7Rbay()fvK;U_= z)6JC}w%5CVVXW=4LJ0iUsZP6&>;bw$F&f6boc+f#{*f-X!#=-G)iZO}@BeCkiwbiz z?C`+57(V-Ng&v;*36PbR7KAIt1psOC`=E+<@T>qcLinbaw&!?cgeS4V`Z$Op>4Fnn zl!R8#LOy)HEvImtrWZ`~VW3U;-`PGfvf#faD_)P1eNXDf{L|~w)K6vvjUN((A(kkN zVOFGWf1CaikPt_|E^qZ4{?58SZU$d$wS}ZeHU?JRv@M1-9Y%1WvHrQoX$K@v;Y2bC zn#!lKe|6xQDk4or4b4r;PV8j_0RKbZ0Z(FQITp^d@8jYBv4S()CSgFzj!e%jBu{ zemAdfC~X%Yy&eJo$~#5VWdSIclBgbN2E|6*cVUS7nPb|0oLZP4{%%Jwn00?SiF7z# zDI3|gY{=`RX@m?Tpap86TNHiCBfN8sBj#*-xQ2*XW%(GpgH>@21x9X0qKgkIBaCGz zRcGyMlYfYQqr?lXrV8ylP7#B!R`I21l+1>|lC87URzuN-uuHq^jRU+ap^)r)dy7S# zWj#`U$Cx*iFUg_LAenctnzmA=H3S{;Na&p;9Y6RKi^Ze~@c<^R2;zS-)97I;OQ`%< zo%tx|BY-mgbB;@)8MV?v^^ahwzRw4}b!5>_;z&gBC>uzDB$b_cm`9hc_3P%$MoLA2 zf}Df#tRiguxrCrfG=M{4dDLjyFRnu`hx7qDLVsy2ot6XfX?{;#(mLlOgx;RqL}yis ziOKHuU5sw-+^ue%G^7B9#L?l7*^HvHoW)e8^{~CR>qga?GALuxrGL<pQnhpDco8vygtLFC$1Fo5; z;c)J~n2DA>H9&nZ{6B|a8TW5+4Lr1Al@|tpA`B^%J9x=zby`IM|HVGqClv7y2de4k z$cBvkh*o@77M)5#OTeuh!23&H$;t+>i&yMjP%nDqPW{wiRHdNqt-8qN$`gN)Gf9e( z`@=plxdiP*-dD%!B1^YtGFwC8jpMiY}yX#2Y3yh(eGr?r<#pzlv^?r~WsQIf$wEokg}Ab+w~^@Vie)c$_|_-J9Do&ot`IN85(_#lw{- zziN)0zT6uJ{M~YvOWg%rp^`wkGKtD5MF^(H?vVJ=B8M)miTJe)2j^kB2eNxFwx7QM zjF1rwx2Hmko z0V4BZ#BjJ_7$Fz-!65Mw!#qti{7lef$*?&vY_!=K^oqO^_8`qSGij2+7I1T`FkC@B zHCjw6P!_2N4G`gHszPN86_GSDw!yLDTdJ6x ztTGIGKbXhdWvvbj)JfH`oqWw=5h|LF0p#qEvak~a`=qU0hNu+j^V%e+9YstTa!$pA zUZUhTW?>ZD5!jJN{>hcN?7c&(LCt+A$>%({*|BK)n-n6ZKbYGH8}Qd*?oobEP&HI^ zQy2OvcFJC6`RI z7vUE#B$N0z0Flb)IhKW6uLeN@fT6=c0}KE6lL}5Q)6Z)709kH;SIZzWbxm5#9w}C% zzWoep;sHa<-q^k0SAc7~c-oS|%1#>djADS!4{B~(e22I7C&5Ctos*;TVY$jppH0)S z^2~7PsqI~8tL?v*^^Hxv3;Q$sEBlS6RG*EJ2Ep8?yUGMhfBuUD_YVVKz@f8$%wF2l z@sSI=pq!83r~9kDS0p^ol`G&~Egi9&5WOGlVKBHh^h6R@tw7QwWc%&|TQBz4=at=4 z-d^9_9M8b*uA6VOA>zn@Q10jPPk>j$R`-WBj$yUZ%s~h82KR-AzM~j>LM&=NY-?dvRec^r$G7oPBv9eA zZ2uhv>#dS>3_lN6E{&nD83)3&)5rPlXOexppd@@S^c1)l8z`;;cn%b=L$bk&894~4 zLnDaTW4?bEYaGEa_h7ty2 zrJZt{;zK?k;ZM0r?tfXfTK00v2deyo3Q6R`P_w zB-W;Q9!1Jar*NJ`m9F79_+5?CO|O3Y5PCz$+{yXT@W}cBu;n%bq(1U~(C190Odrcy zx;8bmt*_}{*;RXRY4K%M9i;xwI%=Q$2hY7;KE#deCd~{Kn;v z!HkYVsR*^@@6w2lvslL5sSi{ogzFAkZRWc0ar`4vI$p4ie-0S8Sbo}uNry0Osd*X3 zT$4IcFc$$JO?hVec5#ay+wj|x#UP-;x4@Idj2`kk#_s#dj6=uXe>MN<#wmQA{<91p z>r&U?HX^^=65$tfD|m@am~K}%{qEU1{-P^8{vZ!2t#|osFWuB}DG^9o*1ztV+G$w1 z;^=63jLJ-pv-D4QG8M&wy=urfNG1*v8I#3R{hJd%@^Zk$_ zZ)u^-aI|pMgo#$J3?ZV9!mFBW$3o`^74ZtRPTpJMzwyW2#n*l@H42B2Z=Uis8t$1Y z)4!ZR!F@mJVpdamVDfi#q8PMarl~4AB|dy6K}=`-?^6lAhvc?HYu#-16@-_?p0&VT z34|-43wEHVf4PS36aG9P?%HSzvvv2|X#94pn%z%G@HPyg=L+i>n#!Z<$z#XJx1%8= zFJ-l9QSZ8H^H0)Et-A=n)(-x*$psj{noXC|>N?6c;{&K(R-WYO+jZTO3A>q+&W#8A zL4~nx$=aX)PWYyNXIPGrCf`G}K<^H~OUeMai?D@`AS<`7k>V?jKI6}NGPBr9i7YBJ z_Xwr0{u*=d%TM-@C@Bk*gl_PZzqXWPVIb)yjr=+p9YaR5X0Ryc5kqHDhK)|!F{Zli z7^WLl8*lJXccA4JKM$aTP0P56$tx$`uTN4%H4G$C^Qzm6y_7_EkbSGq`g`~R+m{6p zj;!#xEcr^zvr=USCzWZi7MNLDr+NaRAD&HLRJ;8;vj&w%apo;M@k{-uco8Hfo2yRV zSuuIF4MP8hqdk@eMlaO$3yl0)IGQhUAE~Gaoc2t(oS66VA+v?|c9`~h+MG-!ZV+ab zuvz5r!?MyhsOWhY#7~CqQ?&d65xN_YB=?`#dg9tq^*vYbRhdDKz{~42KYJO=;Vx5! z;UMvp(0wQz;Lr6yuo*RMnrxSbR7OzbEx|cpW8=(w-Q~k=sIf7$&+w4pDNl^KQZVwh^ z2Hv#Mf^wxLY5!MIxYE^gE#$%oc&XX_ht7{~J4ZXAI5un@h#*-;akZS8uyN;c+W(-zieSGxN6ut`givx&jtEASKlV*Yd2*x-Gg?;4?R5$`3(Ci5IxGdtf;emH!oTK#KP|?Z0Gu%(6G&xc|xe z>c6YA!TqHv=sb4|s}_ZG5na z4`#1QYDa$*a6EY%3bUI~?pi>FN4(X;&ITe(TlL|8-)adZ0Rb-@JSTjx_o0Z?P|0a{ zZf%me`q|8 zQWmtrpOMpGa{2PowQER&f@wJVyDZtHV88CcO|gjxw7||n#>2uaUe16Qa7@Q=j~8w} zd|}-LI6U<0&eQSGQ`;#EOm2i+Hk2~s|eEgLMxxYr|1$w=n_D5i5r=@UJQ_I z9;#o|Q|GTPV;PkdabL3+jQK;F=g5r*5fj)xjecvI9|_AG_+e|diyTFT*87c@dzMjv zq#`e95ppB#+1s3vGjt9{Vq6g-az0xW1{PC60o9Pj7i*oRl(O*-=Z>0DFSIyk5S4en zXoP2GwxgKHSn_;dmAE^%dpqVh=UyxzU>;|t9?^+Ef$IY6Vbd{&S8oHfEwj8vppuN| z&u1g%Y$H9fDl93|9oy2Sx#aZ*M(-%#f?`Qi^x3(oEC7X6seX+=D&@+XSZfDdQ?fvZjD8FDl}aZwSNpv-2gC&;5Ru7x1Y1NMszyUdNRylx zwzHb(R^af%bm1h38k0LKy60*1^-jSitL)rYty$oEq5~B3e(!4|rl4_RZ6FkY5uVJ4 z><#UV%x~EF#VPk82nSmC?uGnoz#qe_h|zMp!lfbn%<3_V!O=Q>y9Q^ep2QvoXHNG$ zZ|VinH4&6-Mqj@gk~@^kNVB@9x!9sX9pCI>UtUl23Let+#Jd==Glm>9C#$%X!{EGM zZp+r<8+OVbL(4GqZ9v%x8&L{?0dcfy1+p$|#VPm4!ieq+H{*F|^E>bQm_2DXhM3^0 zNs&-3aXt59muF`RgEoo64Jz)>D-EKZq>L$+?xLeGSgYvBbjBXd`i*_BYm zv(ntz*2H6;AorR$^a-PvW0lB;zRLd+l*w;^*}Qq|BX|hNoN0gZKpEXccGu zqq*&dgS09;PH74c4cA{eThwP}uPjvrW%W#=>UB6)dI+s_Wot}5E#C!aJO>x=D3A_f z;t?PzxmWIR1^gDMn@;WZ=cNsG`ynumjRW^+!W9v`seGMwpn@WiA97fXXugN^Ho34D>#xX2)EJ2W5AXRG$NzZGU@X7>|0tg+qqZT9 z5qR^B=^vwy$=$^qK|qC>UA{=bHs}gQM}7&F%=Sm>4?E{iKrUCUxy&{UR5(z1;k@Pf z<9&?m6bkjx`_`F_2Nyn^p*fnCqfK%Wu98Pe7l(mC3W&@5qWI;-V>&43xc4{ih4wZg z*^ApGxu}nW7P|24embly4*;d|+Kt2K>Uu(5-MW`<>>_b?>vC`5#EbhWke?4Bf?*AH z53wv>c(%3s`6nMY79axQYC9|RR>?<^9CSh8kN?R^!U=vD4VsK+moA(c%ux*wPSuiu z^v5eI>-RY(cb?*i7-Q#7xT+7}Td;953*!gokIQraf6X)Tu5t89)Bv+8&BHjHp;Q}= zzj%7naNgWZUjdjB4>xmU*w8b1u_=b$liHOS5s(jW*y4Xo{}|>_)GZZfs+Hv`Rb)&e z{5E#}b>lxF3Z^Gk0b9Ylw34J<8h24^(?4nOG2#7g^5>1&upNt@azM5LliqqDh4YQv zhV(bt1LdoF`F`096C+??4?AtLZkqW&XMFOjeClFMyBZ4NUd&lHVP%CO=WDgcwJZj> zyp(ATwGomQliYC_%(|9FdmCDxRS1h8^w2bkgECnfOi0=~^&G}Z14U~aVws_h@=!}O zk}XJ~g7+c;QfZpHyr1HWE3d|gPt*0ZuwP>hfiDCDwApl*ga*Vl_6E;``>ka3ZW<%i z1*or_8R(C^>uZ%8c+t>RE7Ra@tLT_Ufp@AoOq5Jl+G#z%ML2Kf=?F#0`+WPIofEaw z-I%2@9n4OR!})hzFO=IvsAMF^tWts$g=;pMveakXoDc0X06B{0;emo7twZXyl8Rgm zXFz>HBlyRVQ@}jz57T+fC0a#hv#N=xy=86t?r+Rg*_D*ZT@QhT&&DhVO;gHK^7%MN zg@52@l38xxWKB3U7+k8C5L}Yxuv}}P&G4dL>KcmzeVWKix%wN0JXwr=RPow5c@TC_ zy7j;dL!p&d(5R*$+a9{Qd)XCuu9!I1nFPCJVP2O7NI?3O-2rrc9C3ub2Idy7BYl@1 z%5(3OQ)R3Vp_45uvgybal0X)fw(UYxGhNugqD5bi^Bw+9yvo0X)mB1ir-YSyPL?Dam|=SD*FvVkrCqM16ZSA+=aijim>_r4gEg=$4 zpEa^NmGjqD2ryxL*86-QlX_3(eUle%{$Q+sw~(rO=1I#$k&ETgr8z6|{4m$_#8q*) zu3p#A#6GtBVJmZ@ZNQm;OZpSJ)QPp2?kRzhloI(@^_4ma4VAwAjtqPVrCAp5S{9GLGvubA#t}k^M+)7X-9DR`E=be(owVhwkV^FHb3jF&xh(x zCL|fK|0{w1B;+GiBZhLwp({)ZqhrU?PNcSjR#wHbj0I@1e(9wGXyB!fffjhlJ;{cx z26(}ce~ORpFB~LzIuhS}drAcgdPEkV6v9X;ws(Bo!t&9l|IGD`%9)gG^kk5*L9VL66Y(F=`R$|0`xQ=sz_b__4Vik zjF788ah!eL3V?sOKJktW>50>&s^FpNeRna8D#Qm-oamK%VXZjsy75p1xvOASfHNp9 z8SK+&ea*02MIMg6P8RnBqUe*ag%okJ=Oe^b^=l@Z7heH>eesExfjXa)MRM8CeN#^{ z5yB-tL>lX3SAO8ceb|PyH*+tIK8ISr#=AxfznTsCBcPGehHq6vH{c>}6(($42iZ|H z4@~@s{Li+GHY{>mXd9(UP=ta+ELY+YvfaZM*1S0UNO$)b8$@Fpyl{w=^K`)s=L$2l z5~4VJoDTUnADoD%0AW%-CCsot#D;dXBC^{wNuOJ(NT#r+Qm@_%V?#n*V!CVzL^K7q zV9e`3dRve2BGE7kgw`)8pA_m*!=Z)utJ>}lJ&j3rjgve*-Lnq4wSKXAB`f~8Y_-Ka zS?&?HzU-_0-Mn=XnJX0aT6}>}CW|3wJkj#VtY89w-624BGvtm_SSE!P?+>TrM=% z1Z@R0$MLyZvqDi4uBNyor3qXmj%OKsbl<4FGT>)2JZdfEkpLttUOj-I)odcc=gB;O zS*3jao=ufCnjvmFRGQ|MD$5$Q&!SUEzuXi`<5ZX2`^Y2&%tQ|Llvva{)wtF!H)=ey5OcJ$B72pt0=-H>`P`j_a%y;WUs)vqpl7hBY&wAxgqC)u;A@0P{i^2sD8%0(N8NO-aFY_D93_ z$zp9wX2IP2<{8=vTIP{|5$!1bzQL9o9S#~x%%+iV0fD6S(7Gn?L%9?r0?<-%DFC7u zk1SP%sTGIJ!LZOWeWn3?YzaEH8i&GRS1Aq5{brq_rmLQLKn$m=HPvT=(_iJ20Uok# zrz3rltwR?Zu;2kXs_5<3D$e~|s|Z)nzVBWtP~K%VGNSux2#a<0W1L83Xvf+Et51Ar zzy>8!kosgnzT7(Den23Z;uF# zq+hY38)9xfJq^xil$+*FMk@-KzYtpXX1GHOpwfZjDhiD+qDykN0lXx$AbPX34-nmd zQ1cK_NiCgd^~1aHSTf0AS^FQh18#t+x`NgNIyPiMKg+vO{w zko2y$H9c|j)mu*^0|1To%@}8oDVVftQ1|Sh-|hXB=A)ybXr+ICT!eV9$2{%Pd7qId zz#2_xwDSMK>&!MTj3pQDn7U&0YLx1SoX)a1Gvk3K=yYBEXY; z=2s`o*$96QH}-Ntk9dW?@1hAxe3e$8$nU-N=0;Y_1bpD^dIsNYW6FLYxIIGVD3ZyA z2|gKI44n-Yv<1LzWp)U7bZj>usHs0NID>IVveHGoIvXOQ#%>H5parLrE2*2x%nrsb z(M_|I%>|d{19)6{T}Zbo6PAk1aYTL?9K7%uI!;I`XG~c z3syN+YLSQ|cE@z`-;%QtCV(a$W}fN2&31%~N~fKjjw{Eg7l0Hh5H?!qOr{49p*h9) z&;Ibts*&0`k9vlL@^?YKIbm?e`L?Fzyd2%$`G#uJ0vZ7$U>F7l059%)Bj%rL*NRjf zvD@GCv2IEoCg2-QX=Q|ZS`C}m!r`RD9AAM5?m2#Q0&gc^dBno9x0NzmgChwa<`d7& z9e*Q@9ovVPix_9D(jUCt3@0R^=IF5)bwF3=2n+5w#^qZMz3wzE;t z#PxPhO;!;OS=T6rS$gV4pay^&m`)ACFl91@fs`YV4msA^Svs}R?e&QoHWvo_5Z}7F zolM4X^*yY=^1M}wJil3!xxDTA$0g5Ns_NZ-u#4hJ4NUd`HC;goUB?C1?C-$o=z^6f zl6=L&oM4jFxeyf7@Mf(75&Rwjf6V}-}`2(QoJ}UKO-s-Ag zzMO3s?&LOO&1ShnTRqiy3v=Vuw^YH}My({9hxzD#s7HWMx&*AHo_+rP2%gCoHJ@AUIV2?bC+4K5^(&*fG!r*6pantst zDbY~$?>38pJR&Kj$tocDh)J7N#7TChl&oV3yS_g+yD!7_}#}fpR7hrdyn6Run*-xg$8bG13=~1Py@( zOde;paq_-p%&S%eF&u5+Xoj>2B7zR*vEf}eH^wv;RIu@8u+-=?YN}v~61vxDXB3OA zDv(D⪼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 delta 43715 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 Date: Mon, 26 Sep 2016 16:05:20 +0200 Subject: [PATCH 224/268] Added K as units for thetao. Minor output fixes for ohc and rewrite diagnostics --- diags.conf | 13 +++++++------ earthdiagnostics/cmor_table.csv | 2 +- earthdiagnostics/general/rewrite.py | 2 +- earthdiagnostics/ocean/heatcontent.py | 2 +- test/unit/test_rewrite.py | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/diags.conf b/diags.conf index 0e8be14..8f8b5dd 100644 --- a/diags.conf +++ b/diags.conf @@ -8,20 +8,21 @@ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below). If you are using the diagnpostics just to CMORize, leave it # empty -DIAGS = +# DIAGS = rewrite,thetao,ocean OHC +DIAGS = OHC # Frequency of the data you want to use by default. Some diagnostics do not use this value: i.e. monmean always stores # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. FREQUENCY = mon # Path to CDFTOOLS binaries -CDFTOOLS_PATH = +CDFTOOLS_PATH = ~/workspace/CDFTOOLS/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -# MAX_CORES = 4 +MAX_CORES = 1 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = True +FORCE = False # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True @@ -76,8 +77,8 @@ STARTDATES = 19600101 MEMBERS = 0 MEMBER_DIGITS = 1 CHUNK_SIZE = 12 -CHUNKS = 50 -# CHUNKS = 1 +# CHUNKS = 50 +CHUNKS = 1 # This ALIAS section is a bit different diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 33749a1..ff3c55e 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -208,7 +208,7 @@ nsss,tauv,surface_downward_northward_stress,Surface downward northward wind stre vtau_ice:iocestrv:iicestrv,strairy,surface_downward_y_stress,Y-Component of Atmospheric Stress On Sea Ice,seaIce,,N m-2,, sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface downward y stress ,ocean,,,, d2m,tdps,dew_point_temperature,2m dewpoint temperature,atmos,,K,, -votemper:mean_3Dsosstsst,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,,, +votemper:mean_3Dsosstsst,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,K,, sctemtot,thetaoga,sea_water_potential_temperature,Global average sea water potential temperature ,ocean,,K,, iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of melt at upper surface of sea ice,seaIce,,,, sosstsst:sstk:mean_sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,, diff --git a/earthdiagnostics/general/rewrite.py b/earthdiagnostics/general/rewrite.py index 952cb6d..96e31cd 100644 --- a/earthdiagnostics/general/rewrite.py +++ b/earthdiagnostics/general/rewrite.py @@ -37,7 +37,7 @@ class Rewrite(Diagnostic): self.domain = domain def __str__(self): - return 'Rewrites output Startdate: {0} Member: {1} Chunk: {2} ' \ + return 'Rewrite output Startdate: {0} Member: {1} Chunk: {2} ' \ 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) def __eq__(self, other): diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index a00e9f9..09f2695 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -77,7 +77,7 @@ class HeatContent(Diagnostic): raise Exception('You must specify 4 parameters for the heat content diagnostic') basin = Basins.parse(options[1]) mixed_layer = int(options[2]) - box = Box(True) + box = Box() box.min_depth = int(options[3]) box.max_depth = int(options[4]) job_list = list() diff --git a/test/unit/test_rewrite.py b/test/unit/test_rewrite.py index dfc8277..3cd0a74 100644 --- a/test/unit/test_rewrite.py +++ b/test/unit/test_rewrite.py @@ -35,5 +35,5 @@ class TestRewrite(TestCase): Rewrite.generate_jobs(self.diags, ['psi', '0', '0', '0', '0', '0', '0', '0']) def test_str(self): - self.assertEquals(str(self.mixed), 'Rewrites output Startdate: 20000101 Member: 1 Chunk: 1 ' + self.assertEquals(str(self.mixed), 'Rewrite output Startdate: 20000101 Member: 1 Chunk: 1 ' 'Variable: domain:var') -- GitLab From f854fe9cd9c77595c20cf55c7823621e532ade24 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 27 Sep 2016 13:30:23 +0200 Subject: [PATCH 225/268] Added option to CMORize only selected variables --- diags.conf | 8 ++++---- earthdiagnostics/cmorizer.py | 2 ++ earthdiagnostics/config.py | 20 ++++++++++++++++++++ earthdiagnostics/datamanager.py | 17 ++++++++--------- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/diags.conf b/diags.conf index 8f8b5dd..9feb834 100644 --- a/diags.conf +++ b/diags.conf @@ -8,8 +8,8 @@ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below). If you are using the diagnpostics just to CMORize, leave it # empty -# DIAGS = rewrite,thetao,ocean OHC -DIAGS = OHC +DIAGS = rewrite,thetao,ocean OHC +# DIAGS = OHC # Frequency of the data you want to use by default. Some diagnostics do not use this value: i.e. monmean always stores # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. FREQUENCY = mon @@ -77,8 +77,8 @@ STARTDATES = 19600101 MEMBERS = 0 MEMBER_DIGITS = 1 CHUNK_SIZE = 12 -# CHUNKS = 50 -CHUNKS = 1 +CHUNKS = 50 +# CHUNKS = 1 # This ALIAS section is a bit different diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index a7244ca..0583ec2 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -263,6 +263,8 @@ class Cmorizer(object): var_cmor = Variable.get_variable(variable) if var_cmor is None: return + if not self.cmor.cmorize(var_cmor): + return if frequency == 'd': frequency = 'day' elif frequency == 'm': diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index a5f53a4..6721a2c 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -103,10 +103,30 @@ class CMORConfig(object): self.add_name = parser.get_bool_option('CMOR', 'ADD_NAME') self.add_startdate = parser.get_bool_option('CMOR', 'ADD_STARTDATE') + vars_string = parser.get_option('CMOR', 'VARIABLE_LIST', '') + if vars_string: + self._variable_list = list() + for domain_var in vars_string.split(' '): + self._variable_list.append(domain_var.lower()) + else: + self._variable_list = None + self._var_hourly = CMORConfig._parse_variables(parser.get_option('CMOR', 'ATMOS_HOURLY_VARS', '')) self._var_daily = CMORConfig._parse_variables(parser.get_option('CMOR', 'ATMOS_DAILY_VARS', '')) self._var_monthly = CMORConfig._parse_variables(parser.get_option('CMOR', 'ATMOS_MONTHLY_VARS', '')) + def cmorize(self, var_cmor): + """ + Checks if var_cmor is on variable list + + :param var_cmor: CMOR variable object + :rtype var_cmor: Variablle + :return: + """ + if self._variable_list is None: + return True + return '{0}:{1}'.format(var_cmor.domain, var_cmor.short_name).lower() in self._variable_list + @staticmethod def _parse_variables(raw_string): variables = dict() diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 50c35df..f226ca0 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -79,15 +79,14 @@ class DataManager(object): self._correct_paths(startdate) continue else: - if not self._is_cmorized(startdate, member): - start_time = datetime.now() - Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) - - cmorizer = Cmorizer(self, startdate, member) - cmorizer.cmorize_ocean() - cmorizer.cmorize_atmos() - Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, - datetime.now() - start_time) + start_time = datetime.now() + Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) + + cmorizer = Cmorizer(self, startdate, member) + cmorizer.cmorize_ocean() + cmorizer.cmorize_atmos() + Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, + datetime.now() - start_time) def _correct_paths(self, startdate): bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) -- GitLab From 56109db087fa30843a4dee82684165dc5b2b222e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 27 Sep 2016 15:27:37 +0200 Subject: [PATCH 226/268] Fixed HDF error in AreaMoc diagnostic --- earthdiagnostics/ocean/areamoc.py | 33 ++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 7ea6f1b..7005388 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -4,6 +4,7 @@ from earthdiagnostics.constants import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.box import Box from earthdiagnostics.utils import Utils, TempFile +import os class AreaMoc(Diagnostic): @@ -116,25 +117,35 @@ class AreaMoc(Diagnostic): # To remove basin dimension nco.ncwa(input=temp, output=temp, options='-O -a basin') - nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time,lev') + source = Utils.openCdf(temp) + destiny = Utils.openCdf(temp2, 'w') - handler = Utils.openCdf(temp) - handler.renameDimension('j', 'lat') - lat_variable = handler.createVariable('lat', lat_type, 'lat') + Utils.copy_dimension(source, destiny, 'time') + Utils.copy_dimension(source, destiny, 'lev') + Utils.copy_dimension(source, destiny, 'j', new_names={'j': 'lat'}) + + lat_variable = destiny.createVariable('lat', lat_type, 'lat') lat_variable[:] = lat_values[:] lat_variable.units = lat_units lat_variable.long_name = lat_long_name - handler.close() + Utils.copy_variable(source, destiny, 'lev') + Utils.copy_variable(source, destiny, 'time') + Utils.copy_variable(source, destiny, 'vsftmyz', new_names={'j': 'lat'}) + + source.close() + destiny.close() - nco.ncks(input=temp, output=temp2, + nco.ncks(input=temp2, output=temp, options='-O -d lev,{0:.1f},{1:.1f} -d lat,{2:.1f},{3:.1f}'.format(self.box.min_depth, self.box.max_depth, self.box.min_lat, self.box.max_lat)) - cdo.vertmean(input=temp2, output=temp) - nco.ncap2(input=temp, output=temp, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') - nco.ncwa(input=temp, output=temp, options='-w coslat -a lat') - nco.ncks(input=temp, output=temp, options='-O -v vsftmyz,time') - self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, box=self.box) + cdo.vertmean(input=temp, output=temp2) + os.remove(temp) + nco.ncap2(input=temp2, output=temp2, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') + nco.ncwa(input=temp2, output=temp2, options='-w coslat -a lat') + nco.ncks(input=temp2, output=temp2, options='-O -v vsftmyz,time') + self.data_manager.send_file(temp2, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, + box=self.box) -- GitLab From 76490a63b3e3fb1e019a39c0914d3a3b9d807936 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 27 Sep 2016 15:42:16 +0200 Subject: [PATCH 227/268] Added force option to unzip --- earthdiagnostics/datamanager.py | 2 +- earthdiagnostics/utils.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index f226ca0..976964a 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -63,7 +63,7 @@ class DataManager(object): filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) if len(filepaths) > 0: Log.info('Unzipping cmorized data...') - Utils.unzip(filepaths) + Utils.unzip(filepaths, True) if not os.path.exists(self.cmor_path): os.mkdir(self.cmor_path) diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 8c5ff39..3d70738 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -464,11 +464,15 @@ class Utils(object): Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) @staticmethod - def unzip(files): + def unzip(files, force=False): for filepath in files: Log.debug('Unzipping {0}', filepath) + if force: + option = ' -f' + else: + option = '' try: - Utils.execute_shell_command('gunzip {0}'.format(filepath)) + Utils.execute_shell_command('gunzip{1} {0}'.format(filepath, option)) except Exception as ex: raise Utils.UnzipException('Can not unzip {0}: {1}'.format(filepath, ex)) -- GitLab From 84962be50cbadd5fd86823c55e7970be5b979068 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 27 Sep 2016 15:42:28 +0200 Subject: [PATCH 228/268] Bumped version and updated doc --- VERSION | 2 +- diags.conf | 2 ++ doc/source/conf.py | 2 +- earthdiagnostics/EarthDiagnostics.pdf | Bin 240809 -> 240950 bytes 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index f0198fa..787863d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b11 +3.0.0b12 diff --git a/diags.conf b/diags.conf index 9feb834..a05a2cd 100644 --- a/diags.conf +++ b/diags.conf @@ -27,6 +27,8 @@ FORCE = False OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = False +# You can specify the variable to cmorize, in the way domain:var domain:var2 domain2:var +VARIABLE_LIST = # Variables to be CMORized from the grib atmospheric files, separated by comma. # You can also specify the levels to extract using the following syntax diff --git a/doc/source/conf.py b/doc/source/conf.py index 35d7609..fc8ba2c 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b11' +release = '3.0.0b12' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index fa9f24d9b22f0879fdcf3a61b1571189f0da3c64..97d0151ed14e16c5686cf2bdfca127d5aa36e942 100644 GIT binary patch delta 40674 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 delta 40664 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 z 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 Ci>X5Z -- GitLab From 94072a8fffbaa3b807f9d9d7fb04230447f451ee Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 28 Sep 2016 17:42:19 +0200 Subject: [PATCH 229/268] If VARIABLE_LIST is specified, only required files are processed --- diags.conf | 6 +++--- earthdiagnostics/cmorizer.py | 6 ++++++ earthdiagnostics/config.py | 12 ++++++++++++ earthdiagnostics/variable.py | 5 +++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/diags.conf b/diags.conf index a05a2cd..035fdc8 100644 --- a/diags.conf +++ b/diags.conf @@ -8,7 +8,7 @@ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below). If you are using the diagnpostics just to CMORize, leave it # empty -DIAGS = rewrite,thetao,ocean OHC +DIAGS = OHC # DIAGS = OHC # Frequency of the data you want to use by default. Some diagnostics do not use this value: i.e. monmean always stores # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. @@ -22,13 +22,13 @@ MAX_CORES = 1 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = False +FORCE = True # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = False # You can specify the variable to cmorize, in the way domain:var domain:var2 domain2:var -VARIABLE_LIST = +VARIABLE_LIST = ocean:thetao # Variables to be CMORized from the grib atmospheric files, separated by comma. # You can also specify the levels to extract using the following syntax diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 0583ec2..103f406 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -201,6 +201,12 @@ class Cmorizer(object): def _cmorize_nc_file(self, filename): Log.info('Processing file {0}', filename) temp = TempFile.get() + handler = Utils.openCdf(filename) + variables = handler.variables.keys() + handler.close() + if not self.cmor.any_required(variables): + os.remove(filename) + return Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filename, temp]) shutil.move(temp, filename) file_parts = os.path.basename(filename).split('_') diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index 6721a2c..166e6c0 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -5,6 +5,7 @@ from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date from earthdiagnostics.parser import Parser +from earthdiagnostics.variable import Variable from utils import Utils @@ -125,8 +126,19 @@ class CMORConfig(object): """ if self._variable_list is None: return True + if not var_cmor: + return False return '{0}:{1}'.format(var_cmor.domain, var_cmor.short_name).lower() in self._variable_list + def any_required(self, variables): + if self._variable_list is None: + return True + for var in variables: + if self.cmorize(Variable.get_variable(var, silent=True)): + return True + + return False + @staticmethod def _parse_variables(raw_string): variables = dict() diff --git a/earthdiagnostics/variable.py b/earthdiagnostics/variable.py index 0757486..de26ac6 100644 --- a/earthdiagnostics/variable.py +++ b/earthdiagnostics/variable.py @@ -24,7 +24,7 @@ class Variable(object): self.valid_max = line[8].strip() @classmethod - def get_variable(cls, original_name): + def get_variable(cls, original_name, silent=False): """ Returns the cmor variable instance given a variable name @@ -36,7 +36,8 @@ class Variable(object): try: return cls._dict_variables[original_name.lower()] except KeyError: - Log.warning('Variable {0} is not defined in the CMOR table. Please add it'.format(original_name)) + if not silent: + Log.warning('Variable {0} is not defined in the CMOR table. Please add it'.format(original_name)) return None @classmethod -- GitLab From 947ff14f69216eab797c0b3ae5ff589d1e20e3a2 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 30 Sep 2016 18:26:38 +0200 Subject: [PATCH 230/268] Refactored datamanager to make THREDDS implementation easier --- diags.conf | 14 +- earthdiagnostics/cmor_table.csv | 4 +- earthdiagnostics/datamanager.py | 395 ++++++++++++++------------ earthdiagnostics/earthdiags.py | 4 +- earthdiagnostics/ocean/heatcontent.py | 4 +- earthdiagnostics/variable.py | 2 + 6 files changed, 222 insertions(+), 201 deletions(-) diff --git a/diags.conf b/diags.conf index 035fdc8..da06762 100644 --- a/diags.conf +++ b/diags.conf @@ -14,15 +14,15 @@ DIAGS = OHC # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. FREQUENCY = mon # Path to CDFTOOLS binaries -CDFTOOLS_PATH = ~/workspace/CDFTOOLS/bin +CDFTOOLS_PATH = ~/CDFTOOLS/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False -# Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -MAX_CORES = 1 +# Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) +# MAX_CORES = 1 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = True +FORCE = False # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True @@ -79,7 +79,7 @@ STARTDATES = 19600101 MEMBERS = 0 MEMBER_DIGITS = 1 CHUNK_SIZE = 12 -CHUNKS = 50 +CHUNKS = 40 # CHUNKS = 1 @@ -95,11 +95,11 @@ STC = mocarea,0,25,0,200,Pac mocarea,-25,0,0,200,Pac mocarea,0,25,0,200,Atl moca HEAT_SAL_MXL = mlotstsc mlotsthc LMSALC = vertmeanmeters,so,300,5400 USALC = vertmeanmeters,so,0,300 -OHC = ohc,glob,0,0,10 +OHC = ohc,glob,0,1,10 XOHC = ohc,glob,1,0,0 LOHC = ohc,glob,0,23,46 MOHC = ohc,glob,0,18,22 -UOHC = ohc,glob,0,0,17 +UOHC = ohc,glob,0,1,17 OHC_SPECIFIED_LAYER = ohclayer,0,300 ohclayer,300,800 3DTEMP = interp,thetao 3DSAL = interp,so diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index ff3c55e..18bae8e 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -256,7 +256,9 @@ scsshtot,zosga,global_average_sea_level_change,Global average sea level change , scsshste,zossga,global_average_steric_sea_level_change,Global average steric sea level change ,ocean,,,, zossq,zossq,square_of_sea_surface_height_above_geoid,Square of sea surface height above geoid ,ocean,,,, scsshtst,zostoga,snthic,Global average thermosteric sea level change ,ocean,,,, -heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,Joules,, +heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,J,, +ohcsum,ohcsum,total_ocean_heat_content,Total Ocean heat content,ocean,,J,, +ohcvmean,ohcvmean,average_ocean_heat_content,Average Ocean heat content,ocean,,J m-3,, transix,transix,sea_ice_x_transport,X-Component of Sea Ice Mass Transport,seaIce,,kg s-1,, transiy,transiy,sea_ice_y_transport,Y-Component of Sea Ice Mass Transport,seaIce,,kg s-1,, windsp,sfcWind,wind_speed,Near-Surface Wind Speed,atmos,,,, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 976964a..2be6549 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -33,86 +33,6 @@ class DataManager(object): self.lock = threading.Lock() self.cmor_path = os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles') - # noinspection PyPep8Naming - def prepare_CMOR_files(self): - """ - Prepares the data to be used by the diagnostic. - - If CMOR data is not created, it show a warning and closes. In the future, an automatic cmorization procedure - will be launched - - If CMOR data is available but packed, the procedure will unpack it. - - :return: - """ - # Check if cmorized and convert if not - - for startdate, member in self.experiment.get_member_list(): - - if not self.config.cmor.force and self._is_cmorized(startdate, member): - continue - member_str = self.experiment.get_member_str(member) - if not self.config.cmor.force: - tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') - tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, - 'cmorfiles') - file_name = 'CMOR?_{0}_{1}_*.tar.gz'.format(self.experiment.expid, startdate, member_str) - filepaths = glob.glob(os.path.join(tar_path, file_name)) - filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) - if len(filepaths) > 0: - Log.info('Unzipping cmorized data...') - Utils.unzip(filepaths, True) - - if not os.path.exists(self.cmor_path): - os.mkdir(self.cmor_path) - - file_name = 'CMOR?_{0}_{1}_*.tar'.format(self.experiment.expid, startdate, member_str) - filepaths = glob.glob(os.path.join(tar_path, file_name)) - filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) - if len(filepaths) > 0: - Log.info('Unpacking cmorized data...') - Utils.untar(filepaths, self.cmor_path) - self._correct_paths(startdate) - continue - else: - start_time = datetime.now() - Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) - - cmorizer = Cmorizer(self, startdate, member) - cmorizer.cmorize_ocean() - cmorizer.cmorize_atmos() - Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, - datetime.now() - start_time) - - def _correct_paths(self, startdate): - bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) - if os.path.exists(bad_path): - Utils.execute_shell_command(['mv', bad_path, os.path.join(bad_path, '..', '..')]) - os.rmdir(os.path.join(self.cmor_path, 'output')) - - if self.experiment.experiment_name != self.experiment.model: - bad_path = os.path.join(self.cmor_path, self.experiment.institute, self.experiment.model, - self.experiment.model) - for (dirpath, dirnames, filenames) in os.walk(bad_path, False): - - for filename in filenames: - filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_output_'.format(self.experiment.model), - '_{0}_{1}_S{2}_'.format(self.experiment.model, - self.experiment.experiment_name, - startdate)) - - good = good.replace('/{0}/{0}'.format(self.experiment.model), - '/{0}/{1}'.format(self.experiment.model, - self.experiment.experiment_name)) - - Utils.move_file(filepath, good) - os.rmdir(dirpath) - def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy @@ -137,51 +57,12 @@ class DataManager(object): :rtype: str """ - if not frequency: - frequency = self.config.frequency - - domain = DataManager.correct_domain(domain) - domain_abbreviation = self.get_domain_abbreviation(domain, frequency) - - start = parse_date(startdate) - member_plus = str(member + 1) - member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) - - chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') - - var = self._get_final_var_name(box, var) - - if grid: - var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) - else: - var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) - - filepath = os.path.join(var_path, '{0}_{1}_{3}_{4}_S{5}_r{6}i1p1_' - '{7}-{8}.nc'.format(var, domain_abbreviation, frequency, - self.experiment.model, - self.experiment.experiment_name, startdate, member_plus, - "{0:04}{1:02}".format(chunk_start.year, - chunk_start.month), - "{0:04}{1:02}".format(chunk_end.year, - chunk_end.month))) + filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, grid, None, None) temp_path = TempFile.get() shutil.copyfile(filepath, temp_path) return temp_path - def get_startdate_path(self, startdate): - """ - Returns the path to the startdate's CMOR folder - :param startdate: target startdate - :type startdate: str - :return: path to the startdate's CMOR folder - :rtype: str - """ - return os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles', self.experiment.institute, - self.experiment.model, self.experiment.experiment_name, 'S' + startdate) - def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, rename_var=None, frequency=None, year=None, date_str=None, move_old=False): """ @@ -232,7 +113,8 @@ class DataManager(object): if not frequency: frequency = self.config.frequency domain = DataManager.correct_domain(domain) - filepath = self._get_file_path(chunk, date_str, domain, frequency, grid, member, startdate, var, year) + filepath = self.get_file_path(startdate, member, domain, cmor_var.short_name, chunk, frequency, box, + grid, year, date_str) if region: self._prepare_region(filepath, filetosend, region, var) @@ -371,73 +253,6 @@ class DataManager(object): Utils.move_file(temp, filetosend) Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') - def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, - frequency=None, year=None, date_str=None, move_old=False): - """ - Creates the link of a given file from the CMOR repository. - - :param move_old: - :param date_str: - :param year: if frequency is yearly, this parameter is used to give the corresponding year - :type year: int - :param domain: CMOR domain - :type domain: str - :param var: variable name - :type var: str - :param startdate: file's startdate - :type startdate: str - :param member: file's member - :type member: int - :param chunk: file's chunk - :type chunk: int - :param grid: file's grid (only needed if it is not the original) - :type grid: str - :param box: file's box (only needed to retrieve sections or averages) - :type box: Box - :param frequency: file's frequency (only needed if it is different from the default) - :type frequency: str - :return: path to the copy created on the scratch folder - :rtype: str - """ - var = self._get_final_var_name(box, var) - - if not frequency: - frequency = self.config.frequency - domain = DataManager.correct_domain(domain) - filepath = self._get_file_path(chunk, date_str, domain, frequency, grid, member, startdate, var, year) - self._create_link(domain, filepath, frequency, var, grid, move_old) - - def _get_file_path(self, chunk, date_str, domain, frequency, grid, member, startdate, var, year): - domain_abreviattion = self.get_domain_abbreviation(domain, frequency) - start = parse_date(startdate) - member_plus = str(member + 1) - member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) - if chunk is not None: - chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') - - time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, - chunk_end.month) - - elif year: - if frequency is not 'yr': - raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') - time_bound = str(year) - elif date_str: - time_bound = date_str - else: - raise ValueError('Chunk, year and date_str can not be None at the same time') - if grid: - var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) - else: - var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) - filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' - '{6}.nc'.format(var, domain_abreviattion, self.experiment.model, - self.experiment.experiment_name, - startdate, member_plus, time_bound)) - return filepath - @staticmethod def _get_final_var_name(box, var): if box: @@ -534,6 +349,117 @@ class DataManager(object): domain_abreviattion = 'day' return domain_abreviattion + # Abstract methods + def get_file_path(self, startdate, member, domain, var, chunk, frequency, + box=None, grid=None, year=None, date_str=None): + """ + :param date_str: exact date_str to use in the cmorized file + :type: str + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int | None + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: file absolute path + :rtype: str + """ + raise NotImplementedError() + + def get_year(self, domain, var, startdate, member, year, grid=None, box=None): + raise NotImplementedError() + + # Overridable methods (not mandatory) + def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, + frequency=None, year=None, date_str=None, move_old=False): + pass + + +class CMORManager(DataManager): + def get_file_path(self, startdate, member, domain, var, chunk, frequency, + box=None, grid=None, year=None, date_str=None): + if not frequency: + frequency = self.config.frequency + var = self._get_final_var_name(box, var) + domain_abreviattion = self.get_domain_abbreviation(domain, frequency) + start = parse_date(startdate) + member_plus = str(member + 1) + + member_path = os.path.join(self._get_startdate_path(startdate), frequency, domain) + if chunk is not None: + chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + + time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, + chunk_end.month) + + elif year: + if frequency is not 'yr': + raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') + time_bound = str(year) + elif date_str: + time_bound = date_str + else: + raise ValueError('Chunk, year and date_str can not be None at the same time') + if grid: + var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) + else: + var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) + filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' + '{6}.nc'.format(var, domain_abreviattion, self.experiment.model, + self.experiment.experiment_name, + startdate, member_plus, time_bound)) + return filepath + + def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, + frequency=None, year=None, date_str=None, move_old=False): + """ + Creates the link of a given file from the CMOR repository. + + :param move_old: + :param date_str: + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ + var = self._get_final_var_name(box, var) + + if not frequency: + frequency = self.config.frequency + domain = DataManager.correct_domain(domain) + filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, grid, year, date_str) + self._create_link(domain, filepath, frequency, var, grid, move_old) + def get_year(self, domain, var, startdate, member, year, grid=None, box=None): """ Gets all the data corresponding to a given year from the CMOR repository to the scratch folder as one file and @@ -586,7 +512,7 @@ class DataManager(object): return temp2 def _is_cmorized(self, startdate, member): - startdate_path = self.get_startdate_path(startdate) + startdate_path = self._get_startdate_path(startdate) if not os.path.exists(startdate_path): return False for freq in os.listdir(startdate_path): @@ -599,6 +525,97 @@ class DataManager(object): return True return False + # noinspection PyPep8Naming + def prepare_CMOR_files(self): + """ + Prepares the data to be used by the diagnostic. + + If CMOR data is not created, it show a warning and closes. In the future, an automatic cmorization procedure + will be launched + + If CMOR data is available but packed, the procedure will unpack it. + + :return: + """ + # Check if cmorized and convert if not + + for startdate, member in self.experiment.get_member_list(): + + if not self.config.cmor.force and self._is_cmorized(startdate, member): + continue + member_str = self.experiment.get_member_str(member) + if not self.config.cmor.force: + tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') + tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, + 'cmorfiles') + file_name = 'CMOR?_{0}_{1}_*.tar.gz'.format(self.experiment.expid, startdate, member_str) + filepaths = glob.glob(os.path.join(tar_path, file_name)) + filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) + if len(filepaths) > 0: + Log.info('Unzipping cmorized data...') + Utils.unzip(filepaths, True) + + if not os.path.exists(self.cmor_path): + os.mkdir(self.cmor_path) + + file_name = 'CMOR?_{0}_{1}_*.tar'.format(self.experiment.expid, startdate, member_str) + filepaths = glob.glob(os.path.join(tar_path, file_name)) + filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) + if len(filepaths) > 0: + Log.info('Unpacking cmorized data...') + Utils.untar(filepaths, self.cmor_path) + self._correct_paths(startdate) + continue + else: + start_time = datetime.now() + Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) + + cmorizer = Cmorizer(self, startdate, member) + cmorizer.cmorize_ocean() + cmorizer.cmorize_atmos() + Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, + datetime.now() - start_time) + + def _correct_paths(self, startdate): + bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) + if os.path.exists(bad_path): + Utils.execute_shell_command(['mv', bad_path, os.path.join(bad_path, '..', '..')]) + os.rmdir(os.path.join(self.cmor_path, 'output')) + + if self.experiment.experiment_name != self.experiment.model: + bad_path = os.path.join(self.cmor_path, self.experiment.institute, self.experiment.model, + self.experiment.model) + for (dirpath, dirnames, filenames) in os.walk(bad_path, False): + + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_output_'.format(self.experiment.model), + '_{0}_{1}_S{2}_'.format(self.experiment.model, + self.experiment.experiment_name, + startdate)) + + good = good.replace('/{0}/{0}'.format(self.experiment.model), + '/{0}/{1}'.format(self.experiment.model, + self.experiment.experiment_name)) + + Utils.move_file(filepath, good) + os.rmdir(dirpath) + + def _get_startdate_path(self, startdate): + """ + Returns the path to the startdate's CMOR folder + :param startdate: target startdate + :type startdate: str + :return: path to the startdate's CMOR folder + :rtype: str + """ + return os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles', self.experiment.institute, + self.experiment.model, self.experiment.experiment_name, 'S' + startdate) + class UnitConversion(object): """ diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index a063b68..4d0e1cb 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -13,7 +13,7 @@ import os from autosubmit.date.chunk_date_lib import * from config import Config -from datamanager import DataManager +from datamanager import CMORManager from earthdiagnostics import cdftools from earthdiagnostics.utils import TempFile from earthdiagnostics.diagnostic import Diagnostic @@ -139,7 +139,7 @@ class EarthDiags(object): self._register_diagnostics() parse_date('20000101') - self.data_manager = DataManager(self.config) + self.data_manager = CMORManager(self.config) self.data_manager.prepare_CMOR_files() # Run diagnostics diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index 09f2695..672113c 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -127,13 +127,13 @@ class HeatContent(Diagnostic): thc = ohcsum_handler.createVariable('ohcsum', float, 'time') thc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" thc.long_name = "Total heat content" - thc.units = "Joules" + thc.units = "J" ohcvmean_handler = Utils.openCdf(ohcvmean_temp) uhc = ohcvmean_handler.createVariable('ohcvmean', float, 'time') uhc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content" uhc.long_name = "Heat content per unit volume" - uhc.units = "Joules/m3" + uhc.units = "J*m^-3" time = 0 # noinspection PyUnboundLocalVariable diff --git a/earthdiagnostics/variable.py b/earthdiagnostics/variable.py index de26ac6..6b7b8f5 100644 --- a/earthdiagnostics/variable.py +++ b/earthdiagnostics/variable.py @@ -30,6 +30,8 @@ class Variable(object): :param original_name: original variable's name :type original_name: str + :param silent: if True, omits log warning when variable is not found + :type silent: str :return: CMOR variable :rtype: Variable """ -- GitLab From 8ac76426f80308f7083205c45757f71d689d218a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 4 Oct 2016 12:45:53 +0200 Subject: [PATCH 231/268] Added diferentiation for sic coming from IFS or LIM. Added support for this in Variable and cmorizer classes --- earthdiagnostics/cmor_table.csv | 595 ++++++++++++++++---------------- earthdiagnostics/cmorizer.py | 2 +- earthdiagnostics/variable.py | 1 + 3 files changed, 300 insertions(+), 298 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 18bae8e..ac70f8a 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -1,297 +1,298 @@ -Variable,Shortname,Name,Long name,Domain,Basin,Units,Valid min,Valid max -iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of sea ice,seaIce,,,, -al,al,surface_albedo,Albedo,atmos,,,, -bgfrcsal,bgfrcsal,change_over_time_in_heat_content_from_forcing,Change over time in salt content from forcing,ocean,,,, -bgfrctem,bgfrctem,change_over_time_in_heat_content_from_forcing,Change over time in heat content from forcing,ocean,,,, -bgfrcvol,bgfrcvol,change_over_time_in_volume_from_forcing,Change over time in volume from forcing,ocean,,,, -bgheatco,bgheatco,change_over_time_in_heat_content,Change over time in sea water heat content,ocean,,,, -bgsaline,bgsaline,change_over_time_in_sea_water_practical_salinity,Change over time in sea water salinity,ocean,,,, -bgsaltco,bgsaltco,change_over_time_in_salt_content,Change over time in sea water salt content,ocean,,,, -bgtemper,bgtemper,change_over_time_in_sea_water_potential_temperature,Change over time in sea water potential temperature,ocean,,,, -bgvole3t,bgvole3t,change_over_time_in_volume_variation,Change over time in volume variation (e3t),ocean,,,, -bgvolssh,bgvolssh,change_over_time_in_sea_surface_height,Change over time in sea surface height,ocean,,,, -bld,bld,boundary_layer_dissipation,Boundary layer dissipation,atmos,,,, -iicebome:iocewflx,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of melt at sea ice base,seaIce,,,, -sobowlin,bowlin,bowl_index,Bowl index,ocean,,,, -cc,cl,cloud_area_fraction_in_atmosphere_layer,Cloud area fraction,atmos,,,, -hcc,clh,high_cloud_area_fraction,High cloud fraction,atmos,,,, -lcc,cll,low_cloud_area_fraction,Low cloud fraction,atmos,,,, -mcc,clm,medium_cloud_area_fraction,Medium cloud fraction,atmos,,,, -ciwc,cli,mass_fraction_of_cloud_ice_in_air,Mass fraction of cloud ice,atmos,,,, -tcc,clt,cloud_area_fraction,Total cloud fraction,atmos,,,, -clwc,clw,mass_fraction_of_cloud_liquid_water_in_air,Mass fraction of cloud liquid water,atmos,,,, -tcw,clwvi,atmosphere_cloud_condensed_water_content,Condensed water path,atmos,,,, -iicedive:sidive,divice,Strain Rate Divergence of Sea Ice,Divergence_of_sea_ice_velocity,seaIce,,,, -e,evspsbl,water_evaporation_flux,Evaporation,atmos,,,, -fal,fal,forecast_albedo,Forecast albedo,atmos,,,, -sowaflep,fatmosocean,atmosphere_ocean_water_flux,Atmos=>ocean net freshwater,ocean,,,, -sowaflcd,fdilution,dilution_water_flux,Concentration/dilution water flux,ocean,,,, -sophtldf,fhbasindif,northward_ocean_heat_transport_due_to_diffusion,Northward ocean heat transport due to diffusion,ocean,,,, -iowaflup,ficeocean,ice_ocean_water_flux,Ice=>ocean net freshwater,ocean,,,, -sorunoff,friver,water_flux_into_sea_water_from_rivers,Water flux into sea water from rivers ,ocean,,,, -sowaflup,fupward,upward_water_flux,Net upward water flux,ocean,,,, -gwd,gwd,gravity_wave_dissipation,Gravity wave dissipation,atmos,,,, -ibgheatco,hcicega,global mean ice heat content,Global mean ice heat content,seaIce,,,, -sbgheatco,hcsnga,global mean snow heat content,Global mean snow heat content,seaIce,,,, -heatc,heatc,integral_of_sea_water_potential_temperature_wrt_depth_expressed_as_heat_content,Heat content vertically integrated,ocean,,,, -sohtatl,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Atl,,, -sohtind,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Ind,,, -sohtipc,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,IndPac,,, -sohtpac,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Pac,,, -sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward ocean heat transport due to advection ,ocean,,,, -sophteiv,hfbasinba,northward_ocean_heat_transport_due_to_bolus_advection,Northward ocean heat transport due to bolus advection ,ocean,,,, -qt_oce:sohefldo:qt,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,, -slhf,hfls,surface_upward_latent_heat_flux,Surface upward latent heat flux,atmos,,,, -sshf,hfss,surface_upward_sensible_heat_flux,Surface upward sensible heat flux,atmos,,,, -sophtove,htovovrt,northward_ocean_heat_transport_due_to_overturning,Northward ocean heat transport due to overturning ,ocean,,,, -q,hus,specific_humidity,Specific humidity,atmos,,,, -soicealb,ialb,sea_ice_albedo,Sea ice albedo,seaIce,,,, -ibgfrcsfx,ibgfrcsfx,global_mean_forcing_salt,Global mean forcing salt (sfx),seaIce,,,, -ibgfrcvol,ibgfrcvol,globa_mean_forcing_volume,Global mean forcing volume (emp),seaIce,,,, -ibghfxbog,ibghfxbog,heat_fluxes_causing_bottom_ice_growth,Heat fluxes causing bottom ice growth,seaIce,,,, -ibghfxbom,ibghfxbom,heat_fluxes_causing_bottom_ice_melt,Heat fluxes causing bottom ice melt,seaIce,,,, -ibghfxdhc,ibghfxdhc,Heat_content_variation_in_snow_and_ice,Heat content variation in snow and ice,seaIce,,,, -ibghfxdif,ibghfxdif,heat_fluxes_causing_ice temperature_change,Heat fluxes causing ice temperature change,seaIce,,,, -ibghfxdyn,ibghfxdyn,heat_fluxes_from_ice-ocean_exchange_during_dynamic,Heat fluxes from ice-ocean exchange during dynamic,seaIce,,,, -ibghfxin,ibghfxin,total_heat_fluxes_at_the_ice_surface,Total heat fluxes at the ice surface,seaIce,,,, -ibghfxopw,ibghfxopw,heat_fluxes_causing_open_water_ice_formation,Heat fluxes causing open water ice formation,seaIce,,,, -ibghfxout,ibghfxout,non_solar_heat_fluxes_received_by_the_ocean,Non solar heat fluxes received by the ocean,seaIce,,,, -ibghfxres,ibghfxres,heat_fluxes_from_ice-ocean_exchange_during_resultant,Heat fluxes from ice-ocean exchange during resultant,seaIce,,,, -ibghfxsnw,ibghfxsnw,heat_fluxes_from_snow-ocean_exchange,Heat fluxes from snow-ocean exchange,seaIce,,,, -ibghfxspr,ibghfxspr,Heat_content_of_snow_precip,Heat content of snow precip,seaIce,,,, -ibghfxsub,ibghfxsub,heat_fluxes_from_sublimation,Heat fluxes from sublimation,seaIce,,,, -ibghfxsum,ibghfxsum,heat_fluxes_causing_surface_ice_melt,Heat fluxes causing surface ice melt,seaIce,,,, -ibghfxthd,ibghfxthd,heat_fluxes_from_ice-ocean_exchange_during_thermo,Heat fluxes from ice-ocean exchange during thermo,seaIce,,,, -ibgsfxbog,ibgsfxbogga,salt_flux_thermo,Global mean salt flux (thermo),seaIce,,,, -ibgsfxbom,ibgsfxbomga,salt_flux_bottom_melt,Global mean salt flux (bottom melt),seaIce,,,, -ibgsfxbri,ibgsfxbriga,salt_flux_brines,Global mean salt flux (brines),seaIce,,,, -ibgsfxdyn,ibgsfxdynga,salt_flux_dynamic,Global mean salt flux (dynamic),seaIce,,,, -ibgsfx,ibgsfxga,salt_flux,Global mean salt flux (total),seaIce,,,, -ibgsfxopw,ibgsfxopwga,salt_flux_open_waters,Global mean salt flux (open water),seaIce,,,, -ibgsfxres,ibgsfxresga,salt_flux_resultant,Global mean salt flux (resultant),seaIce,,,, -ibgsfxsni,ibgsfxsniga,salt_flux_snow_ice_growth,Global mean salt flux (snow-ice growth),seaIce,,,, -ibgsfxsum,ibgsfxsumga,salt_flux_surface_melt,Global mean salt flux (surface melt),seaIce,,,, -ibgvfxbog,ibgvfxbogga,volume_flux_bottom_growth,Global mean volume flux (bottom growth),seaIce,,,, -ibgvfxbom,ibgvfxbomga,volume_flux_bottom_melt,Global mean volume flux (bottom melt),seaIce,,,, -ibgvfxdyn,ibgvfxdynga,volume_flux_dynamic_growth,Global mean volume flux (dynamic growth),seaIce,,,, -ibgvfx,ibgvfxga,volume_flux_emp,Global mean volume flux (emp),seaIce,,,, -ibgvfxopw,ibgvfxopwga,volume_flux_open_water_growth,Global mean volume flux (open water growth),seaIce,,,, -ibgvfxres,ibgvfxresga,volume_flux_resultant,Global mean volume flux (resultant),seaIce,,,, -ibgvfxsni,ibgvfxsniga,volume_flux_snow_ice_growth,Global mean volume flux (snow-ice growth),seaIce,,,, -ibgvfxsnw,ibgvfxsnwga,volume_flux_snow_melt,Global mean volume flux (snow melt),seaIce,,,, -ibgvfxspr,ibgvfxsprga,snheco,Global mean volume flux (snow precip),seaIce,,,, -ibgvfxsub,ibgvfxsubga,volume_flux_snow_sublimation,Global mean volume flux (snow sublimation),seaIce,,,, -ibgvfxsum,ibgvfxsumga,volume_flux_surface_melt,Global mean volume flux (surface melt),seaIce,,,, -ibgvolgrm,ibgvolgrm,global_mean_ice_growth+melt_volume,Global mean ice growth+melt volume,seaIce,,,, -ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce,,,, -sibricat,ibrinvolcat,brine_volume_in_categories,Brine volume for categories,seaIce,,,, -iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce,,,, -iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thickness,seaIce,,,, -iicedypr,iicedypr,daily_dynamic_ice_production,Daily dynamic ice production,seaIce,,,, -iice_etd,iiceetd,brine_volume_distribution,Brine volume distribution,seaIce,,,, -iicelapr,iicelapr,daily_lateral_thermo_ice_production,Daily lateral thermo ice prod.,seaIce,,,, -iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce,,,, -iicesflx,iicesflx,solar_flux_ice_ocean_surface,Solar flux at ice/ocean surface,seaIce,,,, -iiceshea,iiceshea,shear,Shear,seaIce,,,, -iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce,,,, -iicfsbri,iicfsbri,brine_salt_flux,Fsbri - brine salt flux,seaIce,,,, -iicfseqv,iicfseqv,equivalent_FW_salt_flux,Fseqv - equivalent fw salt flux,seaIce,,,, -ioceflxb,ioceflxb,oceanic_flux_ar_ice_base,Oceanic flux at the ice base,seaIce,,,, -iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release,seaIce,,,, -iocesafl,iocesafl,salt_flux_ocean_surface,Salt flux at ocean surface,seaIce,,,, -iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce,,,, -iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce,,,, -iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce,,,, -isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce,,K,, -scmastot,masso,sea_water_mass,Sea water mass ,ocean,,,, -mldkz5,mldkz5,ocean_mixed_layer_thickness_defined_by_vertical_tracer_diffusivity,Turbocline depth (kz = 5e-4),ocean,,,, -somxl010:mldr10_1,mlotst,ocean_mixed_layer_thickness_defined_by_sigma_t,Ocean mixed layer thickness defined by sigma T ,ocean,,,, -swvl1,mrlsl1,moisture_content_of_soil_layer_1, Water content of soil layer 1,land,,,, -swvl2,mrlsl2,moisture_content_of_soil_layer_2, Water content of soil layer 2,land,,,, -swvl3,mrlsl3,moisture_content_of_soil_layer_3, Water content of soil layer 3,land,,,, -swvl4,mrlsl4,moisture_content_of_soil_layer_4, Water content of soil layer 4,land,,,, -ro,mrro,runoff_flux,Total runoff,atmos,,,, -tp:precip,pr,precipitation_flux,Precipitation,atmos,,,, -cp,prc,convective_precipitation_flux,Convective precipitation,atmos,,,, -lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos,,,, -isnowpre,prsn,snowfall_flux,Surface snowfall rate into the sea ice portion of the grid cell,seaIce,,,, -sf:snowpre,prsn,snowfall_flux,Snowfall flux,atmos,,,, -tcwv,prw,atmosphere_water_vapor_content,Water vapor path,atmos,,,, -msl,psl,air_pressure_at_sea_level,Sea level pressure,atmos,,,, -qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,Non-solar heat flux at ice surface: sum over categories,seaIce,,,, -qt_ice,qtice,surface_downward_heat_flux_in_air,Surface downward heat flux in air,seaIce,,,, -strd,rlds,surface_downwelling_longwave_flux_in_air,Surface downwelling longwave radiation,atmos,,,, -strc:str,rls,surface_longwave_flux_in_air,Surface longwave radiation,atmos,,,, -ttr,rlut,toa_outgoing_longwave_flux,Toa outgoing longwave radiation,atmos,,,, -ttrc,rlutcs,toa_outgoing_longwave_flux_assuming_clear_sky,"Top net thermal radiation, clear sky",atmos,,,, -ssrd,rsds,surface_downwelling_shortwave_flux_in_air,Surface downwelling shortwave radiation,atmos,,,, -tsr,rsdt,toa_incoming_shortwave_flux,Toa incident shortwave radiation,atmos,,,, -soshfldo,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net downward shortwave radiation at sea water surface ,ocean,,,, -ssr,rss,surface_shortwave_flux_in_air,Surface shortwave radiation,atmos,,,, -ssrc,rsscs,surface_shortwave_flux_in_air_assuming_clear_sky,Surface clear-sky shortwave radiation,atmos,,,, -tsrc,rsut,toa_outgoing_shortwave_flux,Toa outgoing shortwave radiation,atmos,,,, -saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrated,ocean,,,, -es,sbl,surface_snow_and_ice_sublimation_flux,Surface snow and ice sublimation flux,landIce,,,, -sosalflx,sfs,salt_flux_surface,Surface salt flux,ocean,,,, -si,si,solar_insolation,Solar insolation,atmos,,,, -NArea,siarean,sea_ice_area,Total area of sea ice in the northern hemisphere,seaIce,,10^6 km2,, -SArea,siareas,sea_ice_area,Total area of sea ice in the southern hemisphere,seaIce,,10^6 km2,, -iiceconc:siconc:soicecov:ileadfra:ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce,,%,, -iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,,,, -ibgarea,sicga,sea_ice_content,Global mean sea ice content,seaIce,,,, -NExnsidc,siextentn,sea_ice_extent,Total area of all northern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,, -SExnsidc,siextents,sea_ice_extent,Total area of all southern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,, -iiceprod,sigr,ice_production,Ice production,seaIce,,,, -iiceheco,siheco,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea ice heat content,seaIce,,,, -ibgsaltco,sisaltcga,global mean ice salt content,Global mean ice salt content,seaIce,,,, -iicethic:sithic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce,,m,, -iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce,,,, -iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce,,K,, -ibgtemper,sitempga,sea_ice_temperature,Global mean sea ice temperature,seaIce,,K,, -iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce,,,, -iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce,,,, -iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce,,,, -ibgvoltot,sivolga,sea_ice_volume,Global mean sea ice volume,seaIce,,,, -sivoln:NVolume,sivoln,sea_ice_volume,Total volume of sea ice in the northern hemisphere,seaIce,,10^3 km3,, -sivols:SVolume,sivols,sea_ice_volume,Total volume of sea ice in the southern hemisphere,seaIce,,10^3 km3,, -sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea ice volume per gridcell area unit,seaIce,,,, -sostatl,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, -sostind,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, -sostipc,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, -sostpac,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,, -sopstadv,sltbasinadv,northward_ocean_salt_transport_due_to_advection,Northward ocean salt transport due to advection ,ocean,,,, -sopsteiv,sltbasinba,northward_ocean_salt_transport_due_to_bolus_advection,Northward ocean salt transport due to bolus advection ,ocean,,,, -sopstldf,sltbasindif,northward_ocean_salt_transport_due_to_diffusion,Northward ocean salt transport due to diffusion,ocean,,,, -sltnortha,sltnortha,northward_ocean_salt_transport,Atlantic northward ocean salt transport,ocean,,,, -sopstove,sltovovrt,northward_ocean_salt_transport_due_to_overturning,Northward ocean salt transport due to overturning ,ocean,,,, -zosalatl,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Atl,psu,, -zosalglo,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Glob,psu,, -zosalind,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Ind,psu,, -zosalipc,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,IndPac,psu,, -zosalpac,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Pac,psu,, -asn,snal,snow_albedo,Snow albedo,landIce,,,, -iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce,,,, -isnoheco,snheco,snow_heat_content,Snow total heat content,seaIce,,,, -sd,snld,lwe_thickness_of_surface_snow_amount,Snow depth,atmos,,,, -smlt,snm,surface_snow_melt_flux,Surface snow melt,landIce,,,, -isnowthi,snthic,surface_snow_thickness,Surface snow thickness,seaIce,,,, -sbgvoltot,snvolga,snow_volume,Global mean snow volume,seaIce,,,, -snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow volume per gridcell area unit,seaIce,,,, -vosaline:mean_3Dsosaline,so,sea_water_salinity,Sea water salinity,ocean,,psu,, -scsaltot,soga,sea_water_salinity,Global mean sea water salinity ,ocean,,psu,, -hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic northward ocean heat transport,ocean,,,, -soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,Eddy induced vel. coeff. at w-point,ocean,,,, -soleahtw,soleahtw,lateral_eddy_diffusivity,Lateral eddy diffusivity,ocean,,,, -somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (turbocline),ocean,,,, -sosaline:isssalin:mean_sosaline,sos,sea_surface_salinity,Sea surface salinity ,ocean,,psu,, -sothedep,sothedep,thermocline_depth,Thermocline depth (max dt/dz),ocean,,,, -src,src,skin_reservoir_content,Skin reservoir content,land,,,, -zosrfatl,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Atl,,, -zosrfglo,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Glob,,, -zosrfind,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Ind,,, -zosrfipc,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,IndPac,,, -zosrfpac,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Pac,,, -rsn,srho,snow_density,Snow density,landIce,,,, -iicesali:iice_std,ssi,sea_ice_salinity,Sea ice salinity,seaIce,,psu,, -salincat,ssicat,sea_ice_salinity_in_categories,Sea-ice bulk salinity for categories,seaIce,,psu,, -ibgsaline,ssiga,sea_ice_salinity,Global mean sea ice salinity ,seaIce,,psu,, -iicestre,streng,compressive_strength_of_sea_ice,Compressive sea ice strength,seaIce,,,, -so20chgt,t20d,depth_of_isosurface_of_sea_water_potential_temperature,,ocean,,,, -t,ta,air_temperature,Air temperature,atmos,,K,, -t2m,tas,air_temperature,Near-surface air temperature,atmos,,K,, -mx2t,tasmax,air_temperature,Daily maximum near-surface air temperature,atmos,,K,, -mn2t,tasmin,air_temperature,Daily minimum near-surface air temperature,atmos,,K,, -ewss,tauu,surface_downward_eastward_stress,Surface downward eastward wind stress,atmos,,,, -utau_ice:iocestru:iicestru,strairx,surface_downward_x_stress,X-Component of Atmospheric Stress On Sea Ice,seaIce,,N m-2,, -sozotaux,tauuo,surface_downward_x_stress,Surface downward x stress ,ocean,,,, -nsss,tauv,surface_downward_northward_stress,Surface downward northward wind stress,atmos,,,, -vtau_ice:iocestrv:iicestrv,strairy,surface_downward_y_stress,Y-Component of Atmospheric Stress On Sea Ice,seaIce,,N m-2,, -sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface downward y stress ,ocean,,,, -d2m,tdps,dew_point_temperature,2m dewpoint temperature,atmos,,K,, -votemper:mean_3Dsosstsst,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,K,, -sctemtot,thetaoga,sea_water_potential_temperature,Global average sea water potential temperature ,ocean,,K,, -iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of melt at upper surface of sea ice,seaIce,,,, -sosstsst:sstk:mean_sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,, -tossq,tossq,square_of_sea_surface_temperature,Square of sea surface temperature ,ocean,,K2,, -zotematl,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Atl,K,, -zotemglo,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Glob,K,, -zotemind,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Ind,K,, -zotemipc,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,IndPac,K,, -zotempac,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Pac,K,, -skt,ts,surface_temperature,Surface temperature,atmos,,K,, -iicesurt:soicetem:sistem,tsice,surface_temperature,Surface temperature of sea ice,seaIce,,K,, -istl1,tsice,surface_temperature,Surface temperature of ice,landIce,,K,, -stl1,tsl1,soil_temperature_level_1,Temperature of soil level 1,land,,,, -stl2,tsl2,soil_temperature_level_2,Temperature of soil level 2,land,,,, -stl3,tsl3,soil_temperature_level_3,Temperature of soil level 3,land,,,, -stl4,tsl4,soil_temperature_level_4,Temperature of soil level 4,land,,,, -tsn,tsn,temperature_in_surface_snow,Snow internal temperature,landIce,,,, -u,ua,eastward_wind,U velocity,atmos,,,, -u10m,uas,eastward_wind,Eastward near-surface wind,atmos,,,, -vozocrtx,uo,sea_water_x_velocity,Sea water x velocity,ocean,,,, -v,va,northward_wind,V velocity,atmos,,,, -v10m,vas,northward_wind,Northward near-surface wind,atmos,,,, -vomecrty,vo,sea_water_y_velocity,Sea water y velocity,ocean,,,, -voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt vertical eddy diffusivity,ocean,,,, -vozoeivu,voeivu,sea_water_x_EIV_current,Zonal eiv current,ocean,,,, -vomeeivv,voeivv,sea_water_y_EIV_current,Meridional eiv current,ocean,,,, -voveeivw,voeivz,sea_water_z_EIV_current,Vertical eiv current,ocean,,,, -scvoltot,volo,sea_water_volume,Sea water volume ,ocean,,,, -votkeavm,votkeavm,vertical_eddy_viscosity,Vertical eddy viscosity,ocean,,,, -votkeavt,votkeavt,vertical_eddy_diffusivity,Vertical eddy diffusivity,ocean,,,, -votkeevd,votkeevd,enhanced_vertical_diffusivity,Enhanced vertical diffusivity,ocean,,,, -votkeevm,votkeevm,enhanced_vertical_viscosity,Enhanced vertical viscosity,ocean,,,, -sobarstf,vsftbarot,ocean_barotropic_volume_streamfunction,Ocean barotropic volume streamfunction ,ocean,,,, -zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Atl,,, -zomsfglo,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Glob,,, -zomsfind,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Ind,,, -zomsfipc:zomsfinp,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,IndPac,,, -zomsfpac,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Pac,,, -zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction_due_to_bolus_advection,Ocean meridional overturning volume streamfunction due to bolus advection ,ocean,,,, -w,wa,vertical_velocity,Vertical velocity,atmos,,,, -z,zg,geopotential_height,Geopotential height,atmos,,,, -vovecrtz,zo,sea_water_z_velocity,Sea water z velocity,ocean,,,, -sossheigh:sossheig:mean_sossheig,zos,sea_surface_height_above_geoid,Sea surface height above geoid ,ocean,,,, -scsshtot,zosga,global_average_sea_level_change,Global average sea level change ,ocean,,,, -scsshste,zossga,global_average_steric_sea_level_change,Global average steric sea level change ,ocean,,,, -zossq,zossq,square_of_sea_surface_height_above_geoid,Square of sea surface height above geoid ,ocean,,,, -scsshtst,zostoga,snthic,Global average thermosteric sea level change ,ocean,,,, -heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,J,, -ohcsum,ohcsum,total_ocean_heat_content,Total Ocean heat content,ocean,,J,, -ohcvmean,ohcvmean,average_ocean_heat_content,Average Ocean heat content,ocean,,J m-3,, -transix,transix,sea_ice_x_transport,X-Component of Sea Ice Mass Transport,seaIce,,kg s-1,, -transiy,transiy,sea_ice_y_transport,Y-Component of Sea Ice Mass Transport,seaIce,,kg s-1,, -windsp,sfcWind,wind_speed,Near-Surface Wind Speed,atmos,,,, -vsfsit,vsfsit,virtual_salt_flux_into_sea_water_due_to_sea_ice_thermodynamics,Virtual Salt Flux into Sea Water due to Sea Ice Thermodynamics ,ocean,,,, -sfdsi,sfdsi,downward_sea_ice_basal_salt_flux,Downward Sea Ice Basal Salt Flux,ocean,,,, -hfsithermds,hfsithermds,heat_flux_into_sea_water_due_to_sea_ice_thermodynamics,Heat Flux into Sea Water due to Sea Ice Thermodynamics ,ocean,,,, -u2o,uosq,square_of_sea_water_x_velocity,Square of Sea Water X Velocity ,ocean,,,, -v2o,vosq,square_of_sea_water_y_velocity,Square of Sea Water Y Velocity ,ocean,,,, -vozomatr,umo,ocean_mass_x_transport,Ocean Mass X Transport ,ocean,,,, -vomematr,vmo,ocean_mass_y_transport,Ocean Mass Y Transport ,ocean,,,, -sozohetr,hfx,ocean_heat_x_transport,Ocean Heat X Transport ,ocean,,,, -somehetr,hfy,ocean_heat_y_transport,Ocean Heat Y Transport ,ocean,,,, -uto,uothetao,product_of_xward_sea_water_velocity_and_temperature,Product of X-ward Sea Water Velocity and Temperature,ocean,,,, -vto,vothetao,product_of_yward_sea_water_velocity_and_temperature,Product of Y-ward Sea Water Velocity and Temperature,ocean,,,, -uso,uoso,product_of_xward_sea_water_velocity_and_salinity,Product of X-ward Sea Water Velocity and Salinity,ocean,,,, -vso,voso,product_of_yward_sea_water_velocity_and_salinity,Product of Y-ward Sea Water Velocity and Salinity,ocean,,,, -wfo,wfo,water_flux_into_sea_water,Water Flux into Sea Water ,ocean,,,, -emp_oce,evsmpr,evap_minus_precip_over_sea_water,Evap minus Precip over ocean,ocean,,,, -emp_ice,evsmpr,evap_minus_precip_over_sea_ice,Evap minus Precip over ice,seaIce,,,, -qsr_oce,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net Downward Shortwave Radiation at Sea Water Surface ,ocean,,,, -qns_oce,rlds,surface_net_downward_longwave_flux,Surface Net Downward Longwave Radiation,ocean,,,, -qsr_ice,rsdssi,surface_downwelling_shortwave_flux_in_air,Downwelling Shortwave over Sea Ice,seaIce,,,, -qns_ice,rldssi,surface_downwelling_longwave_flux_in_air,Downwelling Long Wave over Sea Ice,seaIce,,,, -sfx,sfx,downward_salt_flux,Downward Salt Flux,ocean,,,, -taum,taum,surface_downward_stress_module,Surface Downward Stress Module,ocean,,,, -zfull,zfull,depth_below_geoid,Depth Below Geoid of Ocean Layer,ocean,,,, -zhalf,zhalf,depth_below_geoid,Depth Below Geoid of Ocean Layer,ocean,,,, -pbo,pbo,sea_water_pressure_at_sea_floor,Sea Water Pressure at Sea Floor,ocean,,,, -thkcello,thkcello,cell_thickness,Cell Thickness,ocean,,,, -ficeberg,ficeberg,water_flux_into_sea_water_from_icebergs,Water Flux into Sea Water From Icebergs ,ocean,,,, -rsdo,rsds,downwelling_shortwave_flux_in_sea_water,Downwelling Shortwave Radiation in Sea Water ,ocean,,,, -wo,wo,sea_water_upward_velocity,Sea Water Upward Velocity ,ocean,,,, -w2o,wosq,square_of_sea_water_upward_velocity,Square of Sea Water Upward Velocity ,ocean,,,, -difvho,difvho,ocean_vertical_heat_diffusivity,Ocean Vertical Heat Diffusivity,ocean,,,, -vovematr,wmo,upward_ocean_mass_transport,Upward Ocean Mass Transport ,ocean,,,, -qtr_ice,qtr,shortwave_flux_transmitted_through_ice,Shortwave Flux Transmitted Through The Ice,seaIce,,,, +Variable,Shortname,Name,Long name,Domain,Basin,Units,Valid min,Valid max,Grid +iiceages:siage:iice_otd,ageice,age_of_sea_ice,Age of sea ice,seaIce,,,,, +al,al,surface_albedo,Albedo,atmos,,,,, +bgfrcsal,bgfrcsal,change_over_time_in_heat_content_from_forcing,Change over time in salt content from forcing,ocean,,,,, +bgfrctem,bgfrctem,change_over_time_in_heat_content_from_forcing,Change over time in heat content from forcing,ocean,,,,, +bgfrcvol,bgfrcvol,change_over_time_in_volume_from_forcing,Change over time in volume from forcing,ocean,,,,, +bgheatco,bgheatco,change_over_time_in_heat_content,Change over time in sea water heat content,ocean,,,,, +bgsaline,bgsaline,change_over_time_in_sea_water_practical_salinity,Change over time in sea water salinity,ocean,,,,, +bgsaltco,bgsaltco,change_over_time_in_salt_content,Change over time in sea water salt content,ocean,,,,, +bgtemper,bgtemper,change_over_time_in_sea_water_potential_temperature,Change over time in sea water potential temperature,ocean,,,,, +bgvole3t,bgvole3t,change_over_time_in_volume_variation,Change over time in volume variation (e3t),ocean,,,,, +bgvolssh,bgvolssh,change_over_time_in_sea_surface_height,Change over time in sea surface height,ocean,,,,, +bld,bld,boundary_layer_dissipation,Boundary layer dissipation,atmos,,,,, +iicebome:iocewflx,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of melt at sea ice base,seaIce,,,,, +sobowlin,bowlin,bowl_index,Bowl index,ocean,,,,, +cc,cl,cloud_area_fraction_in_atmosphere_layer,Cloud area fraction,atmos,,,,, +hcc,clh,high_cloud_area_fraction,High cloud fraction,atmos,,,,, +lcc,cll,low_cloud_area_fraction,Low cloud fraction,atmos,,,,, +mcc,clm,medium_cloud_area_fraction,Medium cloud fraction,atmos,,,,, +ciwc,cli,mass_fraction_of_cloud_ice_in_air,Mass fraction of cloud ice,atmos,,,,, +tcc,clt,cloud_area_fraction,Total cloud fraction,atmos,,,,, +clwc,clw,mass_fraction_of_cloud_liquid_water_in_air,Mass fraction of cloud liquid water,atmos,,,,, +tcw,clwvi,atmosphere_cloud_condensed_water_content,Condensed water path,atmos,,,,, +iicedive:sidive,divice,Strain Rate Divergence of Sea Ice,Divergence_of_sea_ice_velocity,seaIce,,,,, +e,evspsbl,water_evaporation_flux,Evaporation,atmos,,,,, +fal,fal,forecast_albedo,Forecast albedo,atmos,,,,, +sowaflep,fatmosocean,atmosphere_ocean_water_flux,Atmos=>ocean net freshwater,ocean,,,,, +sowaflcd,fdilution,dilution_water_flux,Concentration/dilution water flux,ocean,,,,, +sophtldf,fhbasindif,northward_ocean_heat_transport_due_to_diffusion,Northward ocean heat transport due to diffusion,ocean,,,,, +iowaflup,ficeocean,ice_ocean_water_flux,Ice=>ocean net freshwater,ocean,,,,, +sorunoff,friver,water_flux_into_sea_water_from_rivers,Water flux into sea water from rivers ,ocean,,,,, +sowaflup,fupward,upward_water_flux,Net upward water flux,ocean,,,,, +gwd,gwd,gravity_wave_dissipation,Gravity wave dissipation,atmos,,,,, +ibgheatco,hcicega,global mean ice heat content,Global mean ice heat content,seaIce,,,,, +sbgheatco,hcsnga,global mean snow heat content,Global mean snow heat content,seaIce,,,,, +heatc,heatc,integral_of_sea_water_potential_temperature_wrt_depth_expressed_as_heat_content,Heat content vertically integrated,ocean,,,,, +sohtatl,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Atl,,,, +sohtind,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Ind,,,, +sohtipc,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,IndPac,,,, +sohtpac,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Pac,,,, +sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward ocean heat transport due to advection ,ocean,,,,, +sophteiv,hfbasinba,northward_ocean_heat_transport_due_to_bolus_advection,Northward ocean heat transport due to bolus advection ,ocean,,,,, +qt_oce:sohefldo:qt,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,,, +slhf,hfls,surface_upward_latent_heat_flux,Surface upward latent heat flux,atmos,,,,, +sshf,hfss,surface_upward_sensible_heat_flux,Surface upward sensible heat flux,atmos,,,,, +sophtove,htovovrt,northward_ocean_heat_transport_due_to_overturning,Northward ocean heat transport due to overturning ,ocean,,,,, +q,hus,specific_humidity,Specific humidity,atmos,,,,, +soicealb,ialb,sea_ice_albedo,Sea ice albedo,seaIce,,,,, +ibgfrcsfx,ibgfrcsfx,global_mean_forcing_salt,Global mean forcing salt (sfx),seaIce,,,,, +ibgfrcvol,ibgfrcvol,globa_mean_forcing_volume,Global mean forcing volume (emp),seaIce,,,,, +ibghfxbog,ibghfxbog,heat_fluxes_causing_bottom_ice_growth,Heat fluxes causing bottom ice growth,seaIce,,,,, +ibghfxbom,ibghfxbom,heat_fluxes_causing_bottom_ice_melt,Heat fluxes causing bottom ice melt,seaIce,,,,, +ibghfxdhc,ibghfxdhc,Heat_content_variation_in_snow_and_ice,Heat content variation in snow and ice,seaIce,,,,, +ibghfxdif,ibghfxdif,heat_fluxes_causing_ice temperature_change,Heat fluxes causing ice temperature change,seaIce,,,,, +ibghfxdyn,ibghfxdyn,heat_fluxes_from_ice-ocean_exchange_during_dynamic,Heat fluxes from ice-ocean exchange during dynamic,seaIce,,,,, +ibghfxin,ibghfxin,total_heat_fluxes_at_the_ice_surface,Total heat fluxes at the ice surface,seaIce,,,,, +ibghfxopw,ibghfxopw,heat_fluxes_causing_open_water_ice_formation,Heat fluxes causing open water ice formation,seaIce,,,,, +ibghfxout,ibghfxout,non_solar_heat_fluxes_received_by_the_ocean,Non solar heat fluxes received by the ocean,seaIce,,,,, +ibghfxres,ibghfxres,heat_fluxes_from_ice-ocean_exchange_during_resultant,Heat fluxes from ice-ocean exchange during resultant,seaIce,,,,, +ibghfxsnw,ibghfxsnw,heat_fluxes_from_snow-ocean_exchange,Heat fluxes from snow-ocean exchange,seaIce,,,,, +ibghfxspr,ibghfxspr,Heat_content_of_snow_precip,Heat content of snow precip,seaIce,,,,, +ibghfxsub,ibghfxsub,heat_fluxes_from_sublimation,Heat fluxes from sublimation,seaIce,,,,, +ibghfxsum,ibghfxsum,heat_fluxes_causing_surface_ice_melt,Heat fluxes causing surface ice melt,seaIce,,,,, +ibghfxthd,ibghfxthd,heat_fluxes_from_ice-ocean_exchange_during_thermo,Heat fluxes from ice-ocean exchange during thermo,seaIce,,,,, +ibgsfxbog,ibgsfxbogga,salt_flux_thermo,Global mean salt flux (thermo),seaIce,,,,, +ibgsfxbom,ibgsfxbomga,salt_flux_bottom_melt,Global mean salt flux (bottom melt),seaIce,,,,, +ibgsfxbri,ibgsfxbriga,salt_flux_brines,Global mean salt flux (brines),seaIce,,,,, +ibgsfxdyn,ibgsfxdynga,salt_flux_dynamic,Global mean salt flux (dynamic),seaIce,,,,, +ibgsfx,ibgsfxga,salt_flux,Global mean salt flux (total),seaIce,,,,, +ibgsfxopw,ibgsfxopwga,salt_flux_open_waters,Global mean salt flux (open water),seaIce,,,,, +ibgsfxres,ibgsfxresga,salt_flux_resultant,Global mean salt flux (resultant),seaIce,,,,, +ibgsfxsni,ibgsfxsniga,salt_flux_snow_ice_growth,Global mean salt flux (snow-ice growth),seaIce,,,,, +ibgsfxsum,ibgsfxsumga,salt_flux_surface_melt,Global mean salt flux (surface melt),seaIce,,,,, +ibgvfxbog,ibgvfxbogga,volume_flux_bottom_growth,Global mean volume flux (bottom growth),seaIce,,,,, +ibgvfxbom,ibgvfxbomga,volume_flux_bottom_melt,Global mean volume flux (bottom melt),seaIce,,,,, +ibgvfxdyn,ibgvfxdynga,volume_flux_dynamic_growth,Global mean volume flux (dynamic growth),seaIce,,,,, +ibgvfx,ibgvfxga,volume_flux_emp,Global mean volume flux (emp),seaIce,,,,, +ibgvfxopw,ibgvfxopwga,volume_flux_open_water_growth,Global mean volume flux (open water growth),seaIce,,,,, +ibgvfxres,ibgvfxresga,volume_flux_resultant,Global mean volume flux (resultant),seaIce,,,,, +ibgvfxsni,ibgvfxsniga,volume_flux_snow_ice_growth,Global mean volume flux (snow-ice growth),seaIce,,,,, +ibgvfxsnw,ibgvfxsnwga,volume_flux_snow_melt,Global mean volume flux (snow melt),seaIce,,,,, +ibgvfxspr,ibgvfxsprga,snheco,Global mean volume flux (snow precip),seaIce,,,,, +ibgvfxsub,ibgvfxsubga,volume_flux_snow_sublimation,Global mean volume flux (snow sublimation),seaIce,,,,, +ibgvfxsum,ibgvfxsumga,volume_flux_surface_melt,Global mean volume flux (surface melt),seaIce,,,,, +ibgvolgrm,ibgvolgrm,global_mean_ice_growth+melt_volume,Global mean ice growth+melt volume,seaIce,,,,, +ibrinvol,ibrinvol,brine_volume,Brine volume,seaIce,,,,, +sibricat,ibrinvolcat,brine_volume_in_categories,Brine volume for categories,seaIce,,,,, +iicebopr,iicebopr,daily_bottom_thermo_ice_production,Daily bottom thermo ice production,seaIce,,,,, +iicecolf,iicecolf,frazil_ice_collection_thickness,Frazil ice collection thickness,seaIce,,,,, +iicedypr,iicedypr,daily_dynamic_ice_production,Daily dynamic ice production,seaIce,,,,, +iice_etd,iiceetd,brine_volume_distribution,Brine volume distribution,seaIce,,,,, +iicelapr,iicelapr,daily_lateral_thermo_ice_production,Daily lateral thermo ice prod.,seaIce,,,,, +iicenflx,iicenflx,nonsolar_flux_ice_ocean_surface,Non-solar flux at ice/ocean surface,seaIce,,,,, +iicesflx,iicesflx,solar_flux_ice_ocean_surface,Solar flux at ice/ocean surface,seaIce,,,,, +iiceshea,iiceshea,shear,Shear,seaIce,,,,, +iicesipr,iicesipr,daily_snowice_ice_production,Daily snowice ice production,seaIce,,,,, +iicfsbri,iicfsbri,brine_salt_flux,Fsbri - brine salt flux,seaIce,,,,, +iicfseqv,iicfseqv,equivalent_FW_salt_flux,Fseqv - equivalent fw salt flux,seaIce,,,,, +ioceflxb,ioceflxb,oceanic_flux_ar_ice_base,Oceanic flux at the ice base,seaIce,,,,, +iocehebr,iocehebr,heat_flux_due_to_brine_release,Heat flux due to brine release,seaIce,,,,, +iocesafl,iocesafl,salt_flux_ocean_surface,Salt flux at ocean surface,seaIce,,,,, +iocesflx,iocesflx,solar_fux_ocean_surface,Solar flux at ocean surface,seaIce,,,,, +iocetflx,iocetflx,total_flux_ocean_surface,Total flux at ocean surface,seaIce,,,,, +iocwnsfl,iocwnsfl,nonsolar_flux_ocean_surface,Non-solar flux at ocean surface,seaIce,,,,, +isstempe,isstempe,sea_surface_temperature,Sea surface temperature,seaIce,,K,,, +scmastot,masso,sea_water_mass,Sea water mass ,ocean,,,,, +mldkz5,mldkz5,ocean_mixed_layer_thickness_defined_by_vertical_tracer_diffusivity,Turbocline depth (kz = 5e-4),ocean,,,,, +somxl010:mldr10_1,mlotst,ocean_mixed_layer_thickness_defined_by_sigma_t,Ocean mixed layer thickness defined by sigma T ,ocean,,,,, +swvl1,mrlsl1,moisture_content_of_soil_layer_1, Water content of soil layer 1,land,,,,, +swvl2,mrlsl2,moisture_content_of_soil_layer_2, Water content of soil layer 2,land,,,,, +swvl3,mrlsl3,moisture_content_of_soil_layer_3, Water content of soil layer 3,land,,,,, +swvl4,mrlsl4,moisture_content_of_soil_layer_4, Water content of soil layer 4,land,,,,, +ro,mrro,runoff_flux,Total runoff,atmos,,,,, +tp:precip,pr,precipitation_flux,Precipitation,atmos,,,,, +cp,prc,convective_precipitation_flux,Convective precipitation,atmos,,,,, +lsp,prs,stratiform_precipitation_flux,Stratiform precipitation,atmos,,,,, +isnowpre,prsn,snowfall_flux,Surface snowfall rate into the sea ice portion of the grid cell,seaIce,,,,, +sf:snowpre,prsn,snowfall_flux,Snowfall flux,atmos,,,,, +tcwv,prw,atmosphere_water_vapor_content,Water vapor path,atmos,,,,, +msl,psl,air_pressure_at_sea_level,Sea level pressure,atmos,,,,, +qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,Non-solar heat flux at ice surface: sum over categories,seaIce,,,,, +qt_ice,qtice,surface_downward_heat_flux_in_air,Surface downward heat flux in air,seaIce,,,,, +strd,rlds,surface_downwelling_longwave_flux_in_air,Surface downwelling longwave radiation,atmos,,,,, +strc:str,rls,surface_longwave_flux_in_air,Surface longwave radiation,atmos,,,,, +ttr,rlut,toa_outgoing_longwave_flux,Toa outgoing longwave radiation,atmos,,,,, +ttrc,rlutcs,toa_outgoing_longwave_flux_assuming_clear_sky,"Top net thermal radiation, clear sky",atmos,,,,, +ssrd,rsds,surface_downwelling_shortwave_flux_in_air,Surface downwelling shortwave radiation,atmos,,,,, +tsr,rsdt,toa_incoming_shortwave_flux,Toa incident shortwave radiation,atmos,,,,, +soshfldo,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net downward shortwave radiation at sea water surface ,ocean,,,,, +ssr,rss,surface_shortwave_flux_in_air,Surface shortwave radiation,atmos,,,,, +ssrc,rsscs,surface_shortwave_flux_in_air_assuming_clear_sky,Surface clear-sky shortwave radiation,atmos,,,,, +tsrc,rsut,toa_outgoing_shortwave_flux,Toa outgoing shortwave radiation,atmos,,,,, +saltc,saltc,salt_content_vertically_integrated,Salt content vertically integrated,ocean,,,,, +es,sbl,surface_snow_and_ice_sublimation_flux,Surface snow and ice sublimation flux,landIce,,,,, +sosalflx,sfs,salt_flux_surface,Surface salt flux,ocean,,,,, +si,si,solar_insolation,Solar insolation,atmos,,,,, +NArea,siarean,sea_ice_area,Total area of sea ice in the northern hemisphere,seaIce,,10^6 km2,,, +SArea,siareas,sea_ice_area,Total area of sea ice in the southern hemisphere,seaIce,,10^6 km2,,, +iiceconc:siconc:soicecov:ileadfra:ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce,,%,,, +ci,sic,sea_ice_area_fraction,Sea Ice Area Fraction,seaIce,,%,,,ifs +iice_itd:siconc_cat:siconcat,siccat,ice_area_in_categories,Ice area in categories,seaIce,,,,, +ibgarea,sicga,sea_ice_content,Global mean sea ice content,seaIce,,,,, +NExnsidc,siextentn,sea_ice_extent,Total area of all northern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,,, +SExnsidc,siextents,sea_ice_extent,Total area of all southern-hemisphere grid cells that are covered by at least 15 % areal fraction of sea ice,seaIce,,10^6 km2,,, +iiceprod,sigr,ice_production,Ice production,seaIce,,,,, +iiceheco,siheco,integral_of_sea_ice_temperature_wrt_depth_expressed_as_heat_content,Sea ice heat content,seaIce,,,,, +ibgsaltco,sisaltcga,global mean ice salt content,Global mean ice salt content,seaIce,,,,, +iicethic:sithic,sit,sea_ice_thickness,Sea Ice Thickness,seaIce,,m,,, +iice_hid:sithic_cat:sithicat,sitcat,ice_thicknesss_in_categories,Ice thickness in categories,seaIce,,,,, +iicetemp,sitemp,ice_temperature,Mean ice temperature,seaIce,,K,,, +ibgtemper,sitempga,sea_ice_temperature,Global mean sea ice temperature,seaIce,,K,,, +iicevelo:sivelo,sivelo,ice_velocity,Ice velocity,seaIce,,,,, +iicevelu:sivelu,sivelu,ice_velocity_u,Ice velocity u,seaIce,,,,, +iicevelv:sivelv,sivelv,ice_velocity_v,Ice velocity v,seaIce,,,,, +ibgvoltot,sivolga,sea_ice_volume,Global mean sea ice volume,seaIce,,,,, +sivoln:NVolume,sivoln,sea_ice_volume,Total volume of sea ice in the northern hemisphere,seaIce,,10^3 km3,,, +sivols:SVolume,sivols,sea_ice_volume,Total volume of sea ice in the southern hemisphere,seaIce,,10^3 km3,,, +sivolu,sivolu,sea_ice_volume_per_unit_gridcell_area,Sea ice volume per gridcell area unit,seaIce,,,,, +sostatl,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,,, +sostind,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,,, +sostipc,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,,, +sostpac,sltbasin,northward_ocean_salt_transport,Northward ocean salt transport,ocean,,,,, +sopstadv,sltbasinadv,northward_ocean_salt_transport_due_to_advection,Northward ocean salt transport due to advection ,ocean,,,,, +sopsteiv,sltbasinba,northward_ocean_salt_transport_due_to_bolus_advection,Northward ocean salt transport due to bolus advection ,ocean,,,,, +sopstldf,sltbasindif,northward_ocean_salt_transport_due_to_diffusion,Northward ocean salt transport due to diffusion,ocean,,,,, +sltnortha,sltnortha,northward_ocean_salt_transport,Atlantic northward ocean salt transport,ocean,,,,, +sopstove,sltovovrt,northward_ocean_salt_transport_due_to_overturning,Northward ocean salt transport due to overturning ,ocean,,,,, +zosalatl,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Atl,psu,,, +zosalglo,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Glob,psu,,, +zosalind,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Ind,psu,,, +zosalipc,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,IndPac,psu,,, +zosalpac,sltzmean,zonal_mean_salinity,Zonal mean salinity,ocean,Pac,psu,,, +asn,snal,snow_albedo,Snow albedo,landIce,,,,, +iice_hsd:snthicat,sndcat,snow_thickness_in_categories,Snow thickness in in categories,seaIce,,,,, +isnoheco,snheco,snow_heat_content,Snow total heat content,seaIce,,,,, +sd,snld,lwe_thickness_of_surface_snow_amount,Snow depth,atmos,,,,, +smlt,snm,surface_snow_melt_flux,Surface snow melt,landIce,,,,, +isnowthi,snthic,surface_snow_thickness,Surface snow thickness,seaIce,,,,, +sbgvoltot,snvolga,snow_volume,Global mean snow volume,seaIce,,,,, +snvolu,snvolu,snow_volume_per_unit_gridcell_area,Snow volume per gridcell area unit,seaIce,,,,, +vosaline:mean_3Dsosaline,so,sea_water_salinity,Sea water salinity,ocean,,psu,,, +scsaltot,soga,sea_water_salinity,Global mean sea water salinity ,ocean,,psu,,, +hfnortha,sohtatl,northward_ocean_heat_transport,Atlantic northward ocean heat transport,ocean,,,,, +soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,Eddy induced vel. coeff. at w-point,ocean,,,,, +soleahtw,soleahtw,lateral_eddy_diffusivity,Lateral eddy diffusivity,ocean,,,,, +somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (turbocline),ocean,,,,, +sosaline:isssalin:mean_sosaline,sos,sea_surface_salinity,Sea surface salinity ,ocean,,psu,,, +sothedep,sothedep,thermocline_depth,Thermocline depth (max dt/dz),ocean,,,,, +src,src,skin_reservoir_content,Skin reservoir content,land,,,,, +zosrfatl,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Atl,,,, +zosrfglo,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Glob,,,, +zosrfind,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Ind,,,, +zosrfipc,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,IndPac,,,, +zosrfpac,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Pac,,,, +rsn,srho,snow_density,Snow density,landIce,,,,, +iicesali:iice_std,ssi,sea_ice_salinity,Sea ice salinity,seaIce,,psu,,, +salincat,ssicat,sea_ice_salinity_in_categories,Sea-ice bulk salinity for categories,seaIce,,psu,,, +ibgsaline,ssiga,sea_ice_salinity,Global mean sea ice salinity ,seaIce,,psu,,, +iicestre,streng,compressive_strength_of_sea_ice,Compressive sea ice strength,seaIce,,,,, +so20chgt,t20d,depth_of_isosurface_of_sea_water_potential_temperature,,ocean,,,,, +t,ta,air_temperature,Air temperature,atmos,,K,,, +t2m,tas,air_temperature,Near-surface air temperature,atmos,,K,,, +mx2t,tasmax,air_temperature,Daily maximum near-surface air temperature,atmos,,K,,, +mn2t,tasmin,air_temperature,Daily minimum near-surface air temperature,atmos,,K,,, +ewss,tauu,surface_downward_eastward_stress,Surface downward eastward wind stress,atmos,,,,, +utau_ice:iocestru:iicestru,strairx,surface_downward_x_stress,X-Component of Atmospheric Stress On Sea Ice,seaIce,,N m-2,,, +sozotaux,tauuo,surface_downward_x_stress,Surface downward x stress ,ocean,,,,, +nsss,tauv,surface_downward_northward_stress,Surface downward northward wind stress,atmos,,,,, +vtau_ice:iocestrv:iicestrv,strairy,surface_downward_y_stress,Y-Component of Atmospheric Stress On Sea Ice,seaIce,,N m-2,,, +sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface downward y stress ,ocean,,,,, +d2m,tdps,dew_point_temperature,2m dewpoint temperature,atmos,,K,,, +votemper:mean_3Dsosstsst,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,K,,, +sctemtot,thetaoga,sea_water_potential_temperature,Global average sea water potential temperature ,ocean,,K,,, +iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of melt at upper surface of sea ice,seaIce,,,,, +sosstsst:sstk:mean_sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,,, +tossq,tossq,square_of_sea_surface_temperature,Square of sea surface temperature ,ocean,,K2,,, +zotematl,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Atl,K,,, +zotemglo,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Glob,K,,, +zotemind,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Ind,K,,, +zotemipc,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,IndPac,K,,, +zotempac,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Pac,K,,, +skt,ts,surface_temperature,Surface temperature,atmos,,K,,, +iicesurt:soicetem:sistem,tsice,surface_temperature,Surface temperature of sea ice,seaIce,,K,,, +istl1,tsice,surface_temperature,Surface temperature of ice,landIce,,K,,, +stl1,tsl1,soil_temperature_level_1,Temperature of soil level 1,land,,,,, +stl2,tsl2,soil_temperature_level_2,Temperature of soil level 2,land,,,,, +stl3,tsl3,soil_temperature_level_3,Temperature of soil level 3,land,,,,, +stl4,tsl4,soil_temperature_level_4,Temperature of soil level 4,land,,,,, +tsn,tsn,temperature_in_surface_snow,Snow internal temperature,landIce,,,,, +u,ua,eastward_wind,U velocity,atmos,,,,, +u10m,uas,eastward_wind,Eastward near-surface wind,atmos,,,,, +vozocrtx,uo,sea_water_x_velocity,Sea water x velocity,ocean,,,,, +v,va,northward_wind,V velocity,atmos,,,,, +v10m,vas,northward_wind,Northward near-surface wind,atmos,,,,, +vomecrty,vo,sea_water_y_velocity,Sea water y velocity,ocean,,,,, +voddmavs,voddmavs,salt_vertical_eddy_diffusivity,Salt vertical eddy diffusivity,ocean,,,,, +vozoeivu,voeivu,sea_water_x_EIV_current,Zonal eiv current,ocean,,,,, +vomeeivv,voeivv,sea_water_y_EIV_current,Meridional eiv current,ocean,,,,, +voveeivw,voeivz,sea_water_z_EIV_current,Vertical eiv current,ocean,,,,, +scvoltot,volo,sea_water_volume,Sea water volume ,ocean,,,,, +votkeavm,votkeavm,vertical_eddy_viscosity,Vertical eddy viscosity,ocean,,,,, +votkeavt,votkeavt,vertical_eddy_diffusivity,Vertical eddy diffusivity,ocean,,,,, +votkeevd,votkeevd,enhanced_vertical_diffusivity,Enhanced vertical diffusivity,ocean,,,,, +votkeevm,votkeevm,enhanced_vertical_viscosity,Enhanced vertical viscosity,ocean,,,,, +sobarstf,vsftbarot,ocean_barotropic_volume_streamfunction,Ocean barotropic volume streamfunction ,ocean,,,,, +zomsfatl,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Atl,,,, +zomsfglo,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Glob,,,, +zomsfind,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Ind,,,, +zomsfipc:zomsfinp,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,IndPac,,,, +zomsfpac,vsftmyz,ocean_meridional_overturning_volume_streamfunction,Ocean meridional overturning volume streamfunction ,ocean,Pac,,,, +zomsfeiv,vsftmyzba,ocean_meridional_overturning_mass_streamfunction_due_to_bolus_advection,Ocean meridional overturning volume streamfunction due to bolus advection ,ocean,,,,, +w,wa,vertical_velocity,Vertical velocity,atmos,,,,, +z,zg,geopotential_height,Geopotential height,atmos,,,,, +vovecrtz,zo,sea_water_z_velocity,Sea water z velocity,ocean,,,,, +sossheigh:sossheig:mean_sossheig,zos,sea_surface_height_above_geoid,Sea surface height above geoid ,ocean,,,,, +scsshtot,zosga,global_average_sea_level_change,Global average sea level change ,ocean,,,,, +scsshste,zossga,global_average_steric_sea_level_change,Global average steric sea level change ,ocean,,,,, +zossq,zossq,square_of_sea_surface_height_above_geoid,Square of sea surface height above geoid ,ocean,,,,, +scsshtst,zostoga,snthic,Global average thermosteric sea level change ,ocean,,,,, +heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,J,,, +ohcsum,ohcsum,total_ocean_heat_content,Total Ocean heat content,ocean,,J,,, +ohcvmean,ohcvmean,average_ocean_heat_content,Average Ocean heat content,ocean,,J m-3,,, +transix,transix,sea_ice_x_transport,X-Component of Sea Ice Mass Transport,seaIce,,kg s-1,,, +transiy,transiy,sea_ice_y_transport,Y-Component of Sea Ice Mass Transport,seaIce,,kg s-1,,, +windsp,sfcWind,wind_speed,Near-Surface Wind Speed,atmos,,,,, +vsfsit,vsfsit,virtual_salt_flux_into_sea_water_due_to_sea_ice_thermodynamics,Virtual Salt Flux into Sea Water due to Sea Ice Thermodynamics ,ocean,,,,, +sfdsi,sfdsi,downward_sea_ice_basal_salt_flux,Downward Sea Ice Basal Salt Flux,ocean,,,,, +hfsithermds,hfsithermds,heat_flux_into_sea_water_due_to_sea_ice_thermodynamics,Heat Flux into Sea Water due to Sea Ice Thermodynamics ,ocean,,,,, +u2o,uosq,square_of_sea_water_x_velocity,Square of Sea Water X Velocity ,ocean,,,,, +v2o,vosq,square_of_sea_water_y_velocity,Square of Sea Water Y Velocity ,ocean,,,,, +vozomatr,umo,ocean_mass_x_transport,Ocean Mass X Transport ,ocean,,,,, +vomematr,vmo,ocean_mass_y_transport,Ocean Mass Y Transport ,ocean,,,,, +sozohetr,hfx,ocean_heat_x_transport,Ocean Heat X Transport ,ocean,,,,, +somehetr,hfy,ocean_heat_y_transport,Ocean Heat Y Transport ,ocean,,,,, +uto,uothetao,product_of_xward_sea_water_velocity_and_temperature,Product of X-ward Sea Water Velocity and Temperature,ocean,,,,, +vto,vothetao,product_of_yward_sea_water_velocity_and_temperature,Product of Y-ward Sea Water Velocity and Temperature,ocean,,,,, +uso,uoso,product_of_xward_sea_water_velocity_and_salinity,Product of X-ward Sea Water Velocity and Salinity,ocean,,,,, +vso,voso,product_of_yward_sea_water_velocity_and_salinity,Product of Y-ward Sea Water Velocity and Salinity,ocean,,,,, +wfo,wfo,water_flux_into_sea_water,Water Flux into Sea Water ,ocean,,,,, +emp_oce,evsmpr,evap_minus_precip_over_sea_water,Evap minus Precip over ocean,ocean,,,,, +emp_ice,evsmpr,evap_minus_precip_over_sea_ice,Evap minus Precip over ice,seaIce,,,,, +qsr_oce,rsntds,net_downward_shortwave_flux_at_sea_water_surface,Net Downward Shortwave Radiation at Sea Water Surface ,ocean,,,,, +qns_oce,rlds,surface_net_downward_longwave_flux,Surface Net Downward Longwave Radiation,ocean,,,,, +qsr_ice,rsdssi,surface_downwelling_shortwave_flux_in_air,Downwelling Shortwave over Sea Ice,seaIce,,,,, +qns_ice,rldssi,surface_downwelling_longwave_flux_in_air,Downwelling Long Wave over Sea Ice,seaIce,,,,, +sfx,sfx,downward_salt_flux,Downward Salt Flux,ocean,,,,, +taum,taum,surface_downward_stress_module,Surface Downward Stress Module,ocean,,,,, +zfull,zfull,depth_below_geoid,Depth Below Geoid of Ocean Layer,ocean,,,,, +zhalf,zhalf,depth_below_geoid,Depth Below Geoid of Ocean Layer,ocean,,,,, +pbo,pbo,sea_water_pressure_at_sea_floor,Sea Water Pressure at Sea Floor,ocean,,,,, +thkcello,thkcello,cell_thickness,Cell Thickness,ocean,,,,, +ficeberg,ficeberg,water_flux_into_sea_water_from_icebergs,Water Flux into Sea Water From Icebergs ,ocean,,,,, +rsdo,rsds,downwelling_shortwave_flux_in_sea_water,Downwelling Shortwave Radiation in Sea Water ,ocean,,,,, +wo,wo,sea_water_upward_velocity,Sea Water Upward Velocity ,ocean,,,,, +w2o,wosq,square_of_sea_water_upward_velocity,Square of Sea Water Upward Velocity ,ocean,,,,, +difvho,difvho,ocean_vertical_heat_diffusivity,Ocean Vertical Heat Diffusivity,ocean,,,,, +vovematr,wmo,upward_ocean_mass_transport,Upward Ocean Mass Transport ,ocean,,,,, +qtr_ice,qtr,shortwave_flux_transmitted_through_ice,Shortwave Flux Transmitted Through The Ice,seaIce,,,,, diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 103f406..03c34d3 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -315,7 +315,7 @@ class Cmorizer(object): self.data_manager.send_file(temp, var_cmor.domain, var_cmor.short_name, self.startdate, self.member, frequency=frequency, rename_var=variable, date_str=date_str, region=region, - move_old=True) + move_old=True, grid=var_cmor.grid) @staticmethod def _merge_grib_files(current_month, prev_gribfile, gribfile): diff --git a/earthdiagnostics/variable.py b/earthdiagnostics/variable.py index 6b7b8f5..0956355 100644 --- a/earthdiagnostics/variable.py +++ b/earthdiagnostics/variable.py @@ -22,6 +22,7 @@ class Variable(object): self.units = line[6].strip() self.valid_min = line[7].strip() self.valid_max = line[8].strip() + self.grid = line[9].strip() @classmethod def get_variable(cls, original_name, silent=False): -- GitLab From 77c4b4c081ad16a4c7c6137f70ea98687770e5f9 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 4 Oct 2016 15:51:35 +0200 Subject: [PATCH 232/268] Added link creation when unpacking CMOR files --- diags.conf | 24 ++++++++++++------------ earthdiagnostics/datamanager.py | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/diags.conf b/diags.conf index da06762..48355a3 100644 --- a/diags.conf +++ b/diags.conf @@ -22,13 +22,13 @@ RESTORE_MESHES = False [CMOR] # If true, recreates CMOR files regardless of presence. Default = False -FORCE = False +FORCE = True # If true, CMORizes ocean files. Default = True OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True -ATMOSPHERE_FILES = False +ATMOSPHERE_FILES = True # You can specify the variable to cmorize, in the way domain:var domain:var2 domain2:var -VARIABLE_LIST = ocean:thetao +VARIABLE_LIST = # Variables to be CMORized from the grib atmospheric files, separated by comma. # You can also specify the levels to extract using the following syntax @@ -60,11 +60,11 @@ ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, INSTITUTE = BSC MODEL = EC-EARTH # Model version: Available versions -MODEL_VERSION =Ec3.1_O25L75 +MODEL_VERSION =Ec2.3_O1L46 # Atmospheric output timestep in hours -ATMOS_TIMESTEP = 6 +ATMOS_TIMESTEP = 3 # Ocean output timestep in hours -OCEAN_TIMESTEP = 6 +OCEAN_TIMESTEP = 3 # For those who use Autosubmit, this will be easy # EXPID is the unique identifier of the experiment. @@ -74,12 +74,12 @@ OCEAN_TIMESTEP = 6 # if 2, fc00 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment -EXPID = m04v -STARTDATES = 19600101 -MEMBERS = 0 +EXPID = i03i +STARTDATES = 19611101 19641101 19811101 19841101 19911101 19621101 19651101 19821101 19891101 19921101 19631101 19801101 19831101 19901101 19931101 +MEMBERS = 0 1 2 3 4 MEMBER_DIGITS = 1 -CHUNK_SIZE = 12 -CHUNKS = 40 +CHUNK_SIZE = 4 +CHUNKS = 15 # CHUNKS = 1 @@ -96,7 +96,7 @@ HEAT_SAL_MXL = mlotstsc mlotsthc LMSALC = vertmeanmeters,so,300,5400 USALC = vertmeanmeters,so,0,300 OHC = ohc,glob,0,1,10 -XOHC = ohc,glob,1,0,0 +XOHC = ohc,glob,1,0,0< LOHC = ohc,glob,0,23,46 MOHC = ohc,glob,0,18,22 UOHC = ohc,glob,0,1,17 diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 2be6549..50aa2d2 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -569,6 +569,7 @@ class CMORManager(DataManager): Log.info('Unpacking cmorized data...') Utils.untar(filepaths, self.cmor_path) self._correct_paths(startdate) + self._create_links(startdate) continue else: start_time = datetime.now() @@ -583,12 +584,15 @@ class CMORManager(DataManager): def _correct_paths(self, startdate): bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) if os.path.exists(bad_path): + Log.debug('Moving CMOR files out of the output folder') Utils.execute_shell_command(['mv', bad_path, os.path.join(bad_path, '..', '..')]) os.rmdir(os.path.join(self.cmor_path, 'output')) + Log.debug('Done') if self.experiment.experiment_name != self.experiment.model: bad_path = os.path.join(self.cmor_path, self.experiment.institute, self.experiment.model, self.experiment.model) + Log.debug('Correcting double experiment model appearance') for (dirpath, dirnames, filenames) in os.walk(bad_path, False): for filename in filenames: @@ -604,6 +608,23 @@ class CMORManager(DataManager): Utils.move_file(filepath, good) os.rmdir(dirpath) + Log.debug('Done') + + def _create_links(self, startdate): + Log.info('Creating links for CMOR files ()') + path = self._get_startdate_path(startdate) + for freq in os.listdir(path): + for domain in os.listdir(os.path.join(path, freq)): + for var in os.listdir(os.path.join(path, freq, domain)): + for member in os.listdir(os.path.join(path, freq, domain, var)): + for name in os.listdir(os.path.join(path, freq, domain, var, member)): + filepath = os.path.join(path, freq, domain, var, member, name) + if os.path.isfile(filepath): + self._create_link(domain, filepath, freq, var, "", False) + else: + for filename in os.listdir(filepath): + self._create_link(domain, os.path.join(filepath, filename), freq, var, "", False) + Log.info('Creating lings for CMOR files') def _get_startdate_path(self, startdate): """ -- GitLab From 0375a4d5c0496744b4467042dc57331326886515 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 4 Oct 2016 16:02:21 +0200 Subject: [PATCH 233/268] Fixed bug on previous commit for 6hourly data --- earthdiagnostics/datamanager.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 50aa2d2..6e7a4f1 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -278,6 +278,8 @@ class DataManager(object): def _create_link(self, domain, filepath, frequency, var, grid, move_old): if frequency in ('d', 'daily', 'day'): freq_str = 'daily_mean' + elif frequency.endswith('hr'): + freq_str = frequency[:-2] + 'hourly' else: freq_str = 'monthly_mean' @@ -592,7 +594,7 @@ class CMORManager(DataManager): if self.experiment.experiment_name != self.experiment.model: bad_path = os.path.join(self.cmor_path, self.experiment.institute, self.experiment.model, self.experiment.model) - Log.debug('Correcting double experiment model appearance') + Log.debug('Correcting double model appearance') for (dirpath, dirnames, filenames) in os.walk(bad_path, False): for filename in filenames: -- GitLab From 845db63d9eef6b149f5219342f3b3eedc9fd23a9 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 4 Oct 2016 16:03:36 +0200 Subject: [PATCH 234/268] Bumped version and updated doc --- VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/EarthDiagnostics.pdf | Bin 240950 -> 239448 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 787863d..ee5d689 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b12 +3.0.0b13 diff --git a/doc/source/conf.py b/doc/source/conf.py index fc8ba2c..5bfeca2 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b12' +release = '3.0.0b13' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index 97d0151ed14e16c5686cf2bdfca127d5aa36e942..17bd255bb6896777abaf6905e11b0d00f20e479a 100644 GIT binary patch delta 113559 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

    I{f#4b|i&r(u$LZcP%lo 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

    $NMfZmEGvHZL>r#qSz&stH;5oYx2C9arH?s(q!! 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

    8lkE)8h?@wxHAJ2C)kK5SvG+KO&6(rKk_E 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 -- GitLab From cfc2d8d31abe6501eeca260fd8f5ef510ed2c1aa Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 14 Oct 2016 11:14:16 +0200 Subject: [PATCH 250/268] Multiple refactorings to improve code readability --- earthdiagnostics/cmorizer.py | 2 +- earthdiagnostics/cmormanager.py | 188 +++++++++++++---------- earthdiagnostics/datamanager.py | 6 +- earthdiagnostics/ocean/interpolatecdo.py | 2 +- earthdiagnostics/utils.py | 50 ++++-- test/unit/test_utils.py | 6 +- 6 files changed, 148 insertions(+), 106 deletions(-) diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 57169c9..99d5a20 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -233,7 +233,7 @@ class Cmorizer(object): os.remove(filename) return - Utils.convert2netcdf4(filename, True) + Utils.convert2netcdf4(filename) frequency = self._get_nc_file_frequency(filename) self._rename_coordinate_variables(filename) handler = Utils.openCdf(filename) diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index 6fc1eca..789fe9f 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -35,7 +35,7 @@ class CMORManager(DataManager): :param grid: file's grid :type grid: str :param year: file's year - :type year: int + :type year: int | str :param date_str: date string to add directly. Overrides year or chunk configurations :type date_str: str :return: path to the file @@ -44,19 +44,17 @@ class CMORManager(DataManager): if not frequency: frequency = self.config.frequency var = self._get_final_var_name(box, var) - domain_abreviattion = self.get_domain_abbreviation(domain, frequency) - start = parse_date(startdate) - member_plus = str(member + 1) - member_path = os.path.join(self._get_startdate_path(startdate), frequency, domain) - if chunk is not None: - chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') + folder_path = self._get_full_cmor_folder_path(startdate, member, domain, var, frequency, grid) + file_name = self._get_cmor_file_name(startdate, member, domain, var, frequency, chunk, year, date_str) - time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, - chunk_end.month) + filepath = os.path.join(folder_path, file_name) + return filepath + def _get_cmor_file_name(self, startdate, member, domain, var, frequency, chunk, year, date_str): + domain_abreviattion = self.get_domain_abbreviation(domain, frequency) + if chunk is not None: + time_bound = self._get_chunk_time_bounds(startdate, chunk) elif year: if frequency is not 'yr': raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') @@ -65,15 +63,27 @@ class CMORManager(DataManager): time_bound = date_str else: raise ValueError('Chunk, year and date_str can not be None at the same time') + file_name = '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_{6}.nc'.format(var, domain_abreviattion, self.experiment.model, + self.experiment.experiment_name, startdate, + member + 1, + time_bound) + return file_name + + def _get_full_cmor_folder_path(self, startdate, member, domain, var, frequency, grid): + folder_path = os.path.join(self._get_startdate_path(startdate), frequency, domain, var) if grid: - var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) - else: - var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) - filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' - '{6}.nc'.format(var, domain_abreviattion, self.experiment.model, - self.experiment.experiment_name, - startdate, member_plus, time_bound)) - return filepath + folder_path = os.path.join(folder_path, grid) + folder_path = os.path.join(folder_path, 'r{0}i1p1'.format(member + 1)) + return folder_path + + def _get_chunk_time_bounds(self, startdate, chunk): + start = parse_date(startdate) + chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, + chunk_end.month) + return time_bound def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, frequency=None, year=None, date_str=None, move_old=False): @@ -136,12 +146,13 @@ class CMORManager(DataManager): chunk_files.append(self.get_file(domain, var, startdate, member, chunk, grid=grid, box=box)) if len(chunk_files) > 1: - temp = TempFile.get() - Utils.nco.ncrcat(input=' '.join(chunk_files), output=temp) - for chunk_file in chunk_files: - os.remove(chunk_file) + temp = self._merge_chunk_files(chunk_files) else: temp = chunk_files[0] + temp2 = self._remove_out_of_year_data(temp, year) + return temp2 + + def _remove_out_of_year_data(self, temp, year): temp2 = TempFile.get() handler = Utils.openCdf(temp) time = Utils.get_datetime_from_netcdf(handler) @@ -155,24 +166,16 @@ class CMORManager(DataManager): start = x elif date.month == 12: end = x - Utils.nco.ncks(input=temp, output=temp2, options='-O -d time,{0},{1}'.format(start, end)) os.remove(temp) return temp2 - def _is_cmorized(self, startdate, member): - startdate_path = self._get_startdate_path(startdate) - if not os.path.exists(startdate_path): - return False - for freq in os.listdir(startdate_path): - freq_path = os.path.join(startdate_path, freq) - for domain in os.listdir(freq_path): - domain_path = os.path.join(freq_path, domain) - for var in os.listdir(domain_path): - member_path = os.path.join(domain_path, var, 'r{0}i1p1'.format(member + 1)) - if os.path.exists(member_path): - return True - return False + def _merge_chunk_files(self, chunk_files): + temp = TempFile.get() + Utils.nco.ncrcat(input=' '.join(chunk_files), output=temp) + for chunk_file in chunk_files: + os.remove(chunk_file) + return temp # noinspection PyPep8Naming def prepare_CMOR_files(self): @@ -189,55 +192,70 @@ class CMORManager(DataManager): # Check if cmorized and convert if not for startdate, member in self.experiment.get_member_list(): - if self._is_cmorized(startdate, member) and not self.config.cmor.force: continue - member_str = self.experiment.get_member_str(member) - if not self.config.cmor.force: - tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') - tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, - 'cmorfiles') - file_name = 'CMOR?_{0}_{1}_*.tar.gz'.format(self.experiment.expid, startdate, member_str) - filepaths = glob.glob(os.path.join(tar_path, file_name)) - filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) - if len(filepaths) > 0: - Log.info('Unzipping cmorized data...') - Utils.unzip(filepaths, True) - - if not os.path.exists(self.cmor_path): - os.mkdir(self.cmor_path) - - file_name = 'CMOR?_{0}_{1}_*.tar'.format(self.experiment.expid, startdate, member_str) - filepaths = glob.glob(os.path.join(tar_path, file_name)) - filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) - if len(filepaths) > 0: - Log.info('Unpacking cmorized data...') - Utils.untar(filepaths, self.cmor_path) - self._correct_paths(startdate) - self._create_links(startdate) - continue - - start_time = datetime.now() - Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) - - cmorizer = Cmorizer(self, startdate, member) - cmorizer.cmorize_ocean() - cmorizer.cmorize_atmos() - Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, - datetime.now() - start_time) + if not self._unpack_cmor_files(startdate, member): + self._cmorize_member(member, startdate) + + def _is_cmorized(self, startdate, member): + startdate_path = self._get_startdate_path(startdate) + if not os.path.exists(startdate_path): + return False + for freq in os.listdir(startdate_path): + freq_path = os.path.join(startdate_path, freq) + for domain in os.listdir(freq_path): + domain_path = os.path.join(freq_path, domain) + for var in os.listdir(domain_path): + member_path = os.path.join(domain_path, var, 'r{0}i1p1'.format(member + 1)) + if os.path.exists(member_path): + return True + return False + + def _cmorize_member(self, member, startdate): + start_time = datetime.now() + member_str = self.experiment.get_member_str(member) + Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) + cmorizer = Cmorizer(self, startdate, member) + cmorizer.cmorize_ocean() + cmorizer.cmorize_atmos() + Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, datetime.now() - start_time) + + def _unpack_cmor_files(self, member, startdate): + if self.config.cmor.force: + return False + filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar.gz') + if len(filepaths) > 0: + Log.info('Unzipping cmorized data...') + Utils.unzip(filepaths, True) + + if not os.path.exists(self.cmor_path): + os.mkdir(self.cmor_path) + + filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar') + if len(filepaths) > 0: + Log.info('Unpacking cmorized data...') + Utils.untar(filepaths, self.cmor_path) + self._correct_paths(startdate) + self._create_links(startdate) + return True + return False + + def _get_transferred_cmor_data_filepaths(self, startdate, member, extension): + tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') + tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, + 'cmorfiles') + file_name = 'CMOR?_{0}_{1}_*.{2}'.format(self.experiment.expid, startdate, extension) + filepaths = glob.glob(os.path.join(tar_path, file_name)) + filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) + return filepaths def _correct_paths(self, startdate): - bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) - if os.path.exists(bad_path): - Log.debug('Moving CMOR files out of the output folder') - Utils.execute_shell_command(['mv', bad_path, os.path.join(bad_path, '..', '..')]) - os.rmdir(os.path.join(self.cmor_path, 'output')) - Log.debug('Done') + self._remove_extra_output_folder() + self._fix_model_as_experiment_error(startdate) + def _fix_model_as_experiment_error(self, startdate): if self.experiment.experiment_name != self.experiment.model: bad_path = os.path.join(self.cmor_path, self.experiment.institute, self.experiment.model, self.experiment.model) @@ -259,6 +277,14 @@ class CMORManager(DataManager): os.rmdir(dirpath) Log.debug('Done') + def _remove_extra_output_folder(self): + bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) + if os.path.exists(bad_path): + Log.debug('Moving CMOR files out of the output folder') + Utils.execute_shell_command(['mv', bad_path, os.path.join(bad_path, '..', '..')]) + os.rmdir(os.path.join(self.cmor_path, 'output')) + Log.debug('Done') + def _create_links(self, startdate): Log.info('Creating links for CMOR files ()') path = self._get_startdate_path(startdate) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 06a0f40..004f391 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -108,12 +108,13 @@ class DataManager(object): if not frequency: frequency = self.config.frequency domain = DataManager.correct_domain(domain) - filepath = self.get_file_path(startdate, member, domain, cmor_var.short_name, chunk, frequency, box, + filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, grid, year, date_str) + Utils.convert2netcdf4(filetosend) if region: self._prepare_region(filepath, filetosend, region, var) - Utils.convert2netcdf4(filetosend, True) + if cmor_var: self._correct_metadata(cmor_var, domain, filetosend, frequency, var) self._rename_coordinate_variables(filetosend) @@ -208,7 +209,6 @@ class DataManager(object): @staticmethod def _prepare_region(filepath, filetosend, region, var): - Utils.convert2netcdf4(filetosend) if not os.path.exists(filepath): handler = Utils.openCdf(filetosend) diff --git a/earthdiagnostics/ocean/interpolatecdo.py b/earthdiagnostics/ocean/interpolatecdo.py index 58942ce..70f7baa 100644 --- a/earthdiagnostics/ocean/interpolatecdo.py +++ b/earthdiagnostics/ocean/interpolatecdo.py @@ -30,7 +30,7 @@ class InterpolateCDO(Diagnostic): :type model_version: str """ - alias = 'interpCDO' + alias = 'interpcdo' "Diagnostic alias for the configuration file" def __init__(self, data_manager, startdate, member, chunk, domain, variable, target_grid, model_version): diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 0c79647..91e4fef 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -233,12 +233,12 @@ class Utils(object): process = subprocess.Popen(command, stdout=subprocess.PIPE) output = list() comunicate = process.communicate() - if log_level != Log.NO_LOG: - for line in comunicate: - if not line: - continue + for line in comunicate: + if not line: + continue + if log_level != Log.NO_LOG: Log.log.log(log_level, line) - output.append(line) + output.append(line) if process.returncode != 0: raise Utils.ExecutionError('Error executing {0}\n Return code: {1}', ' '.join(command), process.returncode) return output @@ -268,28 +268,44 @@ class Utils(object): return Utils._cpu_count @staticmethod - def convert2netcdf4(filetoconvert, force=True): + def convert2netcdf4(filetoconvert): """ Checks if a file is in netCDF4 format and converts to netCDF4 if not - :param force: if true, converts the file regardless of original encoding. Useful to make sure that a file has - deflation and shuffle activated - :type force: bool :param filetoconvert: file to convert :type filetoconvert: str """ - if not force: - handler = Utils.openCdf(filetoconvert) - if handler.file_format == 'NETCDF4': - handler.close() - return - handler.close() + + if Utils._is_compressed_netcdf4(filetoconvert): + return + Log.debug('Reformatting to netCDF-4') temp = TempFile.get() Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetoconvert, temp]) shutil.move(temp, filetoconvert) - # noinspection PyPep8Naming + @classmethod + def _is_compressed_netcdf4(cls, filetoconvert): + is_compressed = True + handler = Utils.openCdf(filetoconvert) + if not handler.file_format == 'NETCDF4': + is_compressed = False + else: + ncdump_result = Utils.execute_shell_command('ncdump -hs {0}'.format(filetoconvert), Log.NO_LOG) + ncdump_result = ncdump_result[0].replace('\t', '').split('\n') + for var in handler.variables: + if not '{0}:_DeflateLevel = 4 ;'.format(var) in ncdump_result: + is_compressed = False + break + if not '{0}:_Shuffle = "true" ;'.format(var) in ncdump_result: + is_compressed = False + break + + handler.close() + return is_compressed + + +# noinspection PyPep8Naming @staticmethod def openCdf(filepath, mode='a'): """ @@ -443,7 +459,7 @@ class Utils(object): Utils.move_file(source, destiny) else: shutil.copy(source, destiny) - Utils.convert2netcdf4(destiny, True) + Utils.convert2netcdf4(destiny) @staticmethod def expand_path(path): diff --git a/test/unit/test_utils.py b/test/unit/test_utils.py index 0810ede..6030011 100644 --- a/test/unit/test_utils.py +++ b/test/unit/test_utils.py @@ -97,14 +97,14 @@ class TestUtils(TestCase): tempfile_mock.return_value = 'tempfile' opencdf_mock.return_value = mock_handler mock_handler.file_format = 'NETCDF4' - Utils.convert2netcdf4('file', False) + Utils.convert2netcdf4('file') mock_handler.file_format = 'OTHER' - Utils.convert2netcdf4('file2', False) + Utils.convert2netcdf4('file2') execute_mock.assert_called_with(['nccopy', '-4', '-d4', '-s', 'file2', 'tempfile']) mock_handler.file_format = 'NETCDF4' - Utils.convert2netcdf4('file3', True) + Utils.convert2netcdf4('file3') execute_mock.assert_called_with(['nccopy', '-4', '-d4', '-s', 'file3', 'tempfile']) self.assertEqual(execute_mock.call_count, 2) -- GitLab From 6bf032b90f8e06faf7cb600549f04e08722222e9 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 17 Oct 2016 11:04:13 +0200 Subject: [PATCH 251/268] More refactorings --- earthdiagnostics/cmormanager.py | 3 +- earthdiagnostics/datamanager.py | 331 +++++++++++++++++--------------- earthdiagnostics/variable.py | 24 +++ 3 files changed, 199 insertions(+), 159 deletions(-) diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index 789fe9f..85d0591 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -8,6 +8,7 @@ from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_e from earthdiagnostics.cmorizer import Cmorizer from earthdiagnostics.datamanager import DataManager from earthdiagnostics.utils import TempFile, Utils +from earthdiagnostics.variable import Variable class CMORManager(DataManager): @@ -52,7 +53,7 @@ class CMORManager(DataManager): return filepath def _get_cmor_file_name(self, startdate, member, domain, var, frequency, chunk, year, date_str): - domain_abreviattion = self.get_domain_abbreviation(domain, frequency) + domain_abreviattion = Variable.get_table_name(domain, frequency) if chunk is not None: time_bound = self._get_chunk_time_bounds(startdate, chunk) elif year: diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 004f391..6fbc754 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -107,147 +107,16 @@ class DataManager(object): if not frequency: frequency = self.config.frequency + domain = DataManager.correct_domain(domain) filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, grid, year, date_str) + netcdf_file = NetCDFFile(filepath, filetosend, domain, var, cmor_var) + netcdf_file.send() - Utils.convert2netcdf4(filetosend) - if region: - self._prepare_region(filepath, filetosend, region, var) - - if cmor_var: - self._correct_metadata(cmor_var, domain, filetosend, frequency, var) - self._rename_coordinate_variables(filetosend) - - Utils.move_file(filetosend, filepath) self._create_link(domain, filepath, frequency, var, grid, move_old) - def _rename_coordinate_variables(self, filetosend): - variables = dict() - variables['x'] = 'i' - variables['y'] = 'j' - variables['nav_lat_grid_V'] = 'lat' - variables['nav_lon_grid_V'] = 'lon' - variables['nav_lat_grid_U'] = 'lat' - variables['nav_lon_grid_U'] = 'lon' - variables['nav_lat_grid_T'] = 'lat' - variables['nav_lon_grid_T'] = 'lon' - Utils.rename_variables(filetosend, variables, False, True) - - def _correct_metadata(self, cmor_var, domain, filetosend, frequency, var): - handler = Utils.openCdf(filetosend) - var_handler = handler.variables[var] - var_handler.standard_name = cmor_var.standard_name - var_handler.long_name = cmor_var.long_name - var_handler.short_name = cmor_var.short_name - var_type = var_handler.dtype - handler.modeling_realm = cmor_var.domain - handler.table_id = 'Table {0} (December 2013)'.format(self.get_domain_abbreviation(cmor_var.domain, - frequency)) - if cmor_var.units: - self._fix_units(cmor_var, var_handler) - handler.sync() - self._fix_coordinate_variables_metadata(domain, handler) - handler.close() - self._fix_values_metadata(cmor_var, filetosend, var, var_type) - - def _fix_values_metadata(self, cmor_var, filetosend, var, var_type): - if cmor_var.valid_min != '': - valid_min = '-a valid_min, {0}, o, {1}, "{2}" '.format(var, var_type.char, cmor_var.valid_min) - else: - valid_min = '' - if cmor_var.valid_max != '': - valid_max = '-a valid_max, {0}, o, {1}, "{2}" '.format(var, var_type.char, cmor_var.valid_max) - else: - valid_max = '' - Utils.nco.ncatted(input=filetosend, output=filetosend, - options='-O -a _FillValue,{0},o,{1},"1.e20" ' - '-a missingValue,{0},o,{1},"1.e20" {2}{3}'.format(var, var_type.char, - valid_min, valid_max)) - - def _fix_coordinate_variables_metadata(self, domain, handler): - if 'lev' in handler.variables: - handler.variables['lev'].short_name = 'lev' - if domain == 'ocean': - handler.variables['lev'].standard_name = 'depth' - if 'lon' in handler.variables: - handler.variables['lon'].short_name = 'lon' - handler.variables['lon'].standard_name = 'longitude' - if 'lat' in handler.variables: - handler.variables['lat'].short_name = 'lat' - handler.variables['lat'].standard_name = 'latitude' - @staticmethod - def _fix_units(cmor_var, var_handler): - if 'units' in var_handler.ncattrs(): - if var_handler.units == 'PSU': - var_handler.units = 'psu' - if var_handler.units == 'C' and cmor_var.units == 'K': - var_handler.units = 'deg_C' - if cmor_var.units != var_handler.units: - try: - new_unit = Units(cmor_var.units) - old_unit = Units(var_handler.units) - - var_handler[:] = Units.conform(var_handler[:], old_unit, new_unit, inplace=True) - - if 'valid_min' in var_handler.ncattrs(): - var_handler.valid_min = Units.conform(float(var_handler.valid_min), old_unit, new_unit, - inplace=True) - if 'valid_max' in var_handler.ncattrs(): - var_handler.valid_max = Units.conform(float(var_handler.valid_max), old_unit, new_unit, - inplace=True) - except ValueError: - factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, - cmor_var.units) - var_handler[:] = var_handler[:] * factor + offset - if 'valid_min' in var_handler.ncattrs(): - var_handler.valid_min = float(var_handler.valid_min) * factor + offset - if 'valid_max' in var_handler.ncattrs(): - var_handler.valid_max = float(var_handler.valid_max) * factor + offset - var_handler.units = cmor_var.units - - @staticmethod - def _prepare_region(filepath, filetosend, region, var): - if not os.path.exists(filepath): - - handler = Utils.openCdf(filetosend) - handler.createDimension('region') - var_region = handler.createVariable('region', str, 'region') - var_region[0] = region - - original_var = handler.variables[var] - new_var = handler.createVariable('new_var', original_var.datatype, - original_var.dimensions + ('region',)) - new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) - value = original_var[:] - new_var[..., 0] = value - handler.close() - - Utils.nco.ncks(input=filetosend, output=filetosend, options='-O -x -v {0}'.format(var)) - Utils.rename_variable(filetosend, 'new_var', var) - else: - - temp = TempFile.get() - shutil.copyfile(filepath, temp) - Utils.nco.ncks(input=temp, output=temp, options='-O --mk_rec_dmn region') - handler = Utils.openCdf(temp) - handler_send = Utils.openCdf(filetosend) - value = handler_send.variables[var][:] - var_region = handler.variables['region'] - basin_index = np.where(var_region[:] == region) - if len(basin_index[0]) == 0: - var_region[var_region.shape[0]] = region - basin_index = var_region.shape[0] - 1 - - else: - basin_index = basin_index[0][0] - - handler.variables[var][..., basin_index] = value - handler.close() - handler_send.close() - Utils.move_file(temp, filetosend) - Utils.nco.ncks(input=filetosend, output=filetosend, options='-O --fix_rec_dmn region') @staticmethod def _get_final_var_name(box, var): @@ -335,30 +204,6 @@ class DataManager(object): freq_str = 'monthly_mean' return freq_str - @staticmethod - def get_domain_abbreviation(domain, frequency): - """ - Returns the table name for a domain-frequency pair - :param domain: variable's domain - :type domain: str - :param frequency: variable's frequency - :type frequency: str - :return: variable's table name - :rtype: str - """ - if frequency == 'mon': - if domain == 'seaIce': - domain_abreviattion = 'OImon' - elif domain == 'landIce': - domain_abreviattion = 'LImon' - else: - domain_abreviattion = domain[0].upper() + 'mon' - elif frequency == '6hr': - domain_abreviattion = '6hrPlev' - else: - domain_abreviattion = 'day' - return domain_abreviattion - # Abstract methods def get_file_path(self, startdate, member, domain, var, chunk, frequency, box=None, grid=None, year=None, date_str=None): @@ -444,6 +289,176 @@ class DataManager(object): pass +class NetCDFFile(object): + """ + Class to manage netCDF file and pr + + :param remote_file: + :type remote_file: str + :param local_file: + :type local_file: str + :param domain: + :type domain: str + :param var: + :type var: str + :param cmor_var: + :type cmor_var: Variable + """ + def __init__(self, remote_file, local_file, domain, var, cmor_var): + self.remote_file = remote_file + self.local_file = local_file, domain, var + self.domain = domain + self.var = var + self.cmor_var = cmor_var + self.region = None + self.frequency = None + + def send(self): + Utils.convert2netcdf4(self.local_file) + if self.region: + self._prepare_region() + + if self.cmor_var: + self._correct_metadata() + self._rename_coordinate_variables() + + Utils.move_file(self.local_file, self.remote_file) + + def _prepare_region(self): + if not os.path.exists(self.remote_file): + self._add_region_dimension_to_var() + else: + self._update_var_with_region_data() + Utils.nco.ncks(input=self.local_file, output=self.local_file, options='-O --fix_rec_dmn region') + + def _update_var_with_region_data(self): + temp = TempFile.get() + shutil.copyfile(self.remote_file, temp) + Utils.nco.ncks(input=temp, output=temp, options='-O --mk_rec_dmn region') + handler = Utils.openCdf(temp) + handler_send = Utils.openCdf(self.local_file) + value = handler_send.variables[self.var][:] + var_region = handler.variables['region'] + basin_index = np.where(var_region[:] == self.region) + if len(basin_index[0]) == 0: + var_region[var_region.shape[0]] = self.region + basin_index = var_region.shape[0] - 1 + + else: + basin_index = basin_index[0][0] + handler.variables[self.var][..., basin_index] = value + handler.close() + handler_send.close() + Utils.move_file(temp, self.local_file) + + def _add_region_dimension_to_var(self): + handler = Utils.openCdf(self.local_file) + handler.createDimension('region') + var_region = handler.createVariable('region', str, 'region') + var_region[0] = self.region + original_var = handler.variables[self.var] + new_var = handler.createVariable('new_var', original_var.datatype, + original_var.dimensions + ('region',)) + new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) + value = original_var[:] + new_var[..., 0] = value + handler.close() + Utils.nco.ncks(input=self.local_file, output=self.local_file, options='-O -x -v {0}'.format(self.var)) + Utils.rename_variable(self.local_file, 'new_var', self.var) + + def _correct_metadata(self): + handler = Utils.openCdf(self.local_file) + var_handler = handler.variables[self.var] + self._fix_variable_name(var_handler) + handler.modeling_realm = self.cmor_var.domain + handler.table_id = 'Table {0} (December 2013)'.format(Variable.get_table_name(self.cmor_var.domain, + self.frequency)) + if self.cmor_var.units: + self._fix_units(var_handler) + handler.sync() + self._fix_coordinate_variables_metadata(handler) + var_type = var_handler.dtype + handler.close() + self._fix_values_metadata(var_type) + + def _fix_variable_name(self, var_handler): + var_handler.standard_name = self.cmor_var.standard_name + var_handler.long_name = self.cmor_var.long_name + var_handler.short_name = self.cmor_var.short_name + + def _fix_values_metadata(self, var_type): + if self.cmor_var.valid_min != '': + valid_min = '-a valid_min, {0}, o, {1}, "{2}" '.format(self.var, var_type.char, self.cmor_var.valid_min) + else: + valid_min = '' + if self.cmor_var.valid_max != '': + valid_max = '-a valid_max, {0}, o, {1}, "{2}" '.format(self.var, var_type.char, self.cmor_var.valid_max) + else: + valid_max = '' + Utils.nco.ncatted(input=self.local_file, output=self.local_file, + options='-O -a _FillValue,{0},o,{1},"1.e20" ' + '-a missingValue,{0},o,{1},"1.e20" {2}{3}'.format(self.var, var_type.char, + valid_min, valid_max)) + + def _fix_coordinate_variables_metadata(self, handler): + if 'lev' in handler.variables: + handler.variables['lev'].short_name = 'lev' + if self.domain == 'ocean': + handler.variables['lev'].standard_name = 'depth' + if 'lon' in handler.variables: + handler.variables['lon'].short_name = 'lon' + handler.variables['lon'].standard_name = 'longitude' + if 'lat' in handler.variables: + handler.variables['lat'].short_name = 'lat' + handler.variables['lat'].standard_name = 'latitude' + + def _fix_units(self, var_handler): + if 'units' not in var_handler.ncattrs(): + return + if var_handler.units == 'PSU': + var_handler.units = 'psu' + if var_handler.units == 'C' and self.cmor_var.units == 'K': + var_handler.units = 'deg_C' + if self.cmor_var.units != var_handler.units: + self._convert_units(var_handler) + var_handler.units = self.cmor_var.units + + def _convert_units(self, var_handler): + try: + self._convert_using_cfunits(var_handler) + except ValueError: + factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, + self.cmor_var.units) + var_handler[:] = var_handler[:] * factor + offset + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = float(var_handler.valid_min) * factor + offset + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = float(var_handler.valid_max) * factor + offset + + def _convert_using_cfunits(self, var_handler): + new_unit = Units(self.cmor_var.units) + old_unit = Units(var_handler.units) + var_handler[:] = Units.conform(var_handler[:], old_unit, new_unit, inplace=True) + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = Units.conform(float(var_handler.valid_min), old_unit, new_unit, + inplace=True) + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = Units.conform(float(var_handler.valid_max), old_unit, new_unit, + inplace=True) + + def _rename_coordinate_variables(self): + variables = dict() + variables['x'] = 'i' + variables['y'] = 'j' + variables['nav_lat_grid_V'] = 'lat' + variables['nav_lon_grid_V'] = 'lon' + variables['nav_lat_grid_U'] = 'lat' + variables['nav_lon_grid_U'] = 'lon' + variables['nav_lat_grid_T'] = 'lat' + variables['nav_lon_grid_T'] = 'lon' + Utils.rename_variables(self.local_file, variables, False, True) + + class UnitConversion(object): """ Class to manage unit conversions diff --git a/earthdiagnostics/variable.py b/earthdiagnostics/variable.py index fb68163..4319fdf 100644 --- a/earthdiagnostics/variable.py +++ b/earthdiagnostics/variable.py @@ -62,3 +62,27 @@ class Variable(object): for old_name in line[0].split(':'): Variable._dict_variables[old_name.lower()] = var Variable._dict_variables[var.short_name.lower()] = var + + @staticmethod + def get_table_name(domain, frequency): + """ + Returns the table name for a domain-frequency pair + :param domain: variable's domain + :type domain: str + :param frequency: variable's frequency + :type frequency: str + :return: variable's table name + :rtype: str + """ + if frequency == 'mon': + if domain == 'seaIce': + domain_abreviattion = 'OImon' + elif domain == 'landIce': + domain_abreviattion = 'LImon' + else: + domain_abreviattion = domain[0].upper() + 'mon' + elif frequency == '6hr': + domain_abreviattion = '6hrPlev' + else: + domain_abreviattion = 'day' + return domain_abreviattion -- GitLab From 9713aeef29899ad7602706a529594ccccc937f8c Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 17 Oct 2016 13:09:00 +0200 Subject: [PATCH 252/268] Fixed bug introduced in previous commit --- earthdiagnostics/datamanager.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6fbc754..9cae961 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -112,6 +112,8 @@ class DataManager(object): filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, grid, year, date_str) netcdf_file = NetCDFFile(filepath, filetosend, domain, var, cmor_var) + netcdf_file.region = region + netcdf_file.frequency = frequency netcdf_file.send() self._create_link(domain, filepath, frequency, var, grid, move_old) @@ -306,7 +308,7 @@ class NetCDFFile(object): """ def __init__(self, remote_file, local_file, domain, var, cmor_var): self.remote_file = remote_file - self.local_file = local_file, domain, var + self.local_file = local_file self.domain = domain self.var = var self.cmor_var = cmor_var -- GitLab From 7e726b08aaaeeb40d461f09a8e27929ef0112712 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 17 Oct 2016 17:59:26 +0200 Subject: [PATCH 253/268] Changed method to modify time units in cmorization. Changed check inside renamevars from ncdump to cdo showvar because it can detect more errors. Fixes #2 --- earthdiagnostics/cmorizer.py | 87 ++++++++++++++++----------------- earthdiagnostics/datamanager.py | 2 +- earthdiagnostics/utils.py | 63 +++++++++++++----------- 3 files changed, 77 insertions(+), 75 deletions(-) diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 99d5a20..9135628 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -31,6 +31,7 @@ class Cmorizer(object): NON_DATA_VARIABLES = ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', + 'deptht_bnds', 'depthu_bnds', 'depthv_bnds', 'depthw_bnds', 'time_counter_bounds', 'ncatice', 'nav_lat_grid_V', 'nav_lat_grid_U', 'nav_lat_grid_T', 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T', 'depth', 'depth_2', 'depth_3', 'depth_4', @@ -236,10 +237,10 @@ class Cmorizer(object): Utils.convert2netcdf4(filename) frequency = self._get_nc_file_frequency(filename) self._rename_coordinate_variables(filename) + self._add_common_attributes(filename, frequency) + self._update_time_variables(filename) + handler = Utils.openCdf(filename) - self._add_common_attributes(frequency, handler) - self._update_time_variables(handler) - handler.sync() Log.info('Splitting file {0}', filename) for variable in handler.variables.keys(): if variable in Cmorizer.NON_DATA_VARIABLES: @@ -271,6 +272,7 @@ class Cmorizer(object): variables = dict() variables['time_counter'] = 'time' variables['time_counter_bnds'] = 'time_bnds' + variables['time_counter_bounds'] = 'time_bnds' variables['tbnds'] = 'bnds' variables['nav_lat'] = 'lat' variables['nav_lon'] = 'lon' @@ -463,51 +465,41 @@ class Cmorizer(object): self._cmorize_nc_file(merged_file) - def _update_time_variables(self, handler): + def _update_time_variables(self, filename): + handler = Utils.openCdf(filename) time_var = handler.variables['time'] - times = Utils.get_datetime_from_netcdf(handler) - time_var.units = 'days since 1850-01-01' - time_var.time_origin = "1850-01-01" - time_var.calendar = 'standard' - time_var.long_name = "Verification time of the forecast" - time_var.standard_name = "time" - time_var.axis = "T" - if type(times[0]) is not datetime: - for x in range(0, times.shape[0]): - # noinspection PyProtectedMember - times[x] = times[x]._to_real_datetime() - time_var[:] = netCDF4.date2num(times, 'days since 1850-01-01', 'standard') - - if 'axis_nbounds' in handler.dimensions: - handler.renameDimension('axis_nbounds', 'bnds') - - self._set_time_bounds(handler, time_var) - - self._set_leadtime_var(handler) + if "time_bnds" in handler.variables: + time_var.bounds = "time_bnds" + handler.variables['time_bnds'].units = time_var.units + handler.close() + temp = TempFile.get() + Utils.cdo.setreftime('1850-01-01,00:00:00,days', input=filename, output=temp) + Utils.move_file(temp, filename) + + self._set_leadtime_var(filename) def _set_time_bounds(self, handler, time_var): - if 'time_counter_bounds' in handler.variables: - handler.renameVariable('time_counter_bounds', 'time_bnds') - handler.sync() - if 'time_bnds' in handler.variables: - time_bounds_var = handler.variables['time_bnds'] - time_var.bounds = "time_bnds" - try: - units = time_bounds_var.units - except AttributeError: - # we suppose that if not units are present, they match the ones in the time variable - units = time_var.units - time_bounds_var.units = units - - time_bounds = Utils.get_datetime_from_netcdf(handler, 'time_bnds') - if type(time_bounds[0, 0]) is not datetime: - for x in range(0, time_bounds.shape[0]): - for y in range(0, time_bounds.shape[1]): - # noinspection PyProtectedMember - time_bounds[x, y] = time_bounds[x, y]._to_real_datetime() - time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') - - def _set_leadtime_var(self, handler): + if not 'time_bnds' in handler.variables: + return + time_bounds_var = handler.variables['time_bnds'] + time_var.bounds = "time_bnds" + try: + units = time_bounds_var.units + except AttributeError: + # we suppose that if not units are present, they match the ones in the time variable + units = time_var.units + time_bounds_var.units = units + + time_bounds = Utils.get_datetime_from_netcdf(handler, 'time_bnds') + if type(time_bounds[0, 0]) is not datetime: + for x in range(0, time_bounds.shape[0]): + for y in range(0, time_bounds.shape[1]): + # noinspection PyProtectedMember + time_bounds[x, y] = time_bounds[x, y]._to_real_datetime() + time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') + + def _set_leadtime_var(self, filename): + handler = Utils.openCdf(filename) if 'leadtime' in handler.variables: var = handler.variables['leadtime'] else: @@ -518,10 +510,12 @@ class Cmorizer(object): leadtime = (Utils.get_datetime_from_netcdf(handler) - parse_date(self.startdate)) for lt in range(0, leadtime.shape[0]): var[lt] = leadtime[lt].days + handler.close() - def _add_common_attributes(self, frequency, handler): + def _add_common_attributes(self, filename, frequency): cmor = self.config.cmor experiment = self.config.experiment + handler = Utils.openCdf(filename) handler.associated_experiment = cmor.associated_experiment handler.batch = '{0}{1}'.format(experiment.institute, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ @@ -548,6 +542,7 @@ class Cmorizer(object): handler.startdate = 'S{0}'.format(self.startdate) handler.tracking_id = str(uuid.uuid1()) handler.title = "{0} model output prepared for SPECS {1}".format(experiment.model, experiment.experiment_name) + handler.close() def gribfiles_available(self): grb_path = os.path.join(self.original_files_path, '*.grb') diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6fbc754..831ee12 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -306,7 +306,7 @@ class NetCDFFile(object): """ def __init__(self, remote_file, local_file, domain, var, cmor_var): self.remote_file = remote_file - self.local_file = local_file, domain, var + self.local_file = local_file self.domain = domain self.var = var self.cmor_var = cmor_var diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 91e4fef..8249d93 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -9,7 +9,7 @@ import os import re import tempfile from autosubmit.config.log import Log -from cdo import Cdo +from cdo import Cdo, CDOException from nco import Nco from earthdiagnostics.constants import Basins @@ -120,44 +120,51 @@ class Utils(object): error = False try: - for old_name, new_name in dic_names.items(): - if rename_dimension: - if old_name in handler.dimensions: - handler.renameDimension(old_name, new_name) - elif must_exist: - raise Exception("Dimension {0} does not exist in file {1}".format(old_name, filepath)) - - if old_name in handler.variables: - if new_name not in handler.variables: - handler.renameVariable(old_name, new_name) - elif must_exist: - raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) - handler.sync() + Utils._rename_vars_directly(dic_names, filepath, handler, must_exist, rename_dimension) except RuntimeError: error = True handler.close() try: - Utils.execute_shell_command(['ncdump', '-h', temp], log_level=Log.NO_LOG) - except Utils.ExecutionError: + Utils.cdo.showvar(input=temp) + except CDOException: error = True if error: - Log.debug('Using secondary rename method for netCDF') - original_handler = Utils.openCdf(filepath) - new_handler = Utils.openCdf(temp, 'w') - for attribute in original_handler.ncattrs(): - setattr(new_handler, attribute, getattr(original_handler, attribute)) - - for dimension in original_handler.dimensions.keys(): - Utils.copy_dimension(original_handler, new_handler, dimension, new_names=dic_names) - for variable in original_handler.variables.keys(): - Utils.copy_variable(original_handler, new_handler, variable, new_names=dic_names) - original_handler.close() - new_handler.close() + Utils._rename_vars_by_creating_new_file(dic_names, filepath, temp) Utils.move_file(temp, filepath) + @staticmethod + def _rename_vars_by_creating_new_file(dic_names, filepath, temp): + Log.debug('Using secondary rename method for netCDF') + original_handler = Utils.openCdf(filepath) + new_handler = Utils.openCdf(temp, 'w') + for attribute in original_handler.ncattrs(): + setattr(new_handler, attribute, getattr(original_handler, attribute)) + for dimension in original_handler.dimensions.keys(): + Utils.copy_dimension(original_handler, new_handler, dimension, new_names=dic_names) + for variable in original_handler.variables.keys(): + Utils.copy_variable(original_handler, new_handler, variable, new_names=dic_names) + original_handler.close() + new_handler.close() + + @staticmethod + def _rename_vars_directly(dic_names, filepath, handler, must_exist, rename_dimension): + for old_name, new_name in dic_names.items(): + if rename_dimension: + if old_name in handler.dimensions: + handler.renameDimension(old_name, new_name) + elif must_exist: + raise Exception("Dimension {0} does not exist in file {1}".format(old_name, filepath)) + + if old_name in handler.variables: + if new_name not in handler.variables: + handler.renameVariable(old_name, new_name) + elif must_exist: + raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) + handler.sync() + @staticmethod def move_file(source, destiny): """ -- GitLab From cb92e1adfdf859d3f93119f5809c265536ae567e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 19 Oct 2016 17:04:27 +0200 Subject: [PATCH 254/268] Added thredds manager. Some code cleaning --- earthdiagnostics/cmorizer.py | 28 ++--- earthdiagnostics/cmormanager.py | 132 ++++++++++++++++----- earthdiagnostics/datamanager.py | 114 +++++------------- earthdiagnostics/earthdiags.py | 5 +- earthdiagnostics/ocean/interpolatecdo.py | 4 +- earthdiagnostics/threddsmanager.py | 141 +++++++++++++++++++++++ earthdiagnostics/utils.py | 16 ++- 7 files changed, 303 insertions(+), 137 deletions(-) create mode 100644 earthdiagnostics/threddsmanager.py diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 9135628..216b7f0 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -37,6 +37,9 @@ class Cmorizer(object): 'depth', 'depth_2', 'depth_3', 'depth_4', 'mlev', 'hyai', 'hybi', 'hyam', 'hybm') + ALT_COORD_NAMES = {'time_counter': 'time', 'time_counter_bnds': 'time_bnds', 'time_counter_bounds': 'time_bnds', + 'tbnds': 'bnds', 'nav_lat': 'lat', 'nav_lon': 'lon', 'x': 'i', 'y': 'j'} + def __init__(self, data_manager, startdate, member): self.data_manager = data_manager self.startdate = startdate @@ -151,7 +154,9 @@ class Cmorizer(object): original_gribfile = self.get_original_grib_path(current_date, grid) Log.info('Processing month {1}', grid, date2str(current_date)) gribfile = self.get_scratch_grib_path(current_date, grid) - self._copy_gribfile(current_date, gribfile, grid, original_gribfile) + if not os.path.isfile(gribfile): + Log.info('Copying file...', grid, date2str(current_date)) + Utils.copy_file(original_gribfile, gribfile) self._obtain_atmos_timestep(gribfile) @@ -202,11 +207,6 @@ class Cmorizer(object): if self.atmos_timestep is None: self.atmos_timestep = self._get_atmos_timestep(gribfile) - def _copy_gribfile(self, current_date, gribfile, grid, original_gribfile): - if not os.path.isfile(gribfile): - Log.info('Copying file...', grid, date2str(current_date)) - shutil.copy(original_gribfile, gribfile) - def get_original_grib_path(self, current_date, grid): return os.path.join(self.original_files_path, self._get_grib_filename(grid, current_date)) @@ -236,7 +236,7 @@ class Cmorizer(object): Utils.convert2netcdf4(filename) frequency = self._get_nc_file_frequency(filename) - self._rename_coordinate_variables(filename) + Utils.rename_variables(filename, Cmorizer.ALT_COORD_NAMES, False, True) self._add_common_attributes(filename, frequency) self._update_time_variables(filename) @@ -268,18 +268,6 @@ class Cmorizer(object): variables = self._get_file_variables(filename) return self.cmor.any_required(variables) - def _rename_coordinate_variables(self, filename): - variables = dict() - variables['time_counter'] = 'time' - variables['time_counter_bnds'] = 'time_bnds' - variables['time_counter_bounds'] = 'time_bnds' - variables['tbnds'] = 'bnds' - variables['nav_lat'] = 'lat' - variables['nav_lon'] = 'lon' - variables['x'] = 'i' - variables['y'] = 'j' - Utils.rename_variables(filename, variables, False, True) - def _get_file_variables(self, filename): handler = Utils.openCdf(filename) variables = handler.variables.keys() @@ -479,7 +467,7 @@ class Cmorizer(object): self._set_leadtime_var(filename) def _set_time_bounds(self, handler, time_var): - if not 'time_bnds' in handler.variables: + if 'time_bnds' not in handler.variables: return time_bounds_var = handler.variables['time_bnds'] time_var.bounds = "time_bnds" diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index 85d0591..f3b6a6d 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -1,3 +1,4 @@ +# coding=utf-8 import glob from datetime import datetime @@ -6,7 +7,7 @@ from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day from earthdiagnostics.cmorizer import Cmorizer -from earthdiagnostics.datamanager import DataManager +from earthdiagnostics.datamanager import DataManager, NetCDFFile from earthdiagnostics.utils import TempFile, Utils from earthdiagnostics.variable import Variable @@ -15,6 +16,35 @@ class CMORManager(DataManager): """ Data manager class for CMORized experiments """ + def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): + """ + Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy + + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str|NoneType + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ + filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, grid, None, None) + + temp_path = TempFile.get() + Utils.copy_file(filepath, temp_path) + return temp_path + def get_file_path(self, startdate, member, domain, var, chunk, frequency, box=None, grid=None, year=None, date_str=None): """ @@ -36,7 +66,7 @@ class CMORManager(DataManager): :param grid: file's grid :type grid: str :param year: file's year - :type year: int | str + :type year: int|str :param date_str: date string to add directly. Overrides year or chunk configurations :type date_str: str :return: path to the file @@ -122,6 +152,64 @@ class CMORManager(DataManager): filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, grid, year, date_str) self._create_link(domain, filepath, frequency, var, grid, move_old) + def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, + rename_var=None, frequency=None, year=None, date_str=None, move_old=False): + """ + Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge + with already existing ones as needed + + :param move_old: if true, moves files following older conventions that may be found on the links folder + :type move_old: bool + :param date_str: exact date_str to use in the cmorized file + :type: str + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int + :param rename_var: if exists, the given variable will be renamed to the one given by var + :type rename_var: str + :param filetosend: path to the file to send to the CMOR repository + :type filetosend: str + :param region: specifies the region represented by the file. If it is defined, the data will be appended to the + CMOR repository as a new region in the file or will overwrite if region was already present + :type region: str + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ + original_var = var + cmor_var = Variable.get_variable(var) + var = self._get_final_var_name(box, var) + + if rename_var and rename_var != var: + Utils.rename_variable(filetosend, rename_var, var) + elif original_var != var: + Utils.rename_variable(filetosend, original_var, var) + + if not frequency: + frequency = self.config.frequency + + domain = DataManager.correct_domain(domain) + filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, + grid, year, date_str) + netcdf_file = NetCDFFile(filepath, filetosend, domain, var, cmor_var) + netcdf_file.send() + + self._create_link(domain, filepath, frequency, var, grid, move_old) + def get_year(self, domain, var, startdate, member, year, grid=None, box=None): """ Ge a file containing all the data for one year for one variable @@ -150,28 +238,18 @@ class CMORManager(DataManager): temp = self._merge_chunk_files(chunk_files) else: temp = chunk_files[0] - temp2 = self._remove_out_of_year_data(temp, year) + temp2 = self._select_data_of_given_year(temp, year) + os.remove(temp) return temp2 - def _remove_out_of_year_data(self, temp, year): + @staticmethod + def _select_data_of_given_year(data_file, year): temp2 = TempFile.get() - handler = Utils.openCdf(temp) - time = Utils.get_datetime_from_netcdf(handler) - handler.close() - start = None - end = None - for x in range(0, len(time)): - date = time[x] - if date.year == year: - if date.month == 1: - start = x - elif date.month == 12: - end = x - Utils.nco.ncks(input=temp, output=temp2, options='-O -d time,{0},{1}'.format(start, end)) - os.remove(temp) + Utils.cdo.selyear(str(year), input=data_file, output=temp2) return temp2 - def _merge_chunk_files(self, chunk_files): + @staticmethod + def _merge_chunk_files(chunk_files): temp = TempFile.get() Utils.nco.ncrcat(input=' '.join(chunk_files), output=temp) for chunk_file in chunk_files: @@ -195,8 +273,8 @@ class CMORManager(DataManager): for startdate, member in self.experiment.get_member_list(): if self._is_cmorized(startdate, member) and not self.config.cmor.force: continue - if not self._unpack_cmor_files(startdate, member): - self._cmorize_member(member, startdate) + if not self._unpack_cmor_files(member): + self._cmorize_member(startdate, member) def _is_cmorized(self, startdate, member): startdate_path = self._get_startdate_path(startdate) @@ -212,7 +290,7 @@ class CMORManager(DataManager): return True return False - def _cmorize_member(self, member, startdate): + def _cmorize_member(self, startdate, member): start_time = datetime.now() member_str = self.experiment.get_member_str(member) Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) @@ -221,10 +299,10 @@ class CMORManager(DataManager): cmorizer.cmorize_atmos() Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, datetime.now() - start_time) - def _unpack_cmor_files(self, member, startdate): + def _unpack_cmor_files(self, startdate): if self.config.cmor.force: return False - filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar.gz') + filepaths = self._get_transferred_cmor_data_filepaths(startdate, 'tar.gz') if len(filepaths) > 0: Log.info('Unzipping cmorized data...') Utils.unzip(filepaths, True) @@ -232,7 +310,7 @@ class CMORManager(DataManager): if not os.path.exists(self.cmor_path): os.mkdir(self.cmor_path) - filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar') + filepaths = self._get_transferred_cmor_data_filepaths(startdate, 'tar') if len(filepaths) > 0: Log.info('Unpacking cmorized data...') Utils.untar(filepaths, self.cmor_path) @@ -241,7 +319,7 @@ class CMORManager(DataManager): return True return False - def _get_transferred_cmor_data_filepaths(self, startdate, member, extension): + def _get_transferred_cmor_data_filepaths(self, startdate, extension): tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, 'cmorfiles') @@ -311,4 +389,4 @@ class CMORManager(DataManager): :rtype: str """ return os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles', self.experiment.institute, - self.experiment.model, self.experiment.experiment_name, 'S' + startdate) \ No newline at end of file + self.experiment.model, self.experiment.experiment_name, 'S' + startdate) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 831ee12..9756b78 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -51,12 +51,7 @@ class DataManager(object): :return: path to the copy created on the scratch folder :rtype: str """ - - filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, grid, None, None) - - temp_path = TempFile.get() - shutil.copyfile(filepath, temp_path) - return temp_path + raise NotImplementedError() def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, rename_var=None, frequency=None, year=None, date_str=None, move_old=False): @@ -96,27 +91,28 @@ class DataManager(object): :return: path to the copy created on the scratch folder :rtype: str """ - original_var = var - cmor_var = Variable.get_variable(var) - var = self._get_final_var_name(box, var) - - if rename_var and rename_var != var: - Utils.rename_variable(filetosend, rename_var, var) - elif original_var != var: - Utils.rename_variable(filetosend, original_var, var) - - if not frequency: - frequency = self.config.frequency - - domain = DataManager.correct_domain(domain) - filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, - grid, year, date_str) - netcdf_file = NetCDFFile(filepath, filetosend, domain, var, cmor_var) - netcdf_file.send() - - self._create_link(domain, filepath, frequency, var, grid, move_old) - + raise NotImplementedError() + def get_year(self, domain, var, startdate, member, year, grid=None, box=None): + """ + Ge a file containing all the data for one year for one variable + :param domain: variable's domain + :type domain: str + :param var: variable's name + :type var: str + :param startdate: startdate to retrieve + :type startdate: str + :param member: member to retrieve + :type member: int + :param year: year to retrieve + :type year: int + :param grid: variable's grid + :type grid: str + :param box: variable's box + :type box: Box + :return: + """ + raise NotImplementedError() @staticmethod def _get_final_var_name(box, var): @@ -140,7 +136,10 @@ class DataManager(object): return 'landIce' return domain - def get_varfolder(self, domain, var): + def get_varfolder(self, domain, var, grid=None): + if grid: + var = '{0}-{1}'.format(var, grid) + if domain in ['ocean', 'seaIce']: return '{0}_f{1}h'.format(var, self.experiment.ocean_timestep) else: @@ -151,10 +150,9 @@ class DataManager(object): if not grid: grid = 'original' - var_grid = '{0}-{1}'.format(var, grid) variable_folder = self.get_varfolder(domain, var) - vargrid_folder = self.get_varfolder(domain, var_grid) + vargrid_folder = self.get_varfolder(domain, var, grid) if grid == 'original': link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) @@ -195,7 +193,8 @@ class DataManager(object): raise ValueError('Original file {0} does not exists'.format(filepath)) os.symlink(filepath, link_path) - def frequency_folder_name(self, frequency): + @staticmethod + def frequency_folder_name(frequency): if frequency in ('d', 'daily', 'day'): freq_str = 'daily_mean' elif frequency.endswith('hr'): @@ -204,59 +203,6 @@ class DataManager(object): freq_str = 'monthly_mean' return freq_str - # Abstract methods - def get_file_path(self, startdate, member, domain, var, chunk, frequency, - box=None, grid=None, year=None, date_str=None): - """ - :param date_str: exact date_str to use in the cmorized file - :type: str - :param year: if frequency is yearly, this parameter is used to give the corresponding year - :type year: int | None - :param domain: CMOR domain - :type domain: str - :param var: variable name - :type var: str - :param startdate: file's startdate - :type startdate: str - :param member: file's member - :type member: int - :param chunk: file's chunk - :type chunk: int - :param grid: file's grid (only needed if it is not the original) - :type grid: str - :param box: file's box (only needed to retrieve sections or averages) - :type box: Box - :param frequency: file's frequency (only needed if it is different from the default) - :type frequency: str - :return: file absolute path - :rtype: str - """ - raise NotImplementedError() - - def get_year(self, domain, var, startdate, member, year, grid=None, box=None): - """ - Gets all the data corresponding to a given year from the CMOR repository to the scratch folder as one file and - returns the path to the scratch's copy. - - :param year: year to retrieve - :type year: int - :param domain: CMOR domain - :type domain: str - :param var: variable name - :type var: str - :param startdate: file's startdate - :type startdate: str - :param member: file's member - :type member: int - :param grid: file's grid (only needed if it is not the original) - :type grid: str - :param box: file's box (only needed to retrieve sections or averages) - :type box: Box - :return: path to the copy created on the scratch folder - :rtype: str - """ - raise NotImplementedError() - # Overridable methods (not mandatory) def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, frequency=None, year=None, date_str=None, move_old=False): @@ -372,7 +318,7 @@ class NetCDFFile(object): self._fix_variable_name(var_handler) handler.modeling_realm = self.cmor_var.domain handler.table_id = 'Table {0} (December 2013)'.format(Variable.get_table_name(self.cmor_var.domain, - self.frequency)) + self.frequency)) if self.cmor_var.units: self._fix_units(var_handler) handler.sync() diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 6021bb4..27687df 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -54,6 +54,8 @@ class EarthDiags(object): cdftools.path = self.config.cdftools_path self._create_dic_variables() self.time = dict() + self.data_manager = None + self.threads = None Log.debug('Diags ready') Log.info('Running diags for experiment {0}, startdates {1}, members {2}', self.config.experiment.expid, self.config.experiment.startdates, self.config.experiment.members) @@ -148,8 +150,7 @@ class EarthDiags(object): time = datetime.datetime.now() Log.info("Starting to compute at {0}", time) - num_threads = min(Utils.available_cpu_count(), self.config.max_cores) - self.threads = num_threads + self.threads = min(Utils.available_cpu_count(), self.config.max_cores) Log.info('Using {0} threads', self.threads) threads = list() for num_thread in range(0, self.threads): diff --git a/earthdiagnostics/ocean/interpolatecdo.py b/earthdiagnostics/ocean/interpolatecdo.py index 70f7baa..c2674d3 100644 --- a/earthdiagnostics/ocean/interpolatecdo.py +++ b/earthdiagnostics/ocean/interpolatecdo.py @@ -80,7 +80,7 @@ class InterpolateCDO(Diagnostic): else: target_grid = diags.config.experiment.atmos_grid.lower() - target_grid = cls.translate_ifs_grids_to_cdo_names(target_grid) + target_grid = cls._translate_ifs_grids_to_cdo_names(target_grid) if num_options >= 3: domain = options[3] @@ -94,7 +94,7 @@ class InterpolateCDO(Diagnostic): return job_list @classmethod - def translate_ifs_grids_to_cdo_names(cls, target_grid): + def _translate_ifs_grids_to_cdo_names(cls, target_grid): if target_grid.startswith('T159L'): target_grid = 't106' if target_grid.startswith('T255L'): diff --git a/earthdiagnostics/threddsmanager.py b/earthdiagnostics/threddsmanager.py new file mode 100644 index 0000000..59e6091 --- /dev/null +++ b/earthdiagnostics/threddsmanager.py @@ -0,0 +1,141 @@ +# coding=utf-8 +import os +from earthdiagnostics.datamanager import DataManager +from earthdiagnostics.utils import TempFile +import urllib + + +class THREDDSManager(DataManager): + """ + Data manager class for CMORized experiments + """ + def __init__(self, config): + super(THREDDSManager, self).__init__(config) + self.server_url = 'http://thredds.bsc.es:8080/thredds' + + def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): + """ + Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy + + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ + if not frequency: + frequency = frequency + aggregation_path = self.get_var_url(var, startdate, frequency, box) + temp = TempFile.get() + urllib.urlretrieve(aggregation_path, temp) + return temp + + def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, + rename_var=None, frequency=None, year=None, date_str=None, move_old=False): + """ + Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge + with already existing ones as needed + + :param move_old: if true, moves files following older conventions that may be found on the links folder + :type move_old: bool + :param date_str: exact date_str to use in the cmorized file + :type: str + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int + :param rename_var: if exists, the given variable will be renamed to the one given by var + :type rename_var: str + :param filetosend: path to the file to send to the CMOR repository + :type filetosend: str + :param region: specifies the region represented by the file. If it is defined, the data will be appended to the + CMOR repository as a new region in the file or will overwrite if region was already present + :type region: str + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ + raise NotImplementedError() + + def get_year(self, domain, var, startdate, member, year, grid=None, box=None): + """ + Ge a file containing all the data for one year for one variable + :param domain: variable's domain + :type domain: str + :param var: variable's name + :type var: str + :param startdate: startdate to retrieve + :type startdate: str + :param member: member to retrieve + :type member: int + :param year: year to retrieve + :type year: int + :param grid: variable's grid + :type grid: str + :param box: variable's box + :type box: Box + :return: + """ + + def get_var_url(self, var, startdate, frequency, box): + var = self._get_final_var_name(box, var) + return os.path.join(self.server_url, 'dodsc', 'recon', self.experiment.institute, + self.experiment.model, self.frequency_folder_name(frequency), + var, '{0}_{1}.nc'.format(var, startdate)) + + def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, + frequency=None, year=None, date_str=None, move_old=False): + """ + Creates the link of a given file from the CMOR repository. + + :param move_old: + :param date_str: + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ + # THREDDSManager does not require links + pass diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 8249d93..9993789 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -166,9 +166,9 @@ class Utils(object): handler.sync() @staticmethod - def move_file(source, destiny): + def copy_file(source, destiny): """ - Moves a file from source to destiny, creating dirs if necessary + Copies a file from source to destiny, creating dirs if necessary :param source: path to source :type source: str @@ -192,6 +192,18 @@ class Utils(object): raise Exception('Can not move {0} to {1}'.format(source, destiny)) shutil.copyfile(source, destiny) hash_destiny = Utils.get_file_hash(destiny) + + @staticmethod + def move_file(source, destiny): + """ + Moves a file from source to destiny, creating dirs if necessary + + :param source: path to source + :type source: str + :param destiny: path to destiny + :type destiny: str + """ + Utils.copy_file(source, destiny) os.remove(source) @staticmethod -- GitLab From ae0cf5be338b7a082522117014011759752d3851 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 19 Oct 2016 18:16:44 +0200 Subject: [PATCH 255/268] Added option to use thredds manager --- diags.conf | 17 ++++++++++------- earthdiagnostics/cmormanager.py | 5 ++++- earthdiagnostics/config.py | 13 ++----------- earthdiagnostics/datamanager.py | 7 +++++++ earthdiagnostics/earthdiags.py | 9 +++++++-- earthdiagnostics/threddsmanager.py | 16 +++++++++++----- earthdiagnostics/utils.py | 13 ++++++++++--- 7 files changed, 51 insertions(+), 29 deletions(-) diff --git a/diags.conf b/diags.conf index f57f9c1..13bf70b 100644 --- a/diags.conf +++ b/diags.conf @@ -1,8 +1,11 @@ [DIAGNOSTICS] +# Data adaptor type: CMOR (for our experiments), THREDDS (for other experiments) +DATA_ADAPTOR = THREDDS # Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/$USER # Root path for the cmorized data to use -DATA_DIR = /esnas/exp/ecearth/:/esarchive/exp/ecearth/:/esnas/exp/nemo/:/esarchive/exp/nemo/ +# DATA_DIR = /esnas/exp/ecearth/:/esarchive/exp/ecearth/:/esnas/exp/nemo/:/esarchive/exp/nemo/ +DATA_DIR = https://earth.bsc.es/thredds # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or @@ -18,7 +21,7 @@ CDFTOOLS_PATH = ~/CDFTOOLS/bin # If true, copies the mesh files regardless of presence in scratch dir RESTORE_MESHES = False # Limits the maximum amount of threads used. Default: 0 (no limitation, one per virtual core available) -# MAX_CORES = 1 +MAX_CORES = 1 [CMOR] # If true, recreates CMOR files regardless of presence. Default = False @@ -57,8 +60,8 @@ ATMOS_MONTHLY_VARS = 167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, [EXPERIMENT] # Experiments parameters as defined in CMOR standard -INSTITUTE = BSC -MODEL = EC-EARTH +INSTITUTE = ecmwf +MODEL = system4_m1 # Model version: Available versions MODEL_VERSION =Ec2.3_O1L46 # Atmospheric output timestep in hours @@ -75,11 +78,11 @@ OCEAN_TIMESTEP = 3 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment EXPID = i03i -STARTDATES = 19611101 19641101 19811101 19841101 19911101 19621101 19651101 19821101 19891101 19921101 19631101 19801101 19831101 19901101 19931101 -MEMBERS = 0 1 2 3 4 +STARTDATES = 19611101 +MEMBERS = 0 MEMBER_DIGITS = 1 CHUNK_SIZE = 4 -CHUNKS = 15 +CHUNKS = 1 # CHUNKS = 1 diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index f3b6a6d..e0273ba 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -16,6 +16,9 @@ class CMORManager(DataManager): """ Data manager class for CMORized experiments """ + def __init__(self, config): + super(CMORManager, self).__init__(config) + def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy @@ -257,7 +260,7 @@ class CMORManager(DataManager): return temp # noinspection PyPep8Naming - def prepare_CMOR_files(self): + def prepare(self): """ Prepares the data to be used by the diagnostic. diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index cff5710..2f6f081 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -23,6 +23,8 @@ class Config(object): parser.read(path) # Read diags config + self.data_adaptor = parser.get_option('DIAGNOSTICS', 'DATA_ADAPTOR', 'CMOR').upper() + "Scratch folder path" self.scratch_dir = Utils.expand_path(parser.get_option('DIAGNOSTICS', 'SCRATCH_DIR')) "Scratch folder path" self.data_dir = Utils.expand_path(parser.get_option('DIAGNOSTICS', 'DATA_DIR')) @@ -46,17 +48,6 @@ class Config(object): :rtype: ExperimentConfig """ - - data_folders = self.data_dir.split(':') - self.data_dir = None - for data_folder in data_folders: - if os.path.isdir(os.path.join(data_folder, self.experiment.expid)): - self.data_dir = data_folder - break - - if not self.data_dir: - raise Exception('Can not find model data') - # Read aliases self._aliases = dict() if parser.has_section('ALIAS'): diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 9756b78..556777b 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -234,6 +234,13 @@ class DataManager(object): """ pass + def prepare(self): + """ + Prepares the data to be used by the diagnostic. + :return: + """ + pass + class NetCDFFile(object): """ diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 27687df..e8ed69a 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -14,6 +14,7 @@ from autosubmit.date.chunk_date_lib import * from config import Config from earthdiagnostics.cmormanager import CMORManager +from earthdiagnostics.threddsmanager import THREDDSManager from earthdiagnostics import cdftools from earthdiagnostics.utils import TempFile from earthdiagnostics.diagnostic import Diagnostic @@ -141,8 +142,12 @@ class EarthDiags(object): self._register_diagnostics() parse_date('20000101') - self.data_manager = CMORManager(self.config) - self.data_manager.prepare_CMOR_files() + + if self.config.data_adaptor == 'CMOR': + self.data_manager = CMORManager(self.config) + elif self.config.data_adaptor == 'THREDDS': + self.data_manager = THREDDSManager(self.config, self.config.data_dir) + self.data_manager.prepare() # Run diagnostics Log.info('Running diagnostics') diff --git a/earthdiagnostics/threddsmanager.py b/earthdiagnostics/threddsmanager.py index 59e6091..e6fe30b 100644 --- a/earthdiagnostics/threddsmanager.py +++ b/earthdiagnostics/threddsmanager.py @@ -1,7 +1,7 @@ # coding=utf-8 import os from earthdiagnostics.datamanager import DataManager -from earthdiagnostics.utils import TempFile +from earthdiagnostics.utils import TempFile, Utils import urllib @@ -9,9 +9,9 @@ class THREDDSManager(DataManager): """ Data manager class for CMORized experiments """ - def __init__(self, config): + def __init__(self, config, server_url): super(THREDDSManager, self).__init__(config) - self.server_url = 'http://thredds.bsc.es:8080/thredds' + self.server_url = server_url def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ @@ -37,10 +37,12 @@ class THREDDSManager(DataManager): :rtype: str """ if not frequency: - frequency = frequency + frequency = self.config.frequency aggregation_path = self.get_var_url(var, startdate, frequency, box) temp = TempFile.get() urllib.urlretrieve(aggregation_path, temp) + if not Utils.check_netcdf_file(temp): + raise THREDDSError('Can not retrieve {0} from server'.format(aggregation_path)) return temp def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, @@ -105,7 +107,7 @@ class THREDDSManager(DataManager): def get_var_url(self, var, startdate, frequency, box): var = self._get_final_var_name(box, var) - return os.path.join(self.server_url, 'dodsc', 'recon', self.experiment.institute, + return os.path.join(self.server_url, 'dodsc', 'exp', self.experiment.institute, self.experiment.model, self.frequency_folder_name(frequency), var, '{0}_{1}.nc'.format(var, startdate)) @@ -139,3 +141,7 @@ class THREDDSManager(DataManager): """ # THREDDSManager does not require links pass + + +class THREDDSError(Exception): + pass diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 9993789..211fc34 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -125,9 +125,8 @@ class Utils(object): error = True handler.close() - try: - Utils.cdo.showvar(input=temp) - except CDOException: + + if not Utils.check_netcdf_file(temp): error = True if error: @@ -135,6 +134,14 @@ class Utils(object): Utils.move_file(temp, filepath) + @staticmethod + def check_netcdf_file(filepath): + try: + Utils.cdo.showvar(input=filepath) + except CDOException: + return False + return True + @staticmethod def _rename_vars_by_creating_new_file(dic_names, filepath, temp): Log.debug('Using secondary rename method for netCDF') -- GitLab From 4d712a2a2d427182c1fc026936c4bbff6306df0e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 20 Oct 2016 12:53:52 +0200 Subject: [PATCH 256/268] First version of monthly percentiles --- diags.conf | 2 +- earthdiagnostics/cmormanager.py | 9 ++ earthdiagnostics/earthdiags.py | 8 +- earthdiagnostics/statistics/__init__.py | 1 + .../statistics/monthly_percentiles.py | 94 +++++++++++++++++++ 5 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 earthdiagnostics/statistics/__init__.py create mode 100644 earthdiagnostics/statistics/monthly_percentiles.py diff --git a/diags.conf b/diags.conf index 13bf70b..0127555 100644 --- a/diags.conf +++ b/diags.conf @@ -11,7 +11,7 @@ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below). If you are using the diagnpostics just to CMORize, leave it # empty -DIAGS = OHC +DIAGS = monpercent,ocean,tos,90 monpercent,ocean,tos,10 # DIAGS = OHC # Frequency of the data you want to use by default. Some diagnostics do not use this value: i.e. monmean always stores # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index e0273ba..5f12fea 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -18,6 +18,15 @@ class CMORManager(DataManager): """ def __init__(self, config): super(CMORManager, self).__init__(config) + data_folders = self.config.data_dir.split(':') + self.config.data_dir = None + for data_folder in data_folders: + if os.path.isdir(os.path.join(data_folder, self.experiment.expid)): + self.config.data_dir = data_folder + break + + if not self.config.data_dir: + raise Exception('Can not find model data') def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index e8ed69a..c539038 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -20,6 +20,7 @@ from earthdiagnostics.utils import TempFile from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.ocean import * from earthdiagnostics.general import * +from earthdiagnostics.statistics import * from ocean import ConvectionSites, Gyres, Psi, MaxMoc, AreaMoc, Moc, VerticalMean, VerticalMeanMeters, Interpolate, \ AverageSection, CutSection, MixedLayerSaltContent, Siasiesiv from utils import Utils @@ -112,11 +113,6 @@ class EarthDiags(object): TempFile.clean() return True - # except Exception as e: - # from traceback import format_exc - # Log.critical('Unhandled exception on EarthDiagnostics: {0}\n{1}', e, format_exc(10)) - # return False - def _create_dic_variables(self): self.dic_variables = dict() self.dic_variables['x'] = 'i' @@ -224,6 +220,8 @@ class EarthDiags(object): Diagnostic.register(Rewrite) Diagnostic.register(Relink) + Diagnostic.register(MonthlyPercentil) + def clean(self): Log.info('Removing scratch folder...') if os.path.exists(self.config.scratch_dir): diff --git a/earthdiagnostics/statistics/__init__.py b/earthdiagnostics/statistics/__init__.py new file mode 100644 index 0000000..618dbba --- /dev/null +++ b/earthdiagnostics/statistics/__init__.py @@ -0,0 +1 @@ +from monthly_percentiles import MonthlyPercentil \ No newline at end of file diff --git a/earthdiagnostics/statistics/monthly_percentiles.py b/earthdiagnostics/statistics/monthly_percentiles.py new file mode 100644 index 0000000..a4edda6 --- /dev/null +++ b/earthdiagnostics/statistics/monthly_percentiles.py @@ -0,0 +1,94 @@ +# coding=utf-8 +# coding=utf-8 +from earthdiagnostics import cdftools +from earthdiagnostics.box import Box +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile + + +class MonthlyPercentil(Diagnostic): + """ + Chooses vertical level in ocean, or vertically averages between + 2 or more ocean levels + + :original author: Virginie Guemas + :contributor: Eleftheria Exarchou + :contributor: Javier Vegas-Regidor + + :created: February 2012 + :last modified: June 2016 + + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable to average + :type variable: str + :param box: box used to restrict the vertical mean + :type box: Box + """ + + alias = 'monpercent' + "Diagnostic alias for the configuration file" + + def __init__(self, data_manager, startdate, member, chunk, variable, domain, percentile): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.percentile = percentile + + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.domain == other.domain and self.variable == other.variable and self.percentile == other.percentile + + def __str__(self): + return 'Monthly percentile {0} Startdate: {0} Member: {1} Chunk: {2} ' \ + 'Variable: {3}:{4}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable) + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: domain, variable, percentil number, maximum depth (level) + :type options: list[str] + :return: + """ + num_options = len(options) - 1 + if num_options < 3: + raise Exception('You must specify the variable (and its domain) to average vertically and ' + 'the percentil you want') + if num_options > 3: + raise Exception('You must specify between one and three parameters for the vertical mean') + + domain = options[1] + variable = options[2] + percentile = int(options[3]) + if percentile < 0 or percentile > 100: + raise Exception('Percentile value must be in the interval [0,100]') + + job_list = list() + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): + job_list.append(MonthlyPercentil(diags.data_manager, startdate, member, chunk, + variable, domain, percentile)) + return job_list + + def compute(self): + """ + Runs the diagnostic + """ + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + temp = TempFile.get() + Utils.cdo.monpctl(self.percentile, input=variable_file, output=temp) + self.data_manager.send_file(temp, 'ocean', self.variable + 'p' + self.percentile, self.startdate, self.member, + self.chunk) + -- GitLab From a5f7c015f0730b51601fdffea7f5e0e2c903374e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 20 Oct 2016 15:19:06 +0200 Subject: [PATCH 257/268] Added metadata to generated files --- earthdiagnostics/cmorizer.py | 33 ++----------------- earthdiagnostics/cmormanager.py | 14 ++++++-- earthdiagnostics/datamanager.py | 28 ++++++++++++++-- earthdiagnostics/diagnostic.py | 5 +++ earthdiagnostics/general/monthlymean.py | 4 +-- earthdiagnostics/general/rewrite.py | 2 +- earthdiagnostics/ocean/areamoc.py | 2 +- earthdiagnostics/ocean/averagesection.py | 2 +- earthdiagnostics/ocean/convectionsites.py | 2 +- earthdiagnostics/ocean/cutsection.py | 2 +- earthdiagnostics/ocean/gyres.py | 2 +- earthdiagnostics/ocean/heatcontent.py | 4 +-- earthdiagnostics/ocean/heatcontentlayer.py | 2 +- earthdiagnostics/ocean/interpolate.py | 2 +- earthdiagnostics/ocean/interpolatecdo.py | 2 +- earthdiagnostics/ocean/maxmoc.py | 12 +++---- .../ocean/mixedlayerheatcontent.py | 2 +- .../ocean/mixedlayersaltcontent.py | 2 +- earthdiagnostics/ocean/moc.py | 2 +- earthdiagnostics/ocean/psi.py | 2 +- earthdiagnostics/ocean/siasiesiv.py | 12 +++---- earthdiagnostics/ocean/verticalmean.py | 2 +- earthdiagnostics/ocean/verticalmeanmeters.py | 2 +- .../statistics/monthly_percentiles.py | 2 +- earthdiagnostics/threddsmanager.py | 3 +- earthdiagnostics/utils.py | 7 ++++ 26 files changed, 87 insertions(+), 67 deletions(-) diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 216b7f0..1f00be5 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -3,7 +3,6 @@ import glob import shutil import uuid -import netCDF4 import os from datetime import datetime @@ -38,7 +37,7 @@ class Cmorizer(object): 'mlev', 'hyai', 'hybi', 'hyam', 'hybm') ALT_COORD_NAMES = {'time_counter': 'time', 'time_counter_bnds': 'time_bnds', 'time_counter_bounds': 'time_bnds', - 'tbnds': 'bnds', 'nav_lat': 'lat', 'nav_lon': 'lon', 'x': 'i', 'y': 'j'} + 'tbnds': 'bnds', 'nav_lat': 'lat', 'nav_lon': 'lon', 'x': 'i', 'y': 'j'} def __init__(self, data_manager, startdate, member): self.data_manager = data_manager @@ -265,15 +264,9 @@ class Cmorizer(object): return frequency def _contains_requested_variables(self, filename): - variables = self._get_file_variables(filename) + variables = Utils.get_file_variables(filename) return self.cmor.any_required(variables) - def _get_file_variables(self, filename): - handler = Utils.openCdf(filename) - variables = handler.variables.keys() - handler.close() - return variables - def extract_variable(self, file_path, handler, frequency, variable): """ Extracts a variable from a file and creates the CMOR file @@ -320,7 +313,7 @@ class Cmorizer(object): self.data_manager.send_file(temp, var_cmor.domain, var_cmor.short_name, self.startdate, self.member, frequency=frequency, rename_var=variable, date_str=date_str, region=region, - move_old=True, grid=var_cmor.grid) + move_old=True, grid=var_cmor.grid, cmorized=True) def _add_coordinate_variables(self, handler, temp): handler_cmor = Utils.openCdf(temp) @@ -466,26 +459,6 @@ class Cmorizer(object): self._set_leadtime_var(filename) - def _set_time_bounds(self, handler, time_var): - if 'time_bnds' not in handler.variables: - return - time_bounds_var = handler.variables['time_bnds'] - time_var.bounds = "time_bnds" - try: - units = time_bounds_var.units - except AttributeError: - # we suppose that if not units are present, they match the ones in the time variable - units = time_var.units - time_bounds_var.units = units - - time_bounds = Utils.get_datetime_from_netcdf(handler, 'time_bnds') - if type(time_bounds[0, 0]) is not datetime: - for x in range(0, time_bounds.shape[0]): - for y in range(0, time_bounds.shape[1]): - # noinspection PyProtectedMember - time_bounds[x, y] = time_bounds[x, y]._to_real_datetime() - time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') - def _set_leadtime_var(self, filename): handler = Utils.openCdf(filename) if 'leadtime' in handler.variables: diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index 5f12fea..c1c70f7 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -164,12 +164,14 @@ class CMORManager(DataManager): filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, grid, year, date_str) self._create_link(domain, filepath, frequency, var, grid, move_old) - def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, - rename_var=None, frequency=None, year=None, date_str=None, move_old=False): + def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, + box=None, rename_var=None, frequency=None, year=None, date_str=None, move_old=False, + diagnostic=None, cmorized=False): """ Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge with already existing ones as needed + :param diagnostic: :param move_old: if true, moves files following older conventions that may be found on the links folder :type move_old: bool :param date_str: exact date_str to use in the cmorized file @@ -199,6 +201,7 @@ class CMORManager(DataManager): :type box: Box :param frequency: file's frequency (only needed if it is different from the default) :type frequency: str + :return: path to the copy created on the scratch folder :rtype: str """ @@ -218,6 +221,13 @@ class CMORManager(DataManager): filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, grid, year, date_str) netcdf_file = NetCDFFile(filepath, filetosend, domain, var, cmor_var) + if diagnostic: + netcdf_file.add_diagnostic_history(diagnostic) + elif cmorized: + netcdf_file.add_cmorization_history() + else: + raise ValueError('You must provide a diagnostic or set cmorized to true to store data ' + 'using the CMORManager') netcdf_file.send() self._create_link(domain, filepath, frequency, var, grid, move_old) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 556777b..fd4ad0b 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -2,6 +2,7 @@ import csv import shutil import threading +from datetime import datetime import numpy as np import os @@ -53,8 +54,9 @@ class DataManager(object): """ raise NotImplementedError() - def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, - rename_var=None, frequency=None, year=None, date_str=None, move_old=False): + def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, + box=None, rename_var=None, frequency=None, year=None, date_str=None, move_old=False, + diagnostic=None, cmorized=False): """ Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge with already existing ones as needed @@ -411,6 +413,28 @@ class NetCDFFile(object): variables['nav_lon_grid_T'] = 'lon' Utils.rename_variables(self.local_file, variables, False, True) + def add_diagnostic_history(self, diagnostic): + from earthdiagnostics.earthdiags import EarthDiags + history_line = 'Diagnostic {1} calculated with EarthDiagnostics version {0}'.format(EarthDiags.version, + diagnostic) + self._add_history_line(history_line) + + def add_cmorization_history(self): + from earthdiagnostics.earthdiags import EarthDiags + history_line = 'CMORized with Earthdiagnostics version {0}'.format(EarthDiags.version) + self._add_history_line(history_line) + + def _add_history_line(self, history_line): + utc_datetime = 'UTC ' + datetime.utcnow().isoformat() + history_line = '{0}: {1};'.format(utc_datetime, history_line) + + handler = Utils.openCdf(self.local_file) + try: + handler.history += history_line + except AttributeError: + handler.history = history_line + handler.close() + class UnitConversion(object): """ diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index f19364b..eb49e9a 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -51,6 +51,11 @@ class Diagnostic(object): return Diagnostic._diag_list[name] return None + def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, + box=None, rename_var=None, frequency=None, year=None, date_str=None, move_old=False): + self.data_manager.send_file(filetosend, domain, var, startdate, member, chunk, grid, region, + box, rename_var, frequency, year, date_str, move_old, diagnostic=self) + def compute(self): """ Calculates the diagnostic and stores the output diff --git a/earthdiagnostics/general/monthlymean.py b/earthdiagnostics/general/monthlymean.py index cc74adc..1675311 100644 --- a/earthdiagnostics/general/monthlymean.py +++ b/earthdiagnostics/general/monthlymean.py @@ -96,6 +96,6 @@ class MonthlyMean(Diagnostic): Utils.cdo.monmean(input=variable_file, output=temp, options='-O') os.remove(variable_file) - self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, - frequency='mon', grid=self.grid) + self.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, + frequency='mon', grid=self.grid) diff --git a/earthdiagnostics/general/rewrite.py b/earthdiagnostics/general/rewrite.py index 96e31cd..1665a1d 100644 --- a/earthdiagnostics/general/rewrite.py +++ b/earthdiagnostics/general/rewrite.py @@ -72,5 +72,5 @@ class Rewrite(Diagnostic): Runs the diagnostic """ variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) - self.data_manager.send_file(variable_file, self.domain, self.variable, self.startdate, self.member, self.chunk) + self.send_file(variable_file, self.domain, self.variable, self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 7005388..3801130 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -147,5 +147,5 @@ class AreaMoc(Diagnostic): nco.ncap2(input=temp2, output=temp2, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') nco.ncwa(input=temp2, output=temp2, options='-w coslat -a lat') nco.ncks(input=temp2, output=temp2, options='-O -v vsftmyz,time') - self.data_manager.send_file(temp2, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, + self.send_file(temp2, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, box=self.box) diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 1ac8f8e..97a79d9 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -96,5 +96,5 @@ class AverageSection(Diagnostic): variable_file), output=temp) os.remove(variable_file) - self.data_manager.send_file(temp, self.domain, self.variable + 'mean', self.startdate, self.member, self.chunk, + self.send_file(temp, self.domain, self.variable + 'mean', self.startdate, self.member, self.chunk, box=self.box, grid='regular') diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index 8c49dd0..e9ac8b1 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -112,7 +112,7 @@ class ConvectionSites(Diagnostic): self.mlotst_handler.close() handler.close() - self.data_manager.send_file(output, 'ocean', 'site', self.startdate, self.member, self.chunk) + self.send_file(output, 'ocean', 'site', self.startdate, self.member, self.chunk) Log.info('Finished convection sites for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index 03a3fdb..4138322 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -182,7 +182,7 @@ class CutSection(Diagnostic): box.max_lat = self.value box.min_lat = self.value - self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, + self.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, box=box) Log.info('Finished cut section for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 0fefb93..23ba2a6 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -142,7 +142,7 @@ class Gyres(Diagnostic): handler.close() handler_original.close() - self.data_manager.send_file(output, 'ocean', 'gyre', self.startdate, self.member, self.chunk) + self.send_file(output, 'ocean', 'gyre', self.startdate, self.member, self.chunk) Log.info('Finished gyres for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) def _gyre(self, site, invert=False): diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index dabc54f..e0a66c2 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -165,8 +165,8 @@ class HeatContent(Diagnostic): box_save = self.box Utils.setminmax(ohcsum_temp, 'ohcsum') - self.data_manager.send_file(ohcsum_temp, 'ocean', 'ohcsum', self.startdate, self.member, self.chunk, + self.send_file(ohcsum_temp, 'ocean', 'ohcsum', self.startdate, self.member, self.chunk, box=box_save, region=self.basin.fullname, rename_var='ohcsum') Utils.setminmax(ohcvmean_temp, 'ohcvmean') - self.data_manager.send_file(ohcvmean_temp, 'ocean', 'ohcvmean', self.startdate, self.member, self.chunk, + self.send_file(ohcvmean_temp, 'ocean', 'ohcvmean', self.startdate, self.member, self.chunk, box=box_save, region=self.basin.fullname, rename_var='ohcvmean') diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index c9921fe..bd0cbf1 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -177,4 +177,4 @@ class HeatContentLayer(Diagnostic): handler_results.close() Utils.setminmax(results, 'ohc') - self.data_manager.send_file(results, 'ocean', 'ohc', self.startdate, self.member, self.chunk, box=self.box) + self.send_file(results, 'ocean', 'ohc', self.startdate, self.member, self.chunk, box=self.box) diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index 4a1dab4..ef18456 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -148,7 +148,7 @@ class Interpolate(Diagnostic): if not has_levels: nco.ncks(input=temp2, output=temp2, options='-O -v {0},lat,lon,time'.format(self.variable)) - self.data_manager.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, + self.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, grid=self.grid) def _get_level_file(self, lev): diff --git a/earthdiagnostics/ocean/interpolatecdo.py b/earthdiagnostics/ocean/interpolatecdo.py index c2674d3..b22f14e 100644 --- a/earthdiagnostics/ocean/interpolatecdo.py +++ b/earthdiagnostics/ocean/interpolatecdo.py @@ -120,7 +120,7 @@ class InterpolateCDO(Diagnostic): temp = TempFile.get() cdo.remapbil(self.grid, input=variable_file, output=temp) Utils.setminmax(temp, self.variable) - self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, + self.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, grid=self.grid) diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 2b91345..a5ecc77 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -156,7 +156,7 @@ class MaxMoc(Diagnostic): var.valid_max = 1000. var[0] = maximum handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, frequency='yr', year=self.year) handler = self._create_output_file(temp) @@ -167,7 +167,7 @@ class MaxMoc(Diagnostic): var.valid_max = 90. var[0] = max_lat handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, frequency='yr', year=self.year) handler = self._create_output_file(temp) @@ -178,7 +178,7 @@ class MaxMoc(Diagnostic): var.valid_max = 10000. var[0] = max_lev handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, frequency='yr', year=self.year) handler = self._create_output_file(temp) @@ -189,7 +189,7 @@ class MaxMoc(Diagnostic): var.valid_max = 1000. var[0] = minimum handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, frequency='yr', year=self.year) handler = self._create_output_file(temp) @@ -200,7 +200,7 @@ class MaxMoc(Diagnostic): var.valid_max = 90. var[0] = min_lat handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, frequency='yr', year=self.year) handler = self._create_output_file(temp) @@ -211,7 +211,7 @@ class MaxMoc(Diagnostic): var.valid_max = 10000. var[0] = min_lev handler.close() - self.data_manager.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, + self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, frequency='yr', year=self.year) def _create_output_file(self, temp): diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index e5b43c4..8460851 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -78,4 +78,4 @@ class MixedLayerHeatContent(Diagnostic): Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlheatc': 'ohcvsumlotst'}, False, True) Utils.setminmax(temp, 'ohcvsumlotst') - self.data_manager.send_file(temp, 'ocean', 'ohcvsumlotst', self.startdate, self.member, self.chunk) + self.send_file(temp, 'ocean', 'ohcvsumlotst', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index 9c53bb4..b3c6efe 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -75,4 +75,4 @@ class MixedLayerSaltContent(Diagnostic): Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'scvsummlotst'}, False, True) Utils.setminmax(temp, 'scvsummlotst') - self.data_manager.send_file(temp, 'ocean', 'scvsummlotst', self.startdate, self.member, self.chunk) + self.send_file(temp, 'ocean', 'scvsummlotst', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index 29040a7..daa1ae2 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -106,4 +106,4 @@ class Moc(Diagnostic): options='-O -x -v zomsfglo,zomsfatl,zomsfpac,zomsfinp,zomsfind,zomsfinp0') Utils.setminmax(temp, 'vsftmyz') - self.data_manager.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk) + self.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index bd7356f..342f0e9 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -69,4 +69,4 @@ class Psi(Diagnostic): cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-mean -mask') Utils.rename_variable(temp, 'sobarstf', 'vsftbarot') Utils.setminmax(temp, 'vsftbarot') - self.data_manager.send_file(temp, 'ocean', 'vsftbarot', self.startdate, self.member, self.chunk) + self.send_file(temp, 'ocean', 'vsftbarot', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index cd263de..c954f04 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -107,23 +107,23 @@ class Siasiesiv(Diagnostic): except Exception as ex: print ex - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[4, :], 'sivols', '10^9 m3'), + self.send_file(self._extract_variable_and_rename(sit_file, result[4, :], 'sivols', '10^9 m3'), 'seaIce', 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[5, :], 'siareas', '10^9 m2'), + self.send_file(self._extract_variable_and_rename(sit_file, result[5, :], 'siareas', '10^9 m2'), 'seaIce', 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[7, :], 'siextents', '10^9 m2'), + self.send_file(self._extract_variable_and_rename(sit_file, result[7, :], 'siextents', '10^9 m2'), 'seaIce', 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[0, :], 'sivoln', '10^9 m3'), + self.send_file(self._extract_variable_and_rename(sit_file, result[0, :], 'sivoln', '10^9 m3'), 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[1, :], 'siarean', '10^9 m2'), + self.send_file(self._extract_variable_and_rename(sit_file, result[1, :], 'siarean', '10^9 m2'), 'seaIce', 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) - self.data_manager.send_file(self._extract_variable_and_rename(sit_file, result[3, :], 'siextentn', '10^9 m2'), + self.send_file(self._extract_variable_and_rename(sit_file, result[3, :], 'siextentn', '10^9 m2'), 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 0af7ec8..95eacbb 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -104,6 +104,6 @@ class VerticalMean(Diagnostic): cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, '-debug']) Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) - self.data_manager.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, + self.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index d5a7a5f..cb25a99 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -101,5 +101,5 @@ class VerticalMeanMeters(Diagnostic): cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, '-debug']) Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) - self.data_manager.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, + self.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) diff --git a/earthdiagnostics/statistics/monthly_percentiles.py b/earthdiagnostics/statistics/monthly_percentiles.py index a4edda6..fab6072 100644 --- a/earthdiagnostics/statistics/monthly_percentiles.py +++ b/earthdiagnostics/statistics/monthly_percentiles.py @@ -89,6 +89,6 @@ class MonthlyPercentil(Diagnostic): variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) temp = TempFile.get() Utils.cdo.monpctl(self.percentile, input=variable_file, output=temp) - self.data_manager.send_file(temp, 'ocean', self.variable + 'p' + self.percentile, self.startdate, self.member, + self.send_file(temp, 'ocean', self.variable + 'p' + self.percentile, self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/threddsmanager.py b/earthdiagnostics/threddsmanager.py index e6fe30b..e20eb2c 100644 --- a/earthdiagnostics/threddsmanager.py +++ b/earthdiagnostics/threddsmanager.py @@ -46,7 +46,8 @@ class THREDDSManager(DataManager): return temp def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, - rename_var=None, frequency=None, year=None, date_str=None, move_old=False): + rename_var=None, frequency=None, year=None, date_str=None, move_old=False, + diagnostic=None, cmorized=False): """ Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge with already existing ones as needed diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 211fc34..440c4c3 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -142,6 +142,13 @@ class Utils(object): return False return True + @staticmethod + def get_file_variables(filename): + handler = Utils.openCdf(filename) + variables = handler.variables.keys() + handler.close() + return variables + @staticmethod def _rename_vars_by_creating_new_file(dic_names, filepath, temp): Log.debug('Using secondary rename method for netCDF') -- GitLab From 09ae494ba3ec0f2326a2e81aa5c85445769c1b19 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 20 Oct 2016 16:31:48 +0200 Subject: [PATCH 258/268] Added force_untar option --- earthdiagnostics/cmormanager.py | 12 ++++++------ earthdiagnostics/config.py | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index 85d0591..68a9ffb 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -193,9 +193,9 @@ class CMORManager(DataManager): # Check if cmorized and convert if not for startdate, member in self.experiment.get_member_list(): - if self._is_cmorized(startdate, member) and not self.config.cmor.force: + if not self.config.cmor.force and not self.config.cmor.force_untar and self._is_cmorized(startdate, member): continue - if not self._unpack_cmor_files(startdate, member): + if not self._unpack_cmor_files(startdate): self._cmorize_member(member, startdate) def _is_cmorized(self, startdate, member): @@ -221,10 +221,10 @@ class CMORManager(DataManager): cmorizer.cmorize_atmos() Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, datetime.now() - start_time) - def _unpack_cmor_files(self, member, startdate): + def _unpack_cmor_files(self, startdate): if self.config.cmor.force: return False - filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar.gz') + filepaths = self._get_transferred_cmor_data_filepaths(startdate, 'tar.gz') if len(filepaths) > 0: Log.info('Unzipping cmorized data...') Utils.unzip(filepaths, True) @@ -232,7 +232,7 @@ class CMORManager(DataManager): if not os.path.exists(self.cmor_path): os.mkdir(self.cmor_path) - filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar') + filepaths = self._get_transferred_cmor_data_filepaths(startdate, 'tar') if len(filepaths) > 0: Log.info('Unpacking cmorized data...') Utils.untar(filepaths, self.cmor_path) @@ -241,7 +241,7 @@ class CMORManager(DataManager): return True return False - def _get_transferred_cmor_data_filepaths(self, startdate, member, extension): + def _get_transferred_cmor_data_filepaths(self, startdate, extension): tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, 'cmorfiles') diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index cff5710..c98721f 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -92,6 +92,7 @@ class CMORConfig(object): def __init__(self, parser): self.force = parser.get_bool_option('CMOR', 'FORCE', False) + self.force_untar = parser.get_bool_option('CMOR', 'FORCE_UNTAR', False) self.ocean = parser.get_bool_option('CMOR', 'OCEAN_FILES', True) self.atmosphere = parser.get_bool_option('CMOR', 'ATMOSPHERE_FILES', True) self.use_grib = parser.get_bool_option('CMOR', 'USE_GRIB', True) -- GitLab From b2b585a09df1909d2c7a8cd3c004b3ba0a2bdcf1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 20 Oct 2016 16:44:33 +0200 Subject: [PATCH 259/268] Updated doc and bumped version --- VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/EarthDiagnostics.pdf | Bin 254849 -> 254976 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index bf335c8..e7b2725 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b15 +3.0.0b16 diff --git a/doc/source/conf.py b/doc/source/conf.py index c96fe16..3ef6939 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b15' +release = '3.0.0b16' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index 86a098403b2a4dad60c1e452a444157582137440..550d8976925e20838585040502f4c9329c5c5fa8 100644 GIT binary patch delta 111491 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ΜH{N0PGM-!7m z849joGnhC~Z$_$a1tV?m$EQGNLgvzlHxmRjeKxlu zc_NB?(e2bu_DUo{r2Zts%ZuyVn6DXYvVc@;Lu--m89YfbVWqr#obTyhWkZ$f@7L+J z`m7QD6#o5bfTPVUm6m>owGEjA9VK3^sh_K)8X-FB&rn{QW9sPqly zsXVfjQA}D21>Gy;r_t$mdV1ncBi2g5E%=Y(qD2d#^@qK%eh+(TJ!D}YwLFaDb?pWTFcGZD%+f(uOX23VdhFnlAV1l z({0x~Eqs}M^&$8MHZ@DKgfU5dv;;;4{$GienJsai_D5n>*GgRc!Aoar@3gY9iJj|> zJC!)`)bkoayRF^aHLxm3i5a48E?`Z*ePU^4X+{}vFz`7SDJEa$+r2s2@Nlg`aJh4N zdUANYG3E(H%JYcZd@<*k1q12{V^GkFY1(ul+4hw*rZLe%r!nvyP;`wQW$oLjCOXDd zn?KZRHUQe_(bf$O?)tqt<=F|%4Rmk@L8-!1yV`m)Il8m|a**XgAW6fh#vcF11-U z9jlYw|I*yt?jaupfpQ6TDg;*;7w+`Xr8XC1H~?ZfV+3}K3VowFTxmXpaf|PBOt0mg zwupB^v-2n=xF#S;s)&=wi%2N>%;QFv3aAVfl*d~)o{Cg; zTDjCe4F`xo{j@vD$vTwn8ym|NQ+!v-g;$%^2{8p!h~JwxZjCOm{DW_?rTcdr>?#R< zZUB^OcFFX|nO)|Jh6MY%iVCrI_$vrnWGCsezz9WNzX>OVHKK(biI^PX!mwcyUSKXS z;jnm~>0xMD`zVP7_fvCuP?lgFovV8%isVT_+oZuA_YO0;x-gO;j>megN$c55ZWkhV z3&B|i@6_dKnQdh|(Kd&W17~yZA+AG%WPq7SN^85%y1zyL7xPxg2B=PgtF%0DazU}DJTJ^FBD1L2X#LP1+fiuR2^!Dzl}2!It| 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

    SDBBg5AIDcII- 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 z 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�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 literal 419104 zcmeFadwdi{_CDN`i-wE#h@b&M2OKmgV1lp-%c=yE zDC01gb=_Uobv3%`;%$w}x`?h$xT7KgQSk-=FU$Z+M1_Dt-sh?Ap41G}e80cn`+5I+ z8)~}FQ>RXyI(6#WJ(ES*o@*0qHpRRWm1`7IGpltZ(@03^c7_pCluTu`at1z~%0R)J z97#Df^4`4(0yOW6;t({;pv1I?^z^ic1_|7}Pye$ZmA1$9yP1#NLX$`Ie99wwKJ%Vw zz~(*0$e#PPw=fCuq}z3d*n6Ro&%BeD*Nw>6RdXFX-KX71oNSb5Rll8Q>5S&xY=JWo zxftOZBoD;B3HSbHBI1h>QbA|oem4TIhY)^7_ywU8VFtnq1o@)ew*llJ6dDQt!hIIP zI)mnI0>YaHJrwsP2zw1W_BJXO0DT?83kYKnUPibHfft+eYY|hFxw!j`_>;KzhHihv zeIvqh1Aof6%eTHDW+R-Cz`GDnLuf!4fe=8LhQO-^;ed!KN;B@C8}TyScOhJc@Dsuj zgqaB6Bk;N&p$$QWUSHsT9HBeny!zli4)@In|3!EUf!99~K0!!A*o{zv;70fWp&X$S z;SGev2#+H?k8mzzy@&fMgx3*xJ%g|sAs^vRgrx{u5ne-h72zXV7FnFwBlbOiaj z1;ja!S&aK8BO%EsgXB91)d=q**n$56cV2(hZ{oASi2qi?iV&ZVa1ddEfhQyXAtRn> zlySB}b5P1d{A}Dq2G-5sFj)I@iFiHSWCCB7DpUuHFd0Ls)~b0pSjWsR%b9e1&j+OdSCI zUtj9~bxu8FUqhE3AbTPljgdFdp!XQ}3ypgR?#9q3ka~O$Fw!nE?l0j!8sV(}WqtdB zFU80!-&#QY9^s?`CK&fH?yn$xXVA~#z7ydRgLdIQ3}L@P_lnWu2LtErT!b4DCL;U= zp%=pK2)rgEa6b4o!ZHM2I}rMan4&yk+`lpI=B*WxD-7aC6O``f8}W;A?=IntereDT z#^9gD&=_Od$TJ7}_KsFeA8Mir|;%eMUUf zxDS9nJq^2EZeXTA*g?}5gBROU(y(l?o!jS}#cd54D}Q}!t)uB4C8?yb@64vU^qy;# zv?*5)>h8(yEAE~P3bjDIU}K0VQohL`fKaE zcU<^Fif@P`Ju&gl6eXj{mXLCzQkYb)tQX28)%C8Oks0h|KkE#80)3NhdKUtHXEDOP z2pnhVzdi)knf>u0gg+wCHp>yrdFTH>=OiDa^K$tdJn>v2%J;oi|rjk2pix5+&Sm+GW)>yIw?L68}T1-KZ0P6AB2BK z_yyr43FDHs878E#KbZ43*9!D`uC+`*Gv@%#F3~ti+>4Dcqpah(lbV8y>Y?B*2F&|-d0t8(qXR0Jh6eU6JA3d|m)>1_&7n&ho_u!G7bVpR!|(lD%^8oLweQ$}Qdd2F{%5b< z?{3a@Uiq)B`&>P9#t#1JGVr|~`2K9(-}&5D|HNf|%Z4HT*KOmLJoD;%gP;HT#d&|t zx&7R3>%ETqUwm)yQz&nCx4vbLA6z{TKl{&33ioPED~ckY8Hj=S#s*Jb~nwRSdi%YW^?!IK{zkXus_1(tzymjS!gMDA*58Cm~ z=jA(~TlwWLZ2JiJ*G7)5s5|m(pHH`acVG6A3lpbx`*PQgLHRrX?0Deek3a0_9MJ8) zhxh&XRvz~kfVgCn*&Ys~Y*!>uEJm$)~v>bWoB238s@ZjEm7Obs6{0}FC6FRg1 zHQ@W@yWdEhlXq#_l=A+!ysfSIbfq%xrEA9bOergU^3Fw%+{OD#%Z9Xkc){CsA08{I zzWw@N^6u{UQ}JxrssVL*zrx>T?BoQ;7V@`D9LAP&zbS@ zd(bb=iDd@;G8RX@;^5OQ@a0MI`Da6TJUPp;;Eaclwa~xaqTJtG$bZ8^AC52a%I$>w zcy_qe%5E0=K)m9JW4C+@d`4n?eFmh&$LCq#Ef)4X&%!<{Ey{h|!Vb?^l)J&g4ofll z$FuX@XT`_sE%fPY(T<}m^l7m0pK%s)>=yd>w`i}E7Ixlm;U`Be^a)tB%Nmp$&u(QF zu*0xQSVVy;}3oPV6YQcZ0g`ebF^p`s!C*HWX+oHZa zn~TSP`5E!;Tx?P9Z5H)<0~^nH{?K6I=K%}<8Dhb|2M!faek%?w;^8?Kc(#T8=UMRI zhjQcDEo>pjZqZM3EXLJx3x2yrzi6~5cL3Two}PA#aqKS^wOF&({|6zp=2}4huc+varu);h#N}TI1o!^~lfbG5F6p%K6HU;2=R` zSP<6@!Vh~WjSEmgTzjAguP21vAZN3VdyGNh85{~zj{spmK6h-<|>+e2yEtMgxM@b|~Tq_A6Zw0xUc->uPl zqFBs3r|#n}H~HU>=5ICS_l%am*RRsrBla~pdYU`7(~>!U$j2oLxjLnqVYFG|LvjJZ`S4f9W<{rLyodPTF*Po zdc7Bor=t8`3i|22x|}@pH(n>vMMb$vbh+zHIh&*9%z|Gv@q zHKw2c5?$^uD2{e(^6TYs-O1}YQ%-8Moa+odTd&p`7bWWa>rMXiqxqMc{cX92}|H|M`zre7Y zQ|C9w;c@2tbyl<-hiSLOX#8QbUb~~~)ywEd%C2bqMzf!`MdQyH{?Il_*K?pT-!+3g zM?oPOdbtLy98WatGf=P4W{eBG?lsym*ehC3pIPpg(dDiJ&VJOqOE333{iduk{o$i% z{uO4sABn~*O#G*4{2kcY4*hG>41IJpmA{*Mo)fL-mqxwp|Iis18xK#PHuP-$OjnTm zI$raQ@vZ5&jvK?VGQ*hHTEEfpPQ!3^bG~cS@ss*Z8E^K}Z=&_DG28d!X#7@_|LbV{ zV$=TzM%U|B(|2YlR)oKc)YsoBsAibh+o5?R9Rn zoPoxCRLcigxV9M8>t&9^N2BHZVER8D3D*rqeeX2qy9=Y`SDNi;tdoa{T>7(0j&BtK z9q2Ij9WSAL;^u?l9D~2gSdX-mH+f2G&xe3uw6X>kfZRW4_qd0heHTCEzxqS!9)FXjR%Tw195!|`w(w5#*Hb4-L5kB ziAuQ++-s~eKQ-4a-$l!R!_c$sNnNg~&myCL)m|EH|AprGc05|nRp$8lNi=@g;8)g1 z<7b@S;hoLAxcy@HTKb!pR(fn@1&+SIL7bNKArkefwP&B`imp6M( z`P{rJZ+@jWFHgxUom=Wv@``a&^4wE%@(PP8i)NQrd5bEi=1eFnpIbCFe^yzMo)$kP zuV8*Y1>~2NE(GJmn!L$|gb8K&RaHe*O7Vz_1uUnups27ke>O_ZU63~kvZr_}s|&nJ z?gCfk?7ZCk%BrHN)fHt$uDONR7cH1qURhYB= z%Zf(k{c0qTsS7HK^7w)HwdIxG%KW(|>7G*oAWy&PnZR_ztUHPdym{9Zd0k#_Wu)i{ z25yMTo?nnRxq7a*bWRa;F0VvJLb|L7g4*Olb(+D<@2a|~ytFXaTdCyDtw8NzzdYCE z$*viBu3R_xbUj#nR;jR`u0h_lFjGVsnrTweJd{{e;Vl(4H|l0+i9~7yHsEvesQ}eu zjY?-#dm}oZlFL;^9wYCBvZ8#(4HaBf5d|crA_e3W&4HFhMM{+yo>r+8SFq~EO7XnP zQZLO<4QM{yJlBrMUBD{lp@H4rBC~SvpQt(r7QH&6Dcx05s%LrGo^y)kR26xZDx(-( zzVHpbfGTfg!JG=R6;v!h@j_BoQJGX&K{>2HDJxHSqC$-(xIpu}u3v=`56jkLhsj?_P0w{U2iw(yw&99tYAknjnFjmaY zD;+6eRYhg=e<;X4*Oj-*TV4@CPbsiqZeH=6DrguftIC_FH+&bw&R11jRGC*$l3$r$ zfPv@~7Bg2~A;yq66=OLiv(b6-P~XyWQQ3l$JBv#>kj2w#eiSPzTv$3MKIek?Fow{0 za%+k*n9`*MMAx9VSTK*U5Hq`?goAX%Y7rBm>lDrIGEh7fO5qINl2SBi+*EYl!s5#O zC?#Pkq2#IM!DGtI){tsdQO#PVW3=wlv7mfTMSf*bmos!3p#Wmg*JZotkZzhTM#wFJ zenpi`VA<>jaqCgTF_vjvnRQcV6h?u%rWu7JqtJq~@~WcpY76U|7Q8Zk(QqnZLL^5F zruU0HblyDl5V%q#rMxN+!ycxBE~rwUAq;#@e(78(5rY>7p4qZx36+ZxU7uO!RpwWi z-Q2uaVUEq4Tg16fc>mnuG3m&J!Q@o9bnfr+VBk_(DmII-OdK2)jID-I=a~AU6^iE8 z$QANp$??1D(#mKD03VyMs;IIQ3x-n_p_1s7ag{XWF}-MR6=%9r^Fux>nU_(RS6p6Q zIcovN6*!ayXTBFEo?G-kv6=mtl@e!ve z-X+%Te{|q3w6aL{b}PB38l+2to_}F^T(OnxL-C}>8jnjGSub5`=?IJLY$a6IJFlFL z6hCtj`(mt~LZMT@(Wft_sC0ITSMr9g{QCG2Qxd?rP%x@=VDLPmSVhb!uQ|oBYxLP9 z)>d>$+R9rr9|nqy5SZNHndpoWBzCx$k_={ZB8<|$s-i|XcO&3RTU;~I2ISl zvMKdiFIX7IYNoeCXMKGbhlh1C8ZfGxRg}*wwqXCC+(p-DJ~fJ}9*P+mZ^$xL7HxX!ld3UJU-I)QIiAQ1v28aXH6lN z_$8-JtUg^%4A9nM=UF6{<$Fi40pjU{jpOOk#H<`QU%oeH#zs?>R&Y_<)%ft3qQbnm z;}3R(Me!UBV~*%+aR&8RxmRdFpP&a3njZiht)3G&%5iHFly`TfJiq7!e!muIc2PV9Pt>mv6-;y#6=laJ-8@?-62+4A#H@Ev=Nrl zMp#O_(rWZ6y3%R@DYg(cyDWc>g)}BvsLdn`y_sZH7PeMa0+D1T5J^@7ITXh?`D`Rv z*rLQb7n3Y<)s*8%q@u{mU&^a+Bxkijt|?zwUQp@fq!iCP%CViQ^jhq8Ymi!0T4Q0H z8Z3d3H(n=!-&K`YRh3}ui(hV4`JDM>=^5##N%f|Wuu3f{DlRMJYBf%cs>;hsip#1i ztWv9Hl@wd2md!hzB?nlfyFdhRnF8x3!O_vs+Gv_k4>v_k4>v=XTnTCp!!?f&WO zH5MIO?qOVpFgiY&}@`phELGVdIb9H-d17)*axXt`W4(=65))~lQ1h2rQmj$Mlj z$}QRh^~Z)1?kAUK93DlW0&%t-IT4KDViP+LTcr4vEU2DkSxIv&vT#5#++a|!NUkZb zwrDW+G;e;j#q4NkR8~4mUp5Y}Dj)u9B|;XH9z|Mz#n_F^3=($NqHH=qlk3XE>5C)sVrU3frq1!%clJQ|Ng(QfNo$)ZWQl& zD2fA6b-z-)DUqyv28@>tt^2x>PS1Pz4}V7EoT2P9Fr7asihq%j#{Bg~$I#S?%3%Ym z6?B5q37VJr`$*>dZRzuLJl**HBol8p-m{n)gSWYLPpYuMYh&=Q4gN+8yeS6XZ}2x; z;K3ODkip+-fw#rr9R`291+M&YkT8g8hhL`Y^|f2zju^bt;7_-}Gh^`Nn{@fP7Wm8< zyobSGVS(4i;O7|pjTU%Q41T`B-)w;gWAOe4f2#%F7K2}8@V8sw%EQt2ztrHjTi}iu ze3-$XZh>dU;OPc`t_40b1|MVaS6JY+F?goI-)Mn1#o*T&{LL14Fb4M+{H+#vTMV9K z@V8sw%Aca`f1|-~x4<1S__Q3|pVKYy%ox1f;Lo+dn_}?WO#4{i!5BQxw2uYe7K7)T z_OZYne~z|~sZY8Eo*9Fi`s7;RGh=X5p9%}SHU{4|NwO{c_s!M$n=SBQ41STp z-)e!k#o(1U=2Vsegq9UK@j(`ZrqO zO)Aye$Sd^>4SpGoOmKze(5rGaC1e)7xc9 z48GLB8)NVX4SabFzI(bZrzr;ilfl0t27lbZgE9EC2JUz^TF+WzeV!JJ8};02y!UUe zSL?3P^=Xg6TkqA^`O5Rr@|C~ocuEXj@fRIWjlt6mIhiqd;{!T>=A*iN?kM?NO6H|W zxV%fvmGCc3X56Psxbc-GkvdbtjUokJBH_@{3{7xBH^1Qyivkmk?`db{(A{;lJF}ee1(MnQNo)g zyiLMaN%%_=9+dE)gm02?^Ecs`+$!P6B>tTeK1#ydBz(Vwha~(v32&G1&n3J=!i}#) z>8X!(`TtK6e~N_5zg=gS@Wm2;s)VnUaEF9vNqCxs%fIcJF5%Zo{G%oO7YWal@Yf|= zlki0no-5&pBz(GrAD8f%623#iOCM`k?>6t&fhsSuT}}KGeO*UO8CDe zyiLN*-(6&KNW$Ni_}eA?pAz07;g3tW@_3j38%q$8nj+!mZ)r2ZF5xdqa#AJyX9;&m z_>&TzCgJZ&c)EmtAmO7Wyh*|{CA?I^H3@H*@LUQ1hlEd;aQ@D>dCipY1{1`+M8ZFk z@Cpf+fB$*Dgufy2*Gf2lC*Hi4NH~Af$-EjRe7gzazFfj9B)mz&4@me52_GcMZO88C*|3bpsB%HtPYF?>Ly5HjKh0-${obgL| zqREVVnuMF*`D1drgr6btkCt$jVP2UMZtek?rb&1=lNtA13GXi9( zl}Pv#5mZqsBphGGi(K<1-24tD6Kf^h9^uB{4Uq7C65c4`_)22rS}x)8I=M;0*G9N8 z-by&WVjH=dC7i$gXkM!%ypIXu9+YrnDn#SdSaS{Uo7#b zOSn_QM@#r65}qmH3ng5W@Jl5;SHjaIe7b}Wk?@%kewl=qNciOvULoQClJNNwK2*YM zC488KFOl%!65c4`=@PzN!ZReiNy0}+_zDRRNO-e^Un$|MBz&ZV2PIryCvTGQUrGF} z68>um-znjvCA>|-$4Gcc!p-mKGr3*DpOyGKB>XA~SDx(h|FIIDBH>p{xLv}>NqDM+ zo4-BHWQT-bBk`w6_-`aUUBWXZe6)nSBs^2XS4p@g;o~JdSHdSq_;d-+mhhPp&fm~B zuM!Er&IEC zK2ySTB|Klkr%U)O37;w91rlB&;e`@jA>l<5K3~FXCA?O`*Gu>k2``rLMhTxS;makw zM8caS{0<3UA>qbPg^1K<3BOa~UnSvX5+0QBITF4}!skkOtAu|n;X5U~T*BKV{C5%_ zlJLC}-Y(&l65b)b4ed=5_CV(T(XB71>K7@m*nAEL3bz3rFghP z&$4%-F2oivx) zVMWmIkmeFQ+mAC(Wf}I9y@=}gjX zf?iG9MY>hcuaF*3Iwv zxzq}`9~bRUnoF#3o1m{E&81biRnQ|ybBPoV3i>kAQ%E-pdJt(YmBLMe?njzSq;R94 zdy(eSC|oP(?xeXS3Reg^fi#yq;hBOyj-k7ROPz48pbwM2g>Dq`4#sHwpR?(nX{j1^p0dE-Avbf_{MXY|<5izLzv7pzusVFC<+`I#M6mzi5jOreo^Y0=GJIHD8%?`o=8h%rCm*SEjR^xy*z6 zRL)K&Ns1*;tf_60<)=HkHP`-VJo$bvfpL9b!P+U1%-b|=NQdV8TC3|gyQUA8Ro`5qFRQxU z*4b7pOZHBO(x-ebo zSb4SMe2}A5U#iuO`xqG@()YEur{*6wV%Q)h6hMtb8k+I84aqaXX#3$*eQXy%pSs^D z)jh(ugHzWV<(CfDD-)*3&eq$+`bzVSdpTo}veq;r>Jvt$a3L(l^`h%$&39DuedM}H z3-oy@Xj9z2_g!$Av%Z8I!+EB_Wi+fFA%73+hel=JMx@@^hC5_+0u#U9togE>75td5 z`RbjuNacNrac?y4%XtsfJH;JRLZB&y65FMChZI+!fyu+SIm|eJbli;dX@ePeNbxi& z&L7z|c}7d|CX~gCI;_y6BHk>;S4r`p6yGGpTc!9;BM$3~W)yeM>bz$fclfiQHRH}% zPjnmO&RK}`bmPuhf%Ht{UdVf{Y0Nm0jG!m5R9M;ri?ann2adqhb?Y1%+Z%#v{rE(5 zWxw87ufrh9D+zD+z)cIRbkgV{kLZ(YvG-8xYr(AfGwp(LHO3J|@G?I|GY<_<4@e1} zD>AMZ8Sl5wxWvfFmSjeI=u;@@_N@~c-{N2uuSEJ7ifdRcu64~s6S`ByrFpk19GX^Yo2Ar@->fkwYo7~PwKelQZK;>R7{*)SQ(c*fr9tnhYs z*IjN?>z_cPXY8B8{fS)x>_x#;=A7^C;jWvb0PzdtDKShD9O?wP0a>-NF9^5xo~e=3 zTdj?K)LDxJ?-?58d#7nAxkU3%#mC}x8pLS6*5BUdy47`?>vmV(T76s&{d^extsz+5 zj3NI17sX66`c0b>nu7ju;BSp?|AZ8eZ+B;Iy4W5!YM?O(fG^+nLFjZf^S{mf zeWLQO|JnYgb0=!ODg_@N->uFRKr5ZCpfHzQ^tMd_{ep87Xhfb8ZHCCBqA?M9ShOx8 zOGUFHQtxa6bExu1y){ui*fH$FW>&pOaihK-y}rdjV4v$icT)W<(xK*X z>-uMj`u_y|uK?av|IqJE{$!m$QRnxPe=GUF#V%6fzux3;0S@^e;6+8u{x6XKaq>SK z#qXNxTJ;mUf5zsF?U*)49mIQMLkB6E?)oduKj7p3SYo_GiT<(R84VsfY)Qf7-Dw4k) zcvSa4(;t!lFUWu3Eqxt^by_P;Tt_A2m_S??JMnKH*S5S2wHnrhKL_%-TfH?LVh>G@2?It!PxupQr^iP(8GU&EC;izGbc$ghgos{~9QY`3L$AvK_=CDRe2+{w;d#Z79@r zD-!<#Vd2FPF8A*@qwO2sK>zNvgZ&U@*wr+euLTu9#)|t#X9Pnxe1|gp1MFA;hDQo_ z9+1SvU|`f79rVu87gJfUJfmaZnvYMR9Pep_t{}x$x3ujLr&ZZ2E zy4P@?msoxOfTn&ZZyh-TqrQTq18+k>f!-Wt25Y^}T20o!3f6H0@rrWjJ(}4+st@8Y z2peJH0lB|vb=OdxYS^;+Ty10RbXb!Y7Ob_rYra*4BI{T5tx*eEX5B%1D38L?Z2u8` z_A~D+j-E$qpGUrw>QQKoVz%_N!fHLVz>Q!&7rm#tx8|QBh8;1~PEO}Yo`OY@{kLny z{$oF@I*voC=Gy?f&x3>mXfCYRfS)6Z2XmP1A+`%$t-6Qi zU*ym*jA0Ce^xuZvG=RAt_XMW0=&#ybos}J2xVvt4-Q=3)^8MtR>h|q$O`bwwbq5_; z{+m;?8@6MfOF|Dhsi?~yMKxW}1%Hq^V>`wcMR6Cb$?|P?`+Kg_>W0PtXpTG=x8S0bNk|=WeveDoP1&g_3IhE_~`5W*l)Btj`H}*LAr4 zXS>GyboW`BZH)g6a?N>*Qbr*5Oo?K?ZmKPA;Q=J=wP>;@=)26z#1 ziK?Rp+3F4J>-JrwwH!*+j_$78mzXtXqf5Q6!&TSOU48H_Xt*-M7wf+l}Ot0%aQ>|ZT zlB4T7Q`GwBO)|5tv%A{xkV$H*uvu52qgwwJBEDm;Asw!_5kpJoY;py(U$O%^oh{*n zx)vL%nXOLRniUusAcJejF<0HO1oggpa{KSzwEjeS@@5QnIf0(PWOS};xx2jE`Y)yMRhTKDDM zW6;dD_H}!X-LrMwm&eZAOxtfo*hZ*@4M7-Q3n+Wc2DSc8H2C_Cd2k8XqxX9O4PL+H zp7XVW&2_;90lCJkzvoPCIpga*V?I^uGckL5{G(Q8j!5IC;_6qaNRx0to@({NpLu9{vR9 zsO-mm*pD$6?}S)S!IV_DZ*BIN{c4~V8gQss_7^Z3Lk-q_igLiw$j+xOdj^Di%qF#A zH6mz}?=hfcjoE(pNDaLfBag?Q)MAc44VxFdlhY9NU~W^hwsPe0rLZ(+L!P_dLl;$- zEkjY^q4+TBr`BJC5``AcLfr`tS70)ZiL`*HHKl93(CS9p0yo*z8xCuA!4z%Grs{9Q zi-j1vD3rtK&~OWvzWR9gvW;bjdF0|-10%d}o|plD`ZrsHb8ZjJ+QQmeps4k?u3OCY z{cY~Rtd6xA!2|m;g4B5Fb121K_p{A=08Ui|F>osQlI~QPbYWB9C&I1L;WKorW=sUr zZwYTiV@2izs4xV1MOKXE@UVM@V^Eb^@aqjr?{shCJ^Q=*qZKb`?fTHy{si5h$=J=Af-2e_i0t1ED3MCC1*N_Cb03+bZNj9^2jTK{Kg9PSW@P_-zAeK%YT zpIpTiOSl}VV#5(GV(d&}zhw-oL?wJ9V;BgP@O6w~98<#M7-LrnU&$D{wh|t~7!4o3 z2r<10*zv{AAuwvsN*kLbJcg%?=6uW%0F!lU-Tai!>OmfV?Mw)OyLv}y{w329=lPMOoNH^EqfhqSQCRp*N2q*qOk@*(-aZnNKFozNp(yw_|`z5L|C zy^+ax7>(KXikWXQ4(>uPATw9Q-9rf>kpIQUDl{#RbW*TL;&I}MDY}qxwNNbdw=a>1 z4FvLB9C`~PG~WaVsXiMg@OS~m?9_aBrc%IfZ=*y1B%gm`DZ)cQu?9)e8jg4qupjr2 z8%)ueLbSeZ;hz-?Rzz)J9V zz~e6XTr2&I>bPw?UH*!cx|5yWg*kfL=V0Z(#pPd;i{!dvz0`)ew7ft0H-<)a-`Rxe z3*L`b%I)`TvS()mZ+xB4oljA)ArE2qmTsP??s<@*>bOy5bitlRhFv?;!KamE{hVn zBdX-`ZSnZls}BcVE#D?(`M#_B#+JFn>pa_=QjhbN{mikpRwup?<{S1abr9AzN1+I6 zSprG^3Wv|@Oi^E}=*z6C=1ivKJ{;k14Ao)p$O4|HP~Yc~{=9e{P2usiNk=*8SJ{}mhr0sTb>{fK&e-k_l&!9;{Dw#Jv7JxIyep5^Vr!FnASNID#9TF ztrI|ox-XNw$y!~uf|c*V@MjpuVUI4>s|?mzl)cuWHarXaY5tti+*FNm0pOvl-_;+- z7j?(G&FkiZ10Yg!c_8m|Q_E+N(4@a3B(VB8&x#4CsE&o2C z$nN{j<2#B24VZ%#?2UVl@5dt>vDAMYGrik?lbyA}Nsis+zX^-1Ywc(q-!wGrO%9ju zT9ktk)HlrmIt{68=QPl1pwmI8fyPF1S~}>_ps{<+9t|4aaZ@Jf(XfMWTBf^hxDC=W z(S^`rZvVCL*P}c}8wRp#{LuWl7;QFoPEHS3Vfw}SM3+x2I|zMWAHwbsD0K2*;*w@g znfrct%C9-bc+jtxU4UxC7yKi%x;06G`#MjaJh^VKb~re=7MC~V+tBiz{n^@DblX%r#?xJ#wb%7NTfxecOuqmlU3rwV>ZAwsBOso4evDnug zRe7k}ASm|@cLO+&yLAsL$#pc_M{O7eUo_eV3~Zj?BTajwI3IuRpwQvnz=uZ~PF?MK z6TDIG5P#q&pIEB)2LBWg5HCrG_D0cMZ(2cqK?%t;kV72ekExJM4{K<6ZB>k9JaN$_ zuj-PF=P9VQwyH}w9+YUSx`gv7$Eq&jSLN%JLWtGtdm)m2`{ zEX_AQ1;UZ&z^^fbvV*y*Xg2=j0BSj&y<_x-@eU=t0M7YV3LF4K{m~_hZ>Xptduht*ptnx-|$LeKgVo0c;4`&x63xP3%`!5T@IIQC?z-Ykwc!aAC|=L%@|=bZU=WXJFj)A{*6KDS1>%f2>RXfh zMvXd?X#4Ngw>(aj1K2JMV0@w<81>|{I4ijO69_#MrJ3s+9xuAN_;d4wQ9Rxk>$K}I zAz>)SjJ3=Mj|fbM$CYDKu-0ZShjDsqJ8_Mf*KmW8jbmr&eo_!{vWF7eweUJJC?a z^Avu$17`%z{#dTL6FIw9JMgMQJ+~?WZ1NhZ6in_;tV#7xO3?!M*tLRf5T>>4O$?3u zoc&;*JMkXa;%!zG`f-7XV{vy96tCN87fXXgeIr*O5xQ9(Wq-Jnm!Prim2n1CH)I@CUTXMVjwZoY9K&2W=yo5zhQ;K6g9x1_~E~N4SkUFi(Hb zk7qQ7-{gHndHP1{49ePs52K#`KIgE#1EUuGqsvsw(7kA?@H{Z;_P}{S0{DE#_4jJT zMzEHPL7o|49QgeQ5ZR@laomr$w0u8_ZT8}WtJuC`{Pq4Gy*l+nY@vJ}zYFCwtHH`WYfXJJv#O?TIRTdn^X7?x3=DP6mMV+$@eQAmrs`4?|{V}BMHci;(| z@;Z-|G~ahWJmbv)w7&@u2V)(&9?(H@@gQ74)jinNuw)md2gdyrV4LoTQ->CAhhtQA zwf6*vXc?U6hHnE3QK=9Wx)NP83$4TD#OQ3c&lZ{wuVG|zDF`%`1Xk`?T!o)N!Mgth zMomO^cr{Kduqb{L?n09f65F%m|A*@=ak9@PmS@QEVwW!oD`T9uj-BeXtM`8*BzA@# zKnXZqz(aN(hJ^g6p2jUE2a5MUL?y-+*wsJ}D4$bskSVFFg8HQ$NwUSC{{H^oXBt=in$^*9EH^d3sGAn4Q0AL^iC`F*|-6ofU_61 zem{+h_CGmL@n7u}2heQ|W;$IBU5>o@94^ZAFjFWxIQ9{bQylhMe&R?XMb*%GoJ zU88S8TD8D+oH09;?dn@M_BGZiH;GF3bT$MvzpeUuJeacKz)ADrVG@RwJwgK)#-goU zp>G!?o6i4x2lm@=n9$Sj^ZXb`o7*89N#V&@K!|fLh%)5VSJDPz2v_T0g$1%3j;PC$ zgef{tvuT;|xW%T0(?G7dYY9EHP4|=zxDqU9^H%b)W~!_1y97_5Bz022+wS20=$Icv zH5PSoZMNqz+AP{$F4}98g6E2O_aL&gyVxkshvK+n${F)h^^+doX*~2T?j)nuF6NF& z-z<#?Uw|c$G2g#k2xcxx?4j3TTeJE`Mf9 zpu!ej$-RI-(sGML{~Yz@-??4H5pC#p_!{!CgZ+XAJFWU}7f~a#ShF5x@oJW|1JqW{ zEq4@_7gS+rFt#`OHQ3SNZ>i3P@IJZ#9oe6}1Lf!sG_FE_51%bcpOA_}BmXLP z(a@`ab%*{AK8<6i(6)DlLp2N)y{#?02+QBoXo=$f`Y607{-&6Ea%K9laN5wnHwxPY&oEu}pQovbRTWkZ87j6G`H@!TA4`K#ocR4k+ezf2Q{-}6&F2`RA z?n^X(4YzS#l>LPVg)V_?w|_>a`|=s1bNm@O{slO+a;4{7 zzQEz}PZYZe4>HZ!=|PSPHYL_%BVPoHp|Q-_RIDBfP7DkcPx*6@#}jah zxSFeq5mcG#K6@JA`|Bt8ej$A&}{Pf-V`ssx_!IpUYLcaIyX%UBne(Ne;Y?q zRv*RP>fDLWQcnVp+At^1#+>L5OzQl>rP|N0+momchX9YWxn?Baxn0F#HnEsi52l2j z98ucH+V=-_Mk*pRF5pK$PzclCWs_|p(@vMzDr(5NiaA^HNcz{40{sVSfu2_hDIVK_ zoIvl(JhnACW4_1w7$YAi>}GVkcc7ez+q?_KJ;6KX2i5LShqu+B82jZcQ+!;8f`=gB zJ{^x{uv@jYQ?Ttzw{5>>I|k|CPgjSxi;QELQG8s5OprMP_vu?LGG?iEB}*M1thw+9 zM0@;@tzzPd<5y;xEXC2F|;$sZ6 zijS+9b!%5v=xUbSdkB@L;YDLdTAV%rbo#qFfk}yxoDsw4j5($@oGCUcCp}opHfwco zLz^e@E_Q81=^S?YR=Z{sz35i@j>p-d`FlGxn+L9JgD25_Qap&YX=Af6h%|@;Gye2+?KydLP6qC2Crm2LtT#!!Grl9E`y)=v|zS-8BaY|38El$_d=lNw=b3 zu5jTcB6WDEW(ai*!YcM^2tYrhYAaA>494#Oo^d7O8L0j@OlYE(LEY)mTv{OM${PZ= z4pv}8I07AAt*>WMJYNu-JiL(Pt#so(B=0DcJz5>!QPUUgVozk_B(Pm<{77KCv>7fI z<=1eI6tw9kJ=?j=){8mL;YTlK+iQ_671?&`*)C?bLCi6bAA^|ft2o(&H?M_}!DUZF z{*a#kO6DKItQq_m!TjIA7bpVSl6!Q-Bap45<~*?2&&3CHq_W~ZeJ}FpwSzHIb6YhLiwI{oD++y1qMuu|SxnZQ|EjP^~M??cTd#$C)Y4~q$BQebGE818cdN%b7cr&IWR&P%LUh1<5> zIXyFt zj`{^-{Sce}0ZkiZr(LDLH7U5S4`d~y%f6d4=4W?c=m<}s_f^*idiPZ8zZYHih+6+8 zv~*(;t=97^8i*x$v+3mN&}P(FYI8BktDwxWnpF7mGzA`hF3UYk4Mwo=kK8!x<)Xp% z6AE)OqEci>uQX~#%M7HL|BYoLR-rv~%fKpo|MtJKikumv4$TUSJk8AiTZ<%y!`LRt z;{--)@+4x_sM*S}QX1=ZE>RmMVxZupGn%G!skiJG zPbBeu4)zzwDRg$Q6L5B#gZ?zs$&Rv0`1y5`pZ9l~e!k}s)Zq%)+FqoHcDR_X+ax9| zs@2RSx(56M4Z^0G{vlm_1r==4U7T5(aXy)JePHTYhMQ}FvQg+)y{}U1x0pWuQN+jV zOdrn_P0E(MnVN_Nk?!N?qM-~Q7ehKcYkM5e0#_>BsV{R605JmI`F#yD-%a;6#%v3> z1ec-?PyYO`$n2md39vy+O&>;Y6TWDyqu8?D{ z`_o&yGD2Ux9L1c_I{CBZrUCjv>rZs8i-gw3JPxgQzyOKi<2-&b)?0;f{kKWXY=-}G z0)+oI8~$6#i7p#{OTS-r7+RclGs?yQpY|b~_VzF)w%hR*4rWEnQA?efa2;@+GeljM zh{u|o&bY?m+%}r4vsw`5EWrtiTRqN)nuboY0tBZM4GFCx0oy(|R=rrx1wo5l7&cr> zDYl6KX0uFp%iaVrnc1-6!eN!zRz>!CfuuiDK1L9+dBG<705{D$MQ(f-`-XsXF}Fsm zxVtOCjLW&}2>Qk!@f?}`B%K>qU9+#TJAF!Q89lzCP7nIiOgCPnL+&64gZW}AwCxZR zA64Xb4{N`taR5E?--s(3DhJD*Amy-JqDFIme2LTuhiv(su1lVF6U0n?il2 zgiUe4m?Wl4b9?xrD8|@AighX`RGppEcVr&Les3X~ifT7;(aW_i94lSDKNH_X6;mK{ zx5}G0Tbn1)|1wO48BA|u`c7=IxW%@$h-KlWV&LfXR%115^Ij{~wCrUNyBT7+6!buf z?SPyA4*>D#Aw7(z1o88Wl38!;tPU*H&#%lv^b)vbVksEiMyU5MN`d2;3^7`a zmD9}3y+`OO9>D_`Zg5V`j17+Wax&F4U>p$BtN2JjZ?++b&fFosBq;RD;frb90&!r* zCWl)fOe9Sl!0ogvb~$2R5qs#~aJ9SGEwOp_*zVHzK_Ph`G*rw~hd#rpBRg3T#-Kwi zH}^rDf#|}Vfp)_I->087#q59hL$i`AT&doljORCO>L68W)?Hy@AnD?qz^%jZc2e&V z`m7^bQMAGiwgMiYm5BDw6zxC2XkW-O+V9lH_na}ez&sx@8Vmb`j>tYCMQjn!bU0@4z(iOBVExP0F`CZYC;USU zzT60K=p5Dmk2Zy)=^jdH;`q6X zsaWOWh>F_*tou1)&gWPs_NP9aO=Gdn2?8_U$ND}1ZpM{9Mg%0h>8z!;+)?06YbRBl z7#JyzogxENptmtlVG`mP`>kd>grlI>F+TkrnIWmC7`(*T$dBbYzJu`9EgUD?d4h?} z4ffp}6FIO75AVP;G(681>!k;U|LXgKtIhS&xR?KcnX(5a$vKL8e<6IqSPOZa%k{Mo zbQq~Gg91axGO@{H+vc&Y6-$M&VnD-cpSp9k@4ZE=^l{3>v!qc|D7`zp@G|xOc@WMe z2X>^I?F1wUIb6r&-mY#E~39nERDAryH=;=D}fG}=A7MemXL21W7VDA4qeKGP+xtHCAOJvX}Dxevln z64UNttQ5lu+8v{TyxwHHbEq8leLx>7J2^mZ;l~LN#+fv<9cME>J>vj16LlQLf-+!{M^e8@+9;OhwA9^u1Y zE}p1&!?)tGVAuQ&DW{$mLe!@41>|eQysxiHq822Z!e8Nu8J~YKJ?5|syN|8mf12s2 zmw9x6I@wSj)O-_r1ATwYdYgMDq-QYwr11WK-JHylT%=+^OxN_udgQthc z{9;VHu{l&{9L0J{@Vp1|yPNu9?->-!E{NF_z7{N~e`IG0?T(`WoODCQt>KUH z6fJ|F3<9nKrXxdg^^u-l=iIFlCEM`Mc8_}g9LeGM2jNTb4NIGGT|vz3jCoeW=N zw3Bc{b{qXn98P#IQfRMu{xMgG&(bH!`2JB17WjwczcKA!3kH#nJv|!yf{1JU9OhfK z5&t$$KJ-I(wBvX^QTK2D!ci@T6pW7e3M3w;Vl=`pp+(-WXFAt3W_qefuZ&7xBBgV* zQ^IFPrSp{7%+FC$3BQiF-i`As$ZwL;9U}eCsPxuIdcD{y2$tT0<$zv3@Rh;wkVeZ}O@)dzdy2R%shBW-JV zFfApn$nSqeJ&zCJXF_S9CTfI>@pdWBZxow2U->iRZBo2K;!jW1c|zyCgtr+pUf??s zE-WMK>+t)KS^zBt2E0&q0iM#VR*+E(JnF2)%El9T%1O)Nr`_uAv*84r4+X?e74(E8 zEr4g;J@INxyk-!JCB(Y_F3u3y*eLcIf5j@$yzjvU)%FbNCia!Cn8xlz*smpXf*Uer0%| zt~Gvz3Zg3^It%k5^JWL;+n|9dN?le1f64Oqd8K%e_>OP=rx3X@`EiicTl^T@UKCf{ zs4MFq_0*>Wl>^V1bYPS>1p3d#jT@8a8kxduOQYK0CGnI z%kBC>ds-Z_ayNu8M4UDF9vjUUgcTnH8=^F5tsY&8C{4nr^s5lZJ1QaXi?sWw>U(V@ zSHn^8dqpew!c1o<^;uRzzwgDoXAmM+6_uO`k`xv>lSrc z>96>T+*jC1id~tyY&rmZ&qKJfre+@xJx+!BW=Or0T}iE(G-=!IiJKo^*pqS~1x_$3Jv*`@fES@315k8R9UUpuNUI}bp^W{;|Ugt~pi)4?1=eK*x_`)5RbjvQ+J zgD$H7lu+MO@TRW*8&u!pTj{I-k5C<(FBx%Oyn{m7Xq9G1D^6;<(QI8Mj z{O-^3g+|t~7KppxfLq^Lr@D`R1UsjT4C-TRveeh`J#bCXoo-bN;>Gp#JUWEc&1UEb zrRw#-t9fh*4tDtMiA+{ysnHUTimK=hfgYAB22Svq)lgtXQ}qtuW<1rvS^W_3Y*-UJ z?@ac*6r{OS_xBB-X}&K!1t0Nog@doWIFOKohmWY89Z{adrn`^gHw6~pSArqIr9QSU zTYc?wbs2v)xZyL@>i~WgVn3f^Y7O6-^*RyCd`7en-i2emIH0Tb2Y# zp2FGe3(n6;Zw&Qq=nVYuFSoM7dZ-5VIG5jFJtYz)WTZ z?1%#vc#0HHGvla$193Xo3(i!;Se10#*(4pviXRUtXgS6A`*&$oA+&mT9HvN&iF*br zy1%0zn+nx}qb~xLYs4M@MSO`ApN}}^0SuH!;N3^?(>`?MJQM`aT6|x=;RtjtJunpKHZZK(;3mJ};92M`qcMn{2;K4z z!>(9&oGp~co3%Lw-(|t8#f$3=JMp`faygr&a$4|RW|V`M$MlEk=wE6>8#5Sfhcb?Z zjyxG@yAbNE);|pnPPKT7-f$mA$u99&q8PQnSEVj)!^p}QvkvD1_U2aOp znIV1@jfG>Kv=Ybo9^7BxQ-r{%-`<6p*`GXB+|J6r8>^&qYmhacMdUu(}0ygQwk9e9m}pxW8^ zxenjGJ0Qy_&V^cMvCb1aPZ)_6Y+Y|=B}g;ku)Dk zeDFv{IN?Uz(3G5g)>b$B!5#2Ie& zTKr_ocDHYvT7S_Hm^yom|DMAM-qXg=*R{gNdhANK#^MC zq$9~d>^e_95Kz5IiC=BW8536PHIO;J5Wf44uiYYI$`h4?(fdzLyR0l6Hm*XgGq_>kuRVeehwq$;j`{~4IZQNcz9 zMMWLrs6&DQlu=NL(>R!J?Lmxa@DUk=6}w0lwgVf2(SD_we%Mf9}b-_jCWP%&uL#YSpS$Ypq(f>cxJT zp8rU&m}kV=hGCCgeh3llUw^wf-hYJt&E(%~{>|lIEB}`AZw3F9_zEW9mo*G~sOcz8 zs#tSz{z=2I=MwGp*M2UNP3@OxuV6f<#%S%59u{7Wcg7_h(O&UWeMoT>m-UJ5+3u7E&&fsrF)3N-GHGPf0-I{h! zv;*8gozoLO6l5R8{+jZX6R7`PF#_pfdB`B%bPmy#K047pO;RP42uf0YFw@%w$=8Tf z@NqN;h4_zCIc&%W@8m>4ACyEYNEwrFX$VHTgMiwzvIz7`2HB$_U!r9N^m{v=(XFH` zH|MklKHBkCnPwO2(sTjuU7N=6x1#AA{Eao$@V8sjZcZivrJG0WXk;Iw{Z=v6<-hu_ zom(D;!2?${5_&R<_%Qjq_>Ci}1a@*f zBhw(&B60tBYmHC3G>u9Jw~i+{{p}e%67yBwxg&F35^W>8B!HFSJR)a8WR-wIMt7%> z{x4xeBo?WI39eV^lt*C=!HAtx!SP+$1Mh!{1%hbMQn|~lcLn@TsobB`bEW$)re9PG zxH|Zzjes3*z*6@{z!nOYwU@9Tlbgee2q8yBD)`pU zbh$=XG9Q`>{&WPgmnu*^iNVm28_~5Pca6aHXA1fSLx0+0(J$Guazo-?;UQaLL4=tj z925XH_4|eRr6Ksmc=S^L_u1#$kh^{$QE16ZKIE=vlQu-T=Ig{I1V~2O!U)*r)T71~ z1<=NS4Z$@xqUY-SvtV^Oa89S3#I(g@IXS!p!H0MHHnnu8-XOkQ* zJ&i|Ow=n=yh{xz21}%fND=H=yh$kI?2G^@7%AkOBaQTkOU{rarp@EXl9j8Ml`L}XI zI(MzwJ2|aQZI|x5F1&c>D*atMEW-YrKLj#ZZpP z97%HTw_PiKf{xc_dDe?)*NTyhcH$+-Szsh<=NTJ~ks9I*NrIc=lBfdSiTfvik6vbE z*{D-5xyYouKKH!}#wa_~_h-=kB&{uCI1;pt>^4Ds1}f>`u2ax)i>k;i{5z;Ox>9y3 z^(NO2Du&EF$V}4qtYmrcptFXxWxEkN%xeGE2H5f__$RqAHGaal%P+ZTa_ZjiO&E9n z#p6a@lA3>6)5HmvT|6#nMWhx@_}=;7pF|A1lkuAL7cl8uR+G)? z+}-s&C;}WB2=S=qb6Yme%LHi@NHL67G02Gpq5?Xj|NH0G=K{Gc$#57Cpi2Fdn}@G^ zdsZchU~Sn$2~9v$v@ndCTun#3u#_fhZAXy76ec(%bc_HPqDCbyo6wdWMCfc`>kylu z#ccCMkh3qFaCT~uBgbV;srwx{CVbD+eEGS#n+5?9o&g*IN8dvU9ZD%+qk8bBl6j+u z#DWRzP*qhx`#iX8;e?Al86W`k8%sKI)!mH*(z&~IO&lx;N}^2@ZveZ3hokOjKD1{i z@vgRM%U(_hE)kR8eIDE!aR-^cLsCbK(e!KWS;18OfzEqd_DtT-PRtkmfStNu1eh?T zX+mnj#Z8U`IylCWAhj@Jh7wYoNp(zovg1sAvPJQcpiv^xqef0?0(@KcEMA(>Z+FS! z;gqHVuIr^+kSyw(J(DVc`ZybS}7o2a2Dx$=uzuEbgXTco?YL2ynzw_I92;rjiP2n}x8$U_U{?eTCaW z@7C#jMN^S3Z_u(+F&+TT-}bBuP;J|?*Ar5uQ!NM_lt?TPky9pfM&bFX`eTj69{3vC zUwX#GEPI0r2Neo;{Z(=yE%N>Izjyvcse8}9Y+TbN<3^n<@QW_-?UTAc>D$NCV7-`U zIsoXKgS+46j4y+k$%T_k)fc^qT5KM8(PHgcDe03}gOGAo3B{NBtL~;fs}e*8;I?I7=LPMIDPvkRb#Flj&KGx{e97b{ z&!Fm=UZY65DFLNaK=FRE>64dvZ_BRW{cKPhc#u;liz4lrxZml(*R1cQBY6R8-n4>D z)_1)@KtK;PO!*6Fq8u?_Cv>Pa%uT%yF4dm&mQbpavaIXO_9TQ9_2DsXaV1G9nEe+nx8brFjjz zyZ0PGGn+EqQj?y1NosTER9DiS0-gSh6Qam6V1PV-o&KyO`s7G|?!rqGXdeA_(sowI zR5jb3TyXDq4iQZH6E3vM#vMGO1e^!8AgUnnyYO251<$rU$Cq>C~E z{$t*FjMW>%TgcU@@44(G9{oQ7)hYIVS2GV>Ii!Qk(|M6}%;agcj~XS-f`-``a=AyT z0AnJj7L`k`cy~UCVb2Q~ z9<^P-6!!%<9(!l!v*ICNd&h!)W#Qr(xM*7*9z^sE7kwkqno?NnU}k{Xkb583rjAOO zPVoj21U+O2Hk?ufbl^gRe;k04!F|2Ru4iThs56v93s7o*W7&IDkj<*t zRZx0g+TIUzLNH1)dvS9Fg~N3^1L_F093i$7$yL1s&a8N57Rd>5i9q+=HC=@N>obr` z2M6x`9ZJb9#|f_05TBEd;8s^dut=K};rTZ}x1jdQvstu)J*dp#?blh{Puo}$QsLtU zyL8`Cx?OzSl}bnYw|I8MUX?HXhHA~pYXzmvwc`&pqnUWk%WDOu=II-TJr%!^bJd~1 zYP12d&5_v> zz5l)#yyROUha-A+JhLL{@ox56n+Qf*yWU`nEoi@2(j4_ScvR49uT=lVgV(VhBv6}a zVg699!)GBdCpjE_ZP=WJd6>2Asg;qOv*%QUIkOx3ug4KE z<2^ii?+U(o@)o%ey!Q(i>e}=}zEo)KKhFCj`P;2&Z!6%0VCoT|uH#O^D^x^RFx%qG zceeTE*lm94zs)c4ZGQQ7BN?B5i?<7~LrHlk=N zK%LeA!7w#2Ou3Xg&B{(0tvu15Ko})B+W5xvN-suD+EGv=Uip;eapoR2mcbXigBH2; z3Fltp3ab&P^mI&e8%!d&eN0O&H?EMD`jZR6De6AZNnLf216m4q9a`#e(^7pP+>iJjG-Wk3wI_)hi%rx3mgHu ztMfhH9?rSX`2#QfLq8Uka820GYPjJ;{)hbISo=r0>&8 zzlVB=kJ$dSd4l;q!CTL(BX{dv=##5q4gRO|ezaao76`^?q;YhJeI{vZ)FeL3U|3;2 z`z^MlDH+VNtqW=5$Lc#us!=Np>U?5lVv@Fk4S5{hczG`l=IPTATwK`@oZCIksYzbLh+83pBb-B8=eW&WELNLu zfalo~;B+v@ZMcAHRc=~JYhYDn^#gTU)`|wH*E%djM^aWJTaYcdH&m~%lJDa@M`4n& zTQ#+=ua9y=7E!I^?QW23e`mp&y@Xx%YY1`yx8TZ-lOZA#PgCv90*FC!r#(4&SS>Uu zoQXP=MYV|-|F0(TZ9+-^uTEQwRVsH!-e80&ZbWv=q6Jli)U>Y=4D?!g4`g6ppG26bW8OHUO}fWT!wgJkPW0Z1%s^DRsP6hj%Ag> zb(>4GyVB783P!m0O3q7TVO`f*)l-aAY)d9S6%3haMqD`1WqR$~WP+tE)4gO;<^w1o z9rSqlTcy_HUJmE2T90lmZTK|@^G3n!?O~qhVLr(-9rT{w38p3?w`Gyeau%ud4Fni1 zm^dg5&)tFLslleg<>7dx(Nds8`U5^ZM@0s;`*td7pKTT;MmOX4B3D$G(xUF13M^!> zXMy_bnys*KqrL<^?m4NHNPV|ciYHPxSIUA@ODZ(Nmr_+IWu`CXW-Dd*Nt6PiWX12h zog(hDiijk$m7nW`N=te9N3Je4g;KuiOF7g^iLFNd$?OZ-Z#xBL9L0|G`9Bb3jqT=G zya%xVHUZS0Kc_uFO}Nz|p4ahxk-LTMS-P=>gqPob2hh>%KIrqYAhzjP|) zE88qZYuBul70Msf_AM=?uPBAQQ$nx5{J_;^ zXrYt}UrKjM(fWJN4Ft66JBg#_u%lnY!qQ|*FuDAL`01`^_%OaJdwb#6aHN<7o!E-> zlAdFNe0tK(az~oPcXhiS!o7Ujxh^g1PK#+-4NbAYbqoH&chwNURbK;K7D*S=-ez4H zX*o$qI4t&QrJqU5k%Gmvb8JB%Y3aU{_9mZJogZm2@``EaS=UP1c`ohwKCSdUX<@Wt z+WV|eChdJL?Qqg+!%C}=R`*j(%o$Mbh-UT$?dnG8;VvZS8e^FP^=K${m)x&|sutms zXrA}b2@7}N^8@Mx!}n+<4gJ@#X2v?fs3-h6>9*Yyj&YU@-JtVcgx5-Y(i3*v1t8lO zr`vDn4jx0F!pdz!z9N51(BsO#^s_+kDLzp9ds1A`jZH7Vx`$5{om>|el!Y$?8UCIw z=4pAj5#c+|a$dkb2M%3}`sN$#dTsbgbgEI+KD?r^BLW0Q8UlvGr*{j5O@8BM(EB~! z)h!QF5h9ZgD*kv1BFKQU$(38D4u2vCbYmECcG_VvCFRgc%YyHPXR7?M)UXG+lC=Ml zge~FkwCFdOsH26ov{-5NNj2hs3#+%?#4pXph=ySwHtnm?rme+c4xPo&>%s{lFm#xt z+>jO@)u+FSc44?i^QMMv|FEIpeQsM%t|R;ns##Dsvp_6`U2!$-KYh zv|Zj>pVWrxr#sd@A=#@Pafi2vQvqk{HRM*L^F4MUPQLkM{u`gwTf0+yRkUznt~1+jKdc<1ZP*W&=RO)poUDrDXEq>H#GEL#Skl<-=iVNnV`Q{ z;&lIwiD|a{F~K#R4Y~ht5I!My$GPkqoDcl6j^kbsinF{2%J24IC8qO0vBy`QieZn% zZ+x8OqNur|f|JTq{h!h}?)ael-M}ehK|A*mK8RPU=?L6U1OA*~9$Y`3@;ksSe@hR; z?UVtIt>$@Nk>&%K<3fz=@-Ec1>0vh!pqI-uU9Xut)g@Ry#9><>)jH zmQZWrjA{u#ybKTKd?i3tplWMd(i|`^Rr}#>^Q(AZn>_H%f<>nD)zJc5wTzu%^2bj; z{H?5kols)A4OW z=%assRPE0A(v~DP1miGN-e67W#`ul>-s5V6?BAP4vxKp{=_vkoX&TJmu1yE?w*m#N z1&+J(w_9EOChh)ePnNfFO9^X-w(^ey*|>4-aWMz$5R-bn>f?_4c$eq0#xP9VfG!5c!*QSH`ThY{)zp_}eXhlWp1(H@4_bj;;LT zz*2lGX9#8sSJvs3(of)>trqbauj4ToysqPVY3E?yz9S1PdOoy*;9FzS;J}aS)v*tM zmxnga$o`CWRWPJ_-oDm8X+7-MOIIiUq;^4g1?y22s0z!cruw1acvZnwi z{P6n*^N)h*2f^V$5A$acOgFaiFfZH=%;DOf82-}1950yB48`9sc6c5um_hH)k1dt9 zi?#`}AZ;f&n1a8sp5&_Ybspv#o=DrBonU@%n=lK~w%#PawvS+r@GuYaF#pwH_88L% z=Ed8A>CJkRub{TOU?x4x<==C4|E9t0UDgTaCEJ1Nhdn1cJj(?02oE#wVScD*P&;Qt zDLp4`6J}w+{h72%P`iM9g?2x}!~CVe>@l_z%uBZe)7Sks4(3eiw^04G+USjoT-{GF zn6ZjZFfZER<~Kde8$HbRJn0VRCQ9r6{cXZ53{^Kxvbs+ZOm>VLo=16@ zzt%GtekL$Izc+0Ypk^ISVyWlv9L)2{SD@#r3tin$bg(xYqEFr?-0&<1Y*!)J(f`0k7f$i#my`+{t+yiUy!0vX>&9uf9+XTkE=7>5Z{C<<-+8+@v)b^7L zTy4*eV0O|PQ?>(h_DIMH0+{*5;?i;1``O$XD_7XPImE9Gb3v{36VRrDu%lE5JFsE(@rq?d-I}LKF zI5+Yf9^zr%q-Rh&suRpBw+XYLU2b(S4;9QxlB>=yP6Sr|kZXSKX{7sKP656)qRW-& zN%SWr3u-rswPHT&zY)jn;H#pn8fooqSqT-hUZJd%wA?`SxOsRfb+6hE)}FenO!jMU zCtrcO2Y8rygBh#u1oP_c!1Vg-Ck|$Krkiu2=^r-MVLQCyhzD9m$D%^#GQ4b!%X zL->$MV(kqoo7F|uvYXCz^*PUq99~5MzB1Qr6Huw{yu`trSPJuZ9_H>5f}QM|mTkff zzv6(MAYhSlKg$Dab5BjXl+-q}ZD7wyR|K`+D8+1759|ke2E7kGs|9L)ES(*n%%JZEQ;ScAXV`;D2 zgKgFwzj;s;8$Oc{Tq5*yxZmZDN4XzqYG(&E4v=-EEFO-<{8Fd$WHwNy7Pd^6N6ueR zq7mm5y)y!xWbvG)C@)qsFAd}OR{A>?PjGyVu94;%5#H0|58~=N`5e*R@=u58)3POr>&P zP}DPANTptTI&d|cC>I)8Ij=#vmnir8r?e`-FN_lGiK+F^$_80xdG4!T!7~{Mi}8mu zEv_lQ`9uNzK^<{ar5PdxI(l+V^0cFd!QC> zj#5ZP5RP)n&~S_ZC;;k-#JT3Pq6C4lm9I|v?Sa}IKpaDN&Li;@br@K z+>-RICGqo1!pnRZ|LQ~<^B;a_CVB-hG(A0&XK4M`w1{qtw^>b%R-cq@By6hhDSO0&?$?j6`+}{$c2b}g!C6M4norWHqS=|>7?fxxI_zr#) z_i*l|aHsJIJLlPGnd7=-z|spTx*@1@Zb__Cc*)tMnD(#$)o*@pJf}ETS0#g3Yl^-E z7M#X10P$oqxboDVDN12AC!_Fipfnw0AobhSRUg6&8;RrjjGjSk3UGK8sB5+gN^n-8 ztbj8?aGdF}COm-r2q{zc>%!jYhoC zssj6-|0?V&s+%c`*9y@g9O&>4>32O6tHKK-Bv#Qv;k&#U5`glUA1@?=+ID49tZQ86L+raf#z%Cc&RmEtym=Ysza!T zQsJFma8=KUhad9ih$@a7=DGY4&RQffjZ$>z(qN-+BKO=WC+Gf#=l(hR>{RY^x1^G3 z05Q^sVGV5L;e(s6SP_0@t^+el$0p=fxsM&s4YxrJr>%Sa3DoDm zPO)cEtY60YDwUg0vr%4OiO{r%m40(Es6%bW?mtefO9qZ1qsgmIg#*&2w&96B;cjQS zriD&tR!^dF+r%c#b;ciJNnKDoB^lILcNY^44KF1_o;Qlla&A=OJ_=@fi^&KH%88W5 zGCUQet*r)&?>u`snNyjI)GR^mkB_82iq&adpPp$=MZKE8BgXka=D@2kjy}Gkk3sEu zWZ-onk?S)A1y)I#6!w=gBRBU+rcy&JSYxsIo%btGOC2 zU!ngmQv?dT8BqG6o2vCL#jamGlf|LTe8I^4(0Jxw2q*Hp=6Vm>`zz2pT`i4w<}lp= z_^4)q$j$YMPmGR~TRQhacnCCv7$H%BaCcRih|5DgModjw$=dcI_JhMKW z{#_!+bN8fr*)m;unR-yOhWmqnKi}%AUP*s3m^uUaXHzm>zae~2)k3GEAJ+v%Q}^JRk1wLES~uWXh_H$+vZpjHwJ3l7~E4oi8BaEQ8d%`5Ur)fXCR6vHI>pO+Dl%smwDX>1i+ zg4;vs))KuVFccQ72wY`Jctcc-Ci4I#Yaz-@P;IDJ30DCW{f$6*Y}Eber)1ID1}yH8 z;b6K~h$uNf1Pnp)g#>flcMJy6RkGDni{e9U$M8yOl22C;(L`vCO$~Crj@GWytz8rj zMDNS;ql4?+c!We^Wx}qUO*6@O**MAbS>q<}!kL)$)n_t^9sBW~a3&ehrM-udA)(O= z+2~qVh6&3M&pbs%G^a_GnbM`8Mz@ZhF8OJNSmUk-SzNpTP71$&8ko8^fuS2Yry-uX z1o_hH_UsK3By>eha-r%kGMF8g+VKSrOR0(oEy~to&Q44%-ei$ctK^wrrN>n|%dGr_ z)qt+c!ASIRYB>G!lGa8+yU4(kG-^0CBL5qRvXWL)3ksZ?Yy}Bu32v5LrtE4#{WyQB z3Kb^ntPCa5lx$g2ZfbGyhAN&@ZJIr|Qrtp&ib1ulK`lfpvZ^)=e+QLMKTXE9aVsPf zhwA`iNr-0fm5V0p-S5}^xTkV0!5%O5mPTQJbS+U#Xu~AXZiZ=ZN!-ihqBC27;Eb#XQpZ`2 zhu_2$L(ymP%v<0@-zSC6ev7EfPK@g~nq;0{UIrffcW!*``$e=aB8c720GhI?ndEb* zt8Y?#A)rK8MLZ(Cpg4-H^n@UlXflW-)h;MXm5ml28Na_Iwm;MOdaWT<_}J+}9C4;h zw~X&jA2TQ-Sol+m;m}A}hkJlt4JV(<7+PgXd9N`m>eX=RDUN7E`PlJ>b$o_fje3km z<9c!wxSp_3Q@jOySVE)lM0UH zNTLsNLmI7@L(A${dawqqZz*r@s+VXeSvh zN>!s&LG7x+*I(H@tsE@Zd7%Fu?m2w{erZlw%RN;N_49zWq*5~`D1Nh&1hrv(lMBC-z9^yn|tJKEQV-bh6 z5?0$PehE+02!y5MEZ%pwcltESi{#U#-)76J3~%doguVKn*Ysc{;U3HBhbZ@=@S|^m z0XD@&0H5iB6V$dUl|%66V(^wI=rwu7fjp;JYBagSj?2U8%K%*` z>?cR%dRspZiIGxAU-sBJX!X@eQB!c5$s4swL?FeBEK#dWCu|u(eUji!vD~@as%P^> zeVa5(QZ#n}!yYFAecHpy6^SHVRj+RRqRgOoG1YX#a&QnCfR5ibc-`x#@Ea$iB*NVHX6Q`2ttO@)Zrj78z7 zh}m3EAm)TgB7SRBu@PHFEGKq~SWaxFG%95_&xqv;tO(0ZiTKn2Y{qH79#vr#227QifCi18T<-(gt(fVFj zLZqRN7?{M4S_pAOU^6aF`l2+x^Q94hWF!>Xwnf?~jkHA+R#WH)W<4W09;+(UIAIpN zaPEm}?d7>g!pj}8#ZS2~670mdhv;7%CF6f7PmkZJC9H4AEjhaOiUSx=eD`bRW!$Hp z9FHkl{vf_Tlly#Z#Liz)v3*SyYDu7~)>Boh&q;fFx_Ra?8Y$8dh-Na<{^zMA+ABZ( zDYb#yN=Y@FQXNs9GL6Ee+$mC7UesPQ;m+jJu%)_$W>brlLh;p=m#btc@`$I+(_qQ(?7d(d5um6sEZs5fprkLb=cao(UDZptZ zLgf;CxEK@{`q;;d!8?60k?%_KIsOeJdp5yDz8j(22x;M<%CT--JB4x&CR@VtVNIFQ z@ytNLvPW<7&a!x`uwu2rh9Dk*IW{V?t>uhvBgN$W5-TIN5>^V&J`Lpw^4k3)rxh>5SD;cOBl$~*20~yq9poLFbD64 z`t;v@K%+#=u?tN|mD~BzeirFh1|$P=Q!|YnI-uI(Ve@Mo(C+l_`cqE6 zpKn-gZE$oA=^Dm=H8sAE*twCnWIkg93r&W>k(JCCy~`P?>T%XTZ`;S>nF|@x<@e@m zjjhW)S|dC;-1drR>hx(Zv9gT;ch#%fZ~$PN1s+X*w6>yE>9l1OQ0>BlB5xf1K<*`T z#X*JN91j&x`JgqOeC#xlXKDz#ke)Pr6cLvM4JwtO@Brl@_8%4=EgE%Zof@pPk+f?s z5+4&GGkFWb^GPS+xf!~K8^3ARJQuXNUZx&Fn(DcXib#;QA~F;&@k->o@I8{8dZxcx ziS-=SS%OrUm!LtNBxo|FAVKlWm7;efI^t^2`zy#9nJST5VdtjS32YEhFo<}Tii$Go z8pIgt2GxO*Lb{OuEp;=`NF=1%qj;fcf)x>00;tT>3yC6omdJv{5^jwWkaHPfwQ8es zF5%_NWOb5K*I6Gyb|+e_dUrj9N(tW{$&QIf#-5&RxzCL*n!Y0bpQ7poy(<_|B=W-J<98Noh44h8LwLx z;{5jBX;N^Zc;Cs?aDIY4f%$F}GuwkEC>B*I1l1Zo81)v!Hv3qbYdS$WU)1$vd^Euu ze9-qCeZ1i{D4wAkHZ@x(Go#UlO$2Pf@m@oDJG|YW`fcORob@MuWFPCTkh8oHz8>pK2syeNB1TT040{#>-T z8gl<^{d^D{^FOYi%a8d#RzJ()`F~kIuRA*8{VnzLZha%(_pa|BASnN>`uU$PAKkw3 ze}H_vcGUm5@RJU#U_yBu68WEWNavFN>zg0d)=Gu$)%d~gyWE`E&UxMdp z2sR?-d_CrTFUIKc%*Fata6Q!|$6r+4D>eRb?KEqpQ%dG{pnn>z{)y)p{~YU|XZmNI zp2=xnY|;Z$k%I8@k%4VVmNBg-amo0#x56k3sx0AhH@D30VjQwV6W^A3qYdP>pY+BX zOFvl!N8!Vj#qf6c?2!;nUfiJe&OQCcPd})~>U}-@2no%$Qu@)8e}wJBtlDMgM2k?k zaZw#U7$pr826$mT@LD!-Y=UmtiO)C%LbPmPPw)^6be(*7V!;*T$kX+_b0$pU5XBQJ zlEIHEi>Gfd*dK^($97}*eC!U%T+0St?S#bIo*;?D*|r_S<0| zGx-JMGjwX8Vb;Y0T_+!uoG+ZN7&rKwWN@J-Nj8_hGrExFW)=}}?8-TrOpz&dXOxcoHxo8vjPO!2 z8!XzU(Ts7Gu!2~FN;o7CL0MK3zl5+sA?HMAoq&K0J-rmh=t?GrbC;b(XS+f~O~Fn$!emgQ(b+yTri9^S#La|eZUxu;D*sDzc6s?LEuU0=f7H6g zEQGn0!ZnjR6zgr>;x26?%a~OB8ZWs=IS03j11Pv#tjETVK1A6#U*tFEx1T`E*|5Bh z8eCbKdrUV>Aws=5>6ueL`+rg1;SL$?SZ2xULEaj_iN^2P2+WyV;Yvu_3XvupcEz|h zH@t;OGu4lXa0N!~_?BTrxusmaXz)46r&zlL$hpi^J#3jX)oq=D$c^ad1LrrDip#MT z9gl}Btx+h)b6p$W++PQBjVY?l=6TuEAqGjI5+nr zlgf4j1dwheKt4Ah9C6xCoA7I|@A0{w9l>Y9CU*6{S}&l@HR8}22&}41u$fW`K1@)n zVg}>NWN^z{xMHYs)*i7tbNYMnNj%bbh&p8!t)j4cVE~2yN`zlgyWH*V`s6UOk@Rf7 zP;j?S1>d;Mf(yl-PqFFzfNItatAHZ`lY6_ka(H=oGX=2t*snHO9@Yp?3S6s#SrB@3 zc}l*IGO$c>_o0B^Lg2KIf&GJ(8=73SM}2Rh}QD<@_UY5cv7(V}N^%Bi3vg_fQ)Vn|_XzZ!;ATiKQ~9 zM`2T>Xh6K7ctG7}G^8rkNqPGLw3KuNqqQVlRP26+gED6G-QeJ#LFJCA9_svOiVqi4 z!?CA#+_JIMAL$qW(@EQkZk+yFqH_2y(Il*9VEd>wARIiYP6x2vtzYM0(7O)h6Ri5& zVDor(Ct1%k9x7eG0)HlRYh};ijG6Y1)^R2C}C~ z{4p{v>L}H$2yLwai*|kQW3$BpXD^63!G|IKCBg8LY!9TTR zGf$O(gWCCn{hdmZA_9#lpu(E5Aw zVCa|u(hOK@W&I{w zz8HPQcv+b&fvIhu)DLC;cK9UiPv%}N50wx5Ytxlz5V2c{203@8nt%0gi~e}EhxO-4 zHeaZ*Ix^}L3;sl%6{#Z5p@@Z|60o)A`y8=aaLQc5i>g$mmiEzM96G7|VSk<6qRFmC zn&*W*Y@^GhZg9nxZL?f;pBNrz&}v`6m9+2>K|`djIfN2;zO5%%Fsa6A6v8!`@6O>r zXm6&jxE0pfC7d$TPEPWcFG&vjVDft%Um)lCoQZoZMipAds*tn6l06`VAhAxeWAv3vO0AT>uVUx?31QGu;DxZ^{7X1`pnYW7l%=s+HmQpc)#k=jz>~{Zsi^e@i9}kIJioXE(&k%gkhitGo$j z%KxSC2}d~Q|Irm}9=xbpYqHeevLaKMBl-2?M=9M4lS?Z5eG!X-&e1#StoUSO#e4Y|+R+6xsc=sFrw)4p)knoTxLQ`1tL!e2qkLIE_MFXOM&kX$F( zK+;lg3a=pP>MGMyTgmZrmt%ie^BYt8m8IPBOLWWt%Hv?HhvQk!I#DZzzej!B?hjk< zTiP*2?Po_Gdko9e*wDdt6Zf%hCY*EdR$qY9=S$#aST(4#D#2|KYMBN-4eQLkmwRG9Z zgYB^{Z}wALm9@t{dc%cG5ilcn0dX(;IL(Dm5|7n{F&Yx7t%7QPvVgFLx}21nZysF_MU)=NA*bQ2oP#;wb9uPJxMx?4 zKj|AZ?>-3H1v?5RQ<$yfk@>YQ>;rfpYq~GnIxaC5j$?CLJaax;ktNcEeg3vCvOhK2F}(=O)l<(p`rBqQD3jk9!A5wkD%VaR)^^I=Oyu`W z?zn^+$d8rOP9VSL42@7j8fi*)Flk_AfLvmY&wOH0E}5^Ww%XRnlXT~?Tb-r3%^jV`x4D3E&b5p!s!5{A%wXnQE8j?N zMQR`n@hmK~EuMmAD~>$PdXnc(o=B{XBUccP#-VEoTORQZ>GTr8D|`dqGScb0@*14L zEl<;?DbDVeGgwl6OhNTSz>I$F-i@4g=n<=@ZYas7=ioYFQjGMPm9L>d|p31 zqB%uCot~qDirWcOgYLKL$)SNkcNU{nRCBfUbZ37Je%cnJZMf<{_YRoK_}8EMVV5Sh zHJ!GE7UH^T?i4OxqFZ`j)A4fY^7bV6%|4RveXvk?x@l*Xy(i(-4XpRvTagU(<%Pii zU;??v0nm);UNl#UQqK2Sxtz3*Hcj^UKf~))e>2=8OgFE?B9U3>`~Gpe_>bK-{vTiY zNWS(G70*s%`6NIgK4X*uBAtpqJ|f@ZH@b`*O#fo*qWS13STQ}7dw3>BDFjUC-nwd- z^;pNJ4P`s*?LRm_H<_nI##*YCDm7gkUk4i7F>CSQ;3PRbv0 zrOy?(5Zhxh-VE48c@#aco)Zk%90S&!qNLI8K`)6|;~6P8N*p(^R`oNXD}V zsLI(^BI;d4KO%S=WOdlv2y!MibPzj-F#|#@owZ-3jgC~$W}py@$}Q{`B%LhjuwCpQ z)IPtFOVuLBXxIJKCDGpWo$8TTgc)8&*9=^06nE^6_kMdSd4e#vdy_Lrh z(C(7W{6VSQ|7G^V!JnCyr+bvD$6k2w@BN^r?1gzgRBA8W;^Ru}h36m+a!@6Lw`c&p zHG5%F)i&&f7t}tqMZsP;j+9?+FU%zs5?!zCC;4r=OC4OMBtY z()`=87aEj(OMBt`((K!{7e;}9slD*PzF%rD6paMyS1}UQ+s`tSA(4-l=%%7FBhr?r zqvC4NLCrLDz6^b)tow-;U@Z1%!SirmazSh+WK-HN?%htd}9g`e>H&$Jf?s`&q2d*K|0PR?HV3VQ$l zN_*jp=d6o=;Nwzz;aOD47WTq3q%7JCkMM^6F6$_@7hXQofK4@Ek-cyoz+^8R#sJCN z3-d^~xxFwY0=R{}Fk*eFy)YEP*_OR9G=lM8uos3{xPJhivb&?7Bp5G{gkcArkACrSton`MsYpAj&?9p3| zvnHIZXAs*P40!eB9_W~3D$!_im<~I zyubS=N=3<^=^4akV}KV+KIqF!?&?ZDv9#o4e94uR+^mupMG-nV^8emH_H}+_cS!?H=3UPC*`L>Oe$9LjlgdE->!Oe0;XY(Y`@T(d8bO9eTa|bcf zs{9}_ag(Jku^82$4)=jl(Ir;H)si$XdB>njoJ;M`Ya$ajS?Usd1j-lkdlQ%Jr*EG9 z0%bQ7m*R^qv1?1S7ff6LJW3U9K<|<8lE#u;^TVi}_#f$a7vFeSQ&OMh$Tn}&B)!>i zoZJ%&Ip(oT$lkpUGTQH~R#U>t_qM5kNM8hPjN$JlkikQihNZyc@pq zA7KWX|EVXD5umE505Z??nQaAH4KD^2Kz&LQ4f2VmM4Cl>-l|f7uvAap=jy3uBd$^z z0HRV211wQt&TLy`Xo0sK$-zdkMaztY2=nEXhJsp@3; z>V{!&OrDd%N2Z%CYtl!JsZLJ*mwfNlk7Kx4R|htYy5jdD>ZjWN&AwPY8UB~nv#wJ; zT{V1V6APiPoUp~J(k^GxJx5i%u2{vB3ROI6yY<`5Kep}q{h@RHu9~HqRSLnneC>|Z zM^>?R7rQo%&p1F~-yCWi6kgP@@-#JCJNn8@)Hh#`B)+y}P;ssDj4n9fc&X#XwLUNG ztYIeG3b4&FRR)d^T#A_^%$hV3^ehvCHCLUk^-CiMze__m7f1pY^?qpYvJHh`{shdK%c(Y;H7n2|3{!jDN_0bKSJtzM**+Q+#rOfMG z1sOT3ro*)juiO3b~xma()$8 zO~tdX5J%ID7N2!I?_L`1x>14hsMS*r>B7dlir-yk(d$#hBOOiXr6p^v*ZrXT*6wAFtj_`d}v#Vtkyg48eW2Q8~OH*07_H#)wD6EgXk=!x9@4okh=3 zbjW@m@2w56+!kl!-5MOJ<4CMAmabT9kDbJuwW(Fn!)rRx;Po+h(HQFh;7Kr^gb0vm z4kQ9vilh#-V4iI-%OjZI64@L~cO5MD!m^Iik=7Ht(ysGtubqeKfJuEkx88ib?H<84 zUeV7b`*Cf2QmKx^Pky2R)5sKalT~g8R5PD9R3|OTEaNjZy2dN<%;-urre;7j0O5*b zjZBVUV3K5DqG3gUrofx3$0qx4wE0g|v)(8AvB)jvq>Y9n@k}KaeSLl}geaa_qrt_I z%!!W1e;m&|qgRbf>onF-*95 z3@`qrtshT?S_+}bJ`_$AZv?e((tZm$*GoJb-d0H*&+a?wTkMbTTQo3LuC6QEdP(Z) zg-6)S!E6*v`YnSwS}>8sDp#XxuzogDpuH@gS_`Z*FUpQ72tL zHhkOBmxijNp=^}#Ga5M^+-3t=Ac{f-E1prt>)|@p%tjgFuJAlD#nwg{{)EeDtWi43 zfS8PRhRd_+n*v zP-*tU_yPbsW7Vo_>*-uYHpl5Rr;i*&8}PP*B8`cZ_w%ZIHpOGXYVC;Tz2KsI$W z+1A3yp(>uelalkpZ(Qs~4tP@lC-YCe)7?pp93D}e5yM-{&N9}@oM_M>$_E3oB(#)c z8-jCUtZ}O7tG;rcps$g{>W+fA>i_e2!Ph&jDecFv{6oI> zjR!!MZoR))%aD!Fz->zhf)X?8M~G@bP(_t6!7%>)pkVX~LB$bKU$q zcKusd4KLXB(FFYdBKPj^6b$>NXfGM|HU)2%eH#r0!W$mZ?kl27cQOMpyf^0T%=6wZ0D~s4)O$O#N|ZUxVCEv2$MY(hbQ+Iv0G*9T zM4=Lb%ySgl!p3)WvGItfi#J&r!)!^C!x@jjrFGUY2bB(#cH+eyFw?R2V;CTa9f#IM zl+cVawN`w&+3_C|_n@|ZIcCS+U@zO?t&JODCO2xZ?wnD>*_$?QIcm613CU2+M~xc9 zS>bi%e$=oZfvv3%u=4`Vp5B0Qx23;7DSH}g7JHg&K;RqM)kEz$%lJtAl;l00nOLdo zES9AT{(fgtA5rl2CmZnf%NkDg-+-syeExcmeEa6;AKfs1XO%gKBhxXT@#15I$1?|8 zcvrKscZsa*GtJ8WfO5V2A1hm(6|{eBrL62R)l+3^>l~XZ;!mLoidMF|GCn9nGqfVu ziy%p`t@pXNA5VpP6hfO8y11}Q7i*?_;NF5e{~PQ95cTiSGl-o)@viAr?x_IXdP(X= zg-7^%+J~n9^yLy;_wCPtg_T`{t*fDOc)oxuqSVTMSg9y^fGhc_w@OR?_LrAD#FgA! zTJj`cvaDSzUKrYsiu3X5!6# z;g($t*0h)Dfj9_y%i4M0kADd|*aDRj_xZ~3o7Bta(Fyvd%yFKNi21HFa^A0df$X+E zrBn9G((H+Gr$_mJkKtx^ag=|K@^5KfFQFw1#TTq=5ZD(0Qq<16u93AV!HTSFH5~ub zjm)#zF>hUK{93fGN9zq3W?jn$cRAczQ9*3-jMr2|uy*h4TQ(|HZhj1YLKsND4iHXgM(&u3H{P4biaV9pdiW2*B)Nq;D4=N6v zsw6^vB5TrYOs!&LYAABbce1nV3U)T8=5+-VyS}iWLUuNN!hg#D{y~ZVy=Z4Q4EtpA z9r@m8+zs+iH^pJT*a?JJf7|Rq&L`Ce>}wl1fa=h2`UW%?7st@`b+WJfC?&nlZ#va~ z8Se&YqL6y%6+dcl8tJ zc{`gq7}O_SZo$s30^zON*>xVrirHUgY=6h-$wF8fY&-V$uU8c8?MAeEXM4Nd+1u;4 zXKx!uo$T!gxUmA$5Tan zbRj`H=)YjF&}pGcsz^NL%RA`3K2gVB8-k}_t-2;W=^{Mv`6Qw5^e|O(-@^e?VeA`rhGijxsWaIjMYYaZGB>kF(X|RQ9#ScfYSXZCsZna!Rb>bvC0q4F77k|8wW8NyNA(M2uJhDU8&!Y@xq#=WL zNu;f8ZEj}@lNAH0`>Xs( zx5!OXmyqnwMy@c~|A}dfmE5-M-JZ_1|FMeggjgN8FPP|}&VFm)`A<9O^}X?66n2&E z0NEwymEKAAHP9xHCmc?w<#f}{y368%9m6AOetHM?mBcd}MW*rEXwkyW0Oz*~czY&R zK}!8RxVN4*a2M=Y0x==!`M_PwSfu>Ba9*}ml>ZPyMU-EEnBo2?IU>sUgiNKBfA+&7@=KI_ zOXQ&iWd5DO>V*7EtL#67{3uWn9y)1CM#i4|CY>LzcvRkWd{uQ-03~ zd1QZQQcL#TIow``jB~`#`Pk}1MT<`OFSYt^AOA=P1S86au?-O2mW*dEmqr=SZV%gV zoQnV9g%XKO_y07x`1Q(US3F-6B{Gqhzw{a2@}B5^pRIY)V65fgM%%lXjQ?SMvSkfQ zV3U+Unpv{ND*-lyGo#jof8jDl&%=*B;V2m^rQ}LjF;WH#)h9|ZE*dpZqOpZeJU2JE zEzu<*70F`Ql0$7GEt#7pTTTLHrvQC2ZSfbp`|ZrD0I%~!#Q3g+%_x6EtV)y*GO+{f zIi=URxl6kz7e$J{EwM`?nVWhwc7Q!q*~>~R8zLoX1$@z!)pEG(mMt8w}lx24zJi~1soEjmgpGHRb zwwi@Tj-voD5G_1EVpVLq>3kG0PO_3gdI;xa^;E)umt-z08v;wAX@^8ReXu~bHtnco zv#}3W%%5VagPY|fd$3DBm4F~Tf zw|2bt#XKA!_#@HbGi(wjkhehDl7t2%F)LT^SD3FEQ$3(QIKDhF>;+k(1MreqKg4M} z$^4LNZ-!~@;F@sh8f<$#0Alq`3|oA4RX+Aue^q$$ z6~br+#drJ}eN`BLmr|H=A;ut)x2gTV)^PdQ$yRJrPL_KWcV7N=FMp^Xc(lg`^Ho0` ze{`BvTjYsnKBiTY!7bIzs#VbY1NfJNG`Qf=S; zv|5hZ=N^`)$?<_IJ|QY&XyU8{#^iTYPIS^oWhlDGvvS6?$9_SF%z%^8OYbWIwm_Ci zq1=XTmHRDM?srtKOduLn<-Yr_KvTD&i8B&s#xr-BN~}HnPR;~U%Y`?rva&O08W+X( zk@jGD|U zqjK$?$dtoo<4T9k<<<~pII1%az8Ov<9p#eg0*;`oJq|=X zMgESKa1=T1ta#=ShrvMw45oSvw8xo4DjT3c2?iZU(BXMGXE!bbXDKd(3tH=dqFs!d z#!A_T3<6UMQc#SAI8ba2q8uIx0&uz#)#tlcH+?TTevX0hM|8%oYo>mY195qMu6uR( zJaV(yNr%c?IPEar(wEZg#KXf0utjN4f7)TwF1bh1*KCE()%VzVuI?Wg0C;J$z8$Aq z$J$(YKfd@LDPuAFSV~uMs~^Ok2zm^ISTx1DN34xkFQ#KM+#+LiP53hyTJ`Iw1fcIv zgC2`-vwZVizCV}b6H|#>$3^*eb1I@${F$~oJm&mlrlg<=$dc&m(uXj&2-J;;Ezl_YXY zo|H&+4u9bi?rwvc-glNHtSmsYgqM=gsFcTP6X|yxCRt1d$WG@vv%IXVQEZf(V<&RT z9ZQs{T>9AQgw1QLIDUN26oXP>&2@mwzeo9q2s1#_`~y`9Hq z<>yN5sO_KM`4*UNc@*W7#1?yl*gM#QI@4y5ZF;?hF`>U8j`w#0}ND1Vqu#nkWHSjJEVnglW5DBY+ zRqXr2+j-T@5bM>P9m}qq2U#rl#R|*Xv6!s8_^chorLiUKJj-?A1*KVW8KaS&#&8H9 zR90B%t9-X5qJycHKQHEa8J0G`TZ0Hi^Sh(duzQ_bD#-*@qdsX%*KO4k38wRNswY|M zIn`72q^h$$J1e|43g>i~U^N;bxt?ov&%~*w$w>~pWabwOt?kx+RD`eN57*bE+=g|U z^&PAAl&nPH#K0sQz5F`MdDYD%j%TLtBYSKZbGxX>DwWlAGP{EFwI9S8Kr@bBEcXI) zTYSBs%m%QsKpX4n1ZIM6xSQyK?K4_DK=xc4p9kg3PYcHEuxZ?|=i@i@>@EZNO?n*y z@(glv1K=h_5g1$+(dZ&Dz;dw-w@^AA#B_?_pd-#1D2rcvFPelQe03eYx%E!AQ-sp! z?`ZU9Q7_0;e?(&VB6Xkjh3babb|AA-TikyJVEx$GuK!e*N$s&KeQbN|5+4dbrCwCY z^bp=l0j`55HBlK_0dw3!yd1|iGTjhfFV2hAksVv|GQq`;tzG&6sDc;z`t@+tn~(}8 z0bt9ZG#$0Z85<1R4R(ToL&|MF;udGU!nZEgAv-a=^i@M_ED+=-z=F!W+>5YE)P9gR zfd^$Ro%&W=>1E zNm~vviX+%IX&W74RF03|A4&jv#>KEgxO*u8KW9w#sZ4Bi%07Pq+1;T8%Iyr}mEp6m zmy};T)8JhsD<8Y==Qc*mJO@c6(lvuyA;*-jG2qPam>jZMq13_6l^@RKp<$x(K=v$N_xDT>et#EWfW`A1^V9n zQ@E8U|5F&1Bp}|g*E!Woe3JQ55|S_T;WW6dAl$N{JjsOlQi8ZZ97^#Sz38}tNywn9 zfEdz{A5V|7Hi=7O{Zf^8GX?QUw1p}gMWo||{8lIoc}3mU$*7--`^mucY&<*gP*Ov@ zwG1|^EJB%wpVH)A(y}L!zz8>6kod3xF!-T==6H6(4!qrG z(u}!!7Q&;I=V;G$MFv=pF3h$TsNXcEnBj?%4B?ZTr5jL8*T8ww5#aDQozum$^C;5y zR@7|+q2P#(P%$p4KYY4n+1o zmM>42Kannfw0;;nQ-;MwHZy@=^t-7kp9v}xv~8<%8h4sVH#Q^-7Zz}Oc%n%!R}5QJKom>G}hcu z>E6QmzfZ7CG9Q~d%ZbaG>JG+7x_J-X@p#iX~FBn|HQ z=wMVuK}x2TChA{IR9Twn%#uX$>>@hDt;x|q;uln@dA5|Jy*E~s84ZhaG&=nF`C={N z(|_8-%h8{aM{UK6mGh#`ui${6{t|aoA%DVHz*zcGp8*_(?xZ zhIjMBze=8T{=f%#r@0Y|=ZHvhUqaX3&sa#>EFU|D?`r6}WWIuvWgXw9%a;_`3TbPm zR-=OM0T0reVc(=l>><~}n2i$WNu8t$DFgCNDg{G-O0=RJ;b`k5NfZ)mH(Z<~y+Jq~ z^ok_u`BF)u*h&6;H}%6a#=^#;PL;?#iStS^jLO4Q&@{X(*;Q4OgseV5>-Kd|eZ`!D zJSKX1bDU_8?yRvVfawrTQ9$bv4jFJJu<0IS+#yZwu!c~HMY`PZlsqXg8&bVv}- zKJ(!wmb|mKTFtN671DL+TG zj1+@gJO1ETu+TyFxQN_XYuBUfA}`6x@R!R9D_AxF8LSZk)|?zeVy!lL8UbsMjpR*; zbUY+^qe6l=Yfpn$Z}1rI$b1h^1Rg+QpJ5ZK<02Yp=abZd7R+M|=EpaBn1hNiZ>WBU z3?NzYCm|WFVEOb#4Q(^_(F1kR)O49YBJJ(5-$vkmCE*g*JI=cy@gF5uXa0 z;QRARB)1*BOZv-rrV7V`7@|?lH!}Ars2!ELD0wLDR-1(wOhtEz}PT2Z;R6gq{sq~7!q zVABcnzX6`9fDhkH7}W_N23_+ki&ytp#5(743JD@?lquEnBvzUhj{;Q-ZiFH^(>`4^ zoRKqu6q*XrPhpLE^r}^nTB5BujdSz^-7!E&<6*ZFgIU(0GPr}74B;7orE@Q)y&4F| zJy$T&MQuE(k7~u=r1Z}4A=S6B%vb=X7H@($js~iCG$K>I`CsMM^AwPwTK6iNr51l$ z1&X5;4~nyuj-SGJ5_VNsnWr9etdaCV^wp1G9YOlAGJz|lN>sE+qSVSJlIW-K6v7TR zWfM@G2&|tck49)(SjF&ZmRWbAkJF5fL?RY+3Xgdfn-rUKE{Vxo$wS@ve0$Dv)&MLW z3RYsQR_FDUq&a4c&se{w(mSg`=V!Ch3Hpe_=-cjQI*bbX-Yv}J4??B3v-+-l?TJCf zHMa6HS&ojSJ0J4LJ=L0nB}XJL}Wh8$_T0rH=)dl!B2x1BFr}ey~yfnGW|z*%2H9@jltA{LRCN0JXMx@!$F1A2a}rmN#7}P#A+_F#xNmi>+^?n z&C{Ri-Y;XKsJUXv-LwMsSISKTxmMy@c}FIeq(zOTUNu$T%34sP52ut~Hxo;a0p@>Z zeQR>qOVRq)C)2}N-ui+I!&zR4_TF?D9CcXNKhcl0%EVa(PTQA zKbmViD)0nCpG9hmB2AbPh7!#pj`+K0L>^aX5@r4Bh@?lSZOCDuA-*`VZ8;n|a6 z+k|k6MP&))P7vxx=|FC`P}N8_WlM29u=VQ`^r z01t3&BU)n@01WMgJz1mDmJVX!6%L>VTni%9Fj9bkkd)wF3|<_n3^2SO$rSe_Ny382 zV|i>Y5`q}Z#L|GOb-}*&N4wElPWJ2nWlvH-gvUJZ=~n&P z-;Xh`ldtK0i=xyn1K!hCV?)Hj?Oh{->!$}c*3^-i+cWheW5L)+$CeIke#9F*vUd&p zPFg-{=_vU#DEU*sG?^tiCBKD||D{U)4FA%P;P%UGbCxyRJoh7+ZCa8)8h7}N9QIa0 z0T#xh_>5dWvQ)1G;v>^=a!ZCB%7anqU;ZGR?wBugIrh77B4Zi!*oY689q)m?!D1RN zEGyCSE*#7Nc6o)CZp{b{+wWgKgw{ z(2RJ)o8h$AaUOU$ZA)<2uILYfjok`|J)fLkb>068nTSJkvdO^cOwAc#mrtma_XU>0jBdReZ>`>QIfu=P&+E zf6Am7v zG1fJL7~oOIz=bnlF;Znf0~QS(0~RnQpa3z8H$Vc1G;iI)7T7OFYWOYyf)&dFNiP>( z_YRv1#z<;X@*?qyAyBF`T?X}c$9TmI#w#Z7Kkkt6ifC_*RlE-Kqp^zD3GdWvBk66d ziur~t5}gK_Q|`t_9E}{&X~*J%{D98ydGy`Zlv?)sh!bL%m9QCBc+J2W=;%LqQ4ML^ zeR~&b=lWN{(nxEd#roniAu{AJ${I7nu{~h?ZNe0cCMz}xKaioK1~5oQ*W-|SPY|C; zTE0^?%cyV+8*=vd@gEmt{9()7V=<`!If!*081{73K!cIp{I5~|>>g{ceBGbB#reE` zUp$Z|^Oqe#OkREy^A&(nRv7c0iYvy(zzIy3peh!jYV_B0h`rW?(zd8Bxq77fB+wEe z>{v*4B$|N6!9UGdGH|!;Kam)I00H!6tN?+bVP9eXWO4MlJ3Ha%(XhuUj^1ZQDss2` z;#XV4WhkkIab0x>$pfwnLfG8{O#z+IfWQJIO~Y@F$Q-N-CxwggI6eX4r6DriD~fF$ zxO-^=UrgJvuusdy@EiUEe#Q<4AS>h2UI<`rxPjL(-y2tnVS613(EFFYjh(FVv9N$b z>`G-URTdV~o)6)J5a0}`<+uJe0hH~*?!*v6VDVmlF5!i+T^z=y*LBzw=Fj$qa7G4M zx+IkLNeBmJ>~C3uVyc0Tg$63(c99o~@VVC_?3==JP>Z#{B^g7DLk|UUz8h8^hJZ>4 zuFM2hEy}c{6#Ce)UkfMHl} zVD0VJL6Y%Rtk!%5AC-ZN^@O9|()90BLw zu2knLEFA9nS3o+PEArjpTzx%XdUYaUEsI3Cke0P^v2F$$hl{lx)z~i9A9#%j9eSpn ziv@-6>SC?IdXH*BhkpgH=YP(>s%hh29fg)cFjlZ9E$cw}V@u&>{c9e*tS|Auo0m0E znEao4S(Lg?y(|cmcv-Y(|J(hm@UXvXylTPsj8{EL|4I$+uVETx^~q^)zuw|B4>Y(G zVt7+k4JzEh#y)}g#UglKC;x9L)>t2f-2fihm5n4_EWWewB%q*Q#w<8K-s z^Avn=5_?GSnmnfG{#7IJzeEg{%LUdlzy3Q(!Ttg(WPs1CkIcwV&GQ*LK$rkCP6-o8 z6oIjVttcmU|7pwa>u27J`h6Qre&>C{Uf_<8_|qF8`iAwL&Fp2z-4A>>?}kXj)G zV=?e(1p7>|*Y!tFjq%P6#jnQ4$z(4q{*&rMu`%hP*fj^ycv3Q~Lkn8EAhMv0dOkU6 zDnwWhn^wITJayv){Hu7tP>mWyD!2Q8<5NeB(jww#Cni4%OJ?NJcC3G}qw ziJHkyM2CFu-A=u&+k>q5(&4b(xMUz~5x`lDK`>{0DfFlnNkV+-ou6X_VV9oAT=FL? z*EFpwtQ!^#ycv-#4jSwe-0s^Q)e&U=@nHq#(&At1IG2M9kHsg{My8qn+?;$~km*2S zKd*O`zpj(=cRR|T4-#z>?D7SU^5Z%wA3^zWiElU_$%atSWECwc*@-z>k-x~fH;ner zzwFtb;MYdZZ1J}c$0y77Fzn0<_;1`AF6nL79*_4N@CUU41fS4WeXg6!nvfek%2{|P z3%7=bZ3*~q$EK1U^oywmzrcIx>MRXR0MAJOFSife%~|3vpI~2!CPEzMu$SdkdVq?v z<}ZArFzqjRC50p|9pOW}JbL#CJ4bepJtQZQ;1yynfzf56>nARhwfn3Yc|3S#BU1CN zKca`Y>CCqY%?iR9U^W+S2}aGrqTvz?6}-VcxW^eRqySKBa5t`GM`*imIm+WhU5Nbp zeuhgGmY$8cL{5#BW5EfrG2eLP0teY1j`eOJXsl;35{4Lmj^$}5Cz~DJ(2P<|D1~ig zZMZF6WpR6}3>g4nOp$rQNXGfGp-=d@$G?0d*8aiAZ&4-qco=K6w(N169$Tur&b0Mm zn~}EXj(c*;{N+P76CVO5|1u8{Sqr(`dnO!&4V2EnJyfHiLs-*9Zsi@B zBc2flQrX0K8G)CM@LwUk$lwS`@8SPAGBHVJgWCEdlcBX=aYO2 zT5U%&9>c?<&<<>M93DDf;HEr7D>>E0RXhxGZ>fB zL)(3ZbqR|5;SzAIRoW~w0JDTGP-<5+^D?xS{o;o$G4FzLNygx8mE}C85^Oo=rtfBp zE!@em)w#TU`ai&y(ux#YD0c0}6vqy;DPKrC6_NflI~FJ2?1U5l0H>0i;4vjpxYOXo zup9r!IB|;Ax&MuTOe_DdIdLNT-0J^E-w%L~ngTCd`97be$`}uuz)kIN(RY<(7W@f!jU#rTB(@qMOj^Zk%RYo-JF$AR4iH6K-tfvAqveB! z8+-o)**udAFXXMsfOcVx;rPX?GD7fSH{d3IK7t&&%(~P}g9jH6rdeMEQC%dHF#m)n zKrWqx<%z3@VWkpF5scZ7L|nr&{}^~gB?EDEzz;&{8m8s0&>jyW;GD_*OZb*?+7_%G zyofKjNVF_``a02b^}h#6#7Yu2B8~a>l!@osgc}KrKZE<0KkdUB*(O;A-^fWH|Dg0n zVr)bP&zX*i=E|HPZm7}6Fogu>TNBM|4-!A7z?^9AdYT{D^e^9mRDi50b98#k4lFqH z(QoAuCb5sp95!|)rm)eLp&xVCM__xQhjj#C46LloWCJKy@u9H3~1~hk$|?(e=T%p=rfD%H}u&n z`s^(jM6~xVE%&58dyLNzOJ^+MmjHm!(n-mN`ltNjauEo{rM)+W-9qEd7fsWI`vrSf zV2XvEi;_3u9=@we>7**g9w+lrtA-FvrI=SOw&YU~k?8tz$@Z1<_(tA@i+gQAWX%)Zv+ z*}u*v_M#N3e%}if`TxiuQW-CJ?-~p_{ouHENY4~Do=o)J9a7`KR!VG~4%oCk4r>P# z?A~L)7q$}|*j`@_Y%mxUz#D-GxVfD8&B^J~3o-c@Vd`oW=T!4vHPZhHx*oPKIz0p}FKP z2;K5m@lkmCDHw0^7o;EWU-l<-L9nqq)+9&2WPqKUTaf5kJMTFgX%Y@E^~4J%pc`2ll`Ev=4uhx+Y?ch3Cov>F z6z`E8@^Ju%8qW;HaP-V$Vx(f5B;nbFdboh|^t#XpZe9aP^_wXO%NkKNnO%t2ro$zD zgxLr?pl`PF6-&NkB%M?v5i#s+M^qU_A^q);DM+-Ho7kC9K0aoauulF4=B^e{#Uc4y;YYVQ9UvI_nG zb9=u7#*{=DuRcom(P23z<7TeZU&mb#;bBkIe-OYb0(PE<)39LiLj7|^u~xn&jlgjD zYP1*}$fhe}K>h|_ie=eY3%_%jgVBL@aszYVB5Z}X2B?48FCd&8$OwFptqg9lf9!yy zf0-$QWgXxjUr>+;4cpG}IXeT#&vU%=!y3m#eDAecq>d~M^?SadJA4wnM6nBeL;()_ z*n7_I4}F1CVeZ!;ol^pEZFjo;o??i{l53T8RE1Fg1D}P49Y7SBQf2oLwl>Nc_v9{n zsy_`Lx<@*B4Ja;x7(gidz|UTS+kvo8jJh@BTF6DmP2|f4RA1B`eX#U|Q4Ge~n?lfi z7qCeKu~^chF_iX1D4sDW6t7P!iubx^4OE+minIR~>rM;!uOPVo18^mr_Ch%A=^$PU zeBSE2H4EDH-NK8LeOLagRv!9mbzkgBe8S$3H_<8HUzmSsVhf==$y&CMe~tM(l6VEK zpiyy*KUoBr5W48<6R?XBj?tDkz4X`ReXXwCN1XvzycwG;<;^rdcP?O-hcd&<8?IsA`=!(LmylWmqdhuy- z*qxZ^I6mxgYJ`?sxXD-hXY~x&zx}7`iOwyfusp`Y+xv`*2fHVVh8^@TUygk$p`{n{4N?R zVAtWuM(nT)=k(zkihM8)qjDqw=*EZ4eUO6-rr{9@qt2fq9s6=|4uW1GA5H6w{&BH`aso(_&e$tL zx6lcxEQLWOWoSk03yZ=u zgwSxg4`eI??YMj!moRx^0mxAE!0iyFctK(zT+hCEz~PX0D;;8-G7cFf=kOAlxgL2* zm$(%!F#*#Fi1c!#;-l8yrUU8wswrC!@pNMHj{1=w=sVEL)VOEQZ}3SkS* z#i&oi5aS-44XA)IeJW=TT@qLnACiriT&V3yw}06daCTh3Cvfl+{>EX`Fznele`pJi ziJ>BYDs3EMqTI>Hw<=SOC2p&+2dL^XwUlb$2%>50?Waz*Agn;JW;`P%>hhvtA3Llp zdWAZi>br`{!r}{^Hu6UV56udpccGrnpUZL60^2fCPYcmFR6a$q-24FQDr~LS;82kK zmbmDVg4;S{DnFSr!#bm9ioBk0jsO9eNTEOA3e&fM3Yy_x{w#?H%Zp0J!L!XS8unr+ zJ}Ob~D;l;VdYO2%f1{leR#@#No0-?l)c?T8cH8N7G>82mB(EabgFPbL@dQiJh9xiC zEV+n6e`uBj=TPpc>pEk}E0FUxEO`vC!D5fyDV?+Ab8{GK?8t*<4^r&nzLyuVUC?rP zKauZu=8}seNg>B5I-Y9s8T1t{I~mO8Pu8J5@q!%KKkMt_I4}C=Y~x<@d8A}Jcn`$j z)72x`tu^e0kwx)I-@vhgLdKz2e&=A1pW$0g0&3~+f)A$_gr9;V|dt>`j;)^ zkWhK zN>YIreDb8B@1@ha4mICGH*oac4EBsGnF^GuI_&LX96w15gX^S9#dt#q}55O z_`Tt{^<9(m*=L|vWE%D=Hx!==S68=G1TKVl!`saew<$19*cM8A0V-#eY=g;IZS8~U z5>9)nXxP*6Hz+)E%)9vw$zzwR*VcGOPUBCPwx(Sju{YE#{m@ILCRO_%5C?5a0j5yn zyhZVvv{1hniu&z_Q#LN%<7V*}ut{j#u&tOAEIdm5owoalu?^=FzK^*D!UA8KmzGTFf>)PzD#OWslh0>rO1|9OLg9BS0Pu*IOT zB?p}F5VJRX)V;Bm@}q++Ir=d0ctAQvw}07lU_r|UGB!S9a}^w28%TIKjVo`ybG!`I2a=#%v4cB#SzKKad;Okcfx2;o)}LOW@u39Gx>hR z%c#6CwtZa58#qZ>d`f&Vm|y#iSLWb&e$FdmJ#qrDPV#E;tD=|v!96hIm@9K{(@t|K zI0m(VBc`_*;l^I@Zgxj!7A^iJ0Veyey$PLzwhTbr1skQpvA>yrV0+@ezQ_?bDctXk zqO@&zn=KXi_Ah-M#pI2)uW*4=LJ!B;DS@Xlat!S4q3*=F)$xMABNU{^u~vhBmg5+T z<6{pvGmsPQf`P}qqIA@;}fya~rX6lTUgVse?s46hN&763&9PesEQV(V{^n)Ho!sU{|ei#V#N zzm4Az*@v>2s<8td6E%%XI4ET6S}ueSFZv}u;uZwRtm9MvX7vPW~CNreqNxBF&+LPoV%eb4@=7R=i+j6xuXTADHK?rr-XN`3I!iGjgPIh>DHB z2wcsKVFx3evskc~9Q{$$@0(!S8`jw$#{ia#EEzf0%1sYlWJ#C&#|#4-6$7zo4;-I^ z*@|_ZqkONgD5lc=&q@rSorN((US5KHhrk|2c;Xl5WKyL0PgWjYF&`%bmu@qHv5(O) zlzyzU?S+(^|3u5M?itMK;a~n2w9M*Jl!I+s0gRM4oCWcw9+5fG%z=1Ifxgo&tUntw zRx$IJ92Bv=u_w)5U>Ew5#I~7svp;5_KeFLQga0+( z008NXMIZ`ksiQy2&4t%Xe;llpK6)evFy^Ci?T-^zp`)v1CI=T87$1Wd$|h$M?H3NT z!U9BzZS-cYpq-M_BY8sTk3p^TgwXR)2?U`86(>*l9K}2|{x?Wv0{4415xv051E`$! zc7ZR1v`usD`ppd--Y1j$@q#c=?_XcmS$}_a+4t@5=fQ){`};FA(eCe8S)-0%_x>IN znNIfiH1@Ywj~ZZ;uf;=}2?|Q5{XT|*C;i@+TVnUs{fhC{zt0) z&!*b_kILDcR~_}*_1X2C8z^P{wEv?(ZTCOE0HD_FQ?X`;mCFDxiv1O#Rt$I@o|QRg zV1cA>5M#K{xiaE8@EPfS&)g1PP!3=WFoxeDQJAqqsl8&pFKxy9Skk#8L%@-VNdU;C zBa~SfgD>|Uj$EexH2|w%_4$Yc%X-L1^nkGUCWux`ULW)>DRO9N)x+y@nxtvIf;#X* zU7!2O4s}!(;UO;XLc%dFOi>@mTuU*I7u;J7ZXd4C%$H)!3*xM&ID*~QK$R0uGtCC} z1Z|zwWqT28H}7NtbWiu6v7m1Q#usiaI(~ZyIxHf7s6-4V5j`v-CIF|L%8N7m6XpxJ z<09vWz>DL2x5u6^2UwNf%rx#hy-lUR`|e7ADI!$xH2jxjrLU~O;UzHDjDB8fRryY; z%17~-?L1Md+;N4ooez9>l|RucOPp2C(klCMJ$FB@gR!sJP)k_9JtMCLhC z8KUY=!Fir?Z_A^ z0fD$G7=>54-F#GVGJYK|*a1r|Ei`)*-s;3#*i_tPFK-s-P6C4On4er@WuxF7EZ7~a zF<-ND%~2@Uaz4CkeovT4(`O-3Cm|I3+Ig-z6$1wO ztr#D+Wq1J*yHNawJPb%Uw=ew8a%JTu5OWZEM&7TWisqqp%O=VN-UPW87yNwM47{ay ztNf_-Uo1@Y03%zOvUFSB*(7YuB6*ba>Sowg|D|H(j|6eWiU zO>3k~ed0eHE1c$!Fgn_vxM>E74XN*yOvrd=ct~s%WZZq zhc7sw;FZg)f+J86+V6Y}RYr_qW5v^~2X(OYGZvu(s4G%#<`#~7STEbn+-p7#T(GsG zbGR1p(GvPHUzq2EI1IoqVfY{G1w7_?%bDTZe|g)w8eHp|+M%w=?dn=;)wLff>biq< zQ6SCt2pIP*Y**KO*ScD$qT00UUDEGp*O69T3$?DoWL;NlT|aDB*8hia%>ny9Tdy#^ND_IvE7V{qIK;P-@ z>f-#UbJ@6CI@l>2canYw4_{oQ?K)lS8pyh`Sl4i^>-mbd?ONhm*RT$C{j^bA%YOAgV$Wd27|mrhB42Z>3}hc0hZ+upW{ zs!zKL5nqxDKeYX8a||k^)A>85@ex57hsS7f%->2c`bMEHXQy4)raGrmykC0R$;jWZ z5e`Paa+Nl2l-6}C>*~q60;tQHFTd=ZFFkn?SLB|;+_nhE8ZCZ5S3IGMx&NaFww7U* zBLQR1nIwRPX%XUmH?UgFnb0h9sjvAfiW5KNMQ2;w2lD|i2JsD8xwkJt1K}?MT-<-l zy?{~knEilB{f%(!E3sT3sTETs^U0z{Qu38mSWKK*E8^Sx4q~ReWxMW6~08A&}ryFPclYgB$8K2?ZL=yz( zaU7Oj7r%c2x{}e~HB7-Ma24}K1ZR=AmU*ywndWkIt2h#U{mV}${~;{ridgkNB1w8+ zVEb?SLYz;WdR8d~d*gvpX2|y4Lx^4Ad!pj@MD=^)uV@cJQI<{8Bo_ z+0HMdT`At4Y}L7%X?(8de6KX-N``l zBB`bKG3S%DmQq&jZ|;Y@N-SAHzJ%ILnLp9_<_-%)SQ_uW@H~Q8MnmVM=G_*E@X-db zOoe_I&s<`GG_fL>QLwD{u|TDYS6AkFEE$2Pf;s$J zs?}#^I*Y!EIjF9O1s-KxI6ec#3bii_W0#;*p|j9)Q50IJg_eO2*r1`suI2|~rLsV5 z3`&i0mRieFJe3RaI17Fu;JaGzV*x+b313e5Er?XfcX;vHBnZ$#SWk00R8h;_tiDbB zD(P=%y!)tg(U91);>2*&BI-?Mswl?zb^rs_jC8+Z3*q0u3`+>h>9Em(vqbP~>CrG3 z`o)Z&GNoOYUj~K3ownta331oH;M(SH^96LSyv@Visf8FNy?rR_kYDl2ej>#!5x2av zcQ9IPu@b+miz+QhOb_s;gT%Cp=M}}|`)z^EPz4@QVfcJV0Ov`78KDxd1Pu{y#6IUI zu!TF5m$B_d{@^!eYaJZa#@X=6;Dmwe&rP5t&IU1i5uX|7556Ccm*(`*FZqi5D_q8c zop}QYD{MRs9>f`}mfS4FCf-%o;O6Xj#&3}T71kK(_Vx`deaaj7Gt>!CXXLP-lM70g zbDi|9xh#QQkea;91k1t&wZeuO;yk`Cjxjdph8AySw8tC^of5=>r>F);ho6301XH>o)U_kfsZRg zsL=R4HolODFC8sv8%xCWdt?6^7u&}3E4gbcj*WP{>eF%&pmqHDS3QmEMqmD^c(d|x zI+Os&Z}j!WJ+6i{`m*$DXrr%}UY(H&wZ5~qO{jG{T8U6=bd-cyi-A}U+zH_VK~>)w z7)u~EmtLrUz*5Hj<{w$#o1ruRfJVml=4VE;lrF--u8BUv8O~ThISg3XTf8a9H97}} zRB}8aV+Jz>3@d4gaj|`DXNaC;zSXaMJNNaTDmPGFzf@=nCD-1D+!7B#0E!? zbpZ0~x+&rj3`-coZPc)tjT!678oEdLsLUVwllg3}GXHkmEA#KrtD!9jK|(-A3jf&F zmbWBB?&&$Vyr}o6VRWPKGC@caM_!s_z4k{pirtk=hl?H`ZR$J6jQu!;6Z3!}OUfMSV`RqUt{9A_$y z(E_V<=&V?P?gS8c)AEMOJL;@a_``&5>XtTi*D2D6Y1-nwPZXpWvjED(|5nZ8709oc zwuNo_tjDWGYa;xCW15fU&}A)>ldo12g-g_gj-Nu+SMcMQ>OLUq_#S^2b3` zKt9x+WXCihw}3VQh%NmBj>j56pRP?fp4D&a*}k2PiZVxm(%RGb3`csr=VAJI|2gei z_**;?_yMLj96;SuKrOSS@z;Y^0PUDa zOf-=EK$lBpo33V{Dh&YYxKW zAa<$p&821EqCGI4c$E>d6fW7Evj-IyEl$Yp!)tyDv%%Hs8Ji4c3tpcI$2W`hrbeA1 zwp#w<)M}r$AQ_D`-z^so?uT~>t1M>q5z3f(DO$0-87G1)TZenT7BoXF_d8kKouekwjv6}G( zUk4!^-v(+d*!go|)H^4Em+{`|h3sKU44LHv)<(RL2Vm5CCZ1WA@I&(#kRdKD?}kip zRj)71PG1@|Qn8U#_?KPEa_COpHfHm?lwn+1+agP``5U0?6?72_H2N+i5j5OR?`fhK zGvrKQv76DMWqgkN zwml7EehVYX2g2GUtssvbECUbikiKl=6EVl!$q^AR=tkT^FitNaSt{M;R}nt$dE^Gr zgtIOn+5q;ALV|5Z8)Z8AQ?@nU^8f}LKwegmHv9r< zs`{l1YTl%PuPeq|6>v>kKrc&UZ)YGIFz z8*&zmRhA-6&O>G}SGW(Re|x-m?YWJHp~=Zf za;7QV7k*zTZ7aBk$ddfVT*cz|&q^r?4R{LFzrDd=zc1k(226g6_IU42Fl@YU+XTvM z5Z@*C4U#gggt)+NUzkN7deAioCUg=^kTwls(OeHDoJ_@VA;4#k(L>A`y&2+UwoBw-Z9 z2{Uq}xp?DOQrj5O!_PL0XM#d(yuyUK=Zqp~aGD?;yMIHM1*T!>U&J>vutD((yvaZx z0h`8!cw|Bf$EAH?c1H^YC`G(bzLal51U}!I;a|>IAb4c>vY!A8vasd8tAUd(aaS07 zHL%GrFpD1>3m@0oav1Wg_??;})PfnnxU_f7Ux6m^SW*>XkH35t^;!@v+xpK$O?)x- zOrVji{asKG-vx>7Oz!N?YHc}AYFUI*7KQKNN+|q294b;MA5^^yH^JB*r7srtwzgcK z^tUXNNv6PBww#O8^M&pr9B#|)=UuS-{0M9Jd22B3V{7;M-6^<*=+jqkWO+rcFm$o&6D5WL`gmBD`5n*t4j62c+R;@s>Zx z%No*Nw8uU$*Q*=fA8Qj2%xd?ha&E0x_t`FzQMRj_0S?3XL{A;A7ffraf}3!A?)Y$qKG+p&u6 zN5t0O!gisBZHuPDx+HBsJ`}d+Il|)w9w)Z$7PdO3jRn0{p+DljZUBL%pC1x-1UBWP zZdHOZL*iRhYlIxD+fHV+`tm>RmvChfI_U$pxUt}fII;H5cR^=9rC|527O*Tgu-g@E zq+)x2ENJRT*}tQ`IhqcB?T*T1KX@%|5z!U=mXtM zQta>MWPhV}>Ne%XNEdWwse)aid_CR`Y=nZfDmJeh*bxdg_h-WXx9FaAB0}az+Twi0 zw#^M}hl1@?u)E#B?ohBN6zm!|u=xshgVHw34Q#T41!K~LkQ-Q@f{jpY{oKHO3U;%C z9p(o1I^r%+2aju|`-3igdsx9%tPt9sbpu3U39pwggkAmHPtuW;4(Jp*js9=UR;U8{b7bsYZ zf;|qfPRH>;f;qoAT_NsZ&K&T+i;LczN78foHL zF6hj43Ra+;$Z-R!SFj%``ww#i8?RtrESE|@v?g`!ZHjrag6&e;UUUQVDAu&Wd->;^VM!CqIefo@<&DA;zT?Fcup zkIt7q%~fn)2VBH><$H+q}ZNx1Dmg4gB9Cv+`uL)SjIBx`qge=c?uR$ zu&5iDPr**pN-uN+d;L6N$n%QrOgFHH6>Q{Eq3uLBur&(y2<9LT+GRPL`Iwso46vf$dhXN0lKz za09zf!R}XVU!3W}-en3_px9n>1G_}Qx+u0SZeXV=*aHiNZ}+%?`4w!2R@&$WW=;}@ zY*DZpH?S=V)=k+v*$wO$3U;4jD*#xh*1L{i4(t6QI}g^oaiS1YxsXlsjUwCQy}umM zIa@ne@1LY4=XseP$0W$7M0F9Yy&rZ#XTE-}RQ`ZA@isTGhZSt7HgSm?*ct^pO2K9U ztW!=@5X`}eo$NJmV(|n?+s>c!*g&_r{c4ts7xV$o9~p+`6U$%5E4IO%Ve5Y=YyrjA zjo9!LY*$&>{;6qO+6Ej7+rQWYc!?8Sc;q+>+o=||pEGSN*mt$TK0io)#(M|OV5qVg zZO{c$S+ncV;is}ro!B1+tjSq#FBPM27Z7Fd#OdVy$LZ3Dz(zkHB~D;|0Im%DT*Ks& z^9b-sOJ5`cN3RT4c{TTA`yFVVB9i2rsK%f1nNFR(ESMe(w8Fdiun@+iga=3I;so|}Zj{l2lw-Js>} zztupXjx}OqWRUAvPX)Q3=}B`G3gPrmp1PSZ@1|^F-B5N9TOHY0h!>`t=-y@mhMTu@DP`dJ>cW z;lc~baJ>gGW>2BZmMl4F3)x@e=jfbHx&lw_E(pbZ_x=K1mJ-M&>(&y;TdZ44Ag{M> zn@|bLHd?pRte9_^b!!RaRo1N~kaMitW-VK7-AWTP%2eaCw zw7q`|a&b$!GFKPLqF!HoZRGAoax_*u{Y-`v4%T1S${Rgpy@B*(hLM zp~!D;gS?9(XF2{^?6S+5$TAP3MT+|_Wx2+Jf6Xz_ZM|nG7N0++Dp-?ZJ8-HCb1qP@;;6LgB{#5v3g*?OZ*&9e zreIepZR^~?-Wnq*-WsuJ@V_bCCfaV6~%pj8-Qjt7Q9*~)Q|00pQA@6 zLAf~Puv@A}Y!PqYBd05!QDx2nR@Rw-^-{2&%IX)~z&~;m)r(jVxum%O2rH?UI_Y_wK-q#Ibef_-|0bj!j1E_{0}C=B_a zR>1!52KGk<8>5wOasykXVAYE4RyVL&3N}<}yUGo0q=Nlju}yaaJ4(T(DQy8auun!y zOD8L~6Wzf6qF`qzZ9X@!yA+};V=c;tzcW+zp(cBF#snk{`g)(z~y zS<=!wDg`Xh4Q!`^c@^8?ZeYJsuoo5V^L{Suy;8v{73@_vuqg`mkIRL&W;d|@3U;%C z-R%a}MZsn%dw=Ezw)ae7$P8sjwHw$*1)HZ}Q{2F=Q?PDY=`c62%M|PeWyp`*z(y-r zRKe2S!1^lKKQ0r#y_4(G3!jaUmd;VIoo-;yDcBdv-uvCa?p3gSWyoqbutf?sOe?K* z1G`Yc9#m{o-M|JZ*iV!pL*2l-E7-aUVaPFVU~iux4C$|xdfdSNtYGIUwtt@N!rq$| zY@uR%+6}B)!7fmSJm3ZvQm`V$cB32E@d~zEX`AN;_SNaq(mSNSc!&=I}Pp2`($nDX#s zH?V+$J)vMd+`x`jusap(o$2$7wHr^f@V^YHW#(%80dkGIH=5qI1-{&*q( zJ|({^ssOxGP8=;*1!g+?HY?SF?k+9(!%%5K-&xXv4T!07cH-@8cX_=l}YUwA_Ke7F0#cD@y+3I>>@f+cBg~J!NJ8X(Qb552|wV zDKhAP8vki+=qH~lOUr7D|BGrm=hMKtsG~n31OJN(s_JLg%o|WrT^kuNyS_47AyQyi zy#x8Em|X+;@OY*NCQS-lI6W}2$f&3@s;Z;L#CfA9%)Bg85;dwNQNf;FU0PomfpE^Q z5kW1URa{X8as#7^42Wx8MRk>NQiCzGK59UQ>XLboRw0GhPipXZT=9T_e+SQ)z?49E zxX}S!oxxKks^?Z2ktz(aDy81zafh$0h(^&e1<#Wflt!XxKZavzMOj&-mZMJ}S4HaT z48-MX>#L#_vm-!WQe1U%6vMUxEUv7WA4yWwX22V{?K!Vp>F1e3W?8K`x$U?1e6{(8U7L%a46%fU;K{fM?T#H-72lX4!ZA^VtNfcdBH@urY?1$x_I;_CLjBLZO zbdJ%#e}DVBF1OzRPpS3iXc>wFhmD%*imGU&){`?S zGN*!qGTg}VOrLJiKYco`ORGzewk2Rdq_(!Y)?<*hh>JP%ljp09z(bKIO%+8+`yt143JsYcuS&#i?_0Nkdcwz?ko z5w^CXBntXYsx$f<_}_E#NhK%u_s9s%B~^L+Z+eN%Hw%GEGHQVYfZj-zjJetM7=$w; zMp;Dz!~+DQtjO>zl2lnra!&AkBbN;+jg*1TQiv7G)mKFtYIHED3aNvT4>zhJ zbEora1j^?btV^GYeBv_s(8!%#JP-82`Wdr}tL7PHwUG$81|CG}`gQxS@!Rc7;xBH9 z)D1^x7`c%$=;*4;N1RmJFV9G}!pgGCx$(t~pGIzNq_~m|h%^whjmL#gDIPhQl4n>{ zfUYEwDv4F4z?#Pnra@sP4af25(JuFc3Ujz()MVENb+R#$0H4Ja9I-BZI2uZ&dX z*7O^3()`jhPb$r2&-5EE1EaDUdIAte9T4HNHgZLMMQsFfP*KI^*F_9M+p=cU#1tN@ z{JEvjsg?$<8&EbZ--1phMtxoJtcWq3KBa9TibfaqFN2jgF6v)dF?;YOe2vQfn>cmS z#0irN4J`l5pPfG%LIDoI_@k>zBF3ERO1Q0*=}56r4F4?B!2Y8s8xcr=Q68CHQCCwA z>pFmlY&=s?-U5Z-Q`CS}{NiHpV0J}iajh}8cpfEh{N$qGXbWN8JVVGy;t?UOt*C=r z0v@+P%DcMy+A;_uooU|As;wwB;MG;KN+@sCX#LHcC(W5#9;r&U4IX+4+5(GAuZKo@ zCJGt(0|pi(>mP%5+5@EmF2+1H-8Hqafz|a%{|F3%$^{pU2xMwD1sxm+XJaF)% zzK(K|B-?IJoiR63F{_*$1K}u}q=$XdhHmwADx#pPvXU00Gy>vE#LK9w#vDZ$5STP} z>bS!3QzqLTZm}gPA~Xe2$PT##HwJbHa+4b_8aId(z?2lj`|KyBCQO`CG-14j$ikx% zW?X_!LYcwFoZ{LF>NJBkoCMDSqb)Ai*TJ+V%T*f_rcO~YW$8K?sfx0B1~d%~vXDUs zHBwwkj>_Mp!gHq5c!lFpqw~$O6rN#Ho-PrBrI9RrnC;w7mc5M z$$291hLJlk|I%T`?7>Dq5y&LG^MddJ4h;NR@Pob!zEH=H1D@_j^~}0zQB3{&OLZP+ zHOXt%SJ(iDp|r$NzBBs98zZ3OYAKObjv<;FpBB!^fU5(q+re2+>!KL(#hAQmZ%{WG zQ)~yop3uTOtclcCRI|dUF)tEDcb7&=p%p~7&ksx*Uo?Jfo&ixari6+{pEJI2@?@iE zvN5@EiZNvZh8t>|QZ%j*q!_t|(a#uf6CO(HmLv-dW4zTvb_c0YS^(pvJM6w_^9Ut{ z_wXpRYX`M?jE8L*i>H%q&U8x11g>}*sREu+93{B{2#nr zKfg7x7QYqvHQ-l{Up9WUaD&9m^=EiR{^M}(U#;UQh$NA&*ZiNdY};Dib1N(V0+p53 zP@Ys(bF1s&gGU-lB2dG#p%rWA8K|WKvu&Ko0ykzB)IF_CS!MNHLo5qixsv)y6o*o$ z#xI_Y$rL8wWp;U(J9vAnLESx~@sEj^f_jMDsq$qbLmkwdmBVvM1#ccLvW zEuCInR#q2@)}cj_=`gWT*g-=p8J^PaMtLz-=Y_W9RHn{2et3>h#a?*!*Xao!07s!C4a8b4Vw@t3D zt(}*LeoVojCz5b=z=+5P9iagO=%9_QfQLiTL|9-ZTiNoKDIOE>%A@S+HHXX`Pmly6Q3cshfj1 zK~N8!%#0lNR-Y#6IfSLpL+- zG`+gEViu+b7-O`v7^*;83f-Xgb~@(RSJX$UN)X8#Kc;Bx=)mMcj*ZA*hz|d&sgp~N z!qo5^S2#H|ecISb#(9I`w`l-u{_L5>(eimHYYQ5@7U}WXk-GBf^Jmp!;2CoULn%O# z6c~J<=pBzj-?N;OWS5H!o(lrMPkjn$m;3kX%eRXW38qEgw?0R?dg0?7{NGXZfE}A; z@K;qlXL@C1j!4k|#sB92Uu?9a&Cs4kY5nZk^PpNQ>m!(MM@o+m!d2yb3z58}%1jP$ zm1C;&ikizYu#!5Q`kAh>LIQDdT^;7w#z1O+#2}!nb8&gabmA=4>4(P%*ue<|7$O?s zmjK29V>HGx11sW}7~?AHF#W{DT#;!&!-&qSVdzECPp=)~`Cf1(<(#E+%3N7peK`$; z=waYNt3c@hD>Z5?^EI3mSXDaRgyHI@2tS7-EE289w8WZJ8u86!M}=VeQ6}9(|w6cQ1Kxk5UI3F z$g~o|{m>KmjS9o)vB(s(mp_AaVNI$ILGwAbkGuBa!t-noCLDqDP}eA z#jM%I#!QHmxYl)h?oT8-`(1#1{%Y<^BsTs=f4t{4^EUi8^9eyLQ1PG+{3gpKM-+c?R1z%AkX-3pVQ>lE`$+A~c@=|dhbHF~ zw$J{3QrJvbE|M`fS)L)h>H%XAw%7&tf|?s}Py(-Z;D=R>~ZdBGu{4;lE= z&Yuh2bTEU3fpB=j=)jahXac(hr3g&7p>xPE7d+aIL4$^NN{6R;{aC!RaTa7Q0C7eO zsVOv;T2eK=!Gr(i@xS@}FUtSsKnB2BxhjrYS0Xn0ST5`3xm?akUCxzDibx5sEM*3T z4$~ozA_EmiWS}C54Ajz*fo1x9koA0!^?Z=^e312gu=RYfR#hh1vnq>cOFl28ATOjO zFBGPx9F_t^&BBGk;6h<=p)hQZz~DkED7SNXp;cD1BK+BVSluS6x?Ej$kLt)>Y4LsLUUjpS+Id57O)MNLgiRwO&`2 zmsQr+=yl!9@-q9na&8Ky4lp+S+~O2GuS=v)>#BKODtId7TJg-Uo?TZ4g+Tmr4V9j} zt|^xOlzgm%B=fP1q}K>kC(GhGSr*sHvbau`m1~u;>iO{ciG`e+V_hMyE}17+bxAmI z%Yu_U>nZXaaJ3en2x(s+}X1moUx;a&6^X6PGFo#}%c}U4%_tm0{+> zoU(E&on3di+?P}f!Kea3NNmgTZ&{m%R_6p8QH#_f zJp$hov5pfRU0Oz1iF5!(uv*+V?EGQS9s7U~r-r8ldjaJO4@PHubQn=D;IUBuJ^!GR z;2i4zXe%zjDlC%M;R^Rm?0FpUj<@OO8pb@SpCQJxVo?cQm>s0b*bYQA3Cvdtftiw7CLmsxB0tT=i5fN~G zE-FNSl^|+i$18w?f5r&?gNw=NMp-qYY;)Oa7METgZloQPemdWkJqPe-_*)bFBG|=8 zwkF;`%;U-HgESNON3|yILVhLE%}5s@eF^DiqcyP-@xyOU#68ly9Ka)e25H|6B>C7@gC{@NW=YG6WfrkL;5Mw%2QhtrEp3rvH$Efq|acpE5Ez@K2m-a;2WeDBjx)$ zo0*UFC8Ry@+Ryt)*Oj84uE_sQYa#=5hkw_ah$6ih=}M%}JkXlxg$2fy8(I@nkmmg! zbnqVOH%Q-q5U=!NFW}}!TN61w0FU$xq~9PdMcQLC_=0r7W5C}N&zpf4Y2Fi{AL)Xv zXm1wkeF}Jy_I(=l_`%O-K_Al1&$lL)WrP0RfIA#`5qEnCY2IsS=MT{C*Kv>Z8KiF` z4ZjKeKScR=koNL;?l*x4>1zjC6F2q-Jzs*pBarV)B>El+eA$V_H%M0=lStgv2lV75 z65Eaf{D4HF@@U*&o=EiQ3;b6l5<`wfxkZV@Ye?5E!9k)wLb@!G*o^d<6~Kp}?=#n- z9MZlwBofaceeLJSH-P`vL}CHbb?Xv|mymvQ8}5%s+JyR%_P7W4C!qWTiNqN>Xvfw> zB8n8G%U|03NuIQZ?6hNgbj@6o=JDW>2V{9R_GnEQkTXwK_L!_bXZyR)&0OR;>*&)@ z8Jq)bT0V$$!x60sg4ut>doh0Nk&o_4{yl`ND1J@IKMiu>8I_g2+8fI1vnoBDWyCXz zvT|4Y0$KUjbO~e)UD|bQ)}r+EThp>uq!(qa!EY^oP3adg_ao+xLGBpjjzR92to8V9 zz;7d(!J7qPFA05(nDFs(hTqY-Lm=w1UTH?dr$IaLU-@= zxCv%u7iMLS>n{9`0*`_5sXGFI3x9d|twjD%#i!J!#EV~cF$a)RWH{$uVN!=;@P-wu+_72Bxs_Q> z$k5C>q@!@3KI2EY3IS{spwP=mci^`x_k299aXcI4cm~0dXGG6(ojtR0I-gBsjXylh zqM@i=$;_0C~f>2q34zt;Z-A zE8#B;g`e|dT#J5z{-8d%3;Fx*Xic2ocAT`6Q%f#3WTb!S&DxlO?!#{fe!KA7gWo>< zO#BXHT-=!;vr-*Ly)Yhj-PM|ayO8|jc*#Tl4&+x^ddWFnMNfp1dSVi4pNQJQ5&ZUK z1W|h!c@ea~qj?E-7kj%B_{)2?CbqCvu`f_xmVG%Jh?so_eh&d|!`-ckW@e=HBkYi+ zA17iEde>!v<0%D5So}@F?^Be|zo#{EJ2Oyz74=S>`ferl>owGOOS_EA8tI+dO|%X0 z00NLOg`w_vIzezJ^MHoqHw@#`0K7bn!a*0*utnF@tbACr+|drQh%OhFKdGo$7JtOI z4)|68-{iLZ?yTR#SsOBHI_0fsM~~+v;G@61_TJXSvq(vw)qkDggWr+qt<74I34Mm& z+RR{9Q)U>M>2bInncii{_QHY43?OeF(y#>w4FUM|fZu?0V5A>D)DzRama z{xu4rpE4&~NYXFr+^Q6HPk+91y+790``ci**1(Szc`eF>{JYsg=L{Qk^9FNCu& zI`ciEMEe9>@Fv?aWHS|y_dqop~*1r%}943-Gy`y zl<7XCCei~)4h%ug7Xbs+8Btb=LrGtuT1_^t6yK%Vy>$b=k$Swly6u;i#C z2frIpPyR!#i3zL+dMwTRQPvKi+m$vYivq>$mH2H2+y#GxJX?I}ppR01%Q*B2G{O$l ztDORcB%Km;bP5QC5?GTCc}Lom?v1k4*C=&9N`*U9n(S*(fz?8bSfHg5N>>7Qrb;=0aq`fk~vOPlf9kO1)F5kl>^0+|M>qt zer*O_8@K%LqALofF}^TzTWjJ(_$>}Q)7dzHSJKscXO`I&;{d;d_$|tufz0$QFLI|N zcLGvKbXVBoPTX&+n?z4OgL)6{#QgNT<>zduAdKi07-nnmTZ>;4MmaJ&_woz7mpOo; z9H6oRd>=BQ=hr~SS3s5)d1byg1r}(-Us@AWDL^uhg@GSq8=p~GBXK*+n#@vfF#fU+ z@C)6>W1Dz@57B}ZK1|$wpxXyhaJ|Uqor}yX9GTD)c(?&T8<936-GOu$(mnX?(?YkQ z5YVmhfqq0CfTpNZE|2d14d~26TxjESt%-Nt=uGL`^Rf81D&sd&K-zX-UfTusUC8Ut6g2vPfE|) z0}kx#63jA@9_VsO)~+t|kOwV=dlUHwkfx*>%Av{UPG+bQ@h)e980qKY61+)!K+6?D)#fPnlQ8ZO4e?BEI&h|BTN#F0y+9Bj% zYK)YXHKTny(7s)`--GsPJK?F~{vduj*!MH6 z=jnsfa5V`Km)JQOoeu?-GWDm{A)b8jU~6It{NL|v--a&f|L|G^0dsNC&dN4)@$N$= zCiS3oBVwu>K%3sr=;WTGDSc=fo?rrt;v0bmIce^+_JuPVM7(>SH<5Uw?YJGAj3cG= z;<-=+RatAH5SpME*5kJ!?Ly>v6Udy7Oax<*xh5@wG>rQx?d~VzK43jR$9m3t?``c0 zcyC3vb^`5jJOA-Iy z&@GXe-nJiM1v|tSr$Rx)-)w6Npx3&3%R8-SZ1?nUp}$~THgtui69o?+xLrnB`-}^b zF#$!GLMb91unzs$1M3szy%LF^Gsy5=<7rRR}f|4^{wh4N@%x*}-+H z&>R-J8ig+O`~f$r(gz&GnQ$x%~!+R?;x1+uQPio+d3&W%otjx0VTNt$&np*m)jS*Xw(o*eYg z{a80DpMZ5C22NA`lZs!Y#@X1crtI{s=~?R$ve}Sbi4@(O&ESRRAWVrTP1$1WI?j_2 z)J1$x%FedRV%okw8#A*F*|3~~%}XQ~BLjw0kfl%c;%X{#(3ki%?Q)U#e3IQhev4(A-W1Na8k?=)wiZz&_7RBtGPXKGmNo`<3d?^H9Utr~v~9zqR-^ z`6m27_TB@&sv`RXzw=(+%e~2aDKB{;kO-kBL`p&+6d`m(r8g0f4pIf_Ef5Qc3Q8=1 zfQqXkwq4eWYeN@Zb}fr#5tUVJth?%p4YBh7e$UK(xe4eh>+k>nv*CS`J9FlgIWu$S z%-p%>-G?&l$^#=%hONBpUzefAV-2UAqke??dX7JGXJd!n7dvzq3wlxS(EFgwH|>~R*gdfqL_P}nTPGhmA`c#ay8rORFyLR$ z34P4o(fivFp1Tg6g&#Kj&;4^Y?(hfVz8>BV6GIDb1kl%Cmkt2`) z=l&RsG4&7NvWsV3Ri5{p#kGa~`zYjXpMT`Ymj8S|(mQE1_gIsL*>`GfGEjpxqx;v+`_|G7T~CXF6ZRr;OB>I&|k=Rocb$UXbV8a*><(pl0BoW)>W)^`_}6tPVOJOaw~TFz#6M>DY%tkR8V;^g@l#n6wRCHUv_ z_619h9QnSoAF1%S-u>nNIN#TB33H80!14z}t~_Dk$zb5y0z=?rd|yK;%M$12sFtC8mDxdiX!OO6muLiP2JLJbKs~&j!vw+6@K%a`q-gVwndi zcXPN$#s9v#7{4oy94W(nAnj)r_854c)PwN~7??Q!@HBbwqQe%*rTtWTJv{%q@yL-s zV_)yFyE9_@RrpXdKl>+@1^tg6`&Lc-hzLD-IoSgzd*Eaboa}*<2mY%bD44I=56=5#V)mcGLoNM%W2Ro1$8zsi!FyqH{;LY!3-dVg z6NBf`5kFp-$DfA{UTaYq=5g0|gEfY-_^ApXF?fd9@Z*K4e_)8_cky1Bn8Yf0FU&eq ztKhvb^{-*@Zp@??W?8nuyZU=!>Qu+z`N)(XFU$j++$!~ZVe&MsBHs(M&kGFR?SC)K z$B=CeUJi?@z&!u$R0Z#a8BTDz!MpAE!U$utdKo;&f*&u;IMv<;&%Wfx3nPrl>TmF@ ziytq{0N262_4vB-y)eRbtQl4CUfBD+1Ij+0&$&iFt%YTIVd^xh3f>EoXG|5m7j|vt zr}XmHM>;S3Yt;W@AKfx{{#1o)_N$Ed!mPhe6}%TF=d8Y!`MogPU$wrfu(v*tTVD8N z{r`Rcd;7C${}T3&XH}T}?;TI#y|5m6mj3u>y_p~GT&N0ftb+H#tl#U8S&J8D{WltZ z*ME6o)>*Z_s<5{{%J;&*M*Wn*PcJ;P<;R7GSAnNiftOW**HnQwRDrivfgd)o>vwae z>-y=_`N?jhM-QP0^2xipo}`A&a@R9Ff|pN$!Q)Y_d|bTi_xW8@e!l$S$PA{PxH#eC zj?3PB4ZD754HpM|44K96&hq2N+aQERKCazZo3(ygYka@VGz_6*@^RNcgy_h}9-~vY zeA^kOTqo90L+GxnZhb!-(fSt{dOVeu_PBZ+H1K;pw4kpIe2I~JGCA1;Cwt&z55#(4 zgZ5i7*kpzne>~Bo^Gv$Jq-#yO#iS3K^cj=xG3f!59x`e0d|g3?NgJ88*rYv7I>e+C zO*+q{D@?l9q+3k-ph=%G=^m3FFzF$a2E|)iR)$F%nY7rXJxn^pq!Ud#&!j6%y4Ivy zO!}ZnpE2nklO8bXA(IAYn)aKtkx7e9+QXznOghn|^Gv$Jq-#yO#iS3K^cj=xG3f!5 z9x`e00#m<98=17&q&-YJ#H15VI?tplOuE*jTTJ?(NuM$49+Mt0=^>K_XPNp<+Q_8E zChcL;Ats$@(s?FbVbZlG-D1)QP5O*U_n7p6Ne`JcINQ{3(ncmNHfax&4l(IOlj7w; z@>yZhwI(~B{<@;b~<0p{tvqhsO6pk8S&?J^EY@9Hm#V-@kqCx<&5Fjo3MKXjVCdNRJ zG;!iD5;JjPOa`+M5bM)lBqzod6Xz*0Qe}L8u~gxzB-NBaYQg|{on~w>6U5X|1zt-& zW=?`OxeCyj-cbb{J;Om$tbk~;9?+O(1>O|I_$%AJ3tiSh-!ZH*=~X6uYp5>2&cHXB z)a7&2J4`w51CFqaDL*d$WcuIrK$$uBF8eS2+<&LVN$wx(0r$M3D*oaUJ%945Aa-9= zrC_6mXRfPUUQm^;GCBsWxjdFVnK_Og;P~;M=QQq_%`Xw77e{%4a<#m;I~cyFzB+z> zZ2tdT8{+$n<@XAzW9OmG@P3$}iBlPxH>dfck%rw9-#d{O>jIKeh#<)tieyv9Dj``HmCcOJq0IrGmcw(xBbU0-~?wh?H_-F zH{-a~m-gf5sE%8}3C<|($4_&e;LSL0^%u>+k9SpT|1UqaHnaNrf8GA$HlP!nQS2W- z(|3Y5C`}=bJZUZnfS3;75VyjH$+R06)<_ z`8@ni^oefA$E&}zfBKkeyA3k!udc@*IkT(r+~=H`H)HyQdDS?6P}*OO_kV2vgvs-& z?H*uWwV(fpAjJ{b@vfgIIv>9OaH2QiztX?jw|`7EUi@G=)2ey<@s;pu{h3fyjf3Yg z@)L@x_xzvGqS|i#WZq9`QH{SmMEh@1-R-}6F8~t?tNHvdtmgB-u$s^R!sWfN{1)vWJ85Ed_J7kCOq)~C;@7dJ6Hm(YX*1@` zuEs}Lvn773I`99hcl?@+f3@EKPn%!8*S~34|Eu%*hc^I^n^A2KF=x-1G@&}%|I7*J zBY^S5+qe8$8q52;hK!jux0-&7ar)RXb0)dRwZB%UoT z^RF}d4C&gV>#y3SCzP<+ldJ8k%VeBRw!a$R{KEofPp;nWpM>3Cb&gV4BoHujQ zD7Avqy5!-{-gcXdj6yR)q4I{^Znm>)qMXq zeZuTXqZXYvtGfRF-}EuFr&iat^8iG~e^T`w|8X;B%o;!W{4sMT%&wMZAjkis)gEGQ26OQ9$pj{(verw zPZvJEg!`IRO`l{z!uJ554F8%0`rk|m7I(n|=d-B-qroQ2Y z%G9?zto!eb{9`ld`pPeI>06op4;be>r9uyXY}gU{Jd$C$Bt{-qFG_v=Hq71 zwO}zhod@Q$Xx5@-vjR(%O~i=BSrJIL)wAjNP5A`mFHE(pssk^IgjqI9Vl zZ5)Rfp8%blo@h)kPJo_Hka7b8^m7`;0|*K*)VZ4&Tg`=rqa6nw986G)0Zej65ED{V zc&5{hm=po#IQIh|jHsEwEO3?)lc9P5D07;llY=$XAOIIRi*XHRstZAVv2!aG%~s_A zRyuRD0W?%3SmWG~2%wo-4Pd=9G%`XYiNe?Vb;qPm?zTLWirCYkR67_9veEA+?3 zO-5yYJMJ$ShxlF~OmU`+0+D?%Y+26Ky2x7g>@?=TL%p_@wh>mgQaRleVMoZiE1`3Q zuDc*?=QIk?m=q@-l{q~W+n?#oMP1J6!jt2u3LwuJ1$%VPQVqdc;Jirry;K(fZJf5~ zY^S%H4WN^gjUjXTsM`SabS7gkoxW-xfPRj`1a$hT4*(2x%3uJ_AoV<^)MzJ)k#h#C zmjO(2*0Y`=>NNl}o!KxAXPEi|JPVw=aCL^Op(rbJJ|xcwk+#xVM|I9s*Mne<)0OQR zsdfWc?@S>uM!f}To1MD2I^z}R^;YLDYA{inz0G-!WK+~u^xt-8JjTG8t}a47JDdlo z!38P`)?H2lTRKO2XSb8gN*Ab3!0dHM>?~Bh0PJ@jrsyTA9)|A&=XzL%Q>vN*IOxQ) zLzb!~01l@YlWds`iKWtevq5F5DFoRn{R4LWg=#3|rKt2B)aW8L9#E!A??}pv^%$x2 zwN(8QH50fzmHq{lTCQ#fRG`vdC*KOS1W+55zLWiTsj`uDQtAJOqjOeDD|@Q+e2_So zN$veq`c;&9xj;iz`WbBX6#|V`>GxpDIjaPkq|(R02%Xge%~a{@X^dBjjVw^<7qJcH zsyDj3Okt|fc6|@CJEpZ`b^}dic_tbhv}@y<#J2N4nHLoLkoZ<1>#Qh2784m)p`r~4 zl_vH5iCuE(I3b$s5^+o_hz#YetbgTdp}dBaVc|I z{3jvZLdxUErxhV0=7?;SW5X*N3W|eazDSd@Bx|R--^F|b+sE>|WsSDCu%-7-%Xfzl1g}mOf*H7qz>8x<+Bk-A0_?p~h^}>s z==gN4(sjNDoKLUaCqxgsL@&jNM5a*IXrr7r{s>2Am$NnR6+uVKKASW9edcZZ3VNgi z%%|8d(#!mV`Aqw6>hS^dIrcZq|C9MVyD@5U{>2GiU`APOW^tzuhKhwUCgYh}@3+x)y z^9$z7?3=^Lf5}&-Af*~f|F6U+xr531@H z;GpwQwkJ-2!|79KwgCaKr1T^zC=iyETWR(Q0%1uRNhnbuEGhd?qZ1M+N2PD28exI3 zqm* z9EL~|YcEvk=(eC;3)c+ptMnc-@<&>93soq{)`Ur9mt}@A|y9CLS zGhX9fC?2_n(psuz!mykSO(B9?B|YKk47{{O;#5HL$#BoDqgiI&nX^OkEpq)zs zYRG++u8&Z%G%4b657}PJO@Km92c2)saV}BZ07O=Eq&jMyZeiV>biN5{bvmn+Qq7fa zHQXsBbGuwomlY|YxGw5GA$`~-|WD6&EODO_b}Sds27ine@tkdo-U zEkyqykqj1^P|>H_w1f6VK-Yp90GSmR+K`7dI|7TbvfqXksO*!~ z6wFUMI}BBw?8e|q$bKKXBxW~GD$9ROZqcE?e?4cO5U7e#BsYco)g zeJ5=vdk(THdphWRMD5|3Kz0e3t?XN2zbbn$8iS6w16qe)Cu8JxC=qU^dLmzYFI341 zw^XG7oRZUkXr&%N9=A8Zgp1W90Bq+bxSVhs^&|i|xe~NJT&OMslyNOC$-H1(+arnG zg>1Nm+Jbx%%PGwzU@h47;hM++e-Rn8orzpW{idqFqex8SQ)FbUjW6RyCp=AkPyAT$ zW?+;nOvey)pql5adcb9zMFQ56Oxy6}1f&SV)RzstK+$n!(Di6i;q*`qXQ$0lr65Qu zg23`hlvdP-Cc72BRJ8?_=yNv7#lH(Vr+6~UpwGETYEOq{4Gp*V zwS`s6&40LqPdt^}`~#3v0;eVHF^nS-G$94|;{ba2HbY9LGY?Y2Jq4)g+yV;^_ZFa* z^CiYF+*g1s=N$t5ee9xa-17n$C_s+$HU$h8pn>yecKvYQZJ1MePInN8$N1>V3!I`7 z022jhQ)eRV$9ETqIyp~p0H#ZMPv-dYKBX>l9ZME*NS|?VZTy{B7a~Du2P#_hR0(JGU72av?8z3nAfSlxRf8nC}TuY zlNG6hp$K2E?xk5x0abXTf)B7V>flmE84cvp|LKP=C&VoeYH;gttlFa&oEacJ&qzTb&o_E*@6z1K8#a zffo)xp*{q#-8qbFc!&BF$qr{4JLMVm6@Xn1_ZQ*k)b{{(JFk=HCFRH1?sa&F8-7i3 z0pIT|<`})Dk^y|+{DysXK+*Rebnd5dex$Mh98OqUR_WhUl_cL(K$CDlLcVk#TQ*Z!iLW8$zxcs)%s@JTpiS2pwCMzcHeFrN zraueXbUQ)&2Dx&Jh!X;#=Tr^abYDT6CLOeCeTl76C;vsd52ZBX#NH_3f2{Oc;h+_w zW;7^he<68VSYP8`3SS{^A=4RI z6NuG58fcEQ1L*M80_16xZWApEoN|un?V?{B?SAeM0iB!y9QnJnm#`wODdBG4AF1ru z9QW;_Suco+tHKjBL=p5Z8=yT(sYy0+#Pv3{}$U@t6d@dtq%!J#QD#(;ID-O~XIEDJ?_ehCPBnAB=0Fe2 zM{RluoQ;;4;u{-TR<0WC_}v=d*?HTeW=PpvB?0Ke*}|G-FX&3fB6Tc`8?B5cfF4h@t5CUdg_Ei zOZ~Pjkhm?i@}DH~cm0HR|I#LBvPIi?uIp=hDOLFW6m-->pltdSCbqhloxKL={3*~^ z-A5Jt17zmd8p>C$Q0fp;!w}H$Q`2 z@~jrSW@*y_Xn=Z-V&@P$-v{t{Eq2?oCS}y&1ud4AtNu!{4PlB+&!wE*6q|_N$p4rl z{h}7TerZ0>5!FjYXso|{^V0kokgZ5!QD&q>u@Mu)8O8v`P@LM*Qu4ie0ynrBEdH__-JYVjcnaM z4elt--^D)sy9Rfb<`)rsQ-ixo^E(rKOM}mWn1i)ngS$)fdvUPd*5E6p`Oi^}cQm-S zH2+P4?`m*gY5vW$`}Z`szcin>uqs&bcm zXz#B?yX`2sk9cVJSEAitRc`YJOSHberB-Sk_Q0UH^3A0|R3BHqlIeiB^7TxI#+9!r z4O#^Sh9Nl@ZtQ&z(Cm8y)B@&AEz9v2wDsu<3Tu_>%t%2E_RY4e!hBOU%aqN7%vPq1 z6*TK_0Lr}4l{v|btyMVHpzk&O(4b(hm%rS@|E9~o%jIwOgFzQS{P$XhA<#hgN5y>3kR*Dm*K&D=LW~3Slx#5mb2$rzEJ|VIvoznH#$f;ts21N_{K=yDy~bn zw@2+TJ;YrxKWfvEhS-))hD(%f!(ZWeT2F^Zl&633a5SyQyU;vBvt5YiNo}as2S#Kk zircS7)yFP?`F0lqIS9U~-6~{mU}ilsb)aE02PVN!4;a9JdSW?_{~On+nl&)!;Xu#V zXx}_eJjb8HXZ!p#8*hkcL~Dfz=>6`17j7`tD>x+(3D*P+GYa{!1^=LXi;ywTYtd{FYV19+Ac0_mfMsT&w0=yrocs^p0`c^ zZb3bpgcqB&4^3YQ^^QCg<3op70C&X8P=CUgeyd=fY29DJeA;COpvJpgEh;pwS0+*{ zPSMjk8-TQ5xU@O35$b2qdw>o#&{H3trP(M`{vpaw)#Z-=EVnhyE-+{uom>43n;F=l zF``nBj2W(s(Xpzp_Q=>!S;lxH106x%+3Yulv<|BKqbq4zjA#%$3SDM3d(9A*fbbKS zaEDn-rH|cRv~}7ip8At8c?5l-t9{`&23=23;=`N0XU2CZ#CO)^j^ApmN6l(+$e`IP zSYKi4*bx1Li+lzrvg2QnuSxTFaxYUu7tS<=iJL)Q4yo-|AcK&U{9GGU*OZ|M>-w#* zUwjgIGw~pbj92N9$o=4EwMD4hrV7-w6 zv@BzdCC_8Z2evYHr=&Y>Vgh$a_FK>f?qs%OT?GvvRy;oLI2tW;div>~OICq8`BWB{ z3=P05E@OjB@}Y3ba>-6-=_+PBEkUU--_M8A=+Z*nPbJ?%?WFT4p>rm?><+aJ>L&97 zhx;Is3~r3%rqSv$8!jm|dn|C=l6cOyd3>MDW2mlHml+V2bPcz!oFB>D)9PDD$;pKZ zS>1xzKBx3$zIzeIFr^PyPA!!3tS%!UFtrW|=>C#f2>HJOTSOKBdOaz%dh7$e^Q!n_ z`X{fH7T7Q+cUcVrdLzMDUA{rjrTmei=`AYAA^#SjQs)vyUm)_6??Rh&j^)W?AL2F>O^V*`)-x>Cv@h<~*yY)bI>rC%i=-&MtkQF4c*c zE?=YhNt2o9>_{F8Gfn0Vz18z=4&oFcWhvBYi9M+G8H!D$;lDt~NW-e3qOZomC>Uwz z`|l$S{S}dh{$oTM`hO(S&|eX080U#J3{*rK1`bJoOQd1I6KNRmL>dM>k%j?Jq+!4l zX&CTE8V0J+VZa+{81P0K2E37m0dJ&Xz#C~8@J1R2ype_hZ=_+s8)+EuMj8gZ zk%j?pq+!4tX&CTE8V0J+VZa+{81P0K2E37mfl85v0TXE$sE9NScp?o0o=C&M z77owlqy4l=a+sLcR$kfGgIy$V1F8QT5Sy8v{M zp*=|Lf>+T&hW23f0stLkXb(}Z0MJ2(_AvDccyy4VJzNchlPQxRLwkfs(?N#zx$0Vw z=^#UUq^vos^$YYoW>wSdzlQ0rP3H= zXqTxx)M~3V1{vBHs)3M~qS6>-XkVm80m@Wq3^KGY)?=j77-VQ)qNW0ur_vZ?XfId4 z0aT#U7-VR#Q1bz`QE3b^v@cbDB%M?mgADDJ(#oDHjX{R?Wm0=TmBt`L`*MMXsx$@} z+E)lPTBR|_&|W3bB$YOX_PAQ0nJSGzhW3?WBMVd-gA8p?kRfeXf(-3xt(awyp}jl} z4G!8haZO^|`Jc=S3VF;gL5B8g{c@|ljz&>LJz9b{-mWmW z8&%LjhPE4I$ZEbvacBipH9>~F6 zp+5uH=sCFPjw7uOGPGYEF9cI?6@g1*M3idzcp7Z)y-bL%a*62pw4~Lbu_VaQe(kqH zbiYgVe2hqB3S~wcWxw$_9T|fR?f06o4hb@}-)CM28QKS!*FlE%KbY4+hV}={>mWn> zpUmqZL;GKx;5x|A{?JBV2N~KQF|UIR?T?w)L5B9fIoEZNq5TQVb&#QbkTP|Uq5UcI zI>^xejCmboXn)SU4l=aAU|t6q+Fx?k>mWn>5M}BhL;EY{b&#Qbn0Xy!Xn)PT4l=aA zVO|Fr+TT&84l=aAXI=*x+CMO_gADB>%lsejRHGYeMM#l8QOX38IV{KWN0^5 zbZ|Pz(9T!il39Wb?Ne1FOi>+VXg5(dwADd|c2m^`K%SM#AVa&Ex(QNK8DwY|s$?w1 zK|6|Tl=~`)H?UF}WN5cgO$6D3Nba+=3r=N_phvSX{9n&$8M##%%(EP&@NVY3&*|WpgiuUDmaWb3^KG^E3O@> zd{l0?QFK443^KIaDz5FR3^KIasc%J`!ahTS47s5)LKtLdpQf@=613})fEsdNrRyW4 z?`l&SqhPn!av5Z3chGqT8QLX^8-P>>8QLASP7E@%JL!BAG{WwzE|zL8bF1M_DVe+C zin^>+1{vC2)Nh6KewUP+RZU8#4qfT@f;J~W(5ATsZQ6|vGISbp`zJw$jwi^_$z8)@ z2{Lp%L55B&$Z$Vu$<#rH^+BqG3=fSrSQ@C6R<#5=of#IjRX{NhD#GL=t96Bw?0B5@tyxVU|P^W=SMr zmP8U}NhD#GL=t96Bw^NtG~XsaNF-sXmAVdj9Z47}RvQ86NWxGXbu$2XGDZ@H3e{vlQP!W#3kEM6 zN$Oq5hFYi<$S1L!(p&=860{fLn#i&GJu;yc$iU?@k}xz?J%%DZ{>X^0G7gK8grR9V z(vU-ci1^s38zM#$hR#<$O!nxhxM%@38tusmND+pKk%XZORBJNzk1Rb>cr9mJ)krpaem&!=O&?5B_grzc)Ftk`*Mp{;MdyH1{Bw@%KNf`1*5{A5ygduMvVaOXv z81hCEhKBo=!!PSd!q6BWM_xw~h9(NoruIbGkM9Z)=}5xRbSc-7grV6!+G0N|HHY1H znQDlpNndnDMxQiFUvRgt`y!Q*grQZcuS+?JltL8iUn`Z7grO^iD3y_fp{rDx%Wz|i zK}Oue#Yn=?I(4T@xhqB)BQj>kNWzegBur%_VQ8b;k0g5JM>q`Im2Bk=DiLvC(R^Hv zX&kJ}N@XNr=q6PRD(R3(mB}kq7u6~*bTn3-1uArhx&x7L5=j`^CV3r67}~C$076F+ zh8|W=1JIF#p(oU{0CXf_Xoq?cfQ}>#J)>R)pd$%G&#Auy(2<0pm(;rebR=QuHT6#b zI+8H-mih#MjwB2nP+tPjk%Xa-)VBZ*r!kT+^qJyUP_boYBw^^Visw47(ilk?`dXa= z2-{Ld5{8tvD3!)Y!jSDNqEV?dMiPb`Ut2&uRT?7+LvAEt8Y2lqAzw$}aGJqqrlGK} zJD|}jjYkZjB;Q$pCgBu>eCa;6jFE&7BjvyNK}HhN0U*{6z3avk($xiR`ZG6Hknzm; zma<$q_i=9rdkETeUqPED9kgkEi8W9s|3x|@32DTMO;N)CSm_+$pcT52gs(`RRu;5r zK&gx*3}yIe9j8bnVQ8MrND12u&G+2^c{-9Xv_QI#k%Z@>5L)4y%1FY{93TA);vrFT zN=q>G3$5_Az|p++GM9S2%%#T5FdQyqA_;3Fk}%|rBn++g(Li-1Vd!cBbR=QuHqk;y z5{7OU{d6Q@$Qwx*x=VWrE44M$3El0xg~~FLFtlAX3)&@6Kq3jlJ%%G2w8!8Yy#N>O zH>iM)Bn+SK!<3Rp!f?+^g?2S*8C0kv31v3*b3rSklL`-b1YkNMBqf8<;S_roWimRs zR>n*f?!&-A*_nm=%3fL`3B#U9!telAl9D4a+$NGRM}ja-Bw-FC3B!YzfNHd=%MDz( zQY2w`IP0vJ7e2R?b@BK&JW`y#e8)UIQhdIgafC;4QA@FFVMxQHNuFukq=-(ccQ!jc^` z>pU0NVCsA~+Yn(1y(KIGHCzmq`g745l_@c!s$(rgF;XWKJck9k5o0e^O&`n2Sxd+o z&T?~*(H*ETN22~@3hJN*?Wds06x6|YCdwP7Y9#Zy7gO3eOO;5}tCf3=fjbJXm3xbU zJBgKAx%U~kvw{C;;4Wg3R_@CN?yBcj9%XmavaH5;vPYkk9;%&CC)q)#@=HSM z$qg8xCTQAI9I7T$+{{#yX?i{zA;{czU}!QA@qm|~ccqD6h4pi_QFg*KMEy77Y)zzj@ zsA%|gg$T(S5noq`_*#p|Yx*%e>>Ck);cWmB;f~O!+1qU1cK5Mho+ycuP3MB5IRaX? zvnSQy=7_Z1&e^L5Sp~V|87uZ#aFOOHk1?Ki3gVhL9Am{`KYqFO)csi|@;R-5lR%IEAh6uGfZ*a|Ui*$L;+ zCKJ(bt-mrvZ=x2{KE(O-qkw>aEIBXM?3ZE-#*f<6HV0ifW)|jUz|Z^?$T>~salp@c z{Aa>4mjix|%^WN)E%tDr6aAdPJ+XYXUjtE7G2dI15fSloQfFcnYf+nnkS0~n1>6C% zC0(Gu5yH?%h4uw3&Lv|ngA{x|5#=!|yGl^MeA*vG^5<9urwJ3+TncQj#S?}TeE zWN2nx4kBZ9earB{3gz=|j^R248sTb=h6vXrWV%(Q?@lo#Ul}Py=poVcQ+E&$5whJN zgHWi#VK8(T-Otcnt7LCg{xUPt2;OMV>5w{>+Fc&tptPKo@A8&ae;FiyHPb<=s%skJ{9)9(3joMfKti<@Fqd(b6IHrbA*xXVC=1vkZc} zfLeUp4h8}8(`uGMUkkK#I%7{%eO9&ElaIs(d+9~y2h4>+v@_0 zR|WV&(EUaoj(gD#Pm`ixsnVnuJxwYeYNWLiItnXVVv0D3y`{K6{Xwg|)w*JuMXw> z<9(Z<)Lz2;(xRH+W5>>K0^?DbrCYDmDg!ScHO;r60b-781J^%-OSh^N1M*Rt(G+2+ zEs<%53|5=n5WN9yYVjF${Hy462~Y#i1kI;hi||Q7N2qgsWY9Ok2F2yoh^>Xi zZ>`om|E!STD*H-Z_6X>U`xzjik=Q;f95l|9!B~q;@jOUIFem2`E<>?7(oHKWHMHEm z3^T+;4)QG{i*E_)NV!T^c!}UEFh_M%(NIIV2dZt<)SP7-O))EZ!lO}zD68lh56!zj zLX+(2sYFZ#>8-8C!9&{szB7d{TomOSy3e6TzDt+a8OFj-(H9VRvWoJq(-a(u zsV?8%qvgNjp}X9r%XUYtWZb$6F`}Ynsz!$;mVZ)ut+LxRu-l-KiJL+BG$e#pAoC}y z-Tm~2VY#iFX`~E?sq&*X4Zuv7eRf#(+1E9P|t^~g8E>k}|nS8E>Um7g;ASnuy)*39gNjhKh znjvDP(wm%5XyV85fhP8&`Z9l#mQ`!OdWSOGY@6gdj=d9Nia8Y>^mC*QTf&*le z6IcGhlAu+*!Vp=Ihml4&>qVLibX4Cey2ViBLWNABq8O{!zpi%)2m6-ck)0NP3<*~I zoH)x`1=bF@^TN}{6jTLat&Vsk7dP6V#VwX9Bp$g}D^tc953gW#y};Co5s}Y(6gmrI z(?yzH3aLd44NW%yyNtf*wvu(GoW?8GV|OuzYZY}dI4)Olum-lKl>MQ5sa0pA2v_i; zas#kmiw*Izl*;{D@{}Qp)z->2V{6D;HDGnC{A1CC-G&SsYWb*5_s|$+8CoTGDi5F; zg)`>PAqQ|+M(@)21*^gM?%dZD{eYjlfP;o65EC83ic~mr4sL=T@YDbG zhN#odswo_Nwz~pw>n{!4NYtyv^X8GY;9HfoNj!co=}Ya{;gc|BgIYExHCtj-64dICyy z{sx)atq|NCz;!72!Ytb-bc zQm`5_lohFg9a%hpRcr(209G@j7#UXe0y5{YI)C}@C0#GvsOyTFDtlt>@7@vE?q}js zveuy8Su3{NXp<&xXL#m;XTWfhx5jK5Y_MiC)^)UjlMVF-)-VOs1Loo~1}s+B*;QyB zC(VtdxdWGbgl0t*ns-R^HfcV>CENyb+HXd)7hp=A^Ad{u<-3*)qot(WpsPLztopnG z@SU?!+#M_(SvDXS&^>LDDM03CG;2UxWcr?lOc!J>MP_(!WG*v;+Rub3wrmFUV3ek{ z$Lwi)qpo8X93PA=Zob83=5kZY<)U0L*xHYG=TGsy2E9cy`R7~seo~*Cv?TI8?ea`< zd5RwMpx<-Rb6j-sw9T5EM?W-r5&7-S6(TdCwm6NL$dXCFsXz-VCeA8qV46&AMhPo? zq!uv7RLV^N+)~jBL(0>a`7u(f=sHt=HSG2(Pr1*u{#KOVZptYq!<7F4nqj zg{7bm9sfc14zuVtrY*an!8nbME8n&RZ)c^OwMw2fy3_r#OyB)dovH|<& zTC>@F^M(3x740utS|!h!wsCo+372nm+XWhb0v^m*L$0ISd_;Wieq%KiUik|6A?=kP z5x>0~&1?O>ONQ3dAhmbTr+0r+7LJ34AYyt)ZF&@PMu>NRQsiJgNMumNb10W>5H{ua zaRC`aO2_Xu=-h#n`Vj9o@y#96%8~pYO`Lp>W+cBy6DQxJ8Tl=0i<9rsjN*4^?4Eu; zks8VG&Lo}6V2P3Z?o9GB`u~yq!c6ii$u5WR$kl+<4he@H9z3+-8;It%)B&M22+;*EW#N zqZAz@PbgU~tC6$D@f$J8e`Hm(!wRj(TjTh>m56+Ag+~$DRM_n~!8ZBDc=_1Eox7;h472CT^PO%NrN-AW8Hcb3NK(KOi{XIS8|sFll)` ztd9`I{fU00I~Gv#3S6uS{0dQWAFf^%3R)ANMx`0nUvVWV?OlJ3N5*3kPpv4B+b%8e zeJG&?j{74NiL4_Vw-p|t;|2ng)QT}4@n<8UPn1TkR_T;?QG0?2R8rKqfIL(+3V9F(L zK{tDCc#lv-9Nn17u0Ac}4E05nbV{WeQ~FQ^~ona>!s#AgTY&&IkMLQgk| zSEusL?Qwqtv1-Sx75Fo-Ca(gW1c)QT7x-3Cm^`$WDxOP4{N?*ch8`z4k{}$!J@te?^gD_jWoSl+#uFTEXzn&N@*anw ze8IQBeEqPHyqaN%1~(52$!i_X(cso$A$hHX0k;hcwM>J+vo&`6u#mjC!GJr4h2(`1 zM)IyFfp!lM^K~2j*9x?GL{e9(-RF6LNjurc zJ=m3@Y0UOy76OKaCr@2qsj~<={!2{TP`EHwSXNQEC|0<`IP~PnGjVs==Tp=Xsu2^c zMuw;0&Z4`n$b}6cRnRh zy|w6-!$R+p;Y>}l(xs_K#xpd{s$n4>H@V=NVd3*zlhl{^_$GJ&wu-4%`MGViGjPIBas*Obld-!3Y_FQrLcM)*S z$dvt9t=>XW>Oz!QDJihPf5*VcP48)YJwqpWPpV59`M{uzMO*v^ycQB^_I_oqjuogi z|JJBZMj&6@qPfyGd|4T#i>>raB2ZXyhD7BJJb~WmkCa<9@r5{8=SOYIfZZj6$msxg z4Xf*n{8Z#?u)%y2%=1LR0PjJ*c?l5gvUdTL6JU4N#9a9tK&BXYK%2i6%#@jAKs%Tz zQ^$ZQ!AzMt2Fwg*%4{%TPB2rZodNTLnKH2qSP;yViDkex!J7GK$>5Gqgqb^-nGKb` zcT3LgWKh3nW-U;G&ZcC7o2k_WB@Y9Y(AA)(xS7OmDB+u?momdD-gGl9x})R>P%D@r zs$mb4S;$O1%%A6xv8-Bi(EGI-+q8bxIaSIWhWM{tDhHKS3f71T@OiSuw`v2 z>ja>UE-OG;1s8|pmveFOemNIM`ImFi9DX?$t>$NQ`RurNF{MvY>_?7uZT9`Sn3Iy3 zhzu5#AwXynj=5kKxFi>9l7%r6j=hjv5R&&?l8-e>0Ejwb9P5Gw&Db*f|C~4)2QGO*V;?MO!;(%c5$mYT#)aZI z*tnqlEVjBdVCqOm%q8MzE~^p^*Meiv_~Lx)Fp8Cxr;|RKmL)&gW;*oaV58$d4mK_j zKZ`Ba4Y*^lxR!XhY)Mt`S6Ph3je^X zw!q?e_)MQh<@Pl+%^}pv%S8qCLD`r(HD(U;mG$L)ffcwz48t5Sq_S3E3dLDZp~T%o zpLq(-Ep6f~i(!8J{27OA?jE`Tcop~xb^QgHIJx|Tx$k*N17locUOMu^aP^;a8B4n3 zy989i0&wG5|8894_v6BU*#UE7Ec@f2{V~eo_v1n}4Kj$YM43|R9V@Nrma-wSQg(9u zesHs8vC{5tDVu6a9en4Q9VY(Nu_qDG8}tNjAf5%BDBFid+&;t+j*G{b#&zXo8846U z@)a*XvkN(*FG3K)UDpMvB?X3$u@XvI)s@h(!yu3GQjcH2dxn>n>i+`XE&f-{Q}(oGfwWJ5aH_gU`Ub0N;oabMd;c!TXBPbb;pk!zilA%$gw=%y$$8SGIv2c{{UmWGT`L->I;=~irA)|bB zxEl%H>bH4mlyCJrxD@vsimri1S|cBszA#?N45bxkvPdqPjJ7J+87|p^W0BEhh3qPq zZ2hswXt+Yg_yoy3d@M5BuV8n(WUn2Ij8-gUpSon@h(&tc(YynE-@c-*0F+=Q z-_j01N#Z&rq`H#`_7i zksLI5-u3XKHl6NZIEoqw#VHt`edyGb6pq0A3H1P%^Z|T`=JtL9M?BmY@P|b)_yWSi z8phze2tPm@dq05&5$=Z*ffkTYOY)UlHIpG*=k3Uw1)%#T;SA8hLoST$WIbO>J$S^r zAR@Nv!p|*;B*BQ)=LWxfK}77=#lNy3@;lah$l&)bNE4g>Lf{$Dqt+B0?|mlVb^&p6 zror_7u)Bh~;Qm&$cKj<(h1KDcwP?%?OMRU{*NZd7Sm|sm>TcX$M6e6u)*32T1Fhk+!r+yk{g!NObdw;Q5yAo|=xL^GtN zLK@el1tQt1{h1+O2lCouc`S|(f#_=ncnClXY@S$KsnoWlqPAPOYsY6lh^Bam2H|NV zYGWUvKD?}T0e%K^C>|E-wnU#ad=$P>^WhDyB*GhB*E8kwO0WjXZ(V?=tI;6tp5JiWoc2+bwT`NdFo(G~8aph%Fk;~WmD8BYqw720)z909F$KsQY zlmU{;7|9o%OYdoVW6`mguoKYzad>{^{^*&ZIq80`)|`B@8l7dzpNAR`#>&x4d^peH zY-vTW@X);NrAb&~&9>^5TJ>6H8`5hGDZK~ZZo@HUHCs&i0aTNQ#Z`LgAkO5Xj~R^h z0CwCOgMPE>yyq$J?s8z@tmwQN6-_zUaIlV*raTHs7sbkDz{NVGEgL*Uw^t?->ky*5 z3=us%x1i8AP<{!_#C5hi3;~_?0k0Hswz~|Lo$x~pYek#!rV}5IK?dBX+c{lKIi+=q zm7^}l-!*1B{Z&^hI?zy3u`!x5P=2jPu}L0L%eMD zOa5GLj8e}~TE%9Mu&=x%j(>E8FrVGPif%Qe?2u%v7H-3TZ_1l->~%Q}o*@P`9y7Qu zz=0m$d2o+JtmHHE-~^vcC_%ynWw#-1D!mKTCSL-U5LuF*Ot=lMvR8lX5ZonXIRNeV z|00guS3WI4+`I;JIu>iOD6jj95uIa1YuEaPDWz+LZro0ahrQdhTNTp1luv_ukqOKT z=Pz164p()5!r4e<_ft!o1RRch)TWVCeK=Qv`$fA0&^B=+ygte61q?ms(J8v-;OB93 z8P8)SCo}@r%7h;pYT^__I}YnTKWfv**ePq-D@Asl0XR*XIvG)78ZHBza!;;E;cE3I z;nS###!nfDo_m`s==BM`uH_1Kur!iP{Cbhcm;OiA=Xl_cN+YYVvc>4jmPXpu^}uVE z>J@ga@IM6kX?GR^zfR!SSsz2x)W(FnWX0QGn*Jx#7bK3JY1-HyR&ohiN6X?e1QVi1 z;#wplK+Vj`@SI_x1l$d3x3jVP(gS%`#m{jar6}K1%bz zH*LfQRn<+n3JDukU}*YQj0QqMv~Q{_os~Qkz5g|P8yVgEbrTK%z8$dizNT}|0r~~{ zh`I?s0Nn*}>hpkkhj0}D?XX%TFfa|zs+VR>=7kJ;|KK?7`9wg!n4EOUf-@Gf;ZU0ve zDLzCc+Ba*s*D$n;Mwo(j{0)GAzARg5cmw#gV|Vf28OQGOuQC1T!kbM$YWh9k*PcYfUjvqYEjkyO zZksIY8f4O+#-hWvlRPRxE?9)|)6Mo8Tv--n8X)WAG=0#k4fO{TSD@T>ibK+DW?bK4WTb{n&HJ9>Rso zjHzjPmqDI3H4Q%jSWJyQAsO~W`mJV@6dH?TzrUIB!%`ui_tIQXi{F@)lGsgj=){{oVGKpkLxG)}uh?m@2#q@7CrVmqHpM&~c z*fmv`-ZfPhc1=~&hbFkDs^Knx#X{La$*_g#m$uek<~*RI8%)2^V&-OO>yksjqbx>7 zpN9r@_=po9TFjkZ7IQD>@rwJzVwQ4em#>)~!_dEdG?P9)I?7^d{KK%(VrcmKd{Rzz zs#uGh*T7n=JrbxeEj*iflq2Uh!H+U2VFnS^g z#m7x??f|@&Fu&mj@f4kS9^k9$3;ZPTWrSr})cEHCYoDlL8br-2LGPY6iZLuP#^5fQ zi;XcHHpbw>?h@(JyGx`CyGx{|uQkav1`YQEEH=PKrJvnOcg|dtMpu{~q75v}^mv$~ zY#_EW;_Z_(0kMJKdRdO%b?cRJ3F;Zi7dhf18^EKPs;rLmYxEj5t}tw_4aohNuBVC( z%rqVYzuwRSgVNr)6$uAwhY?ZX9g4CrRKt0z*Gq^$vZic!%D`AYAX@!mf94 z>0R&O!mfAF^kb*G2BG2gfW;u#Ldmd&>DScNUG^Bz(RR)Bh|x0mHk;TKJjya+-r)(u zLhryY7{^$C$~z1z(DiUVIdU}9k9mhn4V!BjKgT<~M9WBao-vlO--xKNjNaGK0-!YMzZrUETi>w*D^H6a=?1s(D2I|hGl5D)%mVv zXt=^MT-ddYx>YPAr;25`uxlAEy=xgR>{^DVzZ3QAEslow0~Ui|3njxArr%~PBQOJ& zF|4q{GVaOt4D*j$##@Gkmhq04<)TX;PRYn#ondE_)wB>BtnNJ$H2!26HnamoV3z| zqP2#B6`WG1QUz;|s-TS(ea2HkA5D)yxSyyXyI5<)3Kn`RkmEU{x_)RCZLLZ97-?H2 zQtx9VtY~<8!q*F!4e+UkjXT+0F*YmO&y*iQU;NvY%QA=WrRir&^DyT|x7C&Myg!(u zI{@Pvony**-d_+aM;AK&8!I|Sonb|n8%mz{_t%vAc@>B;3$5rnkEj`5QG&h6V0rF- zX$)&cUp3`ajN2{_Jrz6PsqQgT&YKop*I`dxZ^XD}WO;X~`%*IyjpV%C$P~6{< z&@0VsuRC}!n$M5g)CfCM?bbqZ_k#a2_==d{dJ2GcJ<&L_`^qQjS~CR93AWK<@tC4f zKh*jb`b?iLt~V7`JzcE){PjqZR`DH+>0*kfjF_xtyAFlS;g`Td*yerfRqR_?rpBI-S2XL&|*XidHh zh1+^{j&|su`KJSd!`Y@iT4W%6oH{6y@O!a~BUuH2KlN)jzk6|{E@2n{=wjX1F1%y0 z?raT5&V-MM(e7Lv8AY{R+FgsYrr_l66I0c5i^U@HzlF|C$~^Y)UK21q;NOdc&Fj}m z+rvL%UGrg{YYz|j)s0xv=DN$=1O9lxvjE5J;|T)px)#QqifnEU`G4}q*0pVIV=%hq zccxp!(w{N9?p}!FZRqa8uPoHv;KF+s>c=}8J|DHD{gZ>M;c~)5G2sook6H|1w?1v; z?^~Guk!fyZK90e6pgV3x--)3{H<%uvp{_zH%q^~b$HHSRfJa9=)Of&f)9V-qXhokl zgZ#nkR*MaLLYI?c0Uq*nA(2{@QZEQg;OWC%bO*2%A9>~AD9Vb~^1JEa>0e+2Xi z-CLoW8wJjJ8&jDY`^z6)mi?$v8`do!zO_cLlJ6LdStVf!$JlotYmvOgFs{ZZ=R+KO zjN`|+q-C%|`FYbQeuzyfq$3()sAPwUV1q#Dv3mY^gBeC}z~~#qJE;8GkO| z#|X>jcxU`rz_Z}Sagsu5+;H42;7lBYXm|-m6UQX@610Y=qIUC4O6cWSqy%j-cs`Rd z&!`MO#rwo5)3d?O$zsUl>+!HUY{}-BkV$FVT-plC*Z87kfZG+v;Ku=H zO{3QP;u*AxANF;%zM7jqx3tU+|D49~Pq%c5TgpPW+1K8yw_Is_4TgF{IwPmdobX)a zW}ao{5{y>+3$a1s?~Xl#R_hJYU8n0ALLc=zl#20fTXc*K5?;V18=FdJ1T}UWezQeF zTqA=HqyIF;^i79cvBD2)JxnCjG4XC<<(l~CDrlwitVK;$6-ZRdU$ubynFTLKvq=8?+Mzh z)G5(Fd3Y^sR;4w&D)D*(MJw~FGjw|yVB13T`t|0*@ehtEiztH4i_mKBz&$KT49zF!8LLe>H>lUg%Fz_ZKcu3!dC+pRq2w0yVNDrV zK3WHSVrEAl^hkQuD@h_{9yeI-LHUjwn1s~7%an8e*zmk4_m^*4gjWF=ggMxtkud1d z%KQSm7&RjP10?$mO@;G*6MHFf-hae&|Kvi~d5?(S1-So3uJaxd|2*K}#q`c_)+5B9 zbrO&fA{tJ)#C6^pKJx!i_a^XF6j}Ia_wA6}5H3sLLLvkbb`eOBMUWj)R%H=1AQ&Qq zMcE`En=FD0ZXXgYy@WgY|K9t( z-+NK&cAazTt5c_{PE}WRS0mm*9xyQRg!8s>>%49Je>m^6)p^gbZcvs<=cYLCdFpJf z^IoWN>%13e{N)vmv*~Q-OZ@T+?AnG+Z=Jctx6a(i~#Gc~`3Q zo^7=j=WVGAt(z9-ZK-oDmCoB1dt;LGUL?lYiELzbx9LTCQO1ieQCs_P(S9ME_j=U4 zao%t0vr%;3b3qk9^MByHaY`lowQ=6dG%cMsC*P8`md<;ZllDBDwwBKO2Pf^rHf=4PceioIpmg3}nzW(wUXXAn zj`RN4c$0$8yAztPl(Kft`_7Y1QabPBOj2g%#s56PFzCFe3Bz&T=T04ZWn7rw{o4`|{uqm#;X6Jo}rla%jY|@GId|2sp-lv3g zao!6P)~54*K_%(D&oPoo&if+=>1r2Aoc9;XrSsk%a=rMEN@xFh($J0b_D?khJ;Ztc zgLB<4G9SlJLzTI)9=jmOo97O)Gw-eFg`KyDa6}b>NM-u z#oJrz6icPIw`RCZy?w4s)$53H{ORKB%aNO0+-WcB{Z1*9cyTSN`+HopIC8RSRwJds z;1uIy?MN_9IUEU=gDP$W4)4$f2Rn^7H>wg&Lg+QCR0tgmaI1|;&4N;sBYWO$2A7QZ zdZn}H?F;GB^DcIJ9;SPjswDf)$DyPbf80U#`ijPa{F;N@DWnVXRSxpemZ~thp|h^6N}8rK4`=hkQJ9r*xKjvqK-Jbe8(5kY1B+XQ(7~``Ack zRF%kNQC8Nx_)-Te+Rv6>bcg%*;%k&o-3miK)<%?0-FiFpXB@mULb~X7jbpdtVKEQI*KKIL;Bw6R}&O-_C z$Jxu@Z7MV@TS-*j+2b!;=+<(>7A=k2s<#mahPhYnifZDfaOCLt#rFGxaX!f~B4IZgT0qTbFXUVes2 z#-)kj`?EWcqNMa@p$E zhg>gykJ5ie-ETH@8P?+uDTBlMF2k_*W%0L_$9dHchNn%m=DT7$Eb7Fn%XDK4Chs*! z+e>o2CC#ktaAIaw&DLph&aABOhrw)fsc~B6<+W~w5%0pxruf;R07G)v;z8cLZ@A7z z{<9Tpfmhhs$c33-BK`p5G8?%t^IOEXY~<_%`>Gepc>cOXc`Iq+xm9*@V&eB8ZYCop zo|uf-xSfpHI3^=9`LOZBKZ!1rj~g@1y5LYdY|G^1+LX!1bt#h%8@H2>-wS{6m3H!B z;`bqLCL1?sdb@6D)7#00&CgCYu2*?G*)Vu@Fncq%mRmE;y5MlDwM;fFb*!CM$YjG( zM_Vc<8@AXRk|rBl#27l+n1I}5vT>um_>C8>w&7D-S7VNG#Z1!>?HuF45Ie_sN;#Zk zybY?fv;8&CF@BT+s_H9jv)7Rz{WZKUO|< zJ3r)O%~h+3x@~soJ(MoAwxmx|NzM#DbtUcUFE^Q|IYJGOw=NPkW zTIqTEEJB*)?Vp{rf3Rskmbs15Hq9L4*xAMc%=ce5t#@yv9^W+I)wTZSS2RrgR>aLDqr0ZJ zlMIVzCmA+BJIUy#@^(Gjr2iIpW|DD?PBMC1t!0v7se|lvLM9oO+Rsus$*{#fKWY8C zml$L2^*XzF-d;5Oy;5fI;&#;IKXK9G)w4}ou+xl5qwF*zw#aZe%@_)*^c;A#nwBy) z(7TU6WSUW^5J}UF0Sgmd>TH86U2442*`;m>>C&Zsak>(zB8FmRc{X7bl;^5l{_R>C1(>K%1Jzgm-XBGC||p7m;uk(~;1Hm*A?H~F%YbTkRY zZS_?;JMj3B4!G=~snbcYNHRtx*?||?teu&_3`s_koX z?`ezpRE_V@=KyVd=Nj{j_UXcJekQ(eXIZ<}$TQfvuVJCVpT>v&kp0ww)x3GK!M^oBI)G%Q8I1jpAEA&YhE&mTdg|<>t|-b}GMNdG1=O-$vt?EzkXXKg2tV zhIm5O&OR2QUi>4KTK#8JONE!7%%!B`)VRrhqEj7o6?9o1U{!;T$o{euZPVb7+iesW@%kHw#ww0+l_AMCDmv1QhB|@7ObHy*qM$A z>M61Ag+)kdP|bw?1*x>`pwO0l0z2M5rFOPdndV#Bj+Xij^|!JmN^LHae=FP8QaSmz zb-y-gh4DFQ5&rbt6H5U1e8xmHR~)3XEcXSrs^>E6%)P#Jn9;fNgO2k~DLkgU?tQ&^GYcM59O(7YPl1Nc zW4ecO&(`jt(N&D1F==#}*Ws-K$?z+tMdxX3@{iuklHlZ&<7m|DqlJiLa@k?!krFKy zHtri&c9pnvpUQ;$W%pSDQF)DMY;I?^y50I-X!Y5-53v>OigpJ|c2I3iI-EwlSKk!- zc%f-WHvZYd=4=)w>QBh+(H_DNM47QaN$h(R?dzZ7T%Vq>d-E0DaJ13=(c@T-b8+zK z(TLs`Jw?j#)xw+$jyCpgzZP||2_{xYy93eN649>^y*G@uc=}~iJI|TQ@%DwRu0v?I zolzPf)61)d5BFPT?8MK$H%*#(KZv}? zC;u*wB3<^yG7d_`P41i z?#P!~v_H~k?T&oQXl;s?e;X3mIj0o!?#3mF|YMSg4xxuoj7U=uKMQ zgou3)@)SmF&Fx0Syi)K7Ez^(s3W1IPqOT0t_}Z0)ufX|H%b;q*%JyHO6unNj4&oD4 z+&YNWwRI2~@0${H4PrXr*tSiVl*MM;FJPUlPSxux_>@G63iDR>nj~S0@y#9xWAB4Y z7^TwVM{5dp-@C#TUi@~YvqwIu^h)@khm_79`DI9#9(l^i5vde<7d%V;x=KF&2$U`p z#WiQVd@~k8yz%$qpF4p4jF^;(TQstY17R=zol3EHPY9*Fc$W{1b*ScChdx;8RP)-9 zE^5wl)Wl=wV^oq(^17po>2pXbHTaDZNNfy6(Zsa&e{X~^~BH!GcL1=CEW(R%ke zXk9|Os8yM)*56c;YMo>xO(jz?4hF9{P;*@<;l8b0Dt3Oz_2Tgl6ZYEd(2rC)?e$bh z7sb{jE7nsbso1}bWF0(VZMGj)L$TowRGo5LcB)P8Smjc&f{=^zo0U$B^>pZ)9kjBL zE{a|1C^p24-{K%I4JFZZ9ONoP$7>UO0j1GLzQ;ed&|Q|ZUzYdW7TQV0K7rW3jTjv{ zba0xe^ed$G;-gfYrp$$NLWh<7ME+xG(sio#OLwhMQ67KY*@{BMi?4J*N-YOUOTqgj z7yKfXWsNL1vdK+livxCjGMF@$oeuxWWPWxq%E_#+*X$9MW&PQb;kbgTLb&O&$OZV} zXtYnIehXKDyajN>oqLPaGDu9g8F888mx+J9?-p+H@NiBOA9O4DS;Zos1Gjw>;*By9 zm+|H{J~@Yo8B{M@*}kM6p5L8ro$cCBOvT0?HO;T4*E6$&NfRQheY!+(j5xkd=RxQv z|4tzM2e>I-H#;Z}SK`J8m3$Ac)bEMZW;!!KQ}eWx7BeI@)O;-Qogdx7E zDcK2bvh5~WXo!JM>TVS^m~l)}YK}_&v0>^nH8sx#nq5m+ZSRda)r>1{P7 zo0ODkl$j0+Gkw-c{XtEs=Om@B%hWjhMr-~DP0f02KC^}bJ1faSzmgt|sW>FispCblH^7T$eV(w~J|}Iy(y82cNI(j z<(>~^@G6$lsoViW&khP4UrwUQI%frOU%Dt;HRPNSL#)}_N zI+fdN=-I(YM>)8Xj$bA^#JiyqIDk{>R4#MADX_U!cZRQ#Dn#WvsgNlFMa}RvUS+7< zkWj{pPggpXn`!9T!HrID#Z=;Im7(QUYueQqTW?c3mHR`8NuxN*-KRoS?(bpZWXnCG zGF0wgp^Vq;A4;ckm@a1r(;Tby$2~$>A!hRfA}8ZV?h#a8PZ`2uT+SlQ`DH0*K!kg{ z<+mX&OF1U~XU3ai85=0%|IGN59un__x%HGkB0j2T$bXFS0qw(h{oCP#>_T$Nx5V<} zz%^@G4f96=!(8X(_eXkjU6|X6SfeFx?1AV>Ot~=&`0eo{^ zlK*F5o9o{Bqkzk6^cn3FZM4s9SXsCSn{)OyK7N)Of(`XVv|M8_w4bDdk2p(Tqmpdu z6``aT-==il`rjPV*#fowZcg03>0N*Cuvt9kB>q=TiEj*Dnm(H7wEh1&iCZjobhkOX z4U+BIZIB%fm=-{_C)JeLx$D%{oVe+n=p^1$Q(||q!t^0W@AIA1uhx{hDq%4^vdA^4 zQopaYS*yQla`uH_i4+@^H4zp+v@^s%RbdWJ&5f`)sDn!9;510-tgocODfW%A5eKIk zVdAiA<;E|rG8~-F4P|g|rF0HX+YCKBm>1UO1ph=YUZyfsZkLnxY^77Vx0QZ~a_6ZK zmGjRzr1nL*i&cio<%cqODpKiGuD_vY2Om1ho#4e^QW+{Y(MkKE(y81Er5~c)cPd2X zwuFh3Eq735sN8*_3_f`Jt+6_ld&AJPgI65oa927^WvJW%C+#GqQ@LhKjZqF!ZjK63 zxxOmox_;izpRF=f?&MGg-&IvQm0N1)*}+qea+s|>s4`UU3McJzN~dx=m41kFZ>tcM zdp%5?Y`G6rhRS^v%6Rebl}_cFER)h_2Y+>xgBvUU&RCbqbv80)#8x_$8>jR`lpCi) zRBlO_I9a(#DnsQi4`pyys&p#%7emhuZg!MIwf;e6sN7yB?Y&B;a$hL@5apg!Au5-P z(JXZ3#vMwBcur-gT&GaRYxa)PsT|T}2bVaC9fzsp__pX}2mBN8!?9z(%HI~)@$>D~ z81G~%dBAUs@iJpO;xc|7@beJAoN*aH5BLR$f6cgzp9lQbh>yPuaTz}k_#F^`lW`e8 z5BQxCpYdlqejf0XbNAlv6og^bP ziLCpiB*6pLHpzufk`JzqLrRau+vF!mnPuM7mq|Fsnt7?#|KW5_e>JjacY_z zR7oO{wJ6UUY=TWXwB0&5_pVJA`=lH=7^~V7${*7LUtm>BbHX#kq!7bmYe~*2)T18d z2sAH#jY{))(zUL%onp9?8#Be=H3O6^W> zSQ}<~BX7=Qh0aNR>?+eR94DV0xbquUjagLBs6v%^@isr2X2o)^s42BO!I4@rHzjqX zcCaPsq<^5M^v)EA2Nl{GP93Q&FFsz=a}NJvm>!FwN@sm%z~e}Ld&%{kXdkTa=bRKr zn-r0A6V0O@%WGOKr6WI?aufe_m0p#Qu4`L3WqUiam#OUPgls*&p^!kH?MOeM(raAl zu!jP>*?B50-I~Xk(L_$?fk$4`8y@);zY;%mFdH>R9a8|@+)p|W9#lN?D}H}?$hmMq z=H~tte+c5c8JC;;SNvg!XJXJXH}|jj^iXRVmz(=n{L$b)$GF_wzv7QW{0NL8j>k>< zPwYVHTlo) zG$Gx=7{Db4P3J~EqbkZy(e%HGPVu`WS&qfn2Xs4yGwaW&YRKfpnw+=lPibj#;Rye7L)|5K=#+ygAnjJyo!D{~Oyc>95{GfjYezqz9RAU>oyU*8Q{_dZTRO1lW$A`n_V%{d$D{*;v@F`_Iv_>#4MVfYZBJnO< zwD)3|Vn8u@n5$XA&qiC@Tq6C-VqwK{l+2`7Dfs*8jFt)oOZsL70+&7(^@Qt3YCwoBt1SbNR+XYi& z?*h@%Ea_>c)N*`w(9C}FI6hgQO*|b+cF_dlmugxm*rvj~_c-1NLv1g zG>S|#jf+cg*tU9FCHV&7^+}TFct^Lbx_xD4Yf9p@g0~#Whh0e=UIx2~%x6x%@3}HE zUDNZXzf~dL&-^zO!Wy8`^?rt(P)__Tz7@{bzxR5C(n)?ZwU|*yY8stn>hJJ{6Y)Iv z9z?@^8m*(GT`#7g{K@wtdKwnsOmq*U&5p9s{=4AI?6Zx3MWoyAHsC$Mm2<9Mca!&} z9w$&xwR2TBd4N-+yH*`7A10D$TQtM&XO?^Z-;C@-tD4-S8s7$1iwitscidaZU+0V9 z*n(Sd%YTblZ@RRj? zImA3qIsaSFWht08rPZ_J23z)R=`fS@ygCK5T_jo0b3@Fb%K6`Vj!nU|DXpISLd@yu zFq8D0kb?Piik@vRwq^e$9j5bm63)p^!L%u@p36eaXke^TW7(7RJU1CLK190}N4cAU zmzc3QlPY-_c8N-I2z@z8Qsy=?CrTbc_iBn`AM?DdOI&P8p?e3qSWNfm#oyN?vyf!K zp-IF!>jP=B(yLDv6>7WZQ+`u4ncP~7TO6QV4jC63E}l5MsR<1Pf zQJkcH=}a55gNBYRc{3;nHEUi(_@*WVI|IZ=LbMZ5wCANYIDtMPK8A`eVZ_`!GPC{; z!qS=$lGMGzK@fF&;t5^{VRuak^TR~YA+a7%>hs>&#{*@5QUsd*HAP66{zV5rc3BN& zbZ@KK;&5;3#eZ;8^{y#Z!id%%(1azb-mpQ3^p)>@plKKC5G%n#yV$x0eU=;zzFwIntkSA9FpECeReP{wSIcw z6s?CitNeZkLJramGa}OSAI&yHvcGvm6?&lDet#du(2Vz7dS2L$N$N4S%IkI3GDMgb zp0L+h%WdRbL~!nk;hf|3l=rf}Z^T5ay`F`IglLKw=g>W`2^4!k~AQ8q_=1x7&t|`uDr8nu5<21HPfK&2gUFJ%tpQ2^IF_q$5akxWAfJ~!Rnc5SeWU` z-+%<`i4@kP1Zzx|Nrjdte~S~WdQro|3a0#Bkzn1XEUU(y3D#a^9jU3FOt225u=Xcd z&9hBjHr3Aw)@)^6p@2=%8qJGLEt=LfsW4rZziuI`s9ITFl%=meb-M)(-amu4B&)kBG2k@%iuNMuJ=of)GOrbgV^p$> zN*?SC;)$A(cI9rzwgqvt64gg^dlV`B;k^WNnoa&NThXw|CL>F{3-f7zc$E;hb=Hi& zpq|6-72+UE9Mc`dFw47OL6{jY=GIp4ojTEjFhgjvTjH8y5|X!A;&)U@CAV4PlXAmiUT8yv!1x zq&-I&J)hWR>c~50@e%llZ+8@-H#w1vI;&cEUZ1g%Xq}z7I5yh1-qF}w%fk5-te$?a zGzZ88UV8oaLcpIW*M9#&jPPqq0O|i9N}b9`Mx_51MoJlpM*6=>u}O^7i}YW_$Ye$u zM*6RXBK~QNG>P=TooS{}qr6D}uP8Q^%LgqY{huV~bY|K)(tk74lu0D$Kbd0FB$Cnp zSVqbvQm6kIM$V8(rZ>Rz2NHM+AO`V`;0$kY^bABIe)JOH^`4LGA@VBnagmJ3CZs*? zxS^Q0c+=|n2=N^;^Mf1AXRpQW^=6QGv3EBjwIbdG3+T^ z1XZuE9QLAIytQ)pJGhwoAPz124=%34Mf5AY+(c3lEHYr3%8Tz&QLay&6N=&`pO`5u7ZQG_bjr6=Iu{alg>+d+ zNcj$47nS5){k~Ari%)WpKX&Nz9OPVBl1lS#01M_%jx^4Wiwc+oE>}s;iMks}d^~Vv z;$5oC9H?*8=%y4>vGX(uCWGyloS=z5hjlP~OM#2<5T?ssu8FYub}RW6Hf zisE@A*eEhautj7H{TcN>Z3zPWJ!XE;vU09Nvx&m?Z=*@Xw<@2t&}5UXNF2zkbk@Sa zkS?~`pC|(M&Ty=_igG>Y3|CZ|jV#hUqasvwMJVFMzfwALztW+5=NNUlk$s=im$IhJ zGm&z?)KF!p;TvIE%23igubHPZ%=bVj<25T%dg{8*&{L4_KDBFgXtJ@_!(`JDjX#8o zxwt6D#qm_0tlyJ*9wPt7#YnO}Ki;T*qIu7Q$yq~7fzVFrRC`lM7sGnGBF9FEw$WWB z*$D45l6Zh;JWI&Nae@Q%vI`{K$qx5dmzy0lakA;|#b-I$6reOvl#^#>11rT>I6!?3 zTMR7RX6uw|+aOBlji4Da#FQJAy_Gh>pTGIk->WI z7k@5>g)X?i5*NP;k^2!57eBZf7qE}F7Z;=H;z!fHkA8;%-Fm!KVY%4*Sy&9(hMpUp zFL|xE^(8958reAdo6i>}>;LO$=zk&}$7K-BI4QCzGhs+>3P-p#+3CD=byj%R-_QuG!FIG@_FUIel3_IE*J-G z#>$T4-ykOAt8YSY#P{g886$?Cif|y+dlwSpI0FAQhFEW23H>KaFKJ-ueax8MaI?kq z#-pGF=?2otIo()37PLicTS|c%3a(@kYXsTBQA)#3g)~-2RrG8tGe1{_m*T?cBT9|+ zZ-&TqR%~!w#YW=75sO6XRN&T2@_on(pVrLENc9-gyl=T>`3f}~7Y@`|zsZf*>%c!z zetC1fSceNoEE3IlzXk62gH4%YivdV5rp~5J*nwfk%q)ab<-MDOH6nKrE8tFsqU9Mj zgLbHBSZ564AsD~^eHgIWV4a9Z8&D)g;wQL8)i~#sgQM3YKH_hSkx_`pZ%!WuZprTeZ4&2$Ci$O$`x?0zg9|7!3yefo{Fd1NNmiHCkQKjRB{>8= z^r9XvkkyMxS(U;$*FGze94kdFm7)$uQH3~Lhzo@{P0IhBQK}=$U!vvbSuLW}mwoi& zM|*)U)frY@T+kvAO<06S;{V@N)9bw%AW|6!Y$t8CO|zXcL@z4r#e7^qk)M(jsf7Ih zZAIDvBvp~yK@-zFK2k59wHL480*b7IgtU6zaJ+;_k{;R8B{6iP>HQf@Y4d!g`%^?F z(g%72nebOcC7)`zRG^Z5BF^W7K5lD2;ieRP+vO$GLtA?c@`)my;=9AeWyCsUxFDrB z2arJ=K%~zkCwsiM$&B;c4{<5jI~We+;(c78gv9C1TXWIR2=kPwQ)v`TAB=Gfou^G1 z`Z?BU91My5San(EHL_Y7xaF07bNJ$eGgpYR|rXZ()HG)rb7=vy?R1A3Uc_@OEiVtQ8 z=_ir~M=3IpZJG}x2&2t$C*HlsJIm=z0J34^eZ zq~Twmx>Ds_GLk9}lBYUcH9E9Ieo$GU$!Ko9uTWz?bb6 zpm#S$+anabrN=N@fl#8EeHr~0!?Q&1=)&kGgp8I>Mfsi}vIH;j>OBTuGw^Ol(11Zp z23;8RV=#)rWCn8>EMssHgKHVw%3vph#~HlH;9Uk^G5C!^{X1BWlcl*0w#{vVG=?Dv zMbkyXoo2aRB--3YM~M;pSR+=pu7fnDbxpX_ky4?XgOE3sm-sBM-C~^!!_QlC3NpAfR zO3(YC0Iv$(i4+n{<<(pUD;ZqE;CcqPGq|6@Qw&~V@BxEw7)1Vrpb>*Y2E_~pFgTIH z6b5H8Si#_82G=q8BZK=GJjvi?2JbUCz`);*pdo`+47xJt&tNoz(-@q|U^#;g3^p;i zjlsPPo?!42gZCKl<%CJzT?iU5XoU` z^HQsGxgd|R$g>1_B0@6u_ zTP)lH%e_$Qcd@PC7o-**wYAVoYN4&Ig>%IkXIg74lYTkVI^V~nym#C3zAR1UZ?>td zl(sR)wv8X8ZG33k#v{VrZn=LEOK!E6{76Qtm+ffvn&kVW=6l-jL1(Y$`j~8^OyPD% z;tCH&!evonR+5A_bs-FT4rvT9mpd0frw_(RcAfv;-8gNuAJpT8S2ha<>b?UHj+PDS zVy;TcF3d4ky~`d&QzLg!**j>1yc%Bi0IbBTv1PxYee}UqY1vlfN8P5C{SnQN8qF@d zAKCG0ZrQsi5V;G>TA@|&YFXLas3&sQmOY8u=GFOSO>sr;hO*bu0eH2s?0)D+?sa8z zFb?o)b6FeMh1_jr{P-lVZZB(xnk9Ef*=ZP2d9`!e!txoy-BtEXb0b$>_8VL$xqHeM zp%QrYY}q)JgDCsTPDF#?)$3)qbT{1nWv6MrACxVCg~n%O-yLm#9Hv=K1BlI-AQvznq^ErEEvP{P-s3va?^l zTdiE;m;Vb5iUPg;^3|$oKTu(Ef(`P^-`6q?_sjpG1|I8|*GCpiHUYb8T7*)+ya#HT z$)@?`_o138FxxM`=qOXq3;pr|F;mgY{4;Pm87qISU;Zbp)eU}m=Uyh&M&Fy>r37kI zr0ly!hU%5=LtaG9C>sT%GplIX9>|f_uGk)r!W9<0)9?E&>e5T`Pcu&ZP(KlRZRDoq+^*?zNG9F%xKwOdzYQBx(_Og_(q}O zWqW%Vg~pc6EiqRU${s)`r@EzOe^+x&E9=>pSsp1_SRmFA~kVvw>``W9-28xLamDd)hj;)cAb zpM%R?O;aNk&qFEyFFB9lht<~Mui!|~l~)q5TBjs}9%Lk_M7GW7XvBr^X>ssqUaJGNZL#WmowOj00nM|AG;b( zi5geK2S<-rF@h80Fk*8ZG3Ig@v8x<0>Twvc2OKfJqEMq)Md$7)dO=Pr{7}2>ok>L( zLkUgnJ|rrY`dc@oc{1k!en?)PoF-9MQencCt8J9KjX@$RG>N7JlHcIy8i>=tj8eA7 zLJXFZ#s^2YJHpQ$PI&4lv~q5>r*?{pX7FDAMLBiV&2!&NT7fsK2a-g*0SLK;D;>$3 z+8K?8+oP#CQ?m=vG{~TD(GJ%h!|ymt^C~vM-2S~em*9sbJD;4Ix>;xxuc971$e-)} zro+NRVG>Cv(H}``bsvHg7|cU}Hu^VECvdTmbw`n!Y$&urSY+&NwsB;wad7lkh+Fd$ zxTd6V=J0N*qRupHz(XLyW_S6@q1p&Rh;7Hp~&D9)}T|?}+j2$Qs2eUgUK2^Xw;e zD)cY}oua2Yw=*%l@E^#YiXWEcyJTsJcH0GnQU+@n+=c*#`WceaaJU6WkwdjPx~0&P z8qU!z(ISq4xHSub4^4{wpTW`79WiEo7_kc+F)DW$vF(o7bB7bF`1okpqkHz7_@O=O z>`tXRWe8_`L||CuY{BqQDh2+861#}asEicm2LGa&z$tkL+PN;wZgCPm-S`I_;HVqQfi zl=fRhf6{r%amnc>?KEx${j}Rzm6C`URI;n%pGu}5$^$n^rw9wH-#4xcom=XraQmhe*DmU{D^z1 zmBr}Bwrl%AdQ?^=en{AwEG^OCVPZ2F$6y%(*!EUPhPI_hO}Yv##kN8##jrQl413(G z71~13W*eGp)eeqk1J>376{sl-)Io_OMimbucB&)BLL5eHwIjw)($y$d@iXpY{C6_H z(7V9bAm~_Gq8%Oq?IZ?E7;HuWyS)v`&~6l|314Wnup0{B1rXLo%&aCjh)rSo~QeF#mFfUQg{1zXI+_0&4Jhs=5uMCto-B{H1J zL2>?6Y@i2tDY6njBYv2Krx&LtNldaU3h0^^MjEPX+FXOQ z&c?jEGx!$=xP+3 zxt`iSeU2*27w4Rc7iGgy(VH2?faO2)bCIzFAJKD!6U9q-%(FJ2zWwWS=Hm0y;-;KZyHMmiE=rfAf{Dym31L_-1gOS*#R%RtSTlV?eqJU@3Zx@9Dn{XGZc*fbbT8bzdjSO-f| zFb+5vL(^dNbuf0PV0`Uhj7fuWhJ$f11>-9RV{#gdiye%?b&~DzrGrtC24jbVaX|{k zJ_loA8jRN*jJ?Si)zLQE9nd#cq`~;NVz52E8)A4_Un-sL=_iMNd~PJH$NrhgW&hmK z`_eRd&UG-(OTqZe!MG|7##Ii+lPMUVIv6*k!Fa&I$j(YG%NGvDAJSmF>tLLig7Jxi z@uxHx(Z-R`rd25zA3GTLq`@e5FkVT)__u@cU>b~59E|*EvOWIeU_71%W0iw3H3j1% z2jiJE7`HeWH>F^F=wQ5*2ICnAPJ?lpgV89KRCezr2V-U$jCBsi z#1xEo9E?S2Fz#?Lu1~>u+re0!24kOt@pcNv%MQjRX)u0pFpBCY*`xYr2jki_7%iJc zLcdp$g27!S{K>ri<}?_`I~aGQVEpP}{5cKATnFRx6pT!#T|bZp<0=QETZ3eKWH=a4 zrNMZ>!B~=lanLEti)k?4buf0PU<8gH@1((q<|XRoU<$@BjvoI>gHh~Y3~rcgj~^Y3 z@6%wM;$U2mg7IGmBQn|OThmyw%E8#1g7K4sQ9ljFEe-}>9dqt}t8*Ni9+3v)83$ur zGKTk*qeuHR7zZ4TYf>=y@Q3X$N2kHa&o{Q>J=Q-{FdlO-2Bg6lb2c zhxfXJ(J~FjXa{3n3dU;=MyE6wl@7*VQZWAIVDw6Z@p}j3yJU>&x{ghUq``R1!RV8h zWRL2G4#r7oFg|uLR;6IncQ7WW!DvvBsF%l5F!fnh3$FHw#=U^;M zgE7^?7?F%oo#kLGPlGW}F?i2Z9%6V|OO(!grsWR(87I$&L%Q5ERTnvVu1}Na0SCj! z){Im3>edd%#xxlDEfaNcd@{z`_7294X)p#k7#F8tbZ{{4NP{uU!FVniqdMEcxHk>P zQpI2$d>CSQS!-FcRWg9*4m^7u z04^-~0|5}!{W|cn4l2Y|(BWYhf|-otGL%`1!dvZGu|i`pTH=*Z*2{`3otFFDp`WF6 zmakiZEw_}fy1;2;FQur*V@T{C)Rhj#k`#_>YH#@4LsKiW7L-=x84rWmXPz8_&*V=JYz4$e-{vxh4EKG0RxtJ|4d z!v8!1;aFww#Zb>be{)fPJZH5Ff&a<1!(@y2(bmGsd7P>Kb3KSb)wUHm&oKHiqc|nc z%G{0aZe`Z4toKnrL_d?A>YN#^aQ*2Gl6>=utcx}0Z=u++U_rU;V13we_(eZ9K(zPq zk?3SE>lR0Tu9aV_`Jzq9-m9FGZBzV3Q}`!&-X$glkc_C8^>S-d8TsJetlUa$V;@jD zQ&lIWIv3n{8Y$B*j zd$L;&K&#IVE>a`F^*FhenZ(Uu7WuLbbFD6qQ5xw%al%E+@Z)eM<|ya zTo=|m-27lK>uMEcYaSSidRfmp(5E`|{SNfHkS@^sUFf#h=2ubH?;llET7_$hy4;P& zA60!e882b4Tos~{AA~|))&iyT0f}E6`X814HSE}=wJkr~Y6p`U-9l+d7v*ccRo}zG z*qnk<+pYT39E|-b7`5H1U*}-7g-df>oc9ed@rQPp9UN5}(a51&9oHyE^Km#%F~sn) zZd7_F&?h+bprgT}{jLk?#(pe^%`@FreJ2OwtrU#+9E@~Z_2V3j!nVm}Kj2`b+p1sY zV9ZFtsO?t$RtMwu6pXJNJ<@H}KjmP2mV!~+t@_U$jFNWA_Som>k#4KL$&nGMK-TTz zWQ1Th!}o=Cx{?NW4TO zFDGNvdaHhpgOPV+l0B+xyH&r@!I+YQQQNKh`yGsJDHyfgs(;79_#g$Nwp;aeIw$I- zW2a<$)OM@Bvx6}=1*5iG^(Q+Rd;!4mLDjY0s$bz?e4Bz%+pYSW91Nb;;p$P_t@=F< z#9*?Ybv5>*J%*-WyzOA5+p6#G zU~EXisO?t$WC!EfWQ9*>JIv6ujFlxJ1f0l!BdkV%cjvnc@>aTP# zK1;#)(ZNW!RlnQ8C@D#{$A2A+bX)cN9gM{(7(Y1}>9*>#N+RJrVOI)9ZMW*XIvBqs zW7K-9exifH*9e_)z^m<6{kaat`6(EWIrd1mRsRPEV^0c3ZMW*5b})GUzgw0k96i!) z)qm|^j7`CK*1<@(RiD=_QMXs8U_9esq}!?==wQ5_g7J3;Bi&a0Ob4Sy_hftQbuiLx z)nD#lOiRId+QCS-Rln20;4w39y}aOHq}!^0)4}*S1>;QzBi&Yg#h2w4#tlu7`5H1-{N5O>zQPa>e_DAKj~nsO~I(` zR{duV#uF(R?v6>it@_5@6LlNym0XtEZq*;_V2n<|sO?sLxr4DW8Kc%)^&1?Fms2om zyH$U;gOPVkl0CfIZq>i)U`$ED_?Oex({0rsbTGChW7K-9zHN_0-F}dQQQNKhQ4U7O z-bwbTuI*O+A_rq`3Px?W>aTY&b|hoedaJ(L!T2^Aqt;vXFDVA^ndXJri{>JEY6{TdlY1XFC|%Q!r|~Reyzp@l`TLt+(p$b1-@wYs)TWSzFt!`nMen zo}TB7X|>*}|4K1f2OC2SFY8C8vkq=|=%@8c)WIhqUG&~p?exdPZcVRq06O7forLu_=q^-|ld z=}HGdsc?JikKVzUS;T#VoXl>?ZOj&m7(jVF*)nEE6@5>hAxK2 zQeUh$4DKJr!+n*Z>vypqaBu3b;0dA1&_O#E6|U63;3|a5 z&_}OgasqZCPrz1&zLy%4V@#Lw7*l2F19LGsDED|Cl&cI~`iaSLtYdf_t1@(c8SBc- zPiT?ITo-y`a*Xb99;2%%bmb)`$H30!F|f+eX?ILckDbZWW0j%z1u;1q_DmiPs|=kW z$K=%C!94X>8MueRm7$A3vE~C|#N)CND&q&u zLr&10#S?Uu@x3zS;N1!yysM1wlp&|;&f%%L%J^0paxnF!Jeb-zGCP3Ax&@IE59DUw_N1rQ0_wZtJ2zmz|g02kRn2X7A z=pA_+x-xXPE!K%HqaZJI8Q%M*|_(EO8pQrqG4<*l6VC&o~yLGIUiTHk*tyPDwCy z*&`;WfcNDo;F?1BA7XOI^L!ritc-smG5%tlu=)#l+_N(Dt}-SEKQH9L&&qgBQ^>*N z$MWEDWxT44gK#hYS)YbZ#(PB>H*w?~$n(WD#mmZ&Q_B0{xlzk_Nf{%t%;it#(b$^e zMPiZ(1@R9 zP{wo0kdwhD@nmpi=qg}L&Iq5(Gs2ajOM5Xn4}2=m16PKwlf~rR@F~kfC*$cNTCnr>lmECW6;*|fnRH1;?@_;G+DCo`A}h8O1tJQ@y1^u^;5 ze99o>1Oz7yA(tQF7((umLlOLN9D-S3G+oQ!dIo=Gu$##`N*??eMg>zehqapW*q){l zUhU)61(GGdVDTPBK498|44M-88D0(NRXKwd42l_C#b7&wCmHZep{Ca{_zQ!X4Blt( z3xhbux~5O_st1D;8FVFW7y^_C{_=ZfK9@G=i7dT1Kc&F4gqpTtIUZ$E=kw|`UM*%Y zk$~*%co6qad`v-uX!{NKP^r`l8@(&!U;({KAsm|K?l&- zQacv#;CEhiF5qGCkAPcJz%SDAs&~O&S7Qs_MlT|_ zw16FzS5pd_;)>j91w0m>SF;OvEIhdj3wSI%uND{ZSa@=m74T?mUac+QdD-M{DB!`^ zyt=Fb%-fK*ve$t^yvV&Z~zC zc#=A~)df6AomYDbc#b-``wDo_H?LkU;OXDwzFtrP^FD*C{ay<>E}hf@9+yr*uYkv; z^D3i&$EA}QE#PtKq%|zyap}BjQgF8#Ca-|Ur4z6ab@c>(8=9{mH;+;662ZUIkCCwF1XC0;k=u&fZL%d;5E{6e0Z zPEFSOMb>T`{32`2jee1BA6NTDwt-v+0j;xbevz%n+x;Tj3by-2wrT7@7TOMW`9-#I zRQpA?UZ3!bY{l;Ji)_vA^NVcN;?(r!QL5N@1au#Qf2|qd?DU4_>~vHD&rZ+hjAafu zV*VrKiskp(MDuxiIv+DIHIqLby@V@CjwHps{ByzJ5`4JmEhIz0)AD3S7QtK zRSCAY($JAi3!Mu(KC+`qb3^yBFmxZwLie#YbRXx3?qfsfJ~oE#wmEhGcMf|D+xt?FduS)PT>KE~=6681Zi}+Ou zUN-TI_*DrCK7aiZk$aYS2uaZRf>YeC4{Stj@kY8jS;c&mmdcv`Z zE;Av~Wl9rWW?G`l%=U};RSDMfLchqm81#1S_iOzkepP~+Z}5xwRSA{{UzKQoJe-g@ zpr0M$F0{5I7_h7Hfd2eG@Th$DKha!ky7D?C&R^#f?$Q~({O^$18;2+ZwCha#v?#{N z){)DEiDvEP^Ppia5t{zmk>?4UOK%2JM!d~1Yt)|##j9g@m!fNNkim-X&d z)~iSH^hJy3cRkrFp1ojRMREBVOXkd-QM_p3JaaK*;)u~hi)YQ9bH?;8M|bVkr+9kh z5^vZ^6AK5QTzGWXqkD8M@%*)ZBd=lR#LOVtJlZbWxDIml8~N?(H_i#_H?QBw&&_Js z42m@Mg8Iki^vxO37%#%K^>T6sfR6!1FQYheu>q(!Q;|QE%4+Nf^>cEV$VW693lVxl zEL)>>Ml@!$uEob|IKDrkF;mnl@wGVgS2YBJ9ThK!<}`@c8pIzx#lQKUNxQMDVn*x|Qrg86kxM9J-HvhOBUS!^O#4auXOOAzxK`BbZ$VUT*X zO@QyTBnmvDaiJKwhvqHS+f%cWNUyH`!2D$UXlaf~q@hN=3y|e_e`2%JoJnH!J~@cs zJ**yHHz{skqk&kA8ugO~hzjVR$d7gypi!7*U_M*Lzy#kA2Dt<#8SE5K`Xao7pj8V zvDwe9g6!w2inMU2m)l0q4o-1t=j`5LqLm4F4m8H)pwT3`oZ8 zWn?IEjMFjEk5hHi?%v1IjotcC-Bhrz+CX*dM>oK1*v-|#RC0h-5*^%lia}lBL6VAz z13iuJ!1`{t#&md891NN0wmLwxuUnWar^*2tGxT4G`rgpN||m*My!G}1aw6n-c(*UQ0A zmYsP;?aV9NPUh;`K6hq*ubiX?lyj`dDH9y2S1)0GS~iBLdKX6PC%B&1Ai=|w+jhW4 z9b`V2o9IG~Z5L|NQXLX)6i*mrzD!YNN`#pl8wX9vPScEi$VT#<4h3EEdmtktc0@~v zu`ZhXes<2-JTt*;QREfpje}$XsfN~4tb*)Y8Of7Wwy?-+ooA$re1B}7rMEWIR`_*0 zn%mh{%KS~caXZr`Oc!tOIK>X8FS8$F>P9frE-+i8OSj`W+XAa5wIw9-pRWlsOu{OcjXDZCA)mWX28)i@TytZ0@YOxUB+q$EHpt zG_wpW6}W07DUojtz-*2Ht~2U3ccS37Nce(+Fq3GUJC<_Zg+(DTN!@ZM$g4Wqg zCc3!hv9+WqU9|`Z_~m0U<84p$C@>OzTw~__gVd%(FQ{OohU|~0cP+SXdTZWJNOK?gU=A_ zfsV^XuN->FB*Y72k|Qb80y&Q&lC3}W2cs#D=@W$W zD14IZ(Z?h_{n&)F8E2i%c*>fw;$-UrC%BGrA|){|GBi6*oGR&IE@<} z$!1WY);U~yNz880&~2_s^BYT?<+dfGiOz1=?hRoM@8=S;89*BPSz+2b9Es<`7Af90 z9M@cz8>IT#j08?fwboHnqC?T=WG15QUs={^vGmc<&0y@a46IOv*yw{v-b~zbqRTn6 zAYyYCBpuRJB6H_VNGC>^37HPmFfny&WcpIB=@*S{zi1-O1c-6lOq!Zz(k#>r)?*3s zXg?kD4CM&ZPMX^u)gn>Z1&KByH?rYPEEeyi_wp8&EeCBxmZ{8T>qHxAV>*4?P>mdu zX*)x(4Wxa7pJ+-QT%t)9PI06Sq^?a)12y7dlLMcK`MG`!p^uT!!$1F!#ZffsMT_TP zb(9ibcBF6~f3bc!&>y{|e{rM^QiI$=pU4dU;rWpa&=zDck8P0}@+e+BZz2DcPZ~V& z%o)X%i>7y-J7@lqWnIj2ELK^M@ro;FmoKWAQCv~JXz}dg$^|nQFGaj~?DEC47tAk) zMAtrDW-h3#>~eHTx1Qz2Se-3iC_J!=E9We(=(4bU`dQ_(Dk_WTFPXP+dGYiGNIqx& z^tnrBR2b6X@)&m9am78l_UU>wQL#EaYx;CuDDJXk{#o-EES=xQs5@)^5*1WjuXsu2 zqA-&)<}9vEq8u*6!xhSE8x{<8F=OW91qsv zUtU(ea8B3RFuzy1c*cy1nYa$H6}x<4MI|m#F(A)bfJ-z-l+j);nLh^%LteOi;ethr zah>UT3(h#RV!B?>t3U_M3c=tbr8 z!$eSjdKf{53zt_cTC`vhl|>AttX#4%q0XFniECp4H*MwOMRVrQaw#+BOkeEAjqMgK zp?ZL4qn@^uzi8CA1b&n68VA3wIuJbWZ3!M;vlzdn@>_R%uypY?_g!-O=^Hj|2%4`8 zj$2n9U7`Oie^CF{C;l#u91}n4l1SUeSC0)=L|;99{ng`xWzkost-pFq^p8{5hg5R6 zpFZi0YaUAcRY(5jH;zuaC}{S87s>FK+`RSXC3kQA>(*sk&kX98P71zV9o@1OoJjDV z7cG^GBM$KA^Wdx12VN7x20zl;57wM%;Ob~mv~dvIxHmcpjE~RR6BK?BOdARAhU^D|h6kcc zqa|CPUpj2=Rl|aunX`hNbr7pQXXDnO<*UINBR^bU*?&^B?ITYNniQP{E&LDP2hV60bxgRx!(m!Vg|b?8;#c)~7; z>lCj7O0ri0A<3(t+opIGP||u8AUIwHu^Rj(FjBk+6>+_Xpl}2--UCsT0{&<&T#4}J zRm?M&{kVC!xXYaR+{C11U=eU&1Cxchrtk6AQ3Af_e%v*Ws_Yi+9Ngg_XuW9k`XHM< z+s`b`e3ritBZy>vkQp5iESnkq_wtj2k5)zd6^-a`gvgzlc~}2d!JTzpjU1Wxe6V6; zP;X|?a2+|(zU!ldNy+X9H%1?_e#D7YL9;#4Cc)e-!MK@0@ywv0>s`c(w$Bu=llfZa zM#O`~4`e>mXMki=MXXDMhK5gMKXZL3^)$JZi=4n<5QE+b{A+_vYa++^!6#lnM1#!8 z2Yzm3QEq0WLt`Qak#6zm-o1Sv6y~d$k@k(F>w}7D?qf`xIWrTd_~9bhwkEom7e7jD z#Yp}PVQ_8c#>^mRaj?v2v<0+CW>A;fM}o?c>+cHSo|bG0a{8TvXwaZEXcCpwL34oT zW=2Qd7>tS*5{gKzqlM9{f@-fcI)bF&%#ruZ3Z_T;`O%Mp_<>;8nk~_#!f3n&;&)53 znFu49*D(y1tgBjoU9fcIG~twH1_cj9mjksy2V@pnhh z2^KF79$ghZ(0E#~bo=P&)~%DK1|@s0{BY81=ky)DAeeCA*-6FGCDEcKl1H>_X0)nm zR8T*f8!2uoH4@B=&WtvWPJQs(KlLBgH^`102?u!~DC`={e)X;(*OWDrttmnSMl$~p zT$T~t2+sDZ$dQeMygkwWORA#9qHlC$X7IkZC#d&8^!@0RE2BRIH?EE@j^1@+@B)Uy zoOM@ht(Y|;+HUWIK@RHl97(f1b1MdhmoOGh3I@S#M@y@sjSUB3z>3HgE$Xs{>TS%N zB+Na+%zRxUY*Td~$b|NA?|Bk(uI6_L??lpQWBXu2g>9^D@8kMVf4PmxG42Ne(<8PtpP zSHd}aqCqiAkB5hbyKbV6)!G;p7%Z&DqGGUMz zMfuOtUeiXp;U|>6Y3YN(!suemVMYdLMY{XZs^F)LSDP%F9dw9xZ5&*(;y`qE)ubT5 zH0V4s7!)mxOm6a8wDJE%+?&8xRh@go`|OR!?SKLah(i@8L040wUjLdte|_OIRYws=^HcsD zuMA6pQ~iV9P5%Ddu*i5~d87CKVfT`hcaFc`U0mj!aQHLcwH4l?6*4rxGvd8-*j<|1 z`|yIQr{TB<{L2o$(R$;-Ga zQZK)!vU2*nzwN!??8fr$fLA!|ZSyA}J>KU3`Ta;F@AQ7`xL2gSB?sKqlfByg-pmT` zUlHH_x%XE-1HE>;b>;pOZXMWN>8?+Czdi0?*`Lbrcg0dziL|Jd$W&zY*al0M@VVw} zORlM{FthdQS(5r?8W{I+jVAfhr(@FoVO)Ioaw(nc&XmhIeJOXVq%>KVCQDRG@J{xM zl3XXFxI68B&=nfb9he}Imv(=l%EwELp5R_I!I$7X&izwrf{NO-yQEBoXxe=+OnCkT zUw9tpem*7a+_Za%M8BJrkLS|vtE$>_8;q2fb>qXr^i=nP2`XJ5=l;TqnNx1W{3uN6 zA2Ni`Qp}8rBB5D6zMFQxY{X#JP?^MiEj2;;C+%J*dL1tV|2Vgc##EFcsiO+ksFo-A z2aLhZ6Vfu`Fa!P4H9G%BksL4XKGm;Ki|OOs4_b}SqhnszbmGoYbST3w=a-Tps&vbgq6tnm7Gd*!W1 zp-2iN<^k`%;r*}w_UM1Fl0ZoL$_lsjG=JnrBTs*Mf-S;Yg&O;s^Q=#iB(juTjcviRz#p;R$@*zD|QIHSuo`ln+$K}JFr|?Gv zs~}3NBz%e*0ON$dTn5D??Ze3`fGjw(WmERrlzjX~r{|frDDhRo* zY^5~5K;*0DGs^SQ+P$j0zpm0z-e#5m-OG736uazSOcV=1D%KOlKV&Ata{q;BG zs_t7z;ca03yGl1xwr{xc8UG{KK!%GG)n${svF>s;|GLx0dxP$+I9O9&{H}QCe$^{( z+CP$Zakwrwe91+}>jjglIN;(7DY)Z)N?PnUEe^OiwU^qxQu|LSc-gvK*=GK+DnbW!(-PSVmZ($i$KW+<)t>xZH4|tpXDc;#D z{5E%bS>&I0lY5y?4k;wa32Cp~U7d2*mbr7v+-oGLjS0u8(Q~T1RMec{OOQg*D{;`^ zUZ1+%`@>Fu$}bBA?>T3;Us)JgfK9{lO79E9?qZxRI5PDi(w-IDK4~m=FM+Ue{t>^= zoi)D7KMG5{v)#s&_nu*ys*CQNl&n>EyTfJP=Z4+Rl=r3KBZ!8+JhEb+S197p2EwPO z0R5u@5|5Pnx2g=mfZU5lMQLP_wAjveU(#+xRd-q8X|#~Ls;Oq|P1hmtHg5=h@f2(u zpFViVJqzmytPy7Q>otORb!vrs9_n5}*>!HhXKbBuEQhR-#<6jy4zd7+najCTi@VKb!Ve;w|B1FoboblzPOhe_Z-nsr^ zFSGl$1p-@vymNPZH~TBHw|P@mcsIL?Qr?u^Scwg#D!nOaqV8voXsROax&Mq4uze}- zf(rK}n0Ghcy>=bEKpi(#EvdR^F4K#t(K~N-x_7eC{+E+d-lYBBmZCRlrnjZ_fOlra zRo<2cZ_*0C++XjVu;LwFpI?;zcvq@y0cOJrZ|n-hfHxM?@cUB}y`Do7@qHDt*Obo{ zn5O(m-ZB|HW&6EO%%>GzXM)Vx-2`UBV$V*pYC5Pp8*#& zBZ{)m`A^(|q3K_<*L}Bp28b~B7GYuXQNWa*dQyPL|?zGxy2`Mj?UANEd6$@-&vcM2Z& zU-eoJcqgR1sw3V+zqt20>~wagCapv6fsZz>+vncuPQp3s3a|eN8beZ9jOyH*+`B;3 zjr~T=5p>N=ue+k?jjxae(f9^`um7<7Gwl9mt@oDr4c?hWFI$07(Vxl+m7~10nCQvG z?8#EXlVy(O+fK8*y@G0-y!(QJJ?=kQ@gdBv0Z}gA$&42hd5plQs5x4wl_q@|&HGveTmc}VjUUR5I)q&qF zX!BdVuOcm;Hvxwwhm^<%pzlkBd|Aqw*$q9(;GREMq*iMysd5pJJ4h~S(ow-#7 zxi>+T{FmgG_!nfdL_=rGL^VeGcZ_m1dhYk`#i#o(&8WIe9m*lu;E-wv-RqaT7oP67 z#c%BMzu;fyzL_eUQFWJE3VLhQt~;j|3f{!SnB}Gk#(0r5fhXba!j#wL-jMPKc6sC6 zd8u8fc9DMPrEsL);0~6#y=5cbM~1Pnm4zbqol0GVsy54nDt^QOHzmro_U%Bab@K6u zd|(kJ7hl%f>YUQ61j6)QOuukDvi>3HhH2Y>`eE-o+pufICS{6O+>MQfKjM$vj$yV! zr7sMXsglevR3>U~Zv@5h6FSVGwMsvx%o1;t?cbexOl+B zNl4$Ix6YlR`|JYUiRx@>jEt8t{?RHVeANK5)7~S)=!o(aDpdE#(P(*v*D=#8FM1s~ zHQeLQ#;)JL#Tz>0SGjekEqnWY3+w#TutOb-bC#+?rF&@^1_juq(!0~{iivK08IDyj z0i1HsT~k)Ipc1FIpC86h7>BIWGt(QV*DorQdpJ(QqE${m&;9ak{_U!ZvE>$zc;W{y z{hWOIZB>4Y-*){^cHFB&Y@5mxW3Xz$?J>A57l_5g{Ba)6ycc- zZF8?$qyEQJ8~>XlAN%k}(W5s$?OsyuPA|s+q2D1No8;pn|LBaWC!Tr8zkR;H(w#Bc zeb_}M_@vT@bmzeg6w~5;}_s*}=((pdc~ zO640(B1^*)u#`NM_VNe(Cl>e*d!HW0xvclJ^MHSJxgJ<@emQX1KYHt^;&bLMnr07Q zeMiUDcjR!!im3zP|D+w=fsf8GK5ErII^%!tBWzmcKk|`&cjo`^KH9H*bnyR`j~){r zDPN@B>rEV;f%QFlWQ<2A;jpf4@B>(~%)M%`%{!qLV}61E+mVqGtigxMWK9O83`v#bd6QVOo%QuZF=q;6;aqu;a*zP zO012h#Q;TJ8RE-5U(@3)A)#0204Mme3)d|q*iOaN4a)1w8N3Le`-bIs{S};oV1~as z*Kze{a$eU#@4|!rxeNSr3;wz8oKv2-v1-9fGf?XD&T+3yxjV|9_6GJKMEk%rg&n*J z(Qpw%4&N+O11ar&51SskI~cZN^%y&B{X=bw_HNxPe!d{;XKeGVpZ)J9yZK)OH>*{p zr%xNxvQj%iM4c!OK3N=$WyAB<1*pVv@ZaQuRTnPlwD>vN1XZW1VH_q@=W?1-^&?US zT>8K;PL6R{FM~L6N%ruFa_GbAK||O*uVHitblr#Pd9OpZc0&i{U&Vgqb&Ty+I+AgF zratG6c(SA~@1!q3di6d3{KSow3m(1|&%tNquUY4xH@*K6n;KP;oa#OoxYZ;?Oia;Z4WVB-qp|bH99jmfq;J<;xVc&YW!^VR{`{~3(xA?7CM^C{H z=K;03!4~Hrma$$L7V^7M^LwnK_v0Br#V5Q|8t_pjkEQ|W$u-e-07!zSGk*0Se?rG z#kU=Q!tFRHo!||)?J51y2jo8ie7?S1DwlhANRXYi!fScJJ8O^E(%_waWWLw38&&QC zIgUuBXX*z)Sb(bqHF83FAC$wxB3a$Z!rZ+^0$$MI4g0)LVtMI5@11xE2RQ!T`>Qzh zgYLS?o4k1sc#GBSCG`CZWcdUc>eIbu;z#}Y`)-?2CByg1GW5WVs(t>dk0E6me4GEd zaA7J2`Hw37${AI+=j00sMX~6DSuOB_{%fl$TSD%7amG>vteF`Va6%baj(B*?;0#OpqUU7!I752xti$*?8+UOz2U}FRPIu?aWuBVr z=L?lO7rjPE7i!XlX}3olx=@a77wRsQ1nIi7rK#sm!@<+^i3K^NR=fFcI!EvzY*EUc zKH1HT!$|@bbYtCxr};bfR;r_Y?<+eWkmIYql=o>@k|0)2is7Z2q24TF;z_#~hxnd* zM3KsF+r^)QpEV9sr+ZIotUK#8f9>AO8omG6@xbztJH4TbAuMiWeIra?@!l=3^>mL) ztV!eF_M_2E2%M=|p{kxO{kHeN!Ju`c5qQ|I^>mh&P&kgX&9UB?K=F zTQ8{24!gyhg$(-S@B`im0^pIOYp`{Y0hHXu4L9*1ME z`Rd&HH7 z53fhetjFsKUl@J>@qD;LnS!SbiiP(LM>5*=c(N6$$H`Kcdv(hDLJIpT_*h82XW-|F zZfnZjT<$Lzk*v3%kDukgkWj-GRl>?w=N2dG2TS8r;S3kAuOn;7?X%sY;Iq@1(&So@ z56L#J>K4;l7E5ecT@|-VQ9p65 zkVjh;GG*)g>XDf2Un}&c&s8h1Q`C8rdf{h+_`X~iPjVNEkjd@_xrCk!O_L4(B|B-7A9Y_&fOohru=Wm|>y^p&@nfm+ zN6|W^UMFyiY5)E&;{}h)5r1d+PY&aVb>=W`yU0?Qh<+t|3=!sf-*V)^|1zB3TqUdY z)4iqc66x1O3$lh0eWT{)1Wy1%(VAAHA%k>hx}NI9C2jGSElt75k$wcj-o>X z*`M~V!V3kvQdpCJeCHm-&GM9b@;T&IVeyD(6zT)bFLqbsz*X3n9Z7q;j(0CiVZ(}v z@ZG}|vU8o50#ft2lrE5x5F>(>KapsTI+Dd;-mpxEF3PRa#5?-|_tMj@TJY4vi!}W{ zc{X-sxvV$##uT`o{jA;N@u6n%V&#xxb@OCW8~oP__So%iS9a~nT!`6q~?3CuX6BMHH(iEbtk$RAwLZROni2RTVqMbufeTU$B`S{8RKE1taiRwOp6B{J6S*M|H3|2c{iv(8MyZ#6+vi$LWD2^u`al;JSZU14wc<2KG8k%n*s9j2Uo+yNX| zc_%gC5C%t-mrQgooTTs8O1tCT52-ot1Wb7^>2)A9sYv^``e#8`O<5dOdr*aR;%|lJz9=X4OU#S9x7G1 zwPU?g-ImnR_u}XZE1Qx{-ei;gp(dC&(d3jPUj6|bf_eD{@02}wsp#eDceneEvi#ls zyw{KMDC>*9GPfZAls^XCo5e9WDtcJ?J+(WHGjMk+x)r&i?@$r1^T{b`mvV$V4uosbox0oW-Hp-&IC0Buaw^vr`A{~s;h{7L^6ek-x@EM3feARbsFpgV zF37n3BJF_JTjWb}>NPumN?Mj1DRsi)mMF<27u;hh{7xVm$^>yqng1kI4E|kM=3Y4Q z>e-U+JVc*b3hEB=B9~dxOD=K_j=>Lmryfy?;zgDQyy1z<9`DpW*r)IFk7C!+h6gQ* zt+x`h!^!)-VyirF!ovaN{uLWkH>^R{=`Fguic%=mLA@b0u}y&%X4zG z&p)Uu^e484nBe4*Z_%6D>aCyYO)YxsE4--{cq!@pGXME!WR{T4oVpxUV)0_q`KKMd zu???7==~A)r~X{jxzi@z@tXg+moN*LtB;4>_h6%R*+lo2GXDh$hKu#T@;kg{B!~Cn zS@3hp9le-@!P~_iYoP)r^`g&Ejbx$bK4kRHGZa}rjsgVe*JxaSyHMd|0B<@>D~Dck z&;PR`JyFe`xaqgz8)oW>`^|mkiTe*HBJEUoeMma{-F51j{RtpB6;GC32R{Y|9Qh`d zd~XHs`gJvR;#)W7MZfs7>1W5fN`iN{i#LNSyh4LFcFL@Nc@lYQaoz1$6S~5%-<_mnz^d`>qwqh+@ylMCj^*)c< zbh}?jO?2DJpMddrLF1m(gxzWP-c;FbSaQkBBj^QhB9aWeftM6^mb)7fe&y~Tap!J? z_fMe0523>SP~mH+`y{TFaKlE}^FR7>nf&yYdC%Yqe!1+TRF!&>5-&YW;Wx`JHFeoJ znPz;!$&rst9`90iw6x}%GWbH7Q$4syegA1~b5qx{zOH7cE4!^#uEnM{b8n6MGE=5C zhh_yQqrZiKhO5+fsWR7Ri%amvf55!ho@?Hk$#oU8T}3BTXvbHVHutsS>jU_m!nw}o zTvtE>n&gPqQ-Ca&*`I<~eHyRb4)jflY`UaLX6`L}PJG#5FN+g9{q zEK!Z|O}Ku%Zv#VuU_rP#9oa6`X{r-IQG}+;^cUw$jI7RX)8g{oeZ^c?7X8*LA!Nq@ zI=2d)t1N15DinMAik(e`t&aLMj@I#^B*FQrM`6mgY}3{bd>hcoklhmbnx9kXL}V13 zHg{z82+7V?DEyxJE>mUM=BIzaH)zlFd)ziHVF^r&w&T4>|I8>UcpC;^Y>gZEJ3hVOH6z)Xa zwoOqVeO-lITUWMa3Ye>JX(1MM>|G~e8!{?iXwS7ucr6`h&WN9LoBN8{rScU_Q(4>B zRm^poDjhw_&0wOwb=sqczwvH2?8y~X+{3equr=4w;j}ju+Kr!(xe+=htD+xz@TE;X zGFGcpky&)z^338jtEv~(Ex&H18Yem>Nf;NKwq|wm!&iL!dNP|aI9ac9IX%XfDo ze=4^_QS^AOnCnOW3MUDrr5)N1<^_zqZk5!uzZC&A6y9Fj8cufztWl*eI zk1r(=-(N=hMLNuH#psqMkkXFt#rEKP%(m4!e6hAWUoVpg^<>6v?da~#XIgUom@JgF zl4!N9GOp^?d|=ZgLR}eOKnyA%d9{GdqSLBOHM-vrZEE5%rP)qKnSrj8AVQM7PJaG! zoeC{q6Ada=0bM|LdV%WSj=|kF;|J*g}%+r9T+i~ z^7PE4(^rrwXREMWTwR~JZu#{l;tScf=59oty0v6c-O{?{tCpIaGe?a|aE8*7P+R)D zJG#`TPRlCiJ1yPK8D*(t$IR$2PG`(FFnA4R&1`Wwa)s&)NML`-JdMe;*Npnm;4vM< zFt|R{Ub<=V%H`FoB-5MJEo%XpqrssY%M9_K>Q~H5HYk>1u-up{wqq5846am>6lP}P z=58dJqA=*nwl%4UR)XNZ`qfpd*W9=|vvl>6<%?DeiB2NbgNx0Sv8b@FJJ(VTVbW%8 zUF~wrj4GobfC4Y9)(KpRRz58BH8*2Ec4QoHgK7vfsOE(7lAh+|+n~rZi0aUErh8g) zLPmuq!b-&v0;5TmYvNa9l}>lf`0jsf)>V-htQORuSGut;G5dwmpX3vr(Uz<4i!+@q z7Nd$>r>PO5SoPVIg#0$Rv zxmkvLuB*2%mmica$Y(p7FbS){Wg=fWTn|8*U+nM-A^^#x4p~lhfbh^68VKQrP(+uh znMQYmEZ{Kbh+5)g`a{o67$eH*P)^yY(x|EdH^!9A!&v?lwl(!&{fZ=j0LUVDVv2U~ z?fq<1m($skL1t_#w#$&lIuF09087=^a^dP8O@;-vtc#IUPMsoNokpWwO+BSuO7Q3 zUzX2m56fyNpKVnO9tefqSWD@|+u5OX7MXBgu2~61L6&R?qKvH6)TUs{sQDILM&)lE z*D}&gT&pR%rMpj7QczT_PlB-Lq@%tCEon}cG6gLDq#H17uoTPn6djrOC3~|wg(-S{ z0DF~|!W=!Wb(oo%wtI6%8Gr$2I#a8Y>uS|&mc>if)XRJuay`Uhi5kvTvfqF{olOHy z1_Kz&PPH_Yt&v)6pt0HvskI3bMF%vI?}md1+^H7r@L(&vuQP*Bv%05@l{~O)ITV%t*GmRRmIlooxgP1O)((8V&UBiZcQE`jYq3Mp`zfd)afw8v z)_qv*7y8t!EM!<#VhjWRW}P0A}GGZe(xCfd+1vb5CEFzTm1GFi18Qyx&6)QoaR+^AiWQTrwAZZLjL zlyO#Ctd||49+oyedDQ@+q}H)EoW!YUsPlx5U`#YBMWeU6J2O3l7+yLyOlKf;GqRY~ ziQR-=*BnP}fE|f7nGvLkY#>$M+q#Y8tUWs*J6f#Js|VL+d;79o&Dn6yUAA(~qB`qd zyJJ*7K-bZ)0%r$FR4-YO`q7ouYFWv(gc?<<+b}6R>Stke{H&2RrwUT7V$gSH+=w6B zGSyAkrq%WJbYvHGwNzyXw_%ARbLJ|Q^d%;gfmrj}W;)(7W+^KB;_AWGDs$3Mn>J+h zhsRxq&iM%DTp`nDHskOx4k6G<;3EdEX>RVz<9Bi-)RB}6#)}R&mCEE`(v(#ODAjKo z=*_4p1$OIoo=i*Psrt1`YnLotrtl3*7geiKpnoTQsrqG}E&W)86fRr5WLX{d;A=CB zSFMo|q37I;zN}J5D~gAtYLj9lck%2b81H%?CdU`(AJMe{l`&lPfL2}Kj}?rLw`2H@ z%Vncy8a>hA7jqDISQa`+ZhGffaFAt#lM)DS#!*6E!m7QwvqudWB^?ouEeA(mu(DF8 zEg6|*^axyznOGZsIeuauF0sQ?TrL??jv&lx*9=$O!GV=>l&pqVF0ZT8x!A;l?sKdp z<@ASx4XlxQ@S{JnY*Zs$^22DeNgS;3c-paAwFoUQksh+(UOjl7Iz*|)!An6>uo}mb z1*AjZE3LAMFN|*47c09ukY5Vfd_O`G)m&eMXVg%&-8*LR8yc8BWH!Nau&DzZ*G@Ta z3(*G4D2dB;YnCr@G8i&Q9y+UFIASnD2Y6NbQFK&!RLD)p!AxVGj;A?hM!_C@w#c$m zT~4j>0?%S*S&W%Q`6`1Ehxx6euhWP|kDKw{X9HSinIPDuEIXJbOIOw{ax#5geT6L6 zNAhO`7Ee(>HZ^4i_EF94mDp!)%XW02*x5ON&#vwnb6fDEQ-Ih)>CZX(GFM#+S-FA? zw=Zu3Y#x|>rQB(1Z^fmvyMMDZYswbzDP-+J)YIGn?+fVe!PF`Qn>#f@$F?4T)=nV< zJ;3D}4Rp(m&7C>@DO%uuQMGI87iIBjbh~_}1+#IZV@L}DeZFYqw0DSJ`IdZF3$CrR zuWXh}p{*e6R6wC^DP(bip)h8x=5}!d>YG|bTI)a|kIR58;(6`v5nF_$f8dJQbHoF- zkQHiMYBqc|VUMBg!BQhzgrFkS#&3w_n>wd-%$}jniDt-rRyh}jMQ`Buz_R-8mGBks z&Ivc0H~VVwNU^Ug8}xD8lo@N#d-8uP6vNQMB54NVA4^S~kL*J z_<@{Umn3*3SXpLhuCfuytX^Vrf&4BQQc4lGN0}otDz~z@hmougfYf>@(=>pkr4g=N zh4i}&yCgm7!Y(=KQfC~PMAa!5H^^bWvK`WD6ySUuM##aY931LAyjV>TYWl|nkHxGx zcVAvuizTxxd*nk+>(r&w>?n;R;LT7cWHN<0vMiVVfLc^J$1=Ye)^L;jMq9HrTdi+f z@n8f;^l-7_Yg{CPuv*S_IM_B~RVI-k8!jAv4Pb46%qv@)f^^AjM<(7N5Ed0o#Ap}F zq^CU?4z=Kr0g`4bljr~@XB%1K?`3*IBaPZIU?bh!GZ+dJ3T*1kA=CD(ObbWr_jFjJu!ymAKpCyxne>RVkHDM~J2@X~_ zJU)<_zKtDz`NgsiZkCUJ96hz=5V|@Pa0i?HpfIZ0yo;S&7Wu3hKaGZ;i0ndc!AcZu zvzbgOt}oM%@aX{HQYg)E6vU6B`~=ei^-xO!$g8en>4C z92pr!7(7E*Cn7XjFuo)Jx>Y?!9y)iZ+u6EB9?N7fi(zUiW>7Cr7qDt`db*nW5g87m z0i@`$4*Z=aOv%oW>_{?L9?QyBaqGe}b(vXYBxhzLd3E>Y<=k0(=it#*Q?U=nQ8sR5 z;ayewZ0)D9uL58JuG25b&7Wx7)pkPjC6sUzsu3e>u987Fe zH(?@lmbkSh$%#T%=a&TU^k?VD6Xd{rw4EhSqoY+tXKPVh)zP5`MA(~%piFy92Ufu? zT6ExOcm-8+TO_?DiN~M0%I5m}om^i>3;xDem@Aq}KXi0tvKT8Er`=txxwd3Jh3+Ak znC}5~w~z!1V9r&2oxdFFA*p`VpKv5x9_pS#(R7IQ0W@J$gjwtEQL}2$xrJi4 z+9}Eg8){@#5{X9(l**ue28WxY!zC=B8Lkr-SVdUTjH4E0n3haeGt3HE3%1fA*R@&M zH2My>W#=aQuOEsQks^~jN!{!lB}n({TeI8dY|Y_;h|`5EjG1e8i}a-)HfmJh3=y+3 z2AwQzvluQI5OP+Xb#gk4qC-rahC7)#Et%rBZW&=nW=M<@ms>f^MhC8Rd!%Nb)1;mt z=mC=$mCE3LY*m|cc*-nuv~p*2QDyC%%%brwRjWnu{^kx@=_I-m52e~$JNhJllo$>D zGWJT{Q=_3ZmzSsEcGZgY2{J7D93x2dN@(1<8B^_`qw)kO%xG^$ev&6-qONiVPQAKu z24+%8JYU&Gh8-Yp(Lpq0ttIJ@O?)yrzkbNww(^l=uN>ozCCaUYui36_QuQaAwL zj2tJ!O|Z=97}N=#=<33bd9%b8o&utyvU7`>Sxy%s2OEBz9cG;&g)y?=s=!g8MIJ^d z6iQB}(-PqG%sz~Nn z=*C*Nxx3%l(u1+)^x(M&e%=(TABk}B{Z_))M$*Mw^sp3{%FG;b zBwDNRGU3k9Q!{}~RMG{d)a%&R+R@UDyQVSvrGQkf=D1v^UM+^j!TI2*XU<^qVXcIu zS?Wo^4h%MTgLiXFXo)US0h3B7lhBNca%w49X32~|N znuN;MWWEyC-ThhoZv2oV-G`S{wyM2A6NKT6KS34M1ggS^39gZ0p6r^a6VI5ep{YBNcVEqOy;1vxT%P6jJXo}i-!Z&GB4?Dw+-3OMl`Es2l~Xdg4_ z&yB446MLm!EXHv^q$ewmwRnj!hC8zSN*DmR180PKTc@1d9I;-{`dB8~8PYBq@HPhC z{D6ZbeUDoGV^cIF;gTp$`?jS=4*c*s&uG!8gL|>e+p4yai45A%Z6$ciEjf)#v~q5V zM*Z2j+Z>D>S+*qjLCuuSnA%lHn-sHEHb@0E`}fH7(l1FyjTiO9T^UTv>TfG#GU3S% zuWI42(#)b^k888%wm3M&!O4}3qOG}6yGp&#lF-Xx{U93|wM^N%Rj4p%X)-1Jyl4w2B&6-AoR~>SscYOWH?~6 zIh?}Ta}n!ikR%5?7yG!Y-vf1;X+?ImbcA@cVqK2EOM=-DOJBTK+2ah! z%Pd<|E(ncDdwgS7ET!!zbaxJP6lcwWpdf(3PMn)7oss*y3pghgJ21`3qXLzQin2$M zZItMp5TH4%-{tvyLYL#=joJxyHgyfc{1W58wOy8tHg=TQ``{fMlt?psiT7Mywj9@Se=I?flP(1Qh^NBn}K`(|Ayj~n&1JqO)>}qb$cXw%t zfmaO0yaYpKD1)<{zC=fI)F+5!^$0KKEIKuI?6p;f0aB@6vV?UGO`hS6Af9lT;~5hs zQ61M$QVyCEuHvWDS4vO(?Lr!%@4Pte!8I_DQfD=)ioy!?+GTVNf zdty^kBKuT`gE(W$gnXWq?4In0;8P?D^OS>@}~X5}PF^4eR? zE!?w)h3iGaz!3OF4aeI*Y8RfMkxEXp@SsX|^LDOPa<&xlb}9xi@}EgT#gHA+kX*`ungyv`swQU+VjtoH&n zFj!=HB)L}(L4~GQ;-aZjG0Lf>pHjy} zp-u7(#75_-;&8D{$04iaJoHM1*~*gA-v^!U1xt)G`pa`bY1p&A3R=SLQS1 zI2=aUSqrBHIx{Brk9krz+Vgm>Dqc%$pi*~d6J}*A0bQWBrM3d;T4gk~R8x<7)hYq| z`VMt+A>Dz^AwCDxCtj2Xmh6^bQoGu{ZpCt5O$AY(%M6L$Q0Hct;rM`}BrDnNMtMlT z!C>^8df@o?Y|lj!s=UrODn{TxwG3eT!A-MV;GIPEWJ`@TseV$z9c$^nZj}SgoSYG= z$EG+z3XdN6CA2WHXAqK^B=PJ0ukA6r6hyyu@JR!x^l?K%uN1o5@y5K~i|I!*qXsEl zXcmUXaC8x-2(y!j`d=Nx@d2S)H^V5E!f;@)ErSCCi4V+GIOj<8oIWBc^@s=aV7AmF z9(Aw8pj2Z+)*MVZs-ABJa$%$jb=+x3ObP{5(_gerV#MSe zPPX8Y&u-K2R)qSEZ(hg|PqC?Q0Otnau8uQCxmNO$yu%h*Q!BOLYrQlTUr$lLOW-&c znrq6bCtP>Dt{dYVP1TQ>`}Q)$plRlsa_R`n^^YCk>;CnGVP175dCj)GY6!^y>2L}H!R5uQPjZpr((p(jt!PG+PG*$5VkbyUa)F2)*bt$Ks@NY&l&)NInjwIcv z=Vy#=ittz!rt%LP#dTv-m};U(tRTMJ)Ir0*B#mg;x{zVSW!7=CZC6ooVNXmWTxa$% zJ3VTHwEdbf;Roib_`QW$L5IyQ*TQg zT5D&G5YsY6811ren2O(;VJ}@l{J(7~s3x3mOiMW%k0la8mSh$O5eE>+2-%gQ2QiHk zZpOZUGgky5APi+NsK@dOtQ5*N4<2t_##7%-Wb)O9wM3QqEe!f3sB8gj51l zrBpaSqyjPJg?p5&lDtiG7!eYB#QznTL&$)EYwnGCJ1LVXLYm1i5kg{yi6Ufy!5XfgAO313Fyo{HjZe6s*D<;Dv!kqMR+V` zD8i^6C+a`N9fUX85Lw4SqK+wN9pPJt$T})p9^`dG20fUS(v-PT;*XeW zNl!)f`g_qpkx9Kw?{HlsGKtsQwLl{wmzVH#^5QMYLG(sA2XN-&GEC$WQ(q+{>LmQw zxB72dXz@Z!EisJ}a`BRKGISf4W+IaKGq%?=$7%tsp(T(&_(#+2B7t~Ju+Ai;ooHFg zN-oQU6ERH+hXU6geO|w>)0!8LDf%<2}i6c)r4=@s&$td$;Ojm#fnb{3i& z*s2qL-BcwXcd+3SLnSH@-(ZA^c-NMffLEmFz+N>yM6egPBa=dcx1x zDSIs;_uiTpOYaCG$H)pUhAnyGz=-fCR^mp&S8P=s;hlCm+DQ08TUAH+MXTyYLMkV! z*4aaYK-Jh@GVY0*xT+iCs@71|pN-LGBeN1NGOCIaH6tw15D*g5kd#wH_>i?}17X;v zngp9-EA1;I?w83aYJt>o()^lrZ8hP!R*jno7uc$5!cW+$n>voyZrEn7NUDTPNGa#0 zEhc8VZR}JN27M%dTy@lc|7h%aDhQMZjmp$l%ps=2h`M&8;6GSJ>qc=#fxX>in0w9% ze;Z-pAuDnHb|djN>#X%aO3 z-W?djXxnMTOZO88;Z_q3HzE7`+^gf*kISUv29yA0fWM)?G0|e50+qa)h|m)?GD1+-K|NjS$~%>#oM1 zz|@g&m#v#Wvc}}{^){zh6K=6pwVyKZ)8;BJCO%-vGOro@C^G1kgTDq%7i09e5D@Ta0vvpUD5U;d#myZyyvvqSvh;O!ab4G|c z>XOF%TMY;vIA8)}^uKANzdGIv)lrX&lj82JrhEUDK6R=I>2c2)OpVazzYpl5DXZ4# z(_-~%*l*xLTUA3V+bFAes+c{(RB^W%c8D^L zx_&!$YT_X~+d3v?I~!+v2D7ulEvm#GL-LrpBGL&TH&uFF%hC@6Lc*VqB4p|HfROOb zQG|bAmAWKV>PD!__pO9FLJHRlT$X+v5E6z}i9h9yd!;5xl^Uzcb5=qPA%*K@E=zw5 z2noZg)WjxWHlz>HL4@Ik@u%KwNQ)7HgyDv99D#+k=XkoFk{pSO(a z31e#2@Io6vep>mOMz^@MkxtPRI&DukajRXP+{a>tUep77(gY7^lXO_grT(zi}w z+f9W1r|K$A$kHX_EFs}MQ>6)6T4@RE34d;@HW5x79~Qz=uFMJ{e8p60AuQchZV3rL zY^pRNOTP{X3I8^VkfpMTmLp-isnQ(v?ckF=x8L?$9U;3*&SgxGv9E+z-3UwP+iu!G zxG~gCbt5dX6Ty*?J*YXd^s4R84TS7LO~}%xO)rBZVR@)O>qc0bYddcPA-h_0WT`SB zBwTH)HWI!$N(f71O*lXsLdJv^!qUuukgz)xN_8VF-5C%PUNb@Wp61BX_f0KC6Eey) zAxmRzC~Y9TI21~CBP>-0goF%7&5@-?142TEqb6j@x52rAFdUrmb5N1X*1qh##!Lx z*uo+1t=EFx;&T*2({Eo!mf3ABt)XHs{c2a3rL~nvf+9ZEXDr=?6{7QeatZ zy+zAfjdn7p6K}T~R}<1ixSUpwGXWqiiD%fLs3xSX8195ji7=G#y(UP688PDmWQ6pK zkkK2A2B|v+!+&l@s2dnbCGN73S{+O~8vWL^I%3Cn9U&RHPS5GYbQd1~|8_^zY*iVR zDXl4=Rw}}%Nvblc-pfX<*8=qjsS*TCAr7hcYLa@d?nqE?N`iW??nqGY)g4jw7&1&U z(pASo^Ni`EpV+>tVXrgr6OIeGuKJ;!nyU$E7M6HaoD*Hb%gMhp3_`7U z2h9kpf@ZU#%}BE@Xhzr=G@BP~Mw+cbGr}HIkND3gjct-5Ef8l1-v&* z%EJ92Q)@<8I$%syTv?#~qIUdnAgW{10Dr-F|EIPWstM09dPp;>za>;h%_@v$LbuLf zDwZUYYHgULds%3RJ53$-yM$B&6AmGrnxq-XdX17)P{@csYwm%J@T`#j#Iy-ygfvaK z5%-yF7m zDPAwyhINEwfYVXJFt7Ng;&sF0_m)>Z;UC^oiFm`hq=s>c>5oGtCvM5?*Pm))Fo> zRoW9Q{dkJzfu&;9Ib?r<1+2hTO|W?n!5AhEhko$JAjpOZYKUrJnk+@Z?$4YQw)9NE^_UX3z#y(TrQH zIU7D>;QyLpd1(-Qe!!@GUtl5OCS!$4A`$mV9c5Fn)CG(+`m$mBwUBp+e;J6JWJJ~3 z4y)T3k%)u+sKA7$P4$KWbx#=MyhU%ybIPbYrH*FNc~TcOuVBPIVXm%o)yNMG4)|Y{ z!2hZQ{#V8LzdgqP>Jj!YJJ)rtjVfQ&x^AmGTJ2m(C_q^(| zoHDU?g4F9Kta{Ac3Yal4vv1Rm3GR$Hy*HI(EMUi~MdsE?_^#7-%3|eeb2H$`F6xcl zVa?-73|Yz82^g|}Z#*ZeJUu&MO7xB{2cPuwImVj^H^Tk4Ds#GV+zfLC6=5*SGjt|h zhZCE*#v*zH4G9@tpo)41RdmS?!vGBl=?GBK1B@tC(R2nqssd{@qRn?117+9~2S#uF zow?1Z5i;Vy>W#FT_6QjbqN-9C)m7@E%1T{S+jS;1yUbM{fO}Ik)tTm+^mYKPN?vTx{`vV zj;^E}siP|y_)-^l<+i96&V6Q}JYcQ}Dnd5LG!$+2qH*$JbH##y@Fi1~ybc=oam{L% zxw=lDL;Tv;^*v8^SS-x=hOQJs;=QI$5$fB)CnY>$B@`XvXF?L{SRhx|DJDv&3wUcp z2^W1rmtCjVA%15_LJbRngx*96HKinc&`QWV#BCu7wJcOwFXbKLu$O8}NmyyUG~f`Q z7;9fvH zjgTc>5vPdqygQNSLdA35Tks51M0rxrjixv8-X$UX4~gjBoh;BE&_xYUbW#3aGCDsK z@qg2(t~o%uPt+;l@|DYo@_xkFoOwYwvnO3PZa)hvWR$C-A>>IN+>N+VK6wCv_QX z9m1AR>nhjTyO5YN#hs0+cNel!A7T+kqE|+(eO~K7Bkk@ahbI&K2T>2Ib6#$WS4hI7L+F z4T(G@0vp~U0X3)uM2aX+>iHwX8%Gg@U;ex%h9B-7W+8A6q_RNgC`uM+IXKc|yX`Cr zjx5lAS-He!%*#wfyfc)?Ym^&n-olNeDWWD{oyb$%So0QctWj+E5mG(U#H~u|?h*qr%vf z2FP!OOFUf#Bkzpmw>wO`JIxglK^SVcFV@bGJO6Hgtaphw8Xd+UFWi!5DPY&s5 z^NCAi>Nd~Xw1JTAVbk+5-PkTf^m>el23%teC_2R74h(p7dzz(yT`}2!Sf@N`c&|1+ zfbgMMUcY6)Gv*5a69)43KDC4N(d)&gLKgMJ{Q3m^ziUUDrGQ;;vih-QJr!AH)sG#8 zk|bchcTa3IQ0KhW6@TT-;136`es)KirGQ;NS=ZPGA*u+z;zhB%USLFBWW#AaVIXhs zizU@xXx!jB0}gS}a3ERHSk{b+#HyJJ^7^<@kb#FIM#4be-bZ6=3AUeS6&-YlgNB32 zipI7pHybV;w)g7^J8e}BVV9{&PHTHk)h2z@TqRo&|Jc?Q9OA>KPNfAFemPDvah(D! zwO0!Gx@A^$i2u#BQ+bnxfLYNpAt1A_8fJJnPxupCwT_VLiRCpTEKv@IJRwCUJnR3Q zVf%B-eq)@`M(W4w4-EBBZL1B0Y>nd)QuF${amViQbZ4JK{Ef-FPWhdM-_m`tT%BMao}I)jN4VyWh5Wx7vKDc4s-?WqQ? z4634Wkr3OLw1PF9*Mf| zSu<3QnyU;W;=jDrFk-`33=yUQ!vD0qwmHP)iS1%FG5JewN_b3qhPG&oxr%1Q$C*0m z*!rkRn5ILWr=Gfa|P)qC>pWw(EC@$x{T>v9LKrNE`@_ zr+r$r&dp{-l(Atgc|ZE<^oA>xMpu_={%;9ZvieQ>Qwdh3|$41D!RZfX`V0 zMThuHwq3tNOrEO4SqKEgJC_0;wE}t_;wPTR|#fI6nh6Y|HBu_c17>@Ev_=Yg`y26Sp zI>Z4lY`t)Zc-ypqFlr*1eb9Dz(II}H6)@}&lcxx%V<8X_Kfj`YzgPji4l&!SfyY9? zEI#naY=>o*cZlf%*BNq%$rG{j)Q&VufrO!`I~+=Q!%7%%h#xi1mAEGUe8}MqEKraT z5(h%#BauS?V1*7k#B8rd9SZ@o_-M)-CXX1+u!y8yY?iRDe79-!Pv(jq+oTteCe_D}9$;n!CAn+V^u-k&`}Ol=ZQhAHveAuWi> z5+Wbp5#^Qi($2a@NLb!Vy~)Tli7;ABF7sFN5hdsPMg* z3zJm%ppo-XAdir-l8~;Zm_Yc4P(C4k{SxMweuwx?Q>T&<3+G-M5E5Tu>-u5?l0w_8 z(4s^9dn;iOggX6aA0eZnxa>4l&z<+rcDm@l`6h4O?yl4l(VOgi9Qf z@OYAhcLt_`@H%U1IaQW{@-s@ zqy%*Ew_@>h415-vaKAMa_Qdzh;P5Co#P^#zHI7*LN{BET0~D~+3Me|n@3Zat9b)oS zV}^x?LxjYE(D+ik*$BJWw8JDrR&16q?@-n4R@GjI_#;+>VTYJ3Mb#P>sGf8`F=Zx= z5egl$Lh}yseOBmBhnR9iXe|pAB$GUGAT&OdD74QC9dL-*UIa9-5HO368ZsNO%my7| zwijlNECkHrqhXUV`JJ}ss{g@28k;a0dW>jFz-ahYY&0ALpQntdOJ_3j`yApuvsl;f z5P!(jiFx%bd_6=+{3BZzpH(RIcq_E%5Wmm1+u;yXjtH$|ArKI=+j+@Yb+=)LDJ0q~ zVODw7w7S};h1r6TR;gKq1!|BmtI)!!*1}$gn9cR9!V;M!jTmyfz;eqw#B8r;6_x^S z@u5I&=U8q74l(VOS%sK9Apx@rOM!&=_@IRItb{>__+Hz;!wxa~MvWO3C`i%@aUe84 zj@BE-Z?}D3{SE`kGGQEDVN|4q#98GS_`GODRn6v@>2ru5oy)p@hxp5;PK_fL{v$+4 z{0CbXA4e2=kri5Wh`(Ul?Qn=GM~x#E0s--Hbev)QIl~NtCfY1v9QmeIqq$;y5Yj3& zj#!`u3FC+sF0&T)I>cZt-zMZr56F0}e6mm2pH& zo_ZXy6iA4VBTBf=N*HvAAGiHG>=3hW)Hq^+f@B;K2SVfHXvi@BN89Js|70LpCXAzc zqar0Fj-zAX<6N%C%BRg0@A(l{UZroz!EF5qOI4;8goGa+Maa?@0z$&`=Z85)*Kt&3 zsZmAVZy^4>sq^q9n=}hlNewR+b{nyZk_GCdC|RIZB8T`J;npmSy;`fSTC;Gvt%OD_ z&_G35%08+uBZipTOT!u#ZZOISAu%nIK{$|Ri6*J$EYK!tPE3<@bCzh6YR&>}(xfbf zEvzYJ;e)mZ^A7QRYs^lEn1+hnS{Bw=!n{LFlVtTtOq1ks12MG|y4Zh4DY_hwAP6gr zNE|;BQXBnLf+gyMwuDp%Z3(Fjs0gW8!T~44p32}U8zIGt5{-5QQZfh$83)J$Ul?G4 z>gd)iQ6sb_WEiN{EHDgoYnB)Wij)N!r%9uJzsvajQFFyhAcV9N+@2bsu}f`d)DhAm zMVFxUQv(V5Jr&FEx5px&nnLMFWLmRn>vaA z*efb*_)bFvzY)I6^4jJQlc&5qLrnhCG4YpYsuya_K4h+<8Szn5hr$2UV49_?mIR3~ zrZ3sGS#~(OGI*A0=sMdS;xMziXwZ<^y9@)oaY#sI5DecNWP!}Y()h2UkXyIqR!jKP z#o8ncOv2xpDhPOEfQ7Jt+St?W?_a06{KQ-nChUJPvVUWBsHXCtvI0-|!3YZ!oWN@A zA}y`lTtPzkPFuAp>e5q9AIvmYyw^!c;}T>oG}IrkJ=o_Ef6CVNJH$`gx;}^acebwI zA>Ohq6iO@%n@Wj9;zw+q`PxCqE-LpSE1>8QQz4lOh^dgw_{4A8wmTi-a|vq1zqeDqGj%5dYZL4LihtGIeSKXMsw}LXqysS|_6@T@4}y-6Vq_TBjPEt_UX2NQHOBSY z7N>YL#8Yn|x4n-JrCFkQHDXzy0>YAbtWic0vQS|v zMGi5wR)nRL{C{oJ;&4Cb*vNT|v zuSi+=r0pjmW$EcKDGRh+b7hGJDXyhF(QUhGz#;Cc(p@Dt5qUrPN*65hTR6}?}y{^)85=%FkS`b=zW0M|S@@CdCn06&%`hnov|V#$i3TaIr93fW z?HO>0A6Tn>Ei(i0lcr9XHL$RyE+8a+!PF^27HGb3B&P8)*ATN~g^rl!2p#b^Y{w5f z#9?z|a}vAnBi7tOhnNcK`GX~@B(F9SQzcEw5|t84Vk)C4qt4%IwCFWg%q)aw)G*F5 zVX!dERLaREG4;go-!~LhP*vVwoJ3tzWmJ{78x?+JVi-hwh8{FQMhjJCwB?X#xyu?+ zPZ-ke6G^&#VyH2$TYOGplGtW+!<yMiOG#K`B*+9pTzL~)?tOkR%@RdPwyI-+!Z3J2%F>^WHj0#mi#Lb4vP3Nv zX(=T$R>@w6`0+r=#|P6aQ7>Uv!vfWUk|1S?dMQ#CsFo&W>15+dMalv-*QBLXztO6m zcZjOtVA_L~tz&G(egYQ-4Ls!n~$H4l%V>gr$_e-YPxd5VIl7 zeLcPpWx&!LN$|wf8!h(@rCFlpLP<=;H6=?_T_}k|+JI-&j(;=yQx?Y9o*@dk)ObZz zM)|4AD7#-8b~FeNzX?BQq7dz#92#RdQv&G7pOK{K7(o>_tkC#oQ=nyvGOEcRj3$3J zSDd;MhHQP@+DaFK+2cc#BkHM2Di{*`cx*p1*#vAz#;zn8yM_|j?TWG6ZM6TCOhQ-5=dT442&pRCy*QY_ z?8Vsg`tKMfj3>kgVTjoqmRYFx-WX(oL59YJj5lcV#vlvqiBJ&IlZq~CDLdsIfu)3l zL69G`dW0hS;9x@V9*mj)sEP2h7Tq&j ze198TqPx;8QIw>^Iu`1TTxm{B1(2H1oTWz$rE1Q?MV(2L~WR+cDVD2XXvQ?f(_gp!!bXv(NIYmA$y z0fr#qgm&#M48bRd7%-o(p@B+<2E{8%7V3<*z%eRxlMzY-(QeNWExX=&8I@5Z6lIj% zt#Nj{EIX=$mb;SJ#Z&$y!|uylwEalt2MnabsG_=bZ$iqy(lENlT;U1A7t9EUR?iO7 zx5dD>&koYJ^njv_TE5J1W-melAyq}Y*9WOA`$Sc;us-N0LK>y$qC!tKLLadH*+l<* zZ7W^2i6Y4=;S1(Yx2A42SL9B@uWZw|^v;2$@0(f>67C)h6Gl~~gsY4M$&$o>%Cn^$ z46#H}Dxa}HVHiRnW$9}Jnt>u^;kTwzld?oD6=^9YueVC}I>h}2tK{>8X_ly$u&ZH# zYC$qcSvotUWDN^cOOvt`Rx02h2ByST_gr+PdhZ5WrKUHFim~70zxfNkZ!W)ALee=d(f`m6>tIjTC*=hak{Y_^W zNC`-zrN*!T{*{&qd?y})Q`_Y&% zBs4w=(-nol0>UeUFnV>6F-fMd;MJI4pZ$sU=Y)T!U+W1!^D|wgCz`0~Z1|ssfy^Jo zzcS3^Cs2t0{im9n%JVE7XG91gaighIge*`OA&mYy$*o}8@2~Ra$i-jm5t(4$y7-5M55>~8af4*hkNZ4(wHW1RYWAVD9x9idKRL7k) z!fMJ9>G5C6`I+JObIZ4ykfRA>`Keo27;lHx-bZg?VX3KSwb5Jtxx1w3X26dmG?R={?Lm^?*59Sebg z_?vhXaM%jyb%--ozz&C)JViha3xR-m(xia@Faq#a93h(_#{NCF!eG0f*mezs*IO^{ zeSU}q>Y~RPOCb@@mlScpifAOf#)!c9BqU2clvrAESa%)>30K>ydcuca(p0)FOH?i? z37D7|_X=a9&msQ6f3mLN5brZ}DzI4C_*y_ne8AKxLKdD55fV@RFWp!XvT%i|l;1ca zzB^3F!bd}d#D5JFvM}~nfsVvmOq~+V!eEGy_)wUTg_lBv#Mk{gWDE;6rc#U{ek4rD z!dF6s#Ao~_#F2%IO{H)oetVdZh4+UDiI0Q{S@=_kkhuA`A<-=4O{It?{y~^9npvJT z5jNIFSkWQ=ppCG8hnPVnol<8DR%*ZF8BC27Aq!N+b>gp9QXG-66KZ zB?Yk%2#Du63i!1ZkavhbYz6Fah{;ndsAVA#5YKTGaH8=gRs@72hCjwQAvx+y#S-}^ zB?IHxvtH*|>2rur{vGRfIK<;kof?FP4T;Y+b+X^bPhzlSjmMYe#+U+SXwp(H`L%V)fJ1zW zb;(YLnB2s_vDaa!@u^nhL5G+Pp$2|*B&x<6rp5m@S3ImE{EMxMy{+&Tt$d?9UXLK8 z1_@ukm}026Sd04{;s=f}$_ftgXKh`dL;N{Yry`Gq$1GvNA)b0Pl*3rK)Kp3iBfc+8 z$ihg7koc6}hd8oOW-5gv@$N7o3-1UK68|ww$ikmPgv49^5E9Kox2Y7-#6JrYM!P@m z|DyGOxM6G%vSGdLIDFH?;E!A1?{J9OFVaahEKowyzLx^#Spj*6_@h?9c88ceML;bJ zfq-~|rT~VUoCgyBlNB)R5R<1GfGh+8;=h#^7cgiAe9{Wo=@65r2xw#>5D@>i&5NdI zFa9G3N}ogA_9xc$JH*XzghGae$~OZ-;^nrk&mn%ht&2~lRAj1Er05Wnr=*|ZG)v8v zThSq=1Wg%@RLYoWW%N44n~h;|YD`S~RKT%75keUKj{;^`0eOe`W-DN)Lrk73;8>u2 zvi~A(v$p0P;y{to-AdsSn8cf`B0C&n%2t8N0)@-aBBpR*NE|2Og1@6@ytBb7 zvfUx3Y!$#PP`G?Gl9kriqm1b@Cb@Z*L0XfXv$fn^6giCLi`+=YM%C>tlJl)m&J`u;jZrbqQj!)n z-CL5#eh`tZQA%bpp&-fgBd96NKEi54 z!%C9kfhWv1vG!Au)pAL`6+tT``SyDz@MuB5yy;{~xL#mGI=`0mk!(qe1W5}UHBVEN z3E2Y?*%~G3mWb?ZCFwX>)8bml#2Y%AVcuhy3%e0X3Kf;I`D@9-bpsPj#m7vd!!`kh zVw!q$a_q4igMVR;J);7Zm86BjA2!k=+py(SjQx=pZZ@L4JSuBbK&kgl%PwI_=X;Xg z?gR5ocWSvAW{`U78C%O;`X4b>xhXMdRORl2xT@>1xHFO6u_{?WVfdIz7A`3cg{7p0 z!W)9khWHOJ>`>gWDcqV3D@}&ftY4V9mO&K!hq9z_mvn!G)s&>Kh_Ex2q^GKhnwF|?x!ml=AQ4J>@?@h( ztC6OQiRVTc;4>qfo)U4Ltt2h^=zx`*T_VMrl5``}=C+j5A0B18MoD@?#8p+2mV7AF zFUrk6k>VO9=|-l_|BFj9?Tj+5C`oS}ah;_kE%{KUOXNl}qTi>HbR*N|)ud!9?TGU# zNnXQ#AUY%|xtQ}Rxs!ZgD@n=H6Itt+_RNTWu_Paepp*a3$+seCu_Ps1ymvi)f(e`% zED_sVIQd}%azn~P5Qc@GU08Z<$E)nFtCbDU8&xU%X!Kgx}MOLVs<kBCwTc}=%sG5E^K(wETRK6rhu?EqD+*IO#Z%|&z zKh1XyONt3e@5|e7-w3vuxnE<6kIPB&k{wKh;8;$Q8yWJiAcbpsWVlR{al_`H-Ej@+ zv%g~bbta=Ym9((w5zTE0mkg^#;Yvl0eMyq-5wu*A!tP%{%F};o7)Hq*rNWj@;N-R} zO@+zbtcIc_QxUXWl80EfZZXA=+af=fNiuHOT-jpyT{fi3mh@c_R#B4Pn%$rVkhBy; zH-OyCi7852%0ih)THN!to_Kd%RIDYEoDx;h>5`PJO;gF;fel4TO5O+tNs1f(W^QGU z#ZjR~@c-*f`wm9fnM%?*#;8!s<>t#VMM-}(!bX&&FOD0#4K1FW7#Y@-q%#p#Rg#v> z$&+PrGagfvwB$}JYDvdEY1-6@C&w`vMr}zBN6=}Kl&qIa0}45 z|Bx?1S_&rB#d6OcvxaD4DS9F=+Qy{5&hjRfJ54coE6e}Ga?`d3U$>nw*ph$sM%7Kp z)c98B`9&;mW;uuVK4q4dusn|Q&$G1IRmA%T<`=tL*k0^@%l50-?+aPFeEhDZddpOk zdY7g6opSvAh2y82kIR1_*VDT!KahHx>S~(%8>bn0C(EzxVD86vH1gf)M$XvDNcZ)1 z)<2o`Ph**8nWX;#+f87-trGN;^ro`@jx2XcuuszaH0$rfa#n(UlHTW7{}7fP3HC{P zpJ)9eSk6nZPtyAW>n~!tG{HVe?~}IImKml6Z`{quAMI}BjG1oBn)^FhZ#ULEiRBuW zd$L^@%atrg68H|>!|hmKmIt!zXX)B6>ofKzvRuh>70Uuk`EAWnzCVNI`7Hm1rOPir zT~#~AoBmTOpkh2@1TFJbB0-+HOZ=U$e-Wce)17g@f-(zQ>2&DdYa@-mj!vHTIs z2U$MF@=q*XzU2=azAv*p>j`sz8%tMzr$^269+sbHc@)c)o6Yl0EM5B(A2ZL-f85B^ zo;LDzmUr^P@F7_sIs|`YT)tQ#ABUd!jNzHeQogb=gYWlXxfjbemJYqDKWlg%WcdWk z*IByyw>@w4?_&8YmM^eu(&vxx%I9}~&G!$n{5{M6VCmYQ&I{ggmglj&Ko-J|!Sk;g z|KyW%|H=1%W%)MC_gQYmAK==Hr9-DSy=(a7?dMzgUf##OgYSRN@&T4lvvm37Ewneb z7+!g=>s`KA?-_hAmacsZAI^V<<-sfuVcE^Hm*rtBzr@nzTgmgR6$c9)PS>j2xEKP;n$RoURV5RCcTgH6v>km7*u3VWpZY z6|I{9&njU)O$MAQ=kc3txnd5lwQwC?2XTXErEI#ER;h3}7_6iVVKAJ9t=t)lAYG}X z$Bc!fS7o3^rj!p@v`^_mE(1SGV8=^JXKCmMs#TTBlnRBgh=Ecib+}!4h zgT!JU4GdJmQMt?KilL-YCz8yUkeShECbv=kAMR;6M_XIoKB|o->>_y^?>{Fow`@lz z^F1wF-}>;wlGyk0K2hZHyl-~x*<8&=g0_@mzmfMJB9G;DG37@(lD{nT4+ciuV*liU zxWOfIdtT=nR4Fc=+^R055X+JOFU>cPM9ybo@n7;0c_h^T5wmYyVC+SXn_ETx6NmWE zu%b6%rEG-V#`Yp*-y`{py_Ek{$9_thSdb6PncJItvZtnT?L%NxCwx4h?faYQX;eRfRu5$^>-<-xc%@-V<0lSpEiqL zoa$6p;t3srNPNt>+!)Nc-0-;i?){Chr7kD-t!&@=3GHu%E%`6@J#63e3GHup?EBch zkL~Nud0HRzD684=aHlwacLH?WQS-*>IC@4MC*-W(B|T*Y4G zqmI4WWbD-@W8dO5xY&t&(y{NmiSxh7*!P`p@|D*&0l#eG{Oh8~xYWDozK4XPq93h1(D?uEdG=HL zPN{7GxEK+f`~y?*KipN*MK7-Ij0F2_?lboHbVsH-;o9%Z_HObbpe`;S-(=jC^>)V(aLC(eHsrVhgH<2ockyCay z_9q==?q@;Vi9ZQPnZIa!_T|6we;E7v0mfcl-TVdj$w`O|Sk}KFq-5P; z(Ll)EZ23X>EsR-5#lMJPX?r1o+&g@+Ga zou`xV*&*LGNwqY=)K4a>*FSV0&~k8sYOa4O=|rr=S32jVDaJQBct7K>Irxd1zfqsk zUk5eb91pbqp?q6uAr`x?MtTB9D>tra4DpqV=3(tW^T;^!N6oXls(;tatIzXb^(O0= zS)Z55YAZNQJmZXa^ZMfu;1du((j9a;hP!%4CC~{FU|jD16;`UGZTIhzVTv%=U9I>U5u-LGWgTXb2MF2&v)<_G(JtKW9|Z6VxZ(;l@2j2mX zk^i?j_LUuC?`__3^iE#sS*U-qv*WPGy2a|h#ntS>wdY8>OXA}T*hk-zJc*P<5SrGD;du^ z_zfDz{K)kz2fRPj_)K+^^D9Dpb0@UeGw|(`om=GtU(c&(?65+H0eO z&t!aqgCEHFwGMum#u0Ddu;XnJ)|5P15{_C{fOddB-c zX9DdkuD;tfZgk?W4{CnI`E+~ye>p+_-30tVOfI? z|1)r%?=S3px5n0PXROc1`CK%B9$k9?C;j^0ZT-1g-{{0&PZRyE?0P#RLH|;%A7?P> z|HVA&-|T#UCj3)v{--tnR8>FQ*mqAd@~@&l!Pegv1E#NC+JNi&`GcMBLcyQ5@zt7V zs*?Ytyqt@24(r!$6f!d>eR6>|T<$C*Tig9u)3<6VD$^G#1YS*Zy;ReUpi{ zh<>NhpN094t{t(p)B68zm+P~F-)G~;0{7M1=^Dp*ON-%OWQ3||y!o7PJ?n3J-YEWq z^)E}{{~mB1ho83V^M2-0B|~r?$L&*$%dhg#c?w;B6`uWUp6&5wm#&A`?DBpVIQ0wp z=GP6enH#8pi#H1(UO*mhB?G0R) z_Ys??OXE02Z!`YzaH|%G{;zEPA;JG@U7gyoA)pcelSjc)X&$9hoE%+`regX5y z56;}f3+wANZaCwwze>O#7yjLB{#O(9r(qKG)$<(Sy1c)&%R4_oe0i1qW>rYkke}S&UI7Qd{2|RnCuzH?)&@|NXT=;g48{7Enf&{#p zfM1h&&TX~_;rH*o1*`wt-l@CBjo?4ON^KIbG+@X@wn$EeI#(5@8dSl$^`w2 z=s#!cZ`AteUpE+DxTmih5_s-lp8C5s&*RJ^KUVwPM8oqk>#JYe`deXX*kV+y*L{HN zay@G6cLNvS;s&QC;O8XZ|HS~WfYX;Zz?FssiCE#xZ$CS}@ZHG4? zsU2J9*!=qd*YUrD-QN$_`b{+I1g+nUpCUZF+B_qg2l2z7f0c3O0@2^c*5Aaqdcdx? zpEHmAD)KB|SNx9kALnxhImi2(@b75zPs3ZwzV_|aIO46s8VJFS~xG;;nICxeiUhPt`c)!Rf|v zI`5!sBticw;5ttBu>Jhs%%gZ7UubC5ZxVQ3Nx-)V|EFyJ8R)RSavhO?=MwO7jUx`( z&!gDSYk*J3xtV*;^Bv&2ygS?e+{--ji?<(gy*RG#8-q8A-SxijEM-w#vB%6Of zjmH!@*#?~Yul%!NIscij@n-##6YzrO$DsH(+s_LV^nb+q^$%_RM-%j4(m39y-qFO> zQtlV;Fwgh_c6oQhM=^A{`1d2fGs%?YV2wAI>%;^+16&%JUOXD&FBJSYHva7d{=0!w|DD47bj4Ra zLH`-xx<3Ea=6{Fr`ujG%+rIwt?x%6=*CtQYIsTm2dtJbFd1u(=T`ah=@gn2uc{|^W zMgJ`u{|<2KFRh18(D`H2xd&i4R~Th#jIP|@FP>#q>} zK^w0zKK>cI9xey&i^DrKj(Xw<5w`FGsk)Z6C6Oor!7GG?;1WX+0V@yZ{~lI_2s8TPGOa|67+YS&F#Lw@#mYY-wNEUf@L`?)7@ z>M!!2Nsq))E?w;!H|hB6;jI7KH3r>^A1-Hp^?z-DstG*Tv3`Au?T^Y-YSr4v;9x4F zg5bD$OM>GUEL|1^DjQb9p3oo_l`7RBJ+e;W zD`Dk)SPQeM?(X(BFng2&`lg!s-dTXJk5$H$`KDTSq)@AQfw;AW|2vV*l! zDPJv*)rL#OLMc0v4^f1{_VQRz4QnIiAeRZVx%7~M_$J7PgA5R%rBW%4)B>AU6hz`T zc+%xuuzGDC6_aXfYwhV$jzw6hl<+SF$PMFEPzd2+7N(ZR{M2Yt*7zV&NUa(vl<^fvG*oYU zs=cSHTV)0V6g}16-P^A6nc>x`_PL!sDpL#!=_=i{wyAtRSLh(TR}}}KTqgawU2UpZ z4lB75r8`t^^?FiiM`DZ;ZAh%6M5`*5YgC|ATUS@AqrGFU(+&qyRj;k2%V4XvYj4p| z;GGY@1B!=SDOkAZr~uxLrYos(x`LLso}kI`?aI7))NVaO1tGLY&7)R)QL2gR_4{NZ&^x9U%Iwx>Ee+IrRcbcvw3YJF8d>%p_$o>WIydxu3@%w>ao zy4IF$MoUExTFVuhG_zqj)@to-bKylts|EEE)T=Uis-5oE&JH9?#i1g;bBf#EE{ijh z4+^0AU_QK?1Ff!gY4E_bLOlD}CSA&AOevy+*gI6-M-|v$sd< zb|F;sJ-Vdf?e3aubi2EHjBYm~j(EGfdbMsh0>AsBGE>?ke$Ta)jAh3oX5bG>gw%=>*2aI`ervG5ZR%lRWNwquG_5|SXdB( z1<^*`IkfQ1U?p5*Bc8fLf77l|E4185vQ{$ydZYWo@AEfhPF`KTyYtz@d z&}ng#E1_iVJrtv8K%_cNg;1R83Tf}Ly8&8#AYB{AzdDFU09010Yc3jgRSpbud##LF zJKp`mj?Ny%U2Jl5;5wc#lX5%e7QT53-9prTaI&AKrwe@$VDJ2Hmd}C5)=PyR|#j z-GPqdTHt?`#|Ap$rRldZ^bxYY3Bf-FX;63drn)=PiZKXdQg=660n;F;Xgn~J0mgvA zTwV|RoqFKVBV>CgdMO@3PfxDxo!#W<{3ZPhj}DGL;V4WWW_iNtV~$^RWdHHOqWSZe z9=$AB)_>&jN0Y{~h4UiqY_${&V`|Hz8yt1=3H=Kf%!5YE9W$;MgY~6C6>AY1D9wmYw&s#KU-1qSi#bZudUTePbzp+c%9G)ks4 ziZ%%rU@%^&*RGubMhFuhE7JLqFeyB+HX1Dz!Z0^F>US|$TALoskCYWHnNh0PD%o#P z1>Gp>Jys$Lr~qSsfY2&@l8Pjkh{GQM)wKSl2d9#YXivYzP(EFt>RA{Tg87w@X0f3{ zsTi2)5Z(N^(O?O0PUhv))hc!-aqfW|@n`4nS~xdpg$;hIw+$ElG#H z=*ysR$iiQSK|M9+@v|KM!qeOqY|(T#Z3-8+I5eb6zpt$=CHH&m zhG<9PcguK<4Tmb|os2UYcmvU_hD|41Hdc=MnCl@*LK)|%5dGEL(_;y`0ftDMW`h z%k-4l++3Z$oxAELy<&a+hHSy}NNb^ZcWksmtyK26K|&jjhHz{> zjI5F%mX1@@Qtu0k> zVCJn@Q%Edt;_-5(_s=1*;I_H0?hkaeK z-nPa()UGG!b!l1(V0E;(5j3S_10dGVCd9NiKBoI zXflkk+uf3;LdUYIHz|WaV{xs2Obmy%r9x01!+E6DLgu)Qw)#>0h8rU}{e&JngA!^qxUu3GFW)<`Z-T9Yb#ZG}X{xZ}N{d zklx97b}?oVxWsf2%%M25kGHkSDwi-p=kgfw@LmNxrk)cls4g8Ds8Jtc!1O0yOVe^^ zL@(uNd&Y<42@ANv;UV(MGXU#>J69~z4%6xeX5w}&ip3x^GGOLz_Zjw+a!7#PPgHYJ zzo63&|8YPpXKtAukGII%v){sd5xOz;ZYatWQG~;CCrYu|FO)``#z#*%1~VmEiMdZ` zdO{`1d5ZfO6<~JtzS8rk;IDwlZ;S)Y2PREzLql;DZ&~QgsvE$x*Fgi}eUIW82APDh zfTpsV9teB~K#@PFM@(=*uG6VXtdfr$$>p>9fWcE!s0zw~#$wk$>fq#Gr@NL*)O1hG zqHWGGVXYr;B1OY<)2ge#O3&d0eq7S*`Tf2Q(~ycsjUIrY^7jBfHNlE(OqEM(otdjS zW^_>G*AC{hh$vLs30O$O;SoLfHS$BPpi7>3ToltvWtEZ}ea@=;$|ao0KmZ zaoFpbZU8#Is@Aair^WHd4rVk|By?+8wfJixb_$u~Jp#}S1Yl^?hgnIq>J6iduJuI!v_oVQ4 zF`l~Zh+`b=ryI-sk60%2)b8mKW~8?dy=6Ixy#bbsnetepD%(2YNFyxFr#L*m(Wrs= zN^bvX1?`r~H&OEh<8fd14p?ma#sYeq)y)9yphxnib2J|TA5663SX{rG?{R^~8yY@n z2jcfaza>O#&_>0X?$Lo$2%Zk Date: Tue, 25 Oct 2016 12:49:56 +0200 Subject: [PATCH 264/268] Added ohc to variable list --- earthdiagnostics/cmor_table.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 791c849..1449bbc 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -261,6 +261,7 @@ scsshtst,zostoga,snthic,Global average thermosteric sea level change ,ocean,,,,, heatc,ohc,ocean_heat_content,Ocean heat content,ocean,,J,,, ohcsum,ohcsum,total_ocean_heat_content,Total Ocean heat content,ocean,,J,,, ohcvmean,ohcvmean,average_ocean_heat_content,Average Ocean heat content,ocean,,J m-3,,, +ohc,ohc,ocean_heat_content,Ocean heat content,ocean,,J,,, transix,transix,sea_ice_x_transport,X-Component of Sea Ice Mass Transport,seaIce,,kg s-1,,, transiy,transiy,sea_ice_y_transport,Y-Component of Sea Ice Mass Transport,seaIce,,kg s-1,,, windsp,sfcWind,wind_speed,Near-Surface Wind Speed,atmos,,,,, -- GitLab From 11ee4f497e2421d0b4d3a9e45b6cbcb2d5ea8a6e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 25 Oct 2016 17:44:30 +0200 Subject: [PATCH 265/268] First version of thredds manager and monthly percentiles working --- diags.conf | 11 ++- earthdiagnostics/config.py | 7 ++ earthdiagnostics/earthdiags.py | 2 +- .../statistics/monthly_percentiles.py | 7 +- earthdiagnostics/threddsmanager.py | 89 +++++++++++++++++-- 5 files changed, 103 insertions(+), 13 deletions(-) diff --git a/diags.conf b/diags.conf index 0127555..b03e6a7 100644 --- a/diags.conf +++ b/diags.conf @@ -4,8 +4,8 @@ DATA_ADAPTOR = THREDDS # Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/$USER # Root path for the cmorized data to use -# DATA_DIR = /esnas/exp/ecearth/:/esarchive/exp/ecearth/:/esnas/exp/nemo/:/esarchive/exp/nemo/ -DATA_DIR = https://earth.bsc.es/thredds +DATA_DIR = /esnas/exp/:/esarchive/exp/ + # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or @@ -15,7 +15,7 @@ DIAGS = monpercent,ocean,tos,90 monpercent,ocean,tos,10 # DIAGS = OHC # Frequency of the data you want to use by default. Some diagnostics do not use this value: i.e. monmean always stores # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. -FREQUENCY = mon +FREQUENCY = 6hr # Path to CDFTOOLS binaries CDFTOOLS_PATH = ~/CDFTOOLS/bin # If true, copies the mesh files regardless of presence in scratch dir @@ -33,6 +33,9 @@ ATMOSPHERE_FILES = True # You can specify the variable to cmorize, in the way domain:var domain:var2 domain2:var VARIABLE_LIST = ocean:tos +[THREDDS] +SERVER_URL = https://earth.bsc.es/thredds + # Variables to be CMORized from the grib atmospheric files, separated by comma. # You can also specify the levels to extract using the following syntax # VARIABLE_CODE, VARIABLE_CODE:LEVEL, VARIABLE_CODE:LEVEL1-LEVEL2, VARIABLE_CODE:MIN_LEVEL:MAX_LEVEL:STEP @@ -78,7 +81,7 @@ OCEAN_TIMESTEP = 3 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment EXPID = i03i -STARTDATES = 19611101 +STARTDATES = 19811101 MEMBERS = 0 MEMBER_DIGITS = 1 CHUNK_SIZE = 4 diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index ac834ad..5866282 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -69,6 +69,7 @@ class Config(object): self.scratch_dir = os.path.join(self.scratch_dir, 'diags', self.experiment.expid) self.cmor = CMORConfig(parser) + self.thredds = THREDDSConfig(parser) def get_commands(self): """ @@ -171,6 +172,12 @@ class CMORConfig(object): return self.get_variables(frequency)[variable] +class THREDDSConfig(object): + def __init__(self, parser): + self.server_url = parser.get_option('THREDDS', 'SERVER_URL', '') + + + class ExperimentConfig(object): """ Encapsulates all chunk related tasks diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 0dbbb44..d496ac2 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -147,7 +147,7 @@ class EarthDiags(object): if self.config.data_adaptor == 'CMOR': self.data_manager = CMORManager(self.config) elif self.config.data_adaptor == 'THREDDS': - self.data_manager = THREDDSManager(self.config, self.config.data_dir) + self.data_manager = THREDDSManager(self.config) self.data_manager.prepare() # Run diagnostics diff --git a/earthdiagnostics/statistics/monthly_percentiles.py b/earthdiagnostics/statistics/monthly_percentiles.py index fab6072..3f6ed5d 100644 --- a/earthdiagnostics/statistics/monthly_percentiles.py +++ b/earthdiagnostics/statistics/monthly_percentiles.py @@ -88,7 +88,8 @@ class MonthlyPercentil(Diagnostic): """ variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) temp = TempFile.get() - Utils.cdo.monpctl(self.percentile, input=variable_file, output=temp) - self.send_file(temp, 'ocean', self.variable + 'p' + self.percentile, self.startdate, self.member, - self.chunk) + Utils.cdo.monpctl(str(self.percentile), input=[variable_file, '-monmin ' + variable_file, + '-monmax ' + variable_file], output=temp) + self.send_file(temp, 'ocean', '{0}p{1}'.format(self.variable, self.percentile), self.startdate, self.member, + self.chunk, frequency='mon') diff --git a/earthdiagnostics/threddsmanager.py b/earthdiagnostics/threddsmanager.py index e20eb2c..6ad91bc 100644 --- a/earthdiagnostics/threddsmanager.py +++ b/earthdiagnostics/threddsmanager.py @@ -1,17 +1,28 @@ # coding=utf-8 import os -from earthdiagnostics.datamanager import DataManager +from earthdiagnostics.datamanager import DataManager, NetCDFFile from earthdiagnostics.utils import TempFile, Utils import urllib +from earthdiagnostics.variable import Variable + class THREDDSManager(DataManager): """ Data manager class for CMORized experiments """ - def __init__(self, config, server_url): + def __init__(self, config): super(THREDDSManager, self).__init__(config) - self.server_url = server_url + self.server_url = config.thredds.server_url + data_folders = self.config.data_dir.split(':') + self.config.data_dir = None + for data_folder in data_folders: + if os.path.isdir(os.path.join(data_folder, self.experiment.institute.lower(), self.experiment.model.lower())): + self.config.data_dir = data_folder + break + + if not self.config.data_dir: + raise Exception('Can not find model data') def get_file(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None): """ @@ -84,7 +95,75 @@ class THREDDSManager(DataManager): :return: path to the copy created on the scratch folder :rtype: str """ - raise NotImplementedError() + original_var = var + cmor_var = Variable.get_variable(var) + var = self._get_final_var_name(box, var) + + if rename_var and rename_var != var: + Utils.rename_variable(filetosend, rename_var, var) + elif original_var != var: + Utils.rename_variable(filetosend, original_var, var) + + if not frequency: + frequency = self.config.frequency + + domain = DataManager.correct_domain(domain) + filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, + grid, year, date_str) + netcdf_file = NetCDFFile(filepath, filetosend, domain, var, cmor_var) + if diagnostic: + netcdf_file.add_diagnostic_history(diagnostic) + else: + raise ValueError('You must provide a diagnostic to store data using the THREDDSmanager') + netcdf_file.send() + + def get_file_path(self, startdate, member, domain, var, chunk, frequency, + box=None, grid=None, year=None, date_str=None): + """ + Returns the path to a concrete file + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param domain: file's domain + :type domain: str + :param var: file's var + :type var: str + :param chunk: file's chunk + :type chunk: int + :param frequency: file's frequency + :type frequency: str + :param box: file's box + :type box: Box + :param grid: file's grid + :type grid: str + :param year: file's year + :type year: int|str + :param date_str: date string to add directly. Overrides year or chunk configurations + :type date_str: str + :return: path to the file + :rtype: str + """ + if not frequency: + frequency = self.config.frequency + var = self._get_final_var_name(box, var) + + folder_path = self._get_folder_path(frequency, domain, var, grid) + file_name = self._get_file_name(startdate, var) + + filepath = os.path.join(folder_path, file_name) + return filepath + + def _get_file_name(self, startdate, var): + return '{0}_{1}.nc'.format(var, startdate) + + def _get_folder_path(self, frequency, domain, variable, grid): + folder_path = os.path.join(self.config.data_dir, + self.experiment.institute.lower(), + self.experiment.model.lower(), + self.frequency_folder_name(frequency), + self.get_varfolder(domain, variable, grid)) + return folder_path def get_year(self, domain, var, startdate, member, year, grid=None, box=None): """ @@ -108,7 +187,7 @@ class THREDDSManager(DataManager): def get_var_url(self, var, startdate, frequency, box): var = self._get_final_var_name(box, var) - return os.path.join(self.server_url, 'dodsc', 'exp', self.experiment.institute, + return os.path.join(self.server_url, 'fileServer', 'exp', self.experiment.institute, self.experiment.model, self.frequency_folder_name(frequency), var, '{0}_{1}.nc'.format(var, startdate)) -- GitLab From 6ecf05737e6b2c8504446ab837af6fca58664369 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 26 Oct 2016 09:55:27 +0200 Subject: [PATCH 266/268] Added Domain class to improve domain management. Added grid parameter to rewrite diagnostic --- diags.conf | 2 +- earthdiagnostics/cmorizer.py | 17 +++--- earthdiagnostics/cmormanager.py | 30 +++++------ earthdiagnostics/config.py | 1 - earthdiagnostics/datamanager.py | 45 ++++++---------- earthdiagnostics/diagnostic.py | 19 +++++++ earthdiagnostics/general/monthlymean.py | 5 +- earthdiagnostics/general/relink.py | 5 +- earthdiagnostics/general/rewrite.py | 26 ++++++---- earthdiagnostics/ocean/areamoc.py | 5 +- earthdiagnostics/ocean/averagesection.py | 10 ++-- earthdiagnostics/ocean/convectionsites.py | 1 + earthdiagnostics/ocean/cutsection.py | 9 ++-- earthdiagnostics/ocean/gyres.py | 1 + earthdiagnostics/ocean/heatcontent.py | 9 ++-- earthdiagnostics/ocean/heatcontentlayer.py | 5 +- earthdiagnostics/ocean/interpolate.py | 8 +-- earthdiagnostics/ocean/interpolatecdo.py | 12 +++-- earthdiagnostics/ocean/maxmoc.py | 27 +++++----- .../ocean/mixedlayerheatcontent.py | 7 +-- .../ocean/mixedlayersaltcontent.py | 7 +-- earthdiagnostics/ocean/moc.py | 5 +- earthdiagnostics/ocean/psi.py | 7 +-- earthdiagnostics/ocean/siasiesiv.py | 24 ++++----- earthdiagnostics/ocean/verticalmean.py | 5 +- earthdiagnostics/ocean/verticalmeanmeters.py | 5 +- earthdiagnostics/statistics/__init__.py | 3 +- .../statistics/monthly_percentiles.py | 8 +-- earthdiagnostics/threddsmanager.py | 36 ++++++------- earthdiagnostics/variable.py | 52 ++++++++++++++----- 30 files changed, 220 insertions(+), 176 deletions(-) diff --git a/diags.conf b/diags.conf index b03e6a7..1331e89 100644 --- a/diags.conf +++ b/diags.conf @@ -11,7 +11,7 @@ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below). If you are using the diagnpostics just to CMORize, leave it # empty -DIAGS = monpercent,ocean,tos,90 monpercent,ocean,tos,10 +DIAGS = monpercent,ocean,tas,90 monpercent,ocean,tas,10 # DIAGS = OHC # Frequency of the data you want to use by default. Some diagnostics do not use this value: i.e. monmean always stores # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 1f00be5..dc8d9db 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -10,7 +10,7 @@ import pygrib from autosubmit.config.log import Log from autosubmit.date.chunk_date_lib import parse_date, chunk_end_date, previous_day, date2str, add_months -from earthdiagnostics.variable import Variable +from earthdiagnostics.variable import Variable, Domains from earthdiagnostics.utils import TempFile, Utils @@ -315,7 +315,8 @@ class Cmorizer(object): frequency=frequency, rename_var=variable, date_str=date_str, region=region, move_old=True, grid=var_cmor.grid, cmorized=True) - def _add_coordinate_variables(self, handler, temp): + @staticmethod + def _add_coordinate_variables(handler, temp): handler_cmor = Utils.openCdf(temp) Utils.copy_variable(handler, handler_cmor, 'lon', False) Utils.copy_variable(handler, handler_cmor, 'lat', False) @@ -323,17 +324,19 @@ class Cmorizer(object): Utils.copy_variable(handler, handler_cmor, 'leadtime', False) handler_cmor.close() - def _rename_level_variables(self, temp, var_cmor): - if var_cmor.domain == 'ocean': + @staticmethod + def _rename_level_variables(temp, var_cmor): + if var_cmor.domain == Domains.ocean: Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev', 'depth': 'lev'}, False, True) - if var_cmor.domain in ('land', 'landIce'): + if var_cmor.domain in [Domains.landIce, Domains.land]: Utils.rename_variables(temp, {'depth': 'sdepth', 'depth_2': 'sdepth', 'depth_3': 'sdepth', 'depth_4': 'sdepth'}, False, True) - if var_cmor.domain == 'atmos': + if var_cmor.domain == Domains.atmos: Utils.rename_variables(temp, {'depth': 'plev'}, False, True) - def translate_frequency(self, frequency): + @staticmethod + def translate_frequency(frequency): if frequency == 'd': frequency = 'day' elif frequency == 'm': diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index 7932bac..9d26018 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -33,7 +33,7 @@ class CMORManager(DataManager): Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy :param domain: CMOR domain - :type domain: str + :type domain: Domain :param var: variable name :type var: str :param startdate: file's startdate @@ -66,7 +66,7 @@ class CMORManager(DataManager): :param member: file's member :type member: int :param domain: file's domain - :type domain: str + :type domain: Domain :param var: file's var :type var: str :param chunk: file's chunk @@ -95,7 +95,7 @@ class CMORManager(DataManager): return filepath def _get_cmor_file_name(self, startdate, member, domain, var, frequency, chunk, year, date_str): - domain_abreviattion = Variable.get_table_name(domain, frequency) + domain_abreviattion = domain.get_table_name(frequency) if chunk is not None: time_bound = self._get_chunk_time_bounds(startdate, chunk) elif year: @@ -138,7 +138,7 @@ class CMORManager(DataManager): :param year: if frequency is yearly, this parameter is used to give the corresponding year :type year: int :param domain: CMOR domain - :type domain: str + :type domain: Domain :param var: variable name :type var: str :param startdate: file's startdate @@ -160,8 +160,7 @@ class CMORManager(DataManager): if not frequency: frequency = self.config.frequency - domain = DataManager.correct_domain(domain) - filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, grid, year, date_str) + filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, grid, str(year), date_str) self._create_link(domain, filepath, frequency, var, grid, move_old) def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, @@ -171,7 +170,6 @@ class CMORManager(DataManager): Copies a given file to the CMOR repository. It also automatically converts to netCDF 4 if needed and can merge with already existing ones as needed - :param diagnostic: :param move_old: if true, moves files following older conventions that may be found on the links folder :type move_old: bool :param date_str: exact date_str to use in the cmorized file @@ -186,7 +184,7 @@ class CMORManager(DataManager): CMOR repository as a new region in the file or will overwrite if region was already present :type region: str :param domain: CMOR domain - :type domain: str + :type domain: Domain :param var: variable name :type var: str :param startdate: file's startdate @@ -201,9 +199,10 @@ class CMORManager(DataManager): :type box: Box :param frequency: file's frequency (only needed if it is different from the default) :type frequency: str - - :return: path to the copy created on the scratch folder - :rtype: str + :param diagnostic: diagnostic used to generate the file + :type diagnostic: Diagnostic + :param cmorized: flag to indicate if file was generated in cmorization process + :type cmorized: bool """ original_var = var cmor_var = Variable.get_variable(var) @@ -217,7 +216,6 @@ class CMORManager(DataManager): if not frequency: frequency = self.config.frequency - domain = DataManager.correct_domain(domain) filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, grid, year, date_str) netcdf_file = NetCDFFile(filepath, filetosend, domain, var, cmor_var) @@ -295,7 +293,7 @@ class CMORManager(DataManager): for startdate, member in self.experiment.get_member_list(): if not self.config.cmor.force and not self.config.cmor.force_untar and self._is_cmorized(startdate, member): continue - if not self._unpack_cmor_files(member): + if not self._unpack_cmor_files(startdate, member): self._cmorize_member(startdate, member) def _is_cmorized(self, startdate, member): @@ -324,7 +322,7 @@ class CMORManager(DataManager): def _unpack_cmor_files(self, startdate, member): if self.config.cmor.force: return False - filepaths = self._get_transferred_cmor_data_filepaths(startdate, 'tar.gz') + filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar.gz') if len(filepaths) > 0: Log.info('Unzipping cmorized data...') Utils.unzip(filepaths, True) @@ -332,7 +330,7 @@ class CMORManager(DataManager): if not os.path.exists(self.cmor_path): os.mkdir(self.cmor_path) - filepaths = self._get_transferred_cmor_data_filepaths(startdate, 'tar') + filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar') if len(filepaths) > 0: Log.info('Unpacking cmorized data...') Utils.untar(filepaths, self.cmor_path) @@ -341,7 +339,7 @@ class CMORManager(DataManager): return True return False - def _get_transferred_cmor_data_filepaths(self, startdate, extension): + def _get_transferred_cmor_data_filepaths(self, startdate, member, extension): tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, 'cmorfiles') diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index 5866282..206e12a 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -177,7 +177,6 @@ class THREDDSConfig(object): self.server_url = parser.get_option('THREDDS', 'SERVER_URL', '') - class ExperimentConfig(object): """ Encapsulates all chunk related tasks diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index fd4ad0b..0669033 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -10,7 +10,7 @@ import re from cfunits import Units from earthdiagnostics.utils import Utils, TempFile -from earthdiagnostics.variable import Variable +from earthdiagnostics.variable import Variable, Domains class DataManager(object): @@ -34,7 +34,7 @@ class DataManager(object): Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy :param domain: CMOR domain - :type domain: str + :type domain: Domain :param var: variable name :type var: str :param startdate: file's startdate @@ -75,7 +75,7 @@ class DataManager(object): CMOR repository as a new region in the file or will overwrite if region was already present :type region: str :param domain: CMOR domain - :type domain: str + :type domain: Domain :param var: variable name :type var: str :param startdate: file's startdate @@ -90,8 +90,10 @@ class DataManager(object): :type box: Box :param frequency: file's frequency (only needed if it is different from the default) :type frequency: str - :return: path to the copy created on the scratch folder - :rtype: str + :param diagnostic: diagnostic used to generate the file + :type diagnostic: Diagnostic + :param cmorized: flag to indicate if file was generated in cmorization process + :type cmorized: bool """ raise NotImplementedError() @@ -99,7 +101,7 @@ class DataManager(object): """ Ge a file containing all the data for one year for one variable :param domain: variable's domain - :type domain: str + :type domain: Domain :param var: variable's name :type var: str :param startdate: startdate to retrieve @@ -122,27 +124,11 @@ class DataManager(object): var += box.get_lon_str() + box.get_lat_str() + box.get_depth_str() return var - @staticmethod - def correct_domain(domain): - """ - Corrects domain capitalization - :param domain: domain name - :type domain: str - :return: domain with correct capitalization - :rtype: str - """ - domain = domain.lower() - if domain == 'seaice': - return 'seaIce' - elif domain == 'landice': - return 'landIce' - return domain - def get_varfolder(self, domain, var, grid=None): if grid: var = '{0}-{1}'.format(var, grid) - if domain in ['ocean', 'seaIce']: + if domain in [Domains.ocean, Domains.seaIce]: return '{0}_f{1}h'.format(var, self.experiment.ocean_timestep) else: return '{0}_f{1}h'.format(var, self.experiment.atmos_timestep) @@ -216,7 +202,7 @@ class DataManager(object): :param year: if frequency is yearly, this parameter is used to give the corresponding year :type year: int :param domain: CMOR domain - :type domain: str + :type domain: Domain :param var: variable name :type var: str :param startdate: file's startdate @@ -253,7 +239,7 @@ class NetCDFFile(object): :param local_file: :type local_file: str :param domain: - :type domain: str + :type domain: Domain :param var: :type var: str :param cmor_var: @@ -325,9 +311,8 @@ class NetCDFFile(object): handler = Utils.openCdf(self.local_file) var_handler = handler.variables[self.var] self._fix_variable_name(var_handler) - handler.modeling_realm = self.cmor_var.domain - handler.table_id = 'Table {0} (December 2013)'.format(Variable.get_table_name(self.cmor_var.domain, - self.frequency)) + handler.modeling_realm = self.cmor_var.domain.name + handler.table_id = 'Table {0} (December 2013)'.format(self.cmor_var.domain.get_table_name(self.frequency)) if self.cmor_var.units: self._fix_units(var_handler) handler.sync() @@ -358,7 +343,7 @@ class NetCDFFile(object): def _fix_coordinate_variables_metadata(self, handler): if 'lev' in handler.variables: handler.variables['lev'].short_name = 'lev' - if self.domain == 'ocean': + if self.domain == Domains.ocean: handler.variables['lev'].standard_name = 'depth' if 'lon' in handler.variables: handler.variables['lon'].short_name = 'lon' @@ -416,7 +401,7 @@ class NetCDFFile(object): def add_diagnostic_history(self, diagnostic): from earthdiagnostics.earthdiags import EarthDiags history_line = 'Diagnostic {1} calculated with EarthDiagnostics version {0}'.format(EarthDiags.version, - diagnostic) + diagnostic) self._add_history_line(history_line) def add_cmorization_history(self): diff --git a/earthdiagnostics/diagnostic.py b/earthdiagnostics/diagnostic.py index eb49e9a..af71dea 100644 --- a/earthdiagnostics/diagnostic.py +++ b/earthdiagnostics/diagnostic.py @@ -53,6 +53,25 @@ class Diagnostic(object): def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, rename_var=None, frequency=None, year=None, date_str=None, move_old=False): + """ + + :param filetosend: + :param domain: + :type domain: Domain + :param var: + :param startdate: + :param member: + :param chunk: + :param grid: + :param region: + :param box: + :param rename_var: + :param frequency: + :param year: + :param date_str: + :param move_old: + :return: + """ self.data_manager.send_file(filetosend, domain, var, startdate, member, chunk, grid, region, box, rename_var, frequency, year, date_str, move_old, diagnostic=self) diff --git a/earthdiagnostics/general/monthlymean.py b/earthdiagnostics/general/monthlymean.py index 1675311..38224e8 100644 --- a/earthdiagnostics/general/monthlymean.py +++ b/earthdiagnostics/general/monthlymean.py @@ -3,6 +3,7 @@ import os from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domain class MonthlyMean(Diagnostic): @@ -24,7 +25,7 @@ class MonthlyMean(Diagnostic): :param variable: variable's name :type variable: str :param domain: variable's domain - :type domain: str + :type domain: Domain :param frequency: original frequency :type frequency: str :param grid: original data grid @@ -70,7 +71,7 @@ class MonthlyMean(Diagnostic): if num_options > 4: raise Exception('You must specify between 2 and 4 parameters for the monthly mean diagnostic') variable = options[1] - domain = options[2] + domain = Domain(options[2]) if num_options >= 3: frequency = options[3] else: diff --git a/earthdiagnostics/general/relink.py b/earthdiagnostics/general/relink.py index c9b04c8..3009f20 100644 --- a/earthdiagnostics/general/relink.py +++ b/earthdiagnostics/general/relink.py @@ -1,5 +1,6 @@ # coding=utf-8 from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.variable import Domain class Relink(Diagnostic): @@ -21,7 +22,7 @@ class Relink(Diagnostic): :param variable: variable's name :type variable: str :param domain: variable's domain - :type domain: str + :type domain: Domain :param move_old: if true, looks for files following the old convention and moves to avoid collisions :type move_old: bool """ @@ -64,7 +65,7 @@ class Relink(Diagnostic): if num_options > 3: raise Exception('You must between 2 and 3 parameters for the relink diagnostic') variable = options[1] - domain = options[2] + domain = Domain(options[2]) if num_options >= 3: move_old = bool(options[3].lower()) else: diff --git a/earthdiagnostics/general/rewrite.py b/earthdiagnostics/general/rewrite.py index 1665a1d..ba89b5e 100644 --- a/earthdiagnostics/general/rewrite.py +++ b/earthdiagnostics/general/rewrite.py @@ -1,5 +1,6 @@ # coding=utf-8 from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.variable import Domain class Rewrite(Diagnostic): @@ -22,19 +23,20 @@ class Rewrite(Diagnostic): :param variable: variable's name :type variable: str :param domain: variable's domain - :type domain: str + :type domain: Domain """ alias = 'rewrite' "Diagnostic alias for the configuration file" - def __init__(self, data_manager, startdate, member, chunk, domain, variable): + def __init__(self, data_manager, startdate, member, chunk, domain, variable, grid): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.variable = variable self.domain = domain + self.grid = grid def __str__(self): return 'Rewrite output Startdate: {0} Member: {1} Chunk: {2} ' \ @@ -51,26 +53,32 @@ class Rewrite(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: variable, domain + :param options: variable, domain, grid :type options: list[str] :return: """ num_options = len(options) - 1 if num_options < 2: raise Exception('You must specify the variable and domain to rewrite') - if num_options > 2: - raise Exception('You must specify 2 parameters for the rewrite diagnostic') + if num_options > 3: + raise Exception('You must between 2 and 3 parameters for the rewrite diagnostic') variable = options[1] - domain = options[2] + domain = Domain(options[2]) + if num_options >= 3: + grid = options[3] + else: + grid = None job_list = list() for startdate, member, chunk in diags.config.experiment.get_chunk_list(): - job_list.append(Rewrite(diags.data_manager, startdate, member, chunk, domain, variable)) + job_list.append(Rewrite(diags.data_manager, startdate, member, chunk, domain, variable, grid)) return job_list def compute(self): """ Runs the diagnostic """ - variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) - self.send_file(variable_file, self.domain, self.variable, self.startdate, self.member, self.chunk) + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk, + grid=self.grid) + self.send_file(variable_file, self.domain, self.variable, self.startdate, self.member, self.chunk, + grid=self.grid) diff --git a/earthdiagnostics/ocean/areamoc.py b/earthdiagnostics/ocean/areamoc.py index 3801130..3942b7f 100644 --- a/earthdiagnostics/ocean/areamoc.py +++ b/earthdiagnostics/ocean/areamoc.py @@ -6,6 +6,8 @@ from earthdiagnostics.box import Box from earthdiagnostics.utils import Utils, TempFile import os +from earthdiagnostics.variable import Domains + class AreaMoc(Diagnostic): """ @@ -147,5 +149,4 @@ class AreaMoc(Diagnostic): nco.ncap2(input=temp2, output=temp2, options='-O -s "coslat[lat]=cos(lat[lat]*3.141592657/180.0)"') nco.ncwa(input=temp2, output=temp2, options='-w coslat -a lat') nco.ncks(input=temp2, output=temp2, options='-O -v vsftmyz,time') - self.send_file(temp2, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk, - box=self.box) + self.send_file(temp2, Domains.ocean, 'vsftmyz', self.startdate, self.member, self.chunk, box=self.box) diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 97a79d9..50961df 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -3,6 +3,8 @@ import os from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domain +from earthdiagnostics.variable import Domains class AverageSection(Diagnostic): @@ -26,7 +28,7 @@ class AverageSection(Diagnostic): :param variable: variable's name :type variable: str :param domain: variable's domain - :type domain: str + :type domain: Domain :param box: box to use for the average :type box: Box @@ -75,9 +77,9 @@ class AverageSection(Diagnostic): box.min_lat = int(options[4]) box.max_lat = int(options[5]) if num_options >= 6: - domain = options[6] + domain = Domain(options[6]) else: - domain = 'ocean' + domain = Domains.ocean job_list = list() for startdate, member, chunk in diags.config.experiment.get_chunk_list(): @@ -97,4 +99,4 @@ class AverageSection(Diagnostic): output=temp) os.remove(variable_file) self.send_file(temp, self.domain, self.variable + 'mean', self.startdate, self.member, self.chunk, - box=self.box, grid='regular') + box=self.box, grid='regular') diff --git a/earthdiagnostics/ocean/convectionsites.py b/earthdiagnostics/ocean/convectionsites.py index e9ac8b1..3ff6a65 100644 --- a/earthdiagnostics/ocean/convectionsites.py +++ b/earthdiagnostics/ocean/convectionsites.py @@ -39,6 +39,7 @@ class ConvectionSites(Diagnostic): self.model_version = model_version self.required_vars = ['vsftbarot'] self.generated_vars = ['gyres'] + self.mlotst_handler = None def __str__(self): return 'Convection sites Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/cutsection.py b/earthdiagnostics/ocean/cutsection.py index 4138322..95701ab 100644 --- a/earthdiagnostics/ocean/cutsection.py +++ b/earthdiagnostics/ocean/cutsection.py @@ -5,6 +5,8 @@ from autosubmit.config.log import Log from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.box import Box from earthdiagnostics.utils import Utils +from earthdiagnostics.variable import Domain +from earthdiagnostics.variable import Domains class CutSection(Diagnostic): @@ -78,9 +80,9 @@ class CutSection(Diagnostic): zonal = options[2].lower() == 'true' value = int(options[3]) if num_options >= 4: - domain = options[4] + domain = Domain(options[4]) else: - domain = 'ocean' + domain = Domains.ocean job_list = list() for startdate, member, chunk in diags.config.experiment.get_chunk_list(): @@ -182,7 +184,6 @@ class CutSection(Diagnostic): box.max_lat = self.value box.min_lat = self.value - self.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, - box=box) + self.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, box=box) Log.info('Finished cut section for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/gyres.py b/earthdiagnostics/ocean/gyres.py index 23ba2a6..93bdb60 100644 --- a/earthdiagnostics/ocean/gyres.py +++ b/earthdiagnostics/ocean/gyres.py @@ -40,6 +40,7 @@ class Gyres(Diagnostic): self.model_version = model_version self.required_vars = ['vsftbarot'] self.generated_vars = ['gyres'] + self.var_vsftbarot = None def __eq__(self, other): return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index e0a66c2..618d54c 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -8,6 +8,7 @@ from earthdiagnostics.constants import Basins from earthdiagnostics.utils import Utils, TempFile from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.box import Box +from earthdiagnostics.variable import Domains class HeatContent(Diagnostic): @@ -165,8 +166,8 @@ class HeatContent(Diagnostic): box_save = self.box Utils.setminmax(ohcsum_temp, 'ohcsum') - self.send_file(ohcsum_temp, 'ocean', 'ohcsum', self.startdate, self.member, self.chunk, - box=box_save, region=self.basin.fullname, rename_var='ohcsum') + self.send_file(ohcsum_temp, Domains.ocean, 'ohcsum', self.startdate, self.member, self.chunk, + box=box_save, region=self.basin.fullname, rename_var='ohcsum') Utils.setminmax(ohcvmean_temp, 'ohcvmean') - self.send_file(ohcvmean_temp, 'ocean', 'ohcvmean', self.startdate, self.member, self.chunk, - box=box_save, region=self.basin.fullname, rename_var='ohcvmean') + self.send_file(ohcvmean_temp, Domains.ocean, 'ohcvmean', self.startdate, self.member, self.chunk, + box=box_save, region=self.basin.fullname, rename_var='ohcvmean') diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index bd0cbf1..65f86cb 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -5,6 +5,7 @@ from earthdiagnostics.constants import Basins from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domains class HeatContentLayer(Diagnostic): @@ -160,7 +161,7 @@ class HeatContentLayer(Diagnostic): nco = Utils.nco results = TempFile.get() - thetao_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) + thetao_file = self.data_manager.get_file(Domains.ocean, 'thetao', self.startdate, self.member, self.chunk) handler = Utils.openCdf(thetao_file) heatc_sl = np.sum(handler.variables['thetao'][:, self.min_level:self.max_level, :] * self.weight, 1) @@ -177,4 +178,4 @@ class HeatContentLayer(Diagnostic): handler_results.close() Utils.setminmax(results, 'ohc') - self.send_file(results, 'ocean', 'ohc', self.startdate, self.member, self.chunk, box=self.box) + self.send_file(results, Domains.ocean, 'ohc', self.startdate, self.member, self.chunk, box=self.box) diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index ef18456..353a14b 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -6,6 +6,7 @@ import os from autosubmit.config.log import Log from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domain, Domains class Interpolate(Diagnostic): @@ -86,9 +87,9 @@ class Interpolate(Diagnostic): target_grid = options[1] variable = options[2] if num_options >= 3: - domain = options[3] + domain = Domain(options[3]) else: - domain = 'ocean' + domain = Domains.ocean if num_options >= 4: invert_lat = bool(options[4].lower()) else: @@ -148,8 +149,7 @@ class Interpolate(Diagnostic): if not has_levels: nco.ncks(input=temp2, output=temp2, options='-O -v {0},lat,lon,time'.format(self.variable)) - self.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, - grid=self.grid) + self.send_file(temp2, self.domain, self.variable, self.startdate, self.member, self.chunk, grid=self.grid) def _get_level_file(self, lev): if not self.tempTemplate: diff --git a/earthdiagnostics/ocean/interpolatecdo.py b/earthdiagnostics/ocean/interpolatecdo.py index b22f14e..a80e8da 100644 --- a/earthdiagnostics/ocean/interpolatecdo.py +++ b/earthdiagnostics/ocean/interpolatecdo.py @@ -4,6 +4,9 @@ from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile import numpy as np +from earthdiagnostics.variable import Domain +from earthdiagnostics.variable import Domains + class InterpolateCDO(Diagnostic): """ @@ -25,7 +28,7 @@ class InterpolateCDO(Diagnostic): :param variable: variable's name :type variable: str :param domain: variable's domain - :type domain: str + :type domain: Domain :param model_version: model version :type model_version: str """ @@ -83,9 +86,9 @@ class InterpolateCDO(Diagnostic): target_grid = cls._translate_ifs_grids_to_cdo_names(target_grid) if num_options >= 3: - domain = options[3] + domain = Domain(options[3]) else: - domain = 'ocean' + domain = Domains.ocean job_list = list() for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append( @@ -120,8 +123,7 @@ class InterpolateCDO(Diagnostic): temp = TempFile.get() cdo.remapbil(self.grid, input=variable_file, output=temp) Utils.setminmax(temp, self.variable) - self.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, - grid=self.grid) + self.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, grid=self.grid) diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index a5ecc77..fe21289 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -7,6 +7,7 @@ from earthdiagnostics.constants import Basins from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils +from earthdiagnostics.variable import Domains class MaxMoc(Diagnostic): @@ -97,7 +98,7 @@ class MaxMoc(Diagnostic): """ nco = Utils.nco - temp = self.data_manager.get_year('ocean', 'vsftmyz', self.startdate, self.member, self.year) + temp = self.data_manager.get_year(Domains.ocean, 'vsftmyz', self.startdate, self.member, self.year) handler = Utils.openCdf(temp) if 'i' in handler.dimensions: @@ -156,8 +157,8 @@ class MaxMoc(Diagnostic): var.valid_max = 1000. var[0] = maximum handler.close() - self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) + self.send_file(temp, Domains.ocean, 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzmaxlat', float, ('time',)) @@ -167,8 +168,8 @@ class MaxMoc(Diagnostic): var.valid_max = 90. var[0] = max_lat handler.close() - self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) + self.send_file(temp, Domains.ocean, 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzmaxlev', float, ('time',)) @@ -178,8 +179,8 @@ class MaxMoc(Diagnostic): var.valid_max = 10000. var[0] = max_lev handler.close() - self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) + self.send_file(temp, Domains.ocean, 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzmin', float, ('time',)) @@ -189,8 +190,8 @@ class MaxMoc(Diagnostic): var.valid_max = 1000. var[0] = minimum handler.close() - self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) + self.send_file(temp, Domains.ocean, 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzminlat', float, ('time',)) @@ -200,8 +201,8 @@ class MaxMoc(Diagnostic): var.valid_max = 90. var[0] = min_lat handler.close() - self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) + self.send_file(temp, Domains.ocean, 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzminlev', float, ('time',)) @@ -211,8 +212,8 @@ class MaxMoc(Diagnostic): var.valid_max = 10000. var[0] = min_lev handler.close() - self.send_file(temp, 'ocean', 'vsftmyzmax', self.startdate, self.member, box=self.box, - frequency='yr', year=self.year) + self.send_file(temp, Domains.ocean, 'vsftmyzmax', self.startdate, self.member, box=self.box, + frequency='yr', year=self.year) def _create_output_file(self, temp): handler = netCDF4.Dataset(temp, 'w') diff --git a/earthdiagnostics/ocean/mixedlayerheatcontent.py b/earthdiagnostics/ocean/mixedlayerheatcontent.py index 8460851..f5af3f5 100644 --- a/earthdiagnostics/ocean/mixedlayerheatcontent.py +++ b/earthdiagnostics/ocean/mixedlayerheatcontent.py @@ -4,6 +4,7 @@ import os from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics import cdftools from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domains class MixedLayerHeatContent(Diagnostic): @@ -66,8 +67,8 @@ class MixedLayerHeatContent(Diagnostic): """ Runs the diagnostic """ - temperature_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk) - mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) + temperature_file = self.data_manager.get_file(Domains.ocean, 'thetao', self.startdate, self.member, self.chunk) + mlotst_file = self.data_manager.get_file(Domains.ocean, 'mlotst', self.startdate, self.member, self.chunk) Utils.nco.ncks(input=mlotst_file, output=temperature_file, options='-A -v mlotst') @@ -78,4 +79,4 @@ class MixedLayerHeatContent(Diagnostic): Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlheatc': 'ohcvsumlotst'}, False, True) Utils.setminmax(temp, 'ohcvsumlotst') - self.send_file(temp, 'ocean', 'ohcvsumlotst', self.startdate, self.member, self.chunk) + self.send_file(temp, Domains.ocean, 'ohcvsumlotst', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/mixedlayersaltcontent.py b/earthdiagnostics/ocean/mixedlayersaltcontent.py index b3c6efe..2fda1b3 100644 --- a/earthdiagnostics/ocean/mixedlayersaltcontent.py +++ b/earthdiagnostics/ocean/mixedlayersaltcontent.py @@ -3,6 +3,7 @@ import os from earthdiagnostics import cdftools from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domains class MixedLayerSaltContent(Diagnostic): @@ -64,8 +65,8 @@ class MixedLayerSaltContent(Diagnostic): """ Runs the diagnostic """ - salinity_file = self.data_manager.get_file('ocean', 'so', self.startdate, self.member, self.chunk) - mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk) + salinity_file = self.data_manager.get_file(Domains.ocean, 'so', self.startdate, self.member, self.chunk) + mlotst_file = self.data_manager.get_file(Domains.ocean, 'mlotst', self.startdate, self.member, self.chunk) Utils.nco.ncks(input=mlotst_file, output=salinity_file, options='-A -v mlotst') @@ -75,4 +76,4 @@ class MixedLayerSaltContent(Diagnostic): Utils.rename_variables(temp, {'x': 'i', 'y': 'j', 'somxlsaltc': 'scvsummlotst'}, False, True) Utils.setminmax(temp, 'scvsummlotst') - self.send_file(temp, 'ocean', 'scvsummlotst', self.startdate, self.member, self.chunk) + self.send_file(temp, Domains.ocean, 'scvsummlotst', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/moc.py b/earthdiagnostics/ocean/moc.py index daa1ae2..459651d 100644 --- a/earthdiagnostics/ocean/moc.py +++ b/earthdiagnostics/ocean/moc.py @@ -6,6 +6,7 @@ from earthdiagnostics import cdftools from earthdiagnostics.constants import Basins from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domains class Moc(Diagnostic): @@ -69,7 +70,7 @@ class Moc(Diagnostic): """ temp = TempFile.get() - input_file = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) + input_file = self.data_manager.get_file(Domains.ocean, 'vo', self.startdate, self.member, self.chunk) Log.debug('Computing MOC') cdftools.run('cdfmoc', input=input_file, output=temp) @@ -106,4 +107,4 @@ class Moc(Diagnostic): options='-O -x -v zomsfglo,zomsfatl,zomsfpac,zomsfinp,zomsfind,zomsfinp0') Utils.setminmax(temp, 'vsftmyz') - self.send_file(temp, 'ocean', 'vsftmyz', self.startdate, self.member, self.chunk) + self.send_file(temp, Domains.ocean, 'vsftmyz', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/psi.py b/earthdiagnostics/ocean/psi.py index 342f0e9..0cabb67 100644 --- a/earthdiagnostics/ocean/psi.py +++ b/earthdiagnostics/ocean/psi.py @@ -2,6 +2,7 @@ from earthdiagnostics import cdftools from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domains class Psi(Diagnostic): @@ -64,9 +65,9 @@ class Psi(Diagnostic): Runs the diagnostic """ temp = TempFile.get() - input_file_u = self.data_manager.get_file('ocean', 'uo', self.startdate, self.member, self.chunk) - input_file_v = self.data_manager.get_file('ocean', 'vo', self.startdate, self.member, self.chunk) + input_file_u = self.data_manager.get_file(Domains.ocean, 'uo', self.startdate, self.member, self.chunk) + input_file_v = self.data_manager.get_file(Domains.ocean, 'vo', self.startdate, self.member, self.chunk) cdftools.run('cdfpsi', input=[input_file_u, input_file_v], output=temp, options='-mean -mask') Utils.rename_variable(temp, 'sobarstf', 'vsftbarot') Utils.setminmax(temp, 'vsftbarot') - self.send_file(temp, 'ocean', 'vsftbarot', self.startdate, self.member, self.chunk) + self.send_file(temp, Domains.ocean, 'vsftbarot', self.startdate, self.member, self.chunk) diff --git a/earthdiagnostics/ocean/siasiesiv.py b/earthdiagnostics/ocean/siasiesiv.py index c954f04..6e46264 100644 --- a/earthdiagnostics/ocean/siasiesiv.py +++ b/earthdiagnostics/ocean/siasiesiv.py @@ -7,6 +7,8 @@ from earthdiagnostics.utils import Utils, TempFile import earthdiagnostics.cdftoolspython as cdftoolspython import numpy as np +from earthdiagnostics.variable import Domains + class Siasiesiv(Diagnostic): """ @@ -87,13 +89,13 @@ class Siasiesiv(Diagnostic): """ Runs the diagnostic """ - sit_file = self.data_manager.get_file('seaIce', 'sit', self.startdate, self.member, self.chunk) + sit_file = self.data_manager.get_file(Domains.seaIce, 'sit', self.startdate, self.member, self.chunk) sit_handler = Utils.openCdf(sit_file) sit = np.asfortranarray(sit_handler.variables['sit'][:]) timesteps = sit_handler.dimensions['time'].size sit_handler.close() - sic_file = self.data_manager.get_file('seaIce', 'sic', self.startdate, self.member, self.chunk) + sic_file = self.data_manager.get_file(Domains.seaIce, 'sic', self.startdate, self.member, self.chunk) sic_handler = Utils.openCdf(sic_file) sic = np.asfortranarray(sic_handler.variables['sic'][:]) sic_handler.close() @@ -108,24 +110,18 @@ class Siasiesiv(Diagnostic): print ex self.send_file(self._extract_variable_and_rename(sit_file, result[4, :], 'sivols', '10^9 m3'), - 'seaIce', 'sivols', self.startdate, self.member, self.chunk, - region=self.basin.fullname) + Domains.seaIce, 'sivols', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.send_file(self._extract_variable_and_rename(sit_file, result[5, :], 'siareas', '10^9 m2'), - 'seaIce', 'siareas', self.startdate, self.member, self.chunk, - region=self.basin.fullname) + Domains.seaIce, 'siareas', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.send_file(self._extract_variable_and_rename(sit_file, result[7, :], 'siextents', '10^9 m2'), - 'seaIce', 'siextents', self.startdate, self.member, self.chunk, - region=self.basin.fullname) + Domains.seaIce, 'siextents', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.send_file(self._extract_variable_and_rename(sit_file, result[0, :], 'sivoln', '10^9 m3'), - 'seaIce', 'sivoln', self.startdate, self.member, self.chunk, - region=self.basin.fullname) + Domains.seaIce, 'sivoln', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.send_file(self._extract_variable_and_rename(sit_file, result[1, :], 'siarean', '10^9 m2'), - 'seaIce', 'siarean', self.startdate, self.member, self.chunk, - region=self.basin.fullname) + Domains.seaIce, 'siarean', self.startdate, self.member, self.chunk, region=self.basin.fullname) self.send_file(self._extract_variable_and_rename(sit_file, result[3, :], 'siextentn', '10^9 m2'), - 'seaIce', 'siextentn', self.startdate, self.member, self.chunk, - region=self.basin.fullname) + Domains.seaIce, 'siextentn', self.startdate, self.member, self.chunk, region=self.basin.fullname) @staticmethod def _extract_variable_and_rename(reference_file, values, cmor_name, units): diff --git a/earthdiagnostics/ocean/verticalmean.py b/earthdiagnostics/ocean/verticalmean.py index 95eacbb..7783ab2 100644 --- a/earthdiagnostics/ocean/verticalmean.py +++ b/earthdiagnostics/ocean/verticalmean.py @@ -3,6 +3,7 @@ from earthdiagnostics import cdftools from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domains class VerticalMean(Diagnostic): @@ -104,6 +105,6 @@ class VerticalMean(Diagnostic): cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, '-debug']) Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) - self.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, - box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) + self.send_file(temp, Domains.ocean, self.variable + 'vmean', self.startdate, self.member, self.chunk, + box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) diff --git a/earthdiagnostics/ocean/verticalmeanmeters.py b/earthdiagnostics/ocean/verticalmeanmeters.py index cb25a99..5d43196 100644 --- a/earthdiagnostics/ocean/verticalmeanmeters.py +++ b/earthdiagnostics/ocean/verticalmeanmeters.py @@ -3,6 +3,7 @@ from earthdiagnostics import cdftools from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domains class VerticalMeanMeters(Diagnostic): @@ -101,5 +102,5 @@ class VerticalMeanMeters(Diagnostic): cdftools.run('cdfvertmean', input=variable_file, output=temp, options=[self.variable, 'T', lev_min, lev_max, '-debug']) Utils.setminmax(temp, '{0}_vert_mean'.format(self.variable)) - self.send_file(temp, 'ocean', self.variable + 'vmean', self.startdate, self.member, self.chunk, - box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) + self.send_file(temp, Domains.ocean, self.variable + 'vmean', self.startdate, self.member, self.chunk, + box=self.box, rename_var='{0}_vert_mean'.format(self.variable)) diff --git a/earthdiagnostics/statistics/__init__.py b/earthdiagnostics/statistics/__init__.py index 618dbba..12da83d 100644 --- a/earthdiagnostics/statistics/__init__.py +++ b/earthdiagnostics/statistics/__init__.py @@ -1 +1,2 @@ -from monthly_percentiles import MonthlyPercentil \ No newline at end of file +# coding=utf-8 +from monthly_percentiles import MonthlyPercentil diff --git a/earthdiagnostics/statistics/monthly_percentiles.py b/earthdiagnostics/statistics/monthly_percentiles.py index 3f6ed5d..7698983 100644 --- a/earthdiagnostics/statistics/monthly_percentiles.py +++ b/earthdiagnostics/statistics/monthly_percentiles.py @@ -1,9 +1,7 @@ # coding=utf-8 -# coding=utf-8 -from earthdiagnostics import cdftools -from earthdiagnostics.box import Box from earthdiagnostics.diagnostic import Diagnostic from earthdiagnostics.utils import Utils, TempFile +from earthdiagnostics.variable import Domain class MonthlyPercentil(Diagnostic): @@ -28,8 +26,6 @@ class MonthlyPercentil(Diagnostic): :type chunk: int :param variable: variable to average :type variable: str - :param box: box used to restrict the vertical mean - :type box: Box """ alias = 'monpercent' @@ -70,7 +66,7 @@ class MonthlyPercentil(Diagnostic): if num_options > 3: raise Exception('You must specify between one and three parameters for the vertical mean') - domain = options[1] + domain = Domain(options[1]) variable = options[2] percentile = int(options[3]) if percentile < 0 or percentile > 100: diff --git a/earthdiagnostics/threddsmanager.py b/earthdiagnostics/threddsmanager.py index 6ad91bc..d044f91 100644 --- a/earthdiagnostics/threddsmanager.py +++ b/earthdiagnostics/threddsmanager.py @@ -17,7 +17,8 @@ class THREDDSManager(DataManager): data_folders = self.config.data_dir.split(':') self.config.data_dir = None for data_folder in data_folders: - if os.path.isdir(os.path.join(data_folder, self.experiment.institute.lower(), self.experiment.model.lower())): + if os.path.isdir(os.path.join(data_folder, self.experiment.institute.lower(), + self.experiment.model.lower())): self.config.data_dir = data_folder break @@ -77,7 +78,7 @@ class THREDDSManager(DataManager): CMOR repository as a new region in the file or will overwrite if region was already present :type region: str :param domain: CMOR domain - :type domain: str + :type domain: Domain :param var: variable name :type var: str :param startdate: file's startdate @@ -92,9 +93,14 @@ class THREDDSManager(DataManager): :type box: Box :param frequency: file's frequency (only needed if it is different from the default) :type frequency: str - :return: path to the copy created on the scratch folder - :rtype: str + :param diagnostic: diagnostic used to generate the file + :type diagnostic: Diagnostic + :param cmorized: flag to indicate if file was generated in cmorization process + :type cmorized: bool + """ + if cmorized: + raise ValueError('cmorized is not supported in THREDDS manager') original_var = var cmor_var = Variable.get_variable(var) var = self._get_final_var_name(box, var) @@ -107,9 +113,8 @@ class THREDDSManager(DataManager): if not frequency: frequency = self.config.frequency - domain = DataManager.correct_domain(domain) - filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, box, - grid, year, date_str) + filepath = self.get_file_path(startdate, domain, var, frequency, box, + grid) netcdf_file = NetCDFFile(filepath, filetosend, domain, var, cmor_var) if diagnostic: netcdf_file.add_diagnostic_history(diagnostic) @@ -117,30 +122,22 @@ class THREDDSManager(DataManager): raise ValueError('You must provide a diagnostic to store data using the THREDDSmanager') netcdf_file.send() - def get_file_path(self, startdate, member, domain, var, chunk, frequency, - box=None, grid=None, year=None, date_str=None): + def get_file_path(self, startdate, domain, var, frequency, + box=None, grid=None): """ Returns the path to a concrete file :param startdate: file's startdate :type startdate: str - :param member: file's member - :type member: int :param domain: file's domain :type domain: str :param var: file's var :type var: str - :param chunk: file's chunk - :type chunk: int :param frequency: file's frequency :type frequency: str :param box: file's box :type box: Box :param grid: file's grid :type grid: str - :param year: file's year - :type year: int|str - :param date_str: date string to add directly. Overrides year or chunk configurations - :type date_str: str :return: path to the file :rtype: str """ @@ -149,14 +146,11 @@ class THREDDSManager(DataManager): var = self._get_final_var_name(box, var) folder_path = self._get_folder_path(frequency, domain, var, grid) - file_name = self._get_file_name(startdate, var) + file_name = '{0}_{1}.nc'.format(var, startdate) filepath = os.path.join(folder_path, file_name) return filepath - def _get_file_name(self, startdate, var): - return '{0}_{1}.nc'.format(var, startdate) - def _get_folder_path(self, frequency, domain, variable, grid): folder_path = os.path.join(self.config.data_dir, self.experiment.institute.lower(), diff --git a/earthdiagnostics/variable.py b/earthdiagnostics/variable.py index 4319fdf..01b8c55 100644 --- a/earthdiagnostics/variable.py +++ b/earthdiagnostics/variable.py @@ -18,7 +18,7 @@ class Variable(object): self.short_name = line[1].strip() self.standard_name = line[2].strip() self.long_name = line[3].strip() - self.domain = line[4].strip() + self.domain = Domain(line[4].strip()) self.basin = Basins.parse(line[5]) self.units = line[6].strip() self.valid_min = line[7].strip() @@ -63,26 +63,52 @@ class Variable(object): Variable._dict_variables[old_name.lower()] = var Variable._dict_variables[var.short_name.lower()] = var - @staticmethod - def get_table_name(domain, frequency): + +class Domain(object): + + def __init__(self, domain_name): + domain_name = domain_name.lower() + if domain_name == 'seaice': + self.name = 'seaIce' + elif domain_name == 'landice': + self.name = 'landIce' + elif domain_name in ['ocean', 'atmos', 'land']: + self.name = domain_name + else: + raise ValueError('Domain {0} not recognized!'.format(domain_name)) + + def __eq__(self, other): + return other.__class__ == Domain and self.name == other.name + + def __str__(self): + return self.name + + def get_table_name(self, frequency): """ Returns the table name for a domain-frequency pair - :param domain: variable's domain - :type domain: str :param frequency: variable's frequency :type frequency: str :return: variable's table name :rtype: str """ if frequency == 'mon': - if domain == 'seaIce': - domain_abreviattion = 'OImon' - elif domain == 'landIce': - domain_abreviattion = 'LImon' + if self.name == 'seaIce': + table_name = 'OImon' + elif self.name == 'landIce': + table_name = 'LImon' else: - domain_abreviattion = domain[0].upper() + 'mon' + table_name = self.name[0].upper() + 'mon' elif frequency == '6hr': - domain_abreviattion = '6hrPlev' + table_name = '6hrPlev' else: - domain_abreviattion = 'day' - return domain_abreviattion + table_name = 'day' + return table_name + + +class Domains(object): + seaIce = Domain('seaice') + ocean = Domain('ocean') + landIce = Domain('landIce') + atmos = Domain('seaice') + land = Domain('land') + -- GitLab From 80d046b5f5a111881e4666443417c5896a2db609 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 26 Oct 2016 12:16:23 +0200 Subject: [PATCH 267/268] Storing history as ascii char when posible (ehn no utf8 char is present) to avoid problems with CDO --- earthdiagnostics/datamanager.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 0669033..403af54 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -415,11 +415,19 @@ class NetCDFFile(object): handler = Utils.openCdf(self.local_file) try: - handler.history += history_line + history_line = handler.history + history_line except AttributeError: - handler.history = history_line + history_line = history_line + handler.history = self.maybe_encode(history_line) handler.close() + @staticmethod + def maybe_encode(string, encoding='ascii'): + try: + return string.encode(encoding) + except UnicodeEncodeError: + return string + class UnitConversion(object): """ -- GitLab From 7c397c356e4e11fe1b6a33e378c0e10db6ad66ee Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 26 Oct 2016 12:22:41 +0200 Subject: [PATCH 268/268] Bumped version and updated doc --- VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/EarthDiagnostics.pdf | Bin 254904 -> 254340 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 249f55c..13d22bb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b17 +3.0.0b18 diff --git a/doc/source/conf.py b/doc/source/conf.py index 42e0fd9..2720414 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b17' +release = '3.0.0b18' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index 86ef33542e589080d0cbe7d704d2ebcdc5ac24fd..87355f4c78cde080d0dc20b23341c2da73ba26de 100644 GIT binary patch delta 106153 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%0A3DKyyKm+e>} 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%0AD8I!?O(#%pNhc`^X?wNm>c-l;C_Go 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 a3XG>jg=JbSgSaW=VUiU5{CD*

    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 -- GitLab From 6f6eb4bb01d4993678bf7053d151a41ad5125684 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 20 Oct 2016 16:51:31 +0200 Subject: [PATCH 260/268] Updated doc and bumped version to the correct one --- VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/EarthDiagnostics.pdf | Bin 254976 -> 254904 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index e7b2725..249f55c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b16 +3.0.0b17 diff --git a/doc/source/conf.py b/doc/source/conf.py index 3ef6939..42e0fd9 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b16' +release = '3.0.0b17' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index 550d8976925e20838585040502f4c9329c5c5fa8..86ef33542e589080d0cbe7d704d2ebcdc5ac24fd 100644 GIT binary patch delta 44678 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 delta 44840 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≫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 -- GitLab From e41ce8627cbc9d1379ff89646436cc554225ade6 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 20 Oct 2016 17:57:43 +0200 Subject: [PATCH 261/268] CDO and NCO logs now active when llog to console set to DEBUG or more verbose --- earthdiagnostics/earthdiags.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 6021bb4..bffbc96 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -93,6 +93,11 @@ class EarthDiags(object): return True Log.set_console_level(args.logconsole) Log.set_file_level(args.logfile) + + if Log.console_handler.level <= Log.DEBUG: + Utils.cdo.debug = True + Utils.nco.debug = True + if args.logfilepath: Log.set_file(Utils.expand_path(args.logfilepath)) -- GitLab From ea941a29a0dc87e3d5dff4e825db2eb26a6f7512 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 21 Oct 2016 13:24:56 +0200 Subject: [PATCH 262/268] Now only the required cmor packages are unpacked --- earthdiagnostics/cmormanager.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py index 68a9ffb..b159e15 100644 --- a/earthdiagnostics/cmormanager.py +++ b/earthdiagnostics/cmormanager.py @@ -195,7 +195,7 @@ class CMORManager(DataManager): for startdate, member in self.experiment.get_member_list(): if not self.config.cmor.force and not self.config.cmor.force_untar and self._is_cmorized(startdate, member): continue - if not self._unpack_cmor_files(startdate): + if not self._unpack_cmor_files(startdate, member): self._cmorize_member(member, startdate) def _is_cmorized(self, startdate, member): @@ -221,10 +221,10 @@ class CMORManager(DataManager): cmorizer.cmorize_atmos() Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, datetime.now() - start_time) - def _unpack_cmor_files(self, startdate): + def _unpack_cmor_files(self, startdate, member): if self.config.cmor.force: return False - filepaths = self._get_transferred_cmor_data_filepaths(startdate, 'tar.gz') + filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar.gz') if len(filepaths) > 0: Log.info('Unzipping cmorized data...') Utils.unzip(filepaths, True) @@ -232,7 +232,7 @@ class CMORManager(DataManager): if not os.path.exists(self.cmor_path): os.mkdir(self.cmor_path) - filepaths = self._get_transferred_cmor_data_filepaths(startdate, 'tar') + filepaths = self._get_transferred_cmor_data_filepaths(startdate, member, 'tar') if len(filepaths) > 0: Log.info('Unpacking cmorized data...') Utils.untar(filepaths, self.cmor_path) @@ -241,11 +241,12 @@ class CMORManager(DataManager): return True return False - def _get_transferred_cmor_data_filepaths(self, startdate, extension): + def _get_transferred_cmor_data_filepaths(self, startdate, member, extension): tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, 'cmorfiles') - file_name = 'CMOR?_{0}_{1}_*.{2}'.format(self.experiment.expid, startdate, extension) + file_name = 'CMOR?_{0}_{1}_{2}_*.{3}'.format(self.experiment.expid, startdate, + self.experiment.get_member_str(member), extension) filepaths = glob.glob(os.path.join(tar_path, file_name)) filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) filepaths += glob.glob(os.path.join(tar_original_files, file_name)) -- GitLab From dd610ffc1a3f4f89e13f67e5fb2d0a10128d0640 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 25 Oct 2016 12:49:33 +0200 Subject: [PATCH 263/268] Changed cdftoolspython.so to a version compiled in moore. Fixes #3 --- earthdiagnostics/cdftoolspython.so | Bin 419104 -> 294192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/earthdiagnostics/cdftoolspython.so b/earthdiagnostics/cdftoolspython.so index 1d8daccff7f34ecd59492bc199c8e5b8213e1af2..2d3916295e882a4723b0fdda32ceab0ed0d26105 100755 GIT binary patch literal 294192 zcmeFadtekr);8Xg3kE@YK+t#}a99Bm6NKGFL^F_J4^A*5XmHUGav{+`VloNfq6CvD z<1m<2SMjoLbX`T)OH}lY!s-N&n->D2;te9+W5kin2;98Sx?hk==u!P{<|8-rDR=4ll)LnN<~_rJ z&3lrOJ?Cq0AzLtTy3P=N_Za!iyV=^SkWbWSl=I)+>;}VBqdu$lwV$Ljns>7YPC(>b zgiDb;822XJ&omPeUyP6pIurL>5qRB$@GHV^2wey>5LP0{7t4JUKsG|5k?=h3vk}%C zG;b3T))@3i+?OKkG3e;q*k}Os@^u}E z{wT8;_f1AZf>8&_EeO>JZzI@&{}p#$59&AZSzyHfEMY~6FF^PXVWEL1BL5FYJl?3I zpFwj{%0s*#?jZx~ZSa^ZZy6CzeWxJ)UkD!{R2lf~#{FvJe!6kz?e7SWAl!#=8Nv{R z2?)G$^_%i9i>04J>zMHEPX)sMK}~y-e80N!nmJp+&ghMrapnx?m(zRn2%s}-6c4J z)t3x8(UW<9#`?a>TeY^NwM+Xno?PoHIL+0tYD?0I&V*SuWx#BuSKNTY+SD`aC)J;agOI)&wk~aZC;NdV$Scxo(WS z9^plVml0@JuOR#vf_%LWVhzF@2yY?;5n2)Ci#D_#VFSV@DPgk_e+PHkPaDGf2s;oy zLg0M%F#<1n?C%2o1;UpITvOzW{T)IG8{j_Nx#sdR$H0#|DLxMv@t<%%h+xhignvc& z4dEyW7)Ez{1-HGpe5eFpj$oR8%>!(5B#1JOn~w&^=}+_!sm z#-^?Fe?0Q;+a3LeI#*9Rt*q(S;KXx(3r@TzspPy~V=`BtF}W@NUc}q0s;~MR?zgWg zsXla8<+9M=)5`h{z4*LaYcKubyoSf0-t>7%b=;`iAFk>3$VuNG{;%Ygf1Ud2t9QDa zbDS4Fzx7*J-|TTie;EP3*8)HG<9*9#w))3LoK|)L;ty^czx2tM-x>PvU!R-*VD=3s z_kPRkxbwMphCYG%=JY6yZ4MM zId97E!HMbD#o1fn6%)p>!x_G zTky>1T|*(;nEf?1pZB{{y*20V-;cO%dVa(!v)9dmZ27OgGj!@b#nT?0d|Abv1Itdn zZQ;s@j@tYPuw21c?mJe_J;EXrxJ~&)beZv*M z<=uMvFU519s|K{?y$XA0+ZjWLJJAmdq0_hzN~*U!o_F4lqndxWUwgy5UpzM8^qrY}Zpc^UWbVW+R)-aRNRBJo)99CITR|Iu6bIU-T)eNKpt--dC~ zKbjfzi*Swx#K3bc@D&NM`RAbUSmm_B;f#elEadO7sP``x<*&Aohx1FUdb?15EIrJ$ z(wl`mC|+^I&|AI*J|jN1Jef(c@tGF*3JZOnVxgZ^7WMwaLJxk6dN)|;VHpx|Yc)2WvG^M->^xv$Kf^8fzkor-D!&bf7P0X87I>D0{vWg8zXSEg z(p%V~9J|Fh&9<0V%Psir7UQDPqTaL6@3G|k#iAb{u&DQJ3%uAuo}Vn*b(h6B+GEl0 zD=h5lLW}kevuGF3{bSj~?-unwWl_#H3w!ff=y|w>{p4AUuN4+@zHY(aXuLZ5w< z;e1$u>q+Q^SJ34DG?IVEAfudDBk{ju-4ya1j>MOmdRQHaUnK0IkJ9v@ULXA@ULPC! zS6U+ZCzyKpG7=wUmj7}j{(&Kn@|BL?uNSYB4K(E37s)@-u!pUDIEHJx!T+k!-r%p1 z{9}aO_EF~T)%l+`3}u_quI9(|0?avKl2~W^C>fvW{A<9+>r5O>3cdXjS-#C|@0*c0 zs>M8W>^|;%lmCrK{x-Ax-y-onrrutU#8b?E|4$_TgQ&NU(s3)L#3qdYuaXIu%I*D#|T z<&#MM8_jmDiNupp{{W?r60X(DNyd2NbreHX)Y}oszuqk8wMhIb%uD1~wngGs80|gv z2fh4ELqGY39oC)_+1{^AJN!AaoYzhJe<>3G%+T}s6ZP`V=hN+`{Dz&I^UMTuJPwGg z_ij`Fy(95UO*{WCvfkfN9radwm##1RoxGkg%SnnX=W;{NpU3Hp*T?JpZ<+ijMDnjN z>kUWNdxvSyA4lRpoA$Xg67Of)!$*<$5yO5a&er8AgnYa@O+CLA$-mi{hkqKW^PBVV z`xxKCPSi;GcNzR)It;i>{y4K;`yF$TiRT*Q zUD*_gZx#N0AElWO@^M{j^vmcty?;}T{>>DrIL9~Ekxf7A{ANE+F!UBYIZ6)(|JCU_ z|DRAUuaq+ky$#g)&3Smdxqkf~DW}8K+fR}BeP+A1M&bjEaiqK#iH|kMX)lT}ew}_(W*F<*Z@YEiOv8V$8~Eyvb-ckSXM#CSKa7;W z#_ZpXk@!rL|AR>UT+{yhN49IGX+NPz{=J4g$=pEUy2g+{*|6IyjRyt~8~A6&{1a3n z%b#M}+xp1zi;Q{is>}2OK7oFD-DS@6KSc6hWbof*%#%0j?8*j{|6nBlN)!J+5_h0F zF)ux&<4Xu{(3Pa8h4ZBS;#+{)CWuP%mZ{o%ompM*S-a5-zvV-kZ$zu3u#N zl}0~4W;`_eqsXN{tK>YHvrGp<#ys!>>L=dr)A4MBzsm5(Y<|7MK$@PAX7<Hcb{K_klct6u_Pl_!6C8M0+kx2f_AwSzYqF0;{bSmtR*LMbg?V!kV zTA>HgFMA@(`J-W<-<_-LhtCywc})GUisavAmh(j=9E@>iz=sO zPb@2+S2Qhuc3F|07CR-cU_m|$$S*6s1&otx@}?RkOf1Wqlb4fUSyeQxx}vPeHLviBqJ{IzD+{ZX{L0Gwg?Yu5 z<#Y2Y7M9Px5zJYYm3dbd6jWDM78M%g)kR*ERXT4D=)4KlrDcWJ)y608^$kT6nCNNz& z`^KUIZ{FoaUYFNf*AwT2PQTwR)bnbZ!x3F0VvJLV8)<2wIZ^(WwSAzpLt+ z^3uW_Z>5qquL7-y{_Eh?Q|?d_KNm|U(Z@)&t1mKEhQZiwKj>J~r}s=I>hqPdW= zs7R^u!qO_0;tDpsSSg-gS?ZaoP}&+9y-|VEixMi`-y0SV9}c+y3$>B zb@gm7`*Uv5+^Qn4Qe{-5moIEXub|3XSunSPYy}kyQN1WBv#3m}te_m)pOTp;EK#9E z6Z0#oU_3(IW=HjO9y_526$PTBqyk}qlS=0mW*5O83zcGOqg#Cw%jXs3dochY19Vhb zRy0qUn_pH|UJy}pkAcYYOe`rXxCtZN9B0{AW}5LTz;nwBF&5_K&n>FTV^U>Nem9`x z%_%kvzcjycPJu+vDZ*SaC$DsjgjE%l(f%PI$6Qa|DsOp3H+oEk1@rQX=T9%Ay`) z=utueiosZy^`b+%YI+z^ZVBWos$>G|<}irajvCIfOzX+4t2(tX0@Nia!&1-#Rq88*fzQn^ohKz? z^1{S3N7gK%axtUpE9?Bq{0eiJoA)ZLvE6kV(nLuD{S?isL7V0kafuXzWL|N43d+Wu zb1Yms@8&%8Ln##+okb`xqDJ@?H&>TdM)oqQWIt6ERhGglIJOv8fsq%p3Zp!x7tO2U za&~Nflur@!QVa8n%d0DAFT~^ltFhqB_d<{JivBxRvtqVgcZDP)Lto~V6vnCnN;f)M zVxNb##7en_wxU%Fixq7eeN3BrOx+xRG~gbzvPiaet8$OkRZj_e{#(jp7F)?N6sy!| zz0$Rj<x}vpGSKgupP>?iQ#lkEh(bK(@gq08$UT7|a5z<#x z)Ck*;UiPs%&MmE~!om&1qLVDEQg8LbTViO<90-tE_YY(6m~E2BmEMK1T5oi9#8|B; zpI;n9q6L&FqIt+XCe~a;5m@k;;|v(Rl@}G#Fs%f;=zowuhD>y?B07j35@y4~A~+e{ zog6Xe!wQZghcxhYO~&ZYnnJkvB`n13kSqQDI)p`3F0~BAQQhr((_#V@HXS;i7|}D&@pvO9!{afceX(ZE0t|@Q5>*z_V5yrJZ7!NusH?L_M`#+C@aPsp z2^Mg7%{^u4qc7$vkLtwWotr;zA!bcF2|f9^5sNJ-9S5Z7WAB*G7aO?P8M|H4Xr)pR zecFy;!kmkuVX?u4tYUj5jr8I|__}#j)w3lGv$pOBbk7Gs=+@1fTgK+cC?1nGHWOBZ zxG2?X1Q(@pI7AC8N*iri+GxwtMq8G4k=5)|bdl8rQfyJ!oU;767Ns%CLTn~k$jv0H zy0EpfDiBFl1tQ6+Ku*Q6RXztv7P=_0&c!5)Ts7r55~(P%vX}BI9LZU2kZa0sDKDt> za_1Y%I?Az~s`Ogyc59GYR9a)9oEo@5$Qx^r!0xKbtEx&c_r{OQx7Lmy;jz) z=fK0!?#qT(2><_o|L--RE12arig!H}#Q~`L^isSjk*ItMjF%0)`5H&Yuv$zt~7){`#WB=<0aofPvKtI!@^V&CC3KB=h~YSv5L7?DiodV&V=1pB06- zXXutxVS(31;a?m4jTU%Q6u#HsZ??dLQTPuAf13r~9)))r{2dm!QWvR*G1+>1?H0Hr z3jdSApJIV$MB(EN{u~Q@Run$b;IFX2YolOarmw_D(jD7?tvPqDx=qVN)fKgR-}6@}ky@K;#iwNdy2gTK)NZ;HYf z8~n`{crXgDH~8Bu@b)OY!Qk((z?Ftb{re1ly9Mru!ULK5cuBFqGotXP4E`JoyeSI* zo2efQJQ#&PVCu&LZ;!$sH1%VFJMM_ok10=z1)dRwoATsX;IpD|Q=SS7yfzB&JxSMp zqXpg+ga)$9KP_-a6#l-! zpJIV$MB(OoonwK|io!oM%CE4%Yol;e{zePDDGE2`Z??dLQMf68n+4t;g`4tsSl}7= zMe5(AYafWjpB@t@{N1Hd__GGy7=^!J;47l=eOKz`G)3XB82l@v@HY)S7=>>(aL0p@ zayFa(c@$o2v~#EN-oNR$|8uM^Pe&B4+^+li%EOW6w;At8Cq>~I_v`%0QTVJSI-U`Q zR~YYiXDrjp=Z=!UrDR^3gv-0s90~u@WX3&L!ugv{<~2*g?=nH$OCJ{GbWq-X!7t?Jo0LDd8`gAnwf)j;{`M zUo8@DyoxQ-f)eiU=EiS-NjQJQ%e>koe7_0ezEi^gE#d7F?vVN=B;mUy{tgLmlkiRn z$E)Z)SD?p!{?>ykNfQ39gxe*&Uc!?l{5A=9NH~A@(Y%I9c&iEGo+9DKR~tlXnuNbB z@n=Z*dI{Ggyi3A!B>X!G&z0~yBz%^Hhb6p3!iP$Dg@pes;R__(7`h_0R>HrM_?Jrf zW(jYU@RuZfg@pe_!kZ-gLJ40f;rB{-vxK)xc#DL;AmKp?4@&qZ2{(Tej>&Bjepuq) zDdA%!yj{ZgN_a@ZznAb13I9yOJ0;xsN|c_uyvP23k@%A&T>kAkyM!;1_>(1km4rJa zJX6AlNx1ymo+%PON#akF@ZTgnL&9H^a81G&OL&fi{~+PH5`IL&XG!=D2``cGXC=Hs z!XJ_F1rokh!fPdbi-a$g@J$llDB)L2_zDTZs+A12{%OL&Tezc1lw65b@?84_M9;hKbZ zNO+Ef|5L(qCEWZDB9muHc!R`WBHwfovB;rL2r_th@p_)2K^6_W5Xx>5XQt%RQ`;hhqGmV_&R?XlalB|J&O&yjGu zggYcWS;7ZPxI@DAn)JkB5`M14pCaK-2~U&oKS+3ngx@0JnuMPx;W-jMOu};|e7J?d!M@IOlYZ4&+`3EwHWNyw@dhV2~U=A^S7s&?2zzFCH`R&ewl=)NO*>Xr%AX=!ZReiMZz@+ zpCI8m5c1e?!~6N+kSp6U4nj!ZitBAmMHaua)rkBz&oaPnPgT3BN+Z zS4g-=!kZ*KTf$dL_!J3mmhdYjyhXxuBs?hLS4sFL312JWZ4&;8gzuE_sS@5U;nO5M zB;nH~yhFmTk?>9lzgEJPdwcBP_z5_Xnk3=562D!-XGnOmg#TH>9TIN*^pHp$CgC$B z{uBwnUc%EP{00fnknlVS*Cc$Fgy%?jzJ%vW_-qNECE*1UULxUz5?&$UMH0S1!fPeG zR>I$s@TC%7Ea8n3K1ae=NO*~aH%a)7624Nxjh_k;sm&68lf>U5;bjsYl<>I{zDdI8 zNqC!te&F2@gs59trP|@Jb2ql<+DESB!J?6M%UoJW0ZvecS)K*vEiH{iq;VHCWg5A*6P+L8O~_e*tJ83C|yI><5N8+12NK~2gB`M zxQ4z?nlo>>P0%lqjw2lu^fRR6NjD4nancE-n*{w3X>KvXje@?1G`AMvT0!4Mn#~Va z2>N!?Nu*~9`WDjMLWFY!T}hf-hj50VZzRnvLpVjyvq^KS5OxUqI?^YRwhMYH>3*aY zK~E;FlI}PPVCV$W+zN!-1${ATy87WZL60U)7e5>n^a#=?lWrFD5Ylw%!%c!doittc zaHF6Hkfuu>t`+o&r0I%>D+C=!nl5;FmY|Oe22IyHoFnK1q)#WEA?UrN>4Jw-1igne zUGK0%(4UZ|%N@20dOK;l+F?b|TS(Kz4tM;{_OB)FAl)wL*GUg1-6rUlNORH-2L=5M z>2pap3;J==be+RZf_{kfP|}TpzK1kj=y0u|?;?F3=?X#LPI?&WS%SWW^l;KSg03V@ zS2&y@=o?AX1rDbOdNyggxM7E&uOoc{X}h4Ok{(4`5%grz7n1JyP4qu$y0+nVL0?Ro zE^W9?(4$Gyl??|4J%Th{)o`<*hmfX=8g3Hw>7?nJh8qPvfHYmwaIK(EBu!T|Tp{Q< z(sV(?vjly_0h+F7I7iS2NYjN3X9#*PX}XT#6hZGHO_wq35cDUc=_-cpg5FM=u3%UZ z^cK=|0mB`?ivA~^LAqVguakC>ZWHuNq$iLL3i=t+6G=A<`f<{kq?-i&5a}$^je@?1 z^d!=?g1(FN<)kYFeLHE5^ejQ&LYgjHI7iTxq$iWk5cG|t>57F@1U;KHU9hl2(ASZs z>lL;OdMatUTwz7flS$Ln3U?e4{ZE=MR=8cz7n7!I6>bysXwr0%!a+fgAbmCIWXBb&~c>c@`Psz`Us}(61qC!96=u-eI4lx zLGL9^mnWPe=sl$A(u5s?{)9ALnXp~Z+ey=f2`hr$LYl5ixZ|+sf6}u^w+s4p()py@ z1pN}}*`$Mleui`b>1IJcPMR)BxJl3tkuDY6b4XVR`gYP>fWor` zeGBPQ(m8^zBz+_43_;&W`XDx#vg5E-UG3ky&qW?+Pl5Pi0{~>fL28tFK+xWIkd9ycCLLb6%LSJCer3QsBQ9MdL zrydD#Edt}ikHgmpB=R<08{Vn;zSinG`_&AB8}jO@x*O8_`mXk3^&HF+*RLz)CFg%y zvYA=rYZ=LECoJn~cI9GYadg7pB)AU0&_@87N1oK2NI~{}eJn zB;VKGzM6l09NHPWo(<8^?CUoqrhw7*)3New?gOFgE>o)egl_<+E;s5=KSgg$m_>HA zT`&9*%{P9@kRi%CSs%z09s?E9zj9rx`3`Bm4_()2fkFRhu_qP;G~x^>|N8Q zU#%_qPJ_3F@?T{8HfB0G77(d-w&RYnx`2%Vi=z25ofZ68p!w>ZwF0SkE;a6r#(f3v zfqJL7qm&S6mckM{qSzee=m?Dy88?dRwhC=% z$2O35jq2Kw+vD>%hlLW6%i~8(;7UHuQr+p({s0Hu=+rYpTpJn2+ zLVS9~=K}G$2%owkhzO@I5n&IB$TBm+&K3x(`2QNA^)#bE&A-gqBJTHzA*lIRIfI~G zT_0*o);A#*s{NTtpDC2?O~N>!SF8AOhjlhgg)p9RGo2OQ6Ww*^+tm8Ukmwn=Mwmab z3xPc+n97_BynWnta}^+dfjl9mDS{)N05>43Httzr*4`5|a(b(^agR7_k>Ks6p?vRj z4KB8*SluAu6Nzw%3G(;%b~Y_!Z>IMRySjczxGkgpnq-#<7%YyK?IKQMg}X0*o8U-a_ShFd|R%y_-b zzAvN9t+2{)5%8Y%%MBq>!M7}61X4od%={PV`Pcnj$TX7q?`Hl%5%~|O_BGC(Xmv{x zK0Lme&LlvqoNb`6wyOVSQ$RoK+yoktCq$ni@`&h6MD7#4i^ww3t%%e+o4_2J@QdD? zXdd(!c470Uo};+YUXR}1Vj$4Z<)FJLekSSAUk(U;stuQeWczjb$B6bHg!~r*?`ePN z3X?xk=YRhZ(cVJx|AYMdvFnof&oKF0fusC?>imz8znuI}NASC*xmtd~@K4>Gx*f~r z*fn_1@MlN^K{lFpyCEHo$_+J5OzQoBWkn@{Au~`M~%Sj471yz`H_-$4L1A$nACG>(JPX@?R!MGKhqwOe-85Rdqen1u+dNx zRpq~+e?K+@@`+J*J_iD&<%+={&F->~hmU3>rZ(^u$gai}z3_)`J8=#K=njtCuEs_{ z%<&+ox=x$ga1|n<c_$2OZ*2qRrAMd0S#0i ztzok_4epzrub`?810X1r`A^sevaNxW6gq@{|1(DI^{CV}6Nz`Cu<%tVTpr(RBJ~^I zK>O~pgMIglHsy6H&DV;CZ-&;<+SFj^9AQsqwZj1nj}hj4)($#@fw9*k2Rb$ME(8vr zh9q6dEQHA)BH7ov?m64o9{oXg7vK@M_}v@ zl(g?n6mXHwI@4gCrn6>|^+CZp{>KNPibtqs|Jbh)heFs1lfRS4n^t!z#mRy$t54Q8 z*5*Q+yx_3b@~-(>2zC3f7+Yg+WSw>2*+UnyaCF<9V$6Q(oz2uA?4``Fa+oKiL42I&2Al&}xo z1%C~=O;iu&F#AJn7kcK8t2O_%4$b!~2Wfw;ZiKD6kLF+O&@hc*4nygG4xdH^nEtry zTGutM>6k@)Kf`VR;A&>Y7RNt7x#6JNFeL#CVBK$uy8K^g)0@;y>Oq(AzqEo4z5|-y z^A=Qb*rwk7c_IeRTAM3<$896Eg0)!hk>W?Im>5JN%3FF6GZmP$jdVB^@GjobaBx9? z&DW_t=stAVqrR{Sv+*yAJN>X)e*~37+mnSF4tsoC&`;NM5DHsdN8Q)0PikRF(z2)4 zuSGsx)S$ayhbQ3upflUw%ay+V){{KGwOZX?MfLpxo~(wi)a6ei;`Z%N-JX@YUF=8F z58OId^Ize}E?7Ioe`c$@?pNDwXN21^(+T}&7ko0spYXApbHv?Sfx1Ma4=nn|U58Dj zONgT`{T(UQecT(fL__^m$>4I=y_J-izNh*TSNhMlUIme|d|x!W(hsPC2iQ{7xvyWN zQJfm6qhJNwHUGeETHO)bZQn2j3R>%`Yqe$jdZEnB^!FCODO&Lz^oodHyXFgLsaLMo zTEDnNYYktPncnJBFW=;<>pVfddkad<O0GMcpw_njj8}VuHVzoP> z)?bG{_V_Q@(i2wFu`QUZ-2PjY(5V=wGj0&}Gub~4O$)l~ zHrSX1u8A*Tj`#(WU{?Cii`(7)Y~^*H#=jv3+kTAq^T@CY4F10)H+0=LLZ1ix6CGN? z2X$|m#r*a>=hcC2m@Za=H~psM#h;48U>bU1C~6;=LZwKKHFC0jJB#7(WGh*|ZR{be zGYir@?90pa*||LlEe(u)u$eV+J-E!GB=}L;Sdd|&;RIwA>rBCc@aH@>@h9f@;uyx7 zyAw^+3aXMd-^R@JZ`437B*iST{9*8=Zr7(7*Xz{7zCW1rl^A%-?+4~i-=sD?g9rx2 zW{8V{JBEV@laI%r(Aqr#HEdqECA%T$@wK|u%q?t}FNw7>Tl#@T?_e~l%l)V_Je+3| z^%?%?4N3qeD2lpl1LdmgvUxv; z@ny5P9^(_r5*CPlN{8JD^IL%`a<2eCF*Ytx+XQKci*t?^@ja-+gQ(9-IHw)73^ za&GI`fui@s!h){b>hWPALFet;0eh_8iUXjx#GLw~ZQokGxv8H*=k<*cG3>;LzVC6Z zhC`=>ZwBDv-=tK+#UhHCN(uj2L^&|T8M^(?E_}PiqC5YtAf165v8p->1oBjya^*-S{zBJpZ*Pob`h)h_I17jWC`5xPg?bbWU zOb_4wf)z<3t_@ zpqibU@1|sm`{(P|r3Ux?BA-{%m%yQ&?nP(~2fcCFKl{gLvFKT%X#I>N6GepF*$*pQV80O$ZDAKTVjc>i`_UYS+xJ#> z!+tDoEX<#k?D6f@{I@zZ|Cr>^z&)6Mv+b_B^>A_CQ3I>M;{lJm;4`iCQ;OrZ?R5Do zlIo6jd2h+q`#u|<`nxXw(i|k$9Uh=I%%kT0iFt-Zb>G{B>I>eB6w2-QY_dbtt6t-C z)nf!~$U`xPJ*4huM`*r~K2xmo_%?=Ce!~+iq34D%VBPmgkAH{;dfydC57irb_PUW} zMD*viF5gFR5q(G5vu=2aSNq<^nQRDx9c)cf8%{>sJmV4v#^Jcu_pZnHmU>^%)w(|+ z)AxPdH@1wWUS~gVQa#Q`_Ad0ZZMX~02)SFo zJPnn!{(8=mbpz1l9{);ia`g&bG?mTVJ;T+;4#Cy+fo}b3eGn6b$G0cbha>lmq4%-Z zV+GFub^AW+9?whGQxzUxyEIi}TxDUU9_0#L-j(h9I(54{P_`b&2<^pCUp%~QnzRNeq^OE*MsXa)ce*#Kw-CRHw||xq>}Ac44(mz ztL{rXcJ^w+9ARb|X)eFlne6s2a$-@;g&kAN9YTeRoOZY<>I>L!tPQQ$jj8h@VN*)& zB47^gOH=W%djg4*yQ znil7+*xjz8CA=_e@NQ`$!^~yJ9@`A9UXg(!{wWVdN70fraM3n zLn`}u80cZ3Q$P;`jg8;*6wqm)vD?f_0}boACIfUD^x&JG;jSBHLunZpLg+EKe-iBV z5Rbhs0O<)7I_*opr{xK;^) zC8E4-gEtxF`C41UWLCZAZcwwiyy28frWLt9-m&pWIjzo3NV zFp$F?;!l8(ObL%hU0O?2$$0Lem)z1*GM;Lnv06({;dor3we%FuXALbqg=acb{&zj6 zwKy)g0Ag2Ev->n(oYvxX%&o5SI%aFW2}vj$i4OcSFep2itBU5}C-l+C2{ie%4HFzn zxDdwqMiMLl^Y@{HTq7E;LwAc;Jz}*|i)>)b)|JjHuhyTWw0OH!$JS+K(9ygP15`{G z81HFf%1|3lz~HUD<@8I164m-nu=poC#=&B|Q~qx(W)ucaq{SqBPS0U_nt#HXI0dXb zEat^2jMQ8h(0<|e{f=GGgP0dTKqR0Y0LXc93L`bWUA;G`4Xuz2%G2k@5g^3e*nmjw zw@GUKYUu8DPLeBCwf=b!9^V)KRIRQxA@JXr`^_}>_k_8>(nR668m4~5XXuUs6otWg zZRcQ4AWi?YDX?>n(Z6#bwBS($CV72wpMWROuDYYAstrRB3txnfH-yuEI=UK-(VLnE zE7rLNA{HKwkD+wuM4vE%V<0p`d!yUL;8vvRHvWd!F|XX~C@yycOVQpCe>TZcAjmZB z4gA@oIo0LWRZPurVd!a!IMaWfQml+u8$u8y{8tQ6QR8?~TfRHDHsH4ZK8lC}zc!q-c&EHR}+YoDxRNt6-TEsj#g&p&w z`i94;a>m_->4#6;17i<7hO>a@K0%rLP_XIG@I25>XV2~X#d!QK{Ibij0Ac>Z3bot^ zYYF6{Kg+QRSZ6ccU!1Pm_U${>@JroGHVUUWeYaZAZIIjlr)=MEc(URi{$1#D*aRL) zed@xgWL+or+!J7J9d1vH;*VGSDpOda<_oY=+`u~Z-Xx0 zWJ4hz9YP#iFZ>18UboRMT!DDq^TL}SXzrb?vmvuuORp-jFkuGKAaCMjM#>J_T{K6Jwe zC}PQa_F#m2nt`W_a+xndVzDjUx6R}GKJ=$g**^>4()@$U4vHcBF2*z-lfmh}I21-I z^|}uZ03<=XsUih_|Dm1x{)#?1NArD>8r0>}HliyrEd|jhYm;2*mnSX$PN@|=H1O{o zD6&UB^L!rr^k2lbddYV!>}j6qH*|R&p)+X9u#!`>Iy~fBvYx3@U;8K8DGbMLf23pv zO7IA~Dj80fExU9-hbWxQD*_3lG+%;q-+)Hlem8o~?H}XJ_I(RIXAeJw z%}nU7onr8Q=)&s;B0%IRSc33q|C*Vnb2Xmpy zPseV=<2&-d^T1j}d*FO|h94<*`4ZsB<9Kx3G^bs?vrQD(6XtwHNF z?kG7=bbW|6j4QCK0e%HMyWl&fB)=}KN;fWcHaW9kG%kMwXJ7jMS^nxI*c%LhvtG9U zInGdQX_7dAITgbJOGPLTmDL3c(O4vnWV$`{>o&@>aRUqiM=fgoKI+t;*tcV_;=jZx z&XrjhTInpWW({2=EDg&CY3!x02gMWt@PaA7bH8*{}%^# z*RY__M_YONn;LA`j*09?wAE;65(Gb1`>#`sQwQ_$;_7jc*o$jjo72 z^dq!N8(=$e?m?6Art<|sJ9%&)$-8*8jP43wjO;FdMpB@{7G49-O7nO3*_~osjvaSD zcY8RB4c!kTLmm#Scw{@C+;0|9AhTAp0cP!LrnFVnTIQ8I3d;+sFe4Znp8OhY@$lEV zxZx@G-C_@?!7^aZZ+$;l36Fs9d%UX6$|5Rx4S$9MR`f~y#<;42{IX)-5hIROf}?a(@k^=x`QTq8{Q|0Hc|AC^-#E%RsDD8 z4WZXyH|*JO(X*y$uC#7~mFz9UM~Zz!es^c`&-~$!reMCBkhEcfT?yZW4umgK+}Yz_ zhxeg&X?;g0e6b&$0LKUpl=^CLUC-K2f1rE)=Zml%Fg3S7BN_7!-*8i| znS8x?Da!4~!B9zx2hSul-y_Z-t<$H!A0?iGVKq_f??4{+p`9M&X##`Ce?zhdYV|Kp z$!_@6gVB}2H?4+gzC}(=txpr&z#kFsvSs^A!Tkr#Ujy#_9$%p|$Kxx*P6`{QT(y4h zSuFc=4=P=Xvfcg}8Se9Eq-Fb4v;7NkDCJ7YK7XOZc4<2Ni#hG24RxHJdd3Ip2 zjW0PStM!XTQ6GDJ%fy>-9={9T@(9g86%|7RWzGsb9pVx>&AC9WPZivvQMIB`r5T>{ zOEC{G9HxmH`+NNPDZ=xi*!qiMp1^$6_Jnv_jIC(ID*-4+^OxywPl}R!U*KVSoX5XR zyk_R{KP$ARLC6r^fWXeghWi@hwZZ%JZU~%tJFPdvJbtL%-P#^U4Ro@g z6s`4}xNO@N%{Kbe>9T!$+0>xO5Exm{+8S9~JkNZP zqk>%tA8gEXKrtnjIh%^rAA*wuBLf7ok;fBoinuy#6Vq3E0we#!w8?=>8hEEf=&Ven z;El;9k8h255!LP6P4mLKJI%RiN+3b-visXPg|hjmZl)7Y_KoMM*<1tXU@>$DrgZ(} zQthYKeG#vYLIECUbIlkkq=nUNVl{0ZECo9`nY5Gjw4c-&$%xE2gCD1ZLdboaUABo# zJM~A*8gjNUXPY~a@TVz(GY4ydz88y9Jhpw=fq^4Dwzb*mKf)izoW}*a8N+T1L=|zH z_ZD%F^QQl#+8yes_8L@UKc97qj}fSNI0Ejuc=UqZsjY(r+rD($_G-4nC>{JM>ZlHp zaU3&>kBgBBWzN7ocdJFlOx3Prs-uE6Xa9s~pP#bS8RFwakTZJo<3yB~yE%4t(W>5J zCP%BXeTP_x9p$y@<(NI|w&hp;wZUb{*0I(I=ftzjFfxaVtir0wM!k=?!g4R z;($x-pN#?YtUknP*gb22u>T)WNOs`1E}9kXa;2;8TMU9w&2Y*XgjVd;C;;P(qOC-e zF&S?GJmVt7Q_*}JhkuKv8m&029@r* zt~l>l)Sae|>Z~~p{bG-2=ftsJZ2X90zqA`B7Gc*gjwJNyCOzB9%r<~I`txG|v+c3S zmW*sW^=#)d+Ysg$%#R_=_En5*!kX7X$>6dNL;jGS|03oe&8(^X7|s0Oz!q2pq$PJ+ zw?!aZXU!>Kv7d|&$Vg$uJ$DcC=&ge?l6A|Ykb?V|q5ieZonmr#=-kJQ?{6VYeE58x zP3ZePVTW4$OlOF8xxy1)1`|a8VXp5B!$U`UV14LtY??G1=h<oy;!5U5OXPI*<5%!rv#jh zTu(8Ugszr3Yau(!N#pXE?c2lkvYD-IMnZ9x`om_Hh@OOFfmMi)MS@ob5|&{h{yR7n zirkW=4#SC50**e`djbh!Y10Ci{7t0ytW;Pfjq^v2ndRkJr?La{yI^nj>#@uFCLY#w zR&Q)8YQ_+AIBX44D74c|0ss;LACx%u)5(ttM&ZK1Y&XCEE;(Vq#65{ zzd@RFNnQ+L4%Z~ZmZxKinsGAgJwORYv+@t!INPPuVEYA?x#6tXwt#h*I_iQn7BLva z=`MBD$2F%SR?QMP*?iAIGXh2Beh|9=Od{hC!B4MoB3m2^XvM4zX|gzKXT&pmCqFJ` z86U+c1MODpd1}jCoF&d$$>N5R93u29%9|_76Kl`sY?Q81G>Ao_QDn!cG+IW@mz_gPLGuHxTV==A!yX{1G`$re5SZkE873_we^ ziIzZ=Zhsgpd0#e1xM8|Ej=jdrcrh{_78x-~5^L6rEc}k8h;YgYh)WjThyR8>1gzRuoI2ZHHL+C?dCe@csUU1LrZXAg*X=95i>7 zt7tRxVZtzXgJOy18Y>oZv0yey+qE@9186)qh5AYfo#I3>K`fW%_V77Tjj@FkekvAJ zot?{f_d1IG-Yw`Virqw~m%c6xD@DCC1K$i4OCWQ%$(uJ@yC-nw2rPxEOmAoUPHeHb z#kREyx9~hMaddgB;mz8-lY~#pQHEkSqgc9v9+YC+=jQ(d$cD^%y6?Y9591U)c79Pa z+l`&ozFUM}*IkKT1Gh}91+&{|_0Gjf=syc7#>r`B=7FPi5f9>l3pY5&X2u4`dp?w4=b05TQ4^5aW&~6yud$hBrsQu5W?7SXR zxJbP-5zlMb)j^8Xtee8*K*G7%fteR5u!GV1sv~+)^uiAI0v?!^i2lzI{ePCxzbMP- zzhgV!bG$?~b|NbD&e6*rkB&j7u=r!kR*b}BEN&y-NMo*J67E0(%8K6?FwaMf&cZ&S zvwNSAB(@0XIvg{2pd$DH@PFwYqwCCl!av32%Z&i1&apH7Hifh47c8ZT^XD$kpWmp< zzk_+x7#ws7N<8>lY!h@zy=QRl)Wq2nr=wx|$(3>JXWP}YLBJ6oHV7}$vA|S^gDb7| z+c=NyE#2j}VOrsK+lQy>qDR+==?N!F&$Abk;pO6pirWGB{o-VcbDh|q`fw@@XPpZK zR=$t)eE`gio<3#-B&>1PQd;gPaHh4BB2EsB5ywv56I5WJF;QU=;vBnQv;Bahpw}=z z{T-Q6QeQE7iMf#qq{+Yk>i-yFCY~jYy_cn*2rC?+-Z>wI)8)X9RI~k#5=1$4=jpPPN}O{oIAJ2f)gCYL z=Evq0(ot`8WYQqO_#`P)-$b;NTW?D9J7w(_2SV>!+9UMi34&7>n4;=JL*N#P>yZd9 zim9`q-m@AdzE$88P6yw*<9h}0I~sA$BP`O3EhNVWt*l)P5{{WBn$=F>TGQ`XVfY;* zFmT{1bB*ofh{0~Mkon?Cy7*CQKLmL3PxiBY68mbo)rBdgtG%4pa?G zc<`w(Ki4yNqv3W($Kg^!jP0%i7xer^0h<-=0xr?-Ig$O&eGr_lsD2l7rI=38@0bl_f0O;rsq%tU6wi+D;sp6F zKYsUMp5aL!S2I4*<^(0)hQMr@0-Ey>_gQqk=!en=)Wm(6lh4F4-}YAzsQv$da3M^aYyEkFDXS%yhKNJUT#|Y^V=nuEE|w-ygHx=AH@ZsZ2jAzD#VS zcW>_WGv?f`@N_+MJrpfWx%+H`r-#V=TvWQTIaFsHfZjOkT(@^}8E&VdvDKXcCl6B}BK?7gBU*7- zn|ma@DUJDE`MNFg%oD|D!oDQ? zjkJ$yu)sbf`;F@VS}=%o?CH_rXYfOq#;@Y7*>3wbPCoQQcl0CQutlP7-~7d)TG%;e zM|@=w4^uH4;g`JdZ6`fH)9KTg>B%C!G9sPZPBWdeof1AFB7KFF&RJ3kzxIV(ev_2$ z5a~BXq_=ga*NeS^U>PV_e)x*N)51cF)nV^&1})B1hpi8vhSxXg%HjLdt3;c40KS*o z|5JECus8hG4?KII`%AX3nEaV~_dxs*1!;Z^+ZrB9O^K`f_qZaS$A|DUmsC&_CBnsc zhZN7i;$z}`#m|iM+vH}vLgG(}*YVIb&3Jq9=I8jHf(veBeI0(^Pz#`^z7X>k&=!=Kj69>4p|!6^HaH?RxAn}iE(uaPqok9L_J z`te!3t<{;R-pTzOzU5M|=oKvaKXiR7#u2_h`RQO?YWyk`ihk(@z5u6-loeQDg9K(# z>hc=cQ>K5=foq50Ehv2P>k|~YF>yCYN}qZ#wJS6P>M3s2h4qj9>g~bGz9&sOFm~0) zpzkkk+?e>hktuu{$^`u=XkOvoq+R$THs3X=9`u?6Aa^v-+^(Ore~Cj@?uPKyh?9zH zY*b$mT6`32h*F`odUO?{R0*Hbw;+ypR6?tsr{2fDf};$OuftH3P{-4JRi-PH`wSbW zYb}fym@p}guit`iejOC83FSgFe6y?%1VmDAG|fobnE2T>y7Zxo45n{Hen{QT@|wwF z7c4Fx-un-N3*UI8_QYF}{Mv|r?EK9r8DD*KiH_WuxY)>9lx1cmcO_d_03Uj62QuhIX5u`H{tdog=s zFl9~6IuhDVf%#@gy^}*pt)DUhy-`r_97!1pmI+_X^#*fusAhoYbfzGlgE*ohu1RtJ zk}q+-z%UDOzDtvaJKoszpqgAn-M%f5xT9gShW@Vr;PL&W9eQ6~eja`$6?_@$qZ>2S zR}ZPnPXW-d*`sP7qHQ1YbTHcx-%aryJ>qlbQ0wn@QT!)__@06_y7;RpzQ?!9Spgm) zI__pOW+84iBUg$qFynXyL_-{E=iy-qq8=a4`Q4x43yW-HEf9CXKDWNJPIe#q5PD7# z8PrGDW~#5QRhMgm?sBVI5HG5~#iK)L-Ry?WQ0_|64R|GwJ;BLNtzVzPrYtjh;t|ml zy(2KflEuUcKC>ALv}iV?6Sx^qHgGnd-`dTBHnH>0;K)ltnoD*6*zl?5``lCTAs<&b z_{xg|3E6n~h}PK=ZbB^E_pv4#Bi<)#2Lf9YX7=d?)9;T(~9pZqaM6Graw%__);6%nZf8g)NwfUN3#z7=LyyNe}RKbEuNw`+<{rL zr+Bz1Ml0}D=nZJTC>}?=f9JS@y)@j8yb<&0&VL#$z?mU_q>PorPg;dzd=Ku=@+m@K z?89EH%>Kmt#O?XhL2W6sa%&;oxWCj?UK3s5%n>h;E!$6eRn z8CxDy>+xTt|EdOlkHF&_?HRr{8x?EAKU}hw<+tvQM}ccSrZ zY{MxSsBgl5S3=ImdS)|fp#EO`#JQf-yCsoN9pN#E;MFUOl1zxQ&hlRkj+(3buHQ`65T>5X; zsP*k51rX=jn2|sWQ|tHWNIZ}v9oe8G2|&aj*iq}7bR-doUFWF>0%{zyWVAsY3oHnvEf^nYo&|;j<=&Tbq zCg8OqES`bvF0m$VZ0O5&V9xLa0%>?KRrkdS9&GCB#R9`GEE;je!A^;n#@3O~;l z@BK4A6TB1gndm(qpS`>%yEdY5QB(NOQz8%irx zs#as;g4TuFM5!VMk|5XXgMPmSYg@In)vB#lZCwCS!y>^QtqU#{#O;Zw;8MW__`g4A zp64#vgns+`{`>p?^MX6`%yQ<;nKNh3oY}}%N3S4qET{g1$jMwU6L@dswz$Bn9w{$n zG+tlpjdmCPw6{tl&|l1J9R>NSn^!@9>w*1uzUAxT+x+6}Z6mCPy#|YI5|F z&ykBdMntXlCPys!9IfPYq>|533Mo?YZsX0h-j6m{+ofdft%CwmCA`^HMyfZqsjc{c zLuf`SE(XkrxOgXS)tYK(?ZhW4QYorBwl>#BFAgfLh=zA(hqM)K)fLZ zDWmcFnD^kJ$oiP)?T=GS$90wEYJ=eKp)pKAV$JVtsAiMMqW+IZ9wMly={IQHl0)uX8ddUCWyszJP2-Timg8lUyyE&}g{dXh8V zo`h39SLK~KI@zas>5+Y^fz`r&Lr#TgRRRhbJCH(#y^Ib~{g4J2?@EinbbOrp^;>o{iEj@{sbW<3y4Tw$)RkBGHpM?ss%_&+WZh$XX;VoereFgf3@DUtC4dx!`QI85;!MP zPW9A<F8yWGyi6 z9S^@giB8&Ib8ZfoTdH80Zcxev4sY$1#MSU ztez*Hbo}XEsiG)@0utUu17hBo{7gdwC6W9NcW|;1gGNmxr>nhVQGgQW@YI|Gs*CcJCQDJa9-fQqNPjkM52 z@)Qmt-6){6l=YL<8ypuVyc2e)1C=*<-@X)6BmMV2aoy7Cs^2)r ziK1A-yU&9K1OYMx`BpBSE;%<24vQtP{h`WAUMq%jOy)?E{BY@X@e_2M-ilizqD>bg z8STVNkTcCl*3L6G86(w3nUZ+3qv}y`E+D65Y8HdayZEsayK48Qt z6-!(D<2%S||JDZB@^JVkHa}i}#;F%waBgG#f%DEd_3ZOc9dki^?u88#&baXWQ)5;{ z{Gl_>JNsu73E^0B&9IJGa`tclCz3ZDj01H6lSsB|u{n{vw+4qIz@Zi&PASn#TN8Yo zA&CMhDrgmhTs==zKxPd4@XVT|C$l9P4#EMd#6P)lg1Wc2sw5F?Y3qUb&Y-JkV;D8L zoPl_LHciypjvxn6nBb7mF#=!+8dH7Y8B1G7;5$v&I>gSACc4%V=UuZd#hlo{y^t@Y3s>+pH@9r^aFPMK@s4LNeySj=bhi+NT7RS90}s{ zLuSY##mQ91x=-t=)_qzt-A5gb5(yqNdQt=6m$sh5M+5Th4rx5x*ObO}y<`hLi~6>n zOcg-=RM!tl$;Vh6U=bv8J6L>h3ZV5D+e6!jDB}E|oqc+}p~he)(IRPZM+-RbN;8)guTq#|9)ptVj$ zc>pxO?X4<6wO!hJB|cR;-b{ys64moWfq&?Npnc*G#)9?59+3i|k7^3ZO`D_Y`VH<%(M z<|=vehBkBVU2e`DE0kw`*ib@ll|quOt8vs`cy9$9qlBgH6RhGzE zZ89)EFD<_2JMneg1+n>!+2V`QL@jm?c+q0*trF75nGm@TAD!SX%AwTz`BLG0K~icG zp+@lsI;8i~q)JKvVt*iM!I-|;%6pcTSmVtA{oyT3!*bp$NMyA&(l3_|f zDHTwBA7}F9Rlb+DuHySNP}_emCr};=rDyenP6obiV=n{Ai%@g+Dl*yF^#&dR-P17T z7tjPbVy?z_pf$|w;=Qw_C!-~lDxfSII$MkI(TfJ-OkG$&Qp&ialrKQSKR`>m$nY%`!q>j!|vXlhSSU@OuI_b z<1UDIW=;(y11ZqS&nP~M%mW6<^Xuei0l~+G@^d>r8bEW@ex%J6$5gd-Ai3b)AMGoc zj3+!W)f#p12oi7{YC%xC!*9pOfzBL=8TcWJ%E(dU(>o3}aHwY9D14YMYjCD6JXkm+ zXD9do@(*wvd506ev~?WcjM8`194M4#A9WCvF$owj6IS3>L2z{+zQ60)KsDd$4e3=D8E0f6Eo{!k!gkBdJDCmS~cFvzSXKAcppiHGy7 z4OH|-5<+gi+FJ#~G2vnO#DwvAp_r|nA4o_hxW6W~`t=QZ@sS3aP;ONDZ@wsFyuO&; zLasW+CtD}t4C8M9dneiV9Zfixa!3c6XYirkaSg83K5Uc(8ye=I$R!`80?dh=SX3^V z;xP z0I~z?&%HVg=!`!b{OJISc?(Lbq%V4fm!<(}t>>B$P%e}U(@@IavFwF4WV0&v6_nz; z=MDuOABaJZ}X_GSN`A+*|dT_sLcLbGc4?d``HrGF9`doOLv3P zZ5M<+sC1;?Gs*QNk=JBPzp7Mg^4dXZYwg%WO=%`v>+;%xsdf6=if5u%-%q>LCf8sE z$Y;~{9l&HE_0E@Shdrj*9LpZt9OF&inKSGC9>VmkKaABvhx1J9;y`F&S%`Tm8&IBB zAjaot%O9PO+o+~HUtgI4KkwHthTlj7GUW6A4Lf#*r+H`oy8qo!t7P}}x&hQXBhwYV z|8pT&$-5zkBYJB+t0IYdxB9F@1Y@mTud>Y+wBJ7xT}!1p4vVPGc1Ciqo)Zmb%&r}_Cb{lc>o?bURrxg)ODFGM%g&YS z;`xs!hJAolKIRR&S1{w=IOiq(*9viISuki$Pp|q-_T+) zVRqIlI^&?-sD3;UDuuX_qS3+Uoh(u zb3>0Y%{|7P-DAvmdyFaXG3Fa#jL{%^^-?OPLmeZvt-gxO>9h-urDRNA56HFqwgH1}UG_H`8`m6K7DH=YINqu#Z15yfe9a8ELlTw2r+`;`Q zFyND`RRDYr5^{5wkY98Onc5}ff-WIH%7jo5#rek)qRTbQqG^r* z-8HGgZ|%Q3Ew$&L=L}_23D0(ItA?v=_&q8FoX$?4$=rNE!*bq~-F&tq&us_XnXymX z0T&mFkGR;UbAk;Fl1lK_3mVAXeiz2%Qdon34Bn5{Xv+fL=*$F$4zbTf9Z8r-v=oL_ zHnLxDTbg3tEIYc8Abh;y5mI&9VNew$Rwfo{`*9$Ts~RsF#Kk;=YrXReYP~ZDO6_W+ z9PK1qAs1j{NuNNs(W!_ENNf+b@?p39$tmFmU-zZF4 z?3GLH>l>`xkVRDMc(*^~+RbTjrZ1tFy+K{h;Z<7caZ*I2;%TY9NdQquZZ(&ShSfq7 z{pE-@X;hmD3I3N=pMWnG{IAl{VwK8Uj#n9BG6#{_FBU)*A+_vl1OvS`zWwJkYIwUo zd93YA&4V=rhgM&Q%GE>)yr1Bu7SxeTm##0}z$fTb`GXN!C}bB5C}bC%OcC2y$Q zHG+wO!tgu}m;p67RJhXrgZim8 zVb@-YSYQ@rJxo^u}gyd2P(hjcDGx2 zfaz{M0;oy;)Bm=^a35h9GRq~CU9DH+(qn#u90F_ruB1nB>M_=W?>1Sj->c1{?OuYF z+?1~KMM?vOrl>5h_|Tj(hW1!S3~^~?Om}76oL$DEOMwNK3{IC)6qGX9Y7%+o=p5DFH9eSAMU2hwM^5y~NdJ zWV)1^pp*oqX#YL;1_E03oyb*l=+UpEVQI0&Ys~*BdZHT{K8|kB*Qa2CbrRg zNzXMwL3+~8vI8Hab*CQu9|mdfa%tIjnn}xUXo@AR+wkY_8>H1(16(#qXVTteLm6qg zNk};42WcgrNz0XjnY6dthCtFXd@1eoB0czO@FOisUMB55HnfuV9+&pEAg$y*X<@WX z+66WylXihidl_kUV5LpKHT+}}a|e{Wl9_Ws+q)UMKZfKyD=bx@1_`C%lJ|2E)gpY1 z5pF-^+x%^aeprK`zaQx}_5YMTGd2i@BjHQ*>YhhJu45EHhCye&@Rv%iF%ov%0U$dU zr`K)ZuCFm1B)mxfy>^$q#VdU9mZ9b;o*Q_|KLDe1`XjDZ-%3=!9Mi=)yblf^!QV5) zJk3k$=zP;H=Q*5n;L^2lY`)5#yM~`cr!rOTpr5BtM1Vl+ov6+`BD4+d>D6vKOIkU7&c{V_=#al ztEaY!R@%F<(C-_E4jYWa7uI^G6|m6~sI#sU)C4!7G{3o_cGx>iu@b2rYm?jw`WGcm z4BJ#a)wVxYFI>xZklP%D&&b_zCg%p{0za?gJGuZKMbBBFg3})C#B>%Y&iKkwQSn&x z>L*Apikd0P`(A#07*8s`j=5>zy};3vg&%1H*D+qhp_reB|E-#JaQ)#*34>dnOjKZY zY5|Vz=6OMZW&^n0`IyHf@JNAfHDjlk-2K_d zf6_R83_TNYmjX^_16KOUpAmrjpLkm+5Wi_6RcF z+foju;Looix$4}0fvfxez@)eNhiAh)uSb~a-gc;iIbJZ23}F5&fcXk8ir1_hnCJHb zGf?ZTe|hBz!HfkkcMD)%VK9rUa$sK23(R2JbM?=Ro>hW*XaMu^^IhE!5^S&hy~DEW zKCwrb=?VAY4(4a%OSk*Q0nC+hy~68qVE(ihm_gm&k)-m;AJIVWy|5M>v>s1(Orw#!Ht5FyD~t zRbCIwpbs_l2vDnz)??wtHR^v}`EBG&({t|t=GD&aG(~Uh5w3ru1NJ>3SQH@m^0}_k zM>=43;xW_FFX|cC_Z+ZY1niIim=^&1r*k_=jf;B(hQyjSk{-U%dU5#!_|vtm2w?s$ zgqb5XCiMcdazDYm&B44?9EqLITIH>uxJuUwrdQmbbQ!7f^BzH_rN$2&%rgZu>^c7x z!2ApssqxoCvteG+Bh0ka$agT0$%a`em|pprzZn|L2p15*32Q8a1c7pOH1-Hjh!zKB zUuI<&9+Fe`rM;9L^srXf+m9k&n(hnFaWoocFpF0ol3kz4y}%5l%K;AN-QwKP7<66$ z^Le>m`OF-cm-PrUEnWU$y}kTG!7L!Tr1j2%mD+dFl>v?P;>&EpbP!#p#DGK}ooz)P zp{!Cul=U^j5~=dNQ$beEv`)0F_%d1VS5}hmW>^=lD9@(ElwPn7sJpkr`YrOMsaqew zeB98AwB*3Nycd{({QA4elk!IOlyEGJ1~4ziMShLQf!Wj}%(VQv+`-&mFvAvmV1kkD z&FexAJj@U-|2qM#+(__lG|v5TD-+(n3lFBVU8UrZ>J#T`{UB?IpV}i1eqUGi6XHO2 z7g_Th5dgczaHy=KfIxOm>k&}4?7Y)@cloW^FxT)nuMj*gL@-CMY3>oO|6>O%C19a& zzcB#TKLnN|np%1WR_uUH$;Rw^0kC;;z2XZG%I31x9$}?r(n84qulz*8+>7L@<;F8z zZO;HEGU=N+FsJtjGcA+Ob1?VIhIv~6b9;kX_}GEjcwW&9%%C^y49xj#??fRj{{jKf z@r!>r1H}D{oyvRl5qN9@;(MZnyHUa?M2Fmy-uf~Ag-}oSJ|=_Z(^yp&7m&jwHq2v<~qju zT{uUooOdZLdFJ58qwyzeTi?WaPkE|rQpKx*iTYji7Et|uQta0ONlzNre^c2sQ_*FP z98v(9qcBzv<3-e zLL)2pH7NHoc4geG&j@Imf+p1NHwHA(o3Rt4r>?-u1SevP%%7%D7$ zmR-A`W!<|dQHR&(SUh(r$px#yxcoE!$Si*y{t&B)S>Y41{4=urcV(q-%L<>H$O7tpVXnFb?T;Im8sY^xzEX&xKx!;P-4fKi1fzyWOZC=eo_Pk>M1A9w} z%(3Jb@#OQ>$){o-r)m}8Ehv4{BA%&9e&k<(q^U{WC1;&`gi=hPeX<#Kj0~Q{}3QnFCdyB5cOh7auE?RE>-eKf{qlrLLz8 zTl=j6P#&YugAOTH6^xvYX4S{LosV1!#9y@$&AfUt(JMb0AhH{;qgEL4OT?@1k-bI> zAEL6qBZ4#yc{MOFEj-I;tW6U}#%bM?aX+N=d>}#g^3O@H>Yh_4a=ha|i<{2h+n-S#u=+t!cT}*V?2tmU=N35_KMbv{1 z;|0cV{(M4`J`J;h;ILt;PhFhL$J}qjx%Ws-YOgi@s~0!`g_{^|gYA{CLB%?l%E+!I zoezvEk*jP(4w&%-s6Y)!`n;jT!yc_%2gYACwusFXY}IJ7meHn=GO=xyV_PK=_WOaW zmC(Gv(&cfR2T^zD(>oe2hxd2QF7D*+iT?9?h-V$aD?ioJzvJI~ipV3(4hORkDQSMj z!q*Z#pGl+I`M@B{G|Tdi|1R!45hS@Ri@S3pZ(Wx@XZ0&?~zG2(yRDLotVBqd~YrfVV*|_cQE*Cq4HQX_9UjzKHJ@$c@!FoJe zjK5Y?w+?W7=@aBMS))FZD!=}+p1PcdF<{6{$7R8};JcnuvACSpB21`J3I}5ivHu{&I2jzE||#O6#W&8x^8s zp3Yy~usxd2+avPxoalRx7SFlb6J11307MB_k`Urlm<(aEHQkWxo>rak1JgI`S( z;2f)8DzmMrGsH@bF;2!m1HW+VQmw(=Rm(7^K65kmSs4ALD%*X1c1+i2Nay;begxVe zrS=c&^YH%E=OfkyREM!dg!QQlFlI?eZ4j$ptgIU7lyZC!D}M~XkkhWEWs3K1H)gRW z=YD^h{O8u>YyF)i78x9>1{l?9Yifq;H$yu-XI!G8~`;|!Eyrc+b;iaXbmeR>2WQjX+Pr>eBb(MW< zgm!dd1C#-B-M#pSYK!9m(Ixxcv*|L1H|y?X(cmr+t{-;(4Xe{qIs_tE-K=N%=bT8b zTqs!9ap6O>6?Q>QMwLtzp`8^;dhk`2%A>Uh@da52RI^njg>KGOD>k zXO)&1fN@z=qa+J-h3dqvw09+2_(cg`JIcFt#QXlKu3L00vZ_W_@8kOR1U2wJ8aipV zCgN~Ucf%#)wZ@2%NLssbl5yoboQ6?Y!wJY5CS`1e+{CVo>p;z4M_6VkB|-_0B`{QZ zh6I@pB}^S~0WBWr6D$2i$iMlehFke2!)>L%oe~1%B3$iN$7sl(fAJ4h`0XY`H6u07 zp-)L%YM;aeTzY=t=KmThxA=j6bbL1X@5b%-_vS^*7ILX>ziB*U$3uzR_nT&`SQQH| zdm9io)U`!t-b*XBdudJOj6W+~|8so_{bbtIaEUwBN(oYH1t-@ zDb-yi%jd|?pIAaJAW|X%sc%&<3(7cZG%-&eQYhvHOw$(>(={nkBfd_nr9+V9EB&Xf z9dnuJ&p+sfiTV?$4CmuwS!gJbdOuan0SX#P^{3rIO{xpZNyM*L?9?UF#Ils!<|6`P z1lsNhtNRz2>;GP+0p#@3@v6ydtWn~QZ2~OrIM*G{#j-)U!&HwF73h`UYy@5FpD`}1 zo10+#bG#5<>pw_%8tTgKpps~XC4TuK32|w?E2!ms_hI8;0YC(7B5qbM_$dwi@nS^i z;FveAbYPEjBCmWmu=H00l|f}VgU(3hD)8?T+~y?(i_??X0=0Yci#`Ee$?{(l z`l-1=O;c=>C1gf#ZiXUttkOJjRkBTCOWl^6ok7^8; z&oZl=rZOYcSR=zx8x3w;>4a>}ttx1W9lr-&Q zghb#Ki>c5o784O*u{IpXV*h@gl5ldQ*&1GQT==i?(kg1RHN5oL7~`b^NE7nX30ZbG z4Og0K7hrjdC!ZM2(e?TRv^7KnRCVu@y)@TSzzVWhQ*NzE>kPYXk4VP!Ny;B#)ciTPVvTip=Z2#yvUUO+*n+t*chqus#Bt< z6Pqr-n@zc#%ygBAKc$hZ&|heW6-6fs(jTCf?$CG24ic4Fwv`IhXC0IvcEB&x}*U zXvmj!VYi=XNy$7Z97`uy2sE&cNrtgm1M&E+Z;Dx^s|*_!bIf&35pv{sab#JB6J0}V zddz&~9sg|z&iGsaPFejt$2ea`ocOCGo_wkn`M|WQPC@Xes#06O7i)R8@tk$ASL5}l z1~y}XFS#mRrcbW=El3@Rx6Jrb0JZnHVL)|id%948g$e~U_D4xNfL<`r0tdRlkgtbZ zpwu?R-R-uP1{O_x_blGE4p7GFAb-sv zEN0y$Mx06ksZfW&D^V4MP7b`V=!BqW;5|3!8m^OwQL9s%;`=Vsat-v-iqbP0MdoC`kD>fJxctryQU?6k>Svd#AjJt(7k)y zdC!2oGF?u>f4lE6qB7Z9QWRqa!(cWHR~B)iX6m9(wcTW_4yFW*stH86-%J-JYmmn8 zcQl_X=(A;{>AlZx~2N6y;%lH6`vq2+Z1SlDfgGQ&x!bvsm~?BS$` z-cb&EVe|j*^^OVPmg%at^0n6g+Gy(?Rm2H(_)G&q;N9Xr;|3GgJ2aRCokJz|);T7Z zmNJ;EqTKXg;;gvY{o_iax3+)KM4kIb&>yZ5G&%>?qW`qck<%H1=6RsTD5(tNb;`CC^UA^0IfFo;gCBpS@vJ0lz^I>Oyc;s!FEifZBn;A)WW4IF3e{8s zb|}NId8Gkq2>O0K`PuM`QHW0;+yNYpUA53WIp9uiBPDr?MK z4Jol`4KJMTpUO|vugjQWifD$3G>1~)ZOC{hWxU#m5G1%Jc-80yr@_+fjNZDD-jOK7dS|~WB%! zXDvT!Ce{1Qd6(@NBU2nz^lv}hs9YjDqc&XF2~+0QcSbdeuJxZ_XaL)DiPDup=TnhD z_fQR?gzBN%34r0RuZL`!Q2WU=QS8`_w9Om(H2lDJ zNzj;rC@5#0e#XQz@!y31;!~Hll>QOVh|Fc+(uHp!$aG>gD}=h0?|HicmYW+p9>MJf zR>QvlYt7^U&>06=cHz_sm79A(Wld!|yVYbXvxg0%8me*U6;Lx8sF)`7_d}XywN5nz z+=|x8JC4@*Nkz~)qL^A|0QSa9J3h6qJ`I)DGB&%Jt46u_)B{cz(Tyu<@-)%2+vY{J zz&*m#@-%F5o+k37snu|5$N>~NH~stpg^L+_YWX!sqyb#~F9A@WQ%}$|-qq6es$i$p z=js*rF?4h_9ZH{$<(dwev;`*ZEioNRz$nB2*mS7AY5Ty{1`uq9++eYwd(&ZHdMZTK zAiV^cWUo3Zd{)9wqv>5UBWv5CdAMXe>MT`p-tPMyi^;MZF|Xk2SaIcj3Ys(;;-qscrw&eY$7$P z)Ri#UKL`NYL;DdMnFH9@0NXY!*v7JzehFDrmaj750tr3;*h6y`b;@-VCZJ0?!YgWZlyQT7D^?pE42rWC^92|Q<=n{2j z?d*`PkUcoK)!%cAxdF3I25s9ST80CbuqGIOp0!t`dyyZr@5X2-0f`LRZ zdzcrhU*4p6NTPH(^F%+PaS+a3b3iq(*Rj8TN*R}E+)O$EzHF3dS59Pm)^%CM=LIni zxaU6>t9axx-m-Hv_9q>*dGnf6bW_P!kX%OSr~5mS*NbU-Ao*Iqb)+LXM~OCf%wQ=N zwh?P&vCVOG&?0TG>3OF|QagW7p+Ntipy*0NmFdC^X|u-^C4-~?c%bbK;ia)9MJMGh zQ^ibFpy>=Ol`1qak-8inbvvNp(a&P3L!G(5{%f|3rKQ)w)#w6wPM|R5?oFvpc5tDL!_F&S{^Oz4=>vbp z2qS(SCSM_tA8plWi9K6Ysc12HynrVRyvRxYLVx=UOImq4&eFwIyx5` zo38X*_jA;HUoJ}^n8_cVvU_~tJAI5)^Tj;et<{FiU|?L7pUB_9mUm>v)FtXbS=~5y zk?~~pQ|QD_Y%2l z^p1~>l)J+|%^RMMw(2TH$5iwT*XKqvD`Xur)u5>k==kN-lb7NNWOG^M{`@T3J=GnL z!dPFYYtFB6Wb1ECz0x1EuOr)ixb)XNN*1Mfg*!U)*Z5-e?*gHd>{mLkM0vCHxV5@r z9iEe*RU&n0RVh6EliL*ofdO09G1g(Y(mLm+;gsLJq>e~RgGp6pvV%32(o^6hm*`j4 zWg05mN9Q%3|C962Y#-h4f{S?|==^MCMsE{y?+1|^3Kb0djJJS*#y#?OYdlo?FTT?p z_FNBCde7SC9wUX@3<>Gl2{aah^Z#H_R{A@DIxVNuS=ZssJr)!+>DqlV`F;}QdxbEB zkUJ@M3OU1rL4nQl0gGSh??DtjMNQ&5r+gK(ceM3FjXz#QPi>{^^FpWkMATTIe)|ES z88l3`uJlRJVZIaxnBZ9O)r|)?OaKcf`qhYU`=f*|Ehx@yIeB9UER;e{wD-ypoq$R` zf9G4)aVAkG!Im%^jNiW;WTA-UOd|llW+(8Y@Ht&y11dXw*K|_)Gx(N7Y}krHO@?kJJ?MA&49-3M82|Y*;foDwEBzT(MKk3NJV2PG( zvci_d(YxRAKeVwWQ93B-H>u*Mj}=;*6nQX_(*DaRoZYj}pGk~Y`PA8R8cGMn>fh(F zN+GDO&G_8XDu$W5(Q0`J_6izTHN0K?L5?9hU_02Al#t9??LR{`rG`!?XGa@9Mu#9@ z1Nnlw$5MkzgZdBa5m<`>Yy94tOL{1+-V!vNgcN@iDNeQHQd@MH#`04~#OrOHm+Q~p zi?4r`_KOW$sfFK|+j&uex5QR^OQ}_+W-{*b!%OAGzlcTQ4|kN z>Nq?eW8`88TkBV)%E`H#*dSiL#Mf2-*1%msP69_VgZFo;`TTt8)gp zEZK?;cNlCGlDh4hvZ`HKPpB+(9nK4l*6E_>tn7OXP2nI4RL|upF)%7V00905mvI3R zsEA6R*T6Zy!smvH-vFkwQTLR-X@I!+8uy%m-Jx^G=Rlhe!%^idG-{PwRLT_Z4mTAp zIuW(XD{fT23!P{a7Mk(wu}ywnbic?PQe4tU=v?ymUeNhkcjycf*nPU76Yq)+8{xsD za0iM2omW32-y2RQ3mqv^pz_aWLsZt_Gs+sHOvgHVk4-f*G zv8oxzj~-=PV0W1C+;uJ{S~FM$eRiQt`8D@f@w)6_gSniu##I~^14nx>t%^}kTSjG* zjzV>7z;Y!d63bSLU74UW`%i@GTfB~ zs11JzXjv8@O_UuVHpLmB&_dw$F}e=LU7b>jSCF_%@5-8PszCqRy*u?O_vkH3(d|s- z!is|4DpK#}>`bCV6aNW)4kt8oDOifq$FOH;<|>Eb6}JEGvOyubFuZVhMWV_7Ghvwt zoV&Ki?@ypIoG%xdA}05rDb2Aw{g}_@%J!#+B26aIqYIxuo^dKQjz=$0HfBzQLJ4o+ z4WN^Etk-XNt=DgQ_=t_|kzi6kW&cF7%_*Wu&PWwWFbpY;?zaMoP{5ff!nWu515Zxt zWtA5%dr2>C*XA#aSA2e1TL%Y&@|r7;Gz2aZ0te&OqZL)W6YwF$_F8;^X}36(g2O6@ z!}x3*5*43M32{hNyf~$;x$^O+sDHF&ny79?Phr6CXSEi8@e)P9;c=?2kAnEZxB9rt z{#E%=vDC?>1$GEKo_v)GY|H;a6#WcE?|?tjSF^79dooN^yK&+XCVFe)6>BehO79BC z=!-?Md}arUiiXmv%l;I~DgQe|8UObbO-jJ8<6{);=E}iBwej8N%AE}7)^XA?o?ynP zvA=h{z(%`q6!vdY3uun^l9FcD-to=OU*8hp1mbh=dyKBNEpMP1P8SvBw+0DL4#P*BHOcE>0;Z%2EohC9I25 z@Zru*Dfl6gl4PnNSZna%r|&P?fC~6y>S~l~N0eI;jQYRCZb~SfdHd?|1D+FL*N43#z0S z6iF`_eA#VkElmsk{b)j`7i@S0z2HOB3)bN^y06O@qSs}s#-&$+prBEe0h%zzNCKl-s0R!>ZViTZzQn5MvywXj&&UQOSENQI&7>SRBS21XYC*{Y*lQSuYkJPunp=aGeAYx-f$2^ z$Ck2=hv?3s0uJvmN6NN5=yXUvfs-vz#~K1vqz{2(EpV&?+atFvfn?_UP1@%LKI~H; zyh|m6Ne+6tME0Jpqpl-UlQMDv22QBGD_EVf{2O#sH)}2b)B7&$r#rg-_Y!U=pnLTU z6kt9b*1c!sm7f&=D-|$SHkby?fQ0@{d}n&RVuZ$~VprsuU5nhi*CHFUiu{C=%K~<{ zfNAzYnb)Yy5uM63EtC7-gF-*V?NraQUJK1rp~a%0S3Wf;bQD0+mjFx<8jsNj(jgdD zR{C=@A@`Iv1ugK0>_Fo(QqCk$IgS^KEIh8GQ^ACyV9(YjtuIw{fE5FEiT^m2h9^gg zZv$(S6iokTJ5gKu>6Ze@(;I{ZXNE8|t@NLxZe+_b3|EoG6vS??gmIdtRy4;0%SLxI zKn1q^;|3YPQN&RLB>^4G-du8`*^Bg*&~8u`*fGWic8tl+j`5YchG0z0m<>XMi0iar z_yVIi<_*(d@`Q)eU;5#t#swB)`pZDP9kW2r_5h{2!IA>Uc2;EmB{b2_-27Ok4yk4i zF+;-;n-w5t))pa_QS8-pw4j*62yQ%Yi;KI__Gyb>%)6&lpd_4SZ|vRzI1$G2kB05Q zLHb*^6h^(jkrYm+uImk*Zq@r;1onU~=$Lw+i%wwq z`|Ke@XZ2g;>u^0#=mhHhE5tffp2270K9JTr+$yt>j8F=f0ctQF-ODRWmEyD{p*XQS zbHA4Ky_O|Gf~u?pRZ0+31Q4_bKoG`fB`~vAogx5NqSP8{^kIsx4GhM(;gw$w<4BzD8I{s2%ZXhlWW&+#2+ItCftdVqJ16l^CsKV(T;sQIpQH4S z=d-!;h6O{V^2zWdwe#VloZ1;f?c7D(+?sRYsy@<8%Jfwi%l8xcs}lL>J*cM%Z`2hr zZ^#|w&l?kL5ef}v+CU+8gYVAeNl0dnFq*E1Nu7&I#HOMj*CsbsKcEyC-=@TPHaoDf zeY$lvwij}3Z1LvByt>1K#s9eMmRPfJ5aI=izL-a1EZ)X0o7V9|DAHW{n+L4++IXVc zC;61(tJ)7C!GBWid$R7uE4IG&2^wI8T48K+<(&COf_-U)uboe~%;8B=MC2_;(bMR`-sR8*M& z6ohv@e!2x#M-LUzuYsqtt&U&BD?X6bk*fg2tj_AlGqFWe{v^gIF~%s-P&Xo$uVY+1 z!%`KUd7e&yXQ#n&14L_M~?Shv#9ry3OX*g&EUxW)bee=_C-glnY|DA2x1adHQl$i8{u_~kf2rY1qWsiq0N*HE$C5%rD<3gnd76RyjFhz~6*f!haKFUuRH*J!?V%=Q*fy)sD}zFh4hk)z&`BzEDFL~K!U}8s z-GV}|=vwFly%u_HAvGQ3YC1M3^w|Q!Y;2^ubpl_fRAC5nkG1}oOvpWsZ3wK$1P12Z zy$MnBwSctNf~c^j=-2Z!Lz_RJ<@OEr&ocjX$jmsbt`SZ%3Pg#4+d^ND+oS~2&BhbS zkJJoCk@KJ?*`&~Fw3F+}-Nz*aZ^|hnP(;3^DYj45~sbGr3g&$AF^ARC9Ngyr z23{rO6GSk@Prgo*L?sZ^-^ho=_@&VD4;62L>3W)CNY_=|;2=(XZqon_^SZf0^AaT(k(FSq6!4J* z=pGDBPL!)efvW_Lk4gHFSXWlf076xN4t_FN_^r4myhw9h816AOpi;`;L|A(DJeZJ> zw2j~poHY6n+zR|5xMg8DGY8{)I_6!33G7_C!OUTX{G>5dJM(hZ%%P2R{znK)@@LvA zJ#(1wq5~~3V5rgY^`6B$Glx~A&@ACjgjcu&`ZCx|VQczGD?wa3bGZ#KXZ6h!ptfyl`7MgI&7d%5aC0?6c5ljiXHEy50Wft~LmpvS} zmpIoXD*k@iA3GkQd7CR|-kDQ@$$Uyf9gBuKg9P28k1Y)JulP#zF@}%bk_w#OlXYGj z2Qt?A^;2>xV7B(=%IE)L6?jGM9w7cS{%jq*N*yOne6WuNYWoO0>Gl4SP*YdGGgyQ3 zrktg$Bcz8HWmf;Uz|7xoH5~H*ERwB=+wy3w98D?!0i$^l zndME-J7ARp=FI$37yJkL&Q^rgXlwnQf+8>PTIBd%i=2s!3yUlaihOLNigX&kNym7n zGR@4t*8jcIQTW%o7W%_p3*A|T7P)$E8x;BjfTdOKI)Qxy9#4mu^8HM9$V8=im=L*F z2o+{U(q4jjN>3Y_wI$apKj#_ovdsBkf<2>77d`u?&9t7^ot|Bw5+k$~*>d#kpOVE% z3e;6hJe|$%31=eTI(0LFGQ7R*HlQ1(26Wy;_&?M-3(Tw?1M#$3yL%n;wrABtY({Vi z&6hJyyKSttPazwX*S+sJnRW7<9! zjT}wW6(4AtYxXzQ?k~#sXEvFWPgqFPJQ*DrWA>w@aO&O9ZtVq~ZZ*wXfjzwoIysuA zLnqKQ2T}x@X0h@O$)FQxnjhQ}qVgs_6Ka9dv$dKgGr|@#DD|XiRw+SeP1E$#RqCFM zdjGd;n#M$(HO(2W&v&C~ZhAsu*Xh;)(SP2vEX&d~M@xPMHtM5Mo258T-GB&@AkES= zHxibS-+`t%oE1NW0#k?sO%vmDM$`P4H+XKktSw8?yrp9?jNDvVoQr>7K0{OJbP{xn zy_wc~Q#1qYQ8d}P`l*cPz2e`q`8a!nYA5`qUKKP~{^%y7KU0Y`-cRAr)-y+_+oVY^ zQ){4Smf=b3nQ4o#CV~d5lfBn$ms_^W^aiF!{y5mBi<+6 zM;DNUb4}>@=a$;>j95M6aXfnG3yEPLv1hL!k^lJw$=2>{V$M*Lb&$i3^RM+^|Ag*Y z@7B9z1XJ&g-nl+8?9AVFhqh4Is%x&{$ zw;2Ln@rQdW;Z=QA&sZw5TAxX#7m?+Hkeq793Ge6ZQGI7aY}jYq5fdBs)YOGa9-LCV z`RGM{>{G2W`>M>jnL9Sv{4@2R;`B^;Qx|R|AUqG5 zsOJcFy!rk7+Oyvm{;XQ1+W}adz8E;4D!OO*6iAu0u0|g>WYp zL&Y7QoYi-*@c2gO$o3YCpy_g2N6$5-*?)}nWP7q=&omOz*58t+8}=U{P+s9T_B8hY zdM59He|E)<&h=5L5-#XlB0_lI9SGyER8aD0d7luN*nI(i$n&CT2-K!u+soxvX{;iavoKBQd$y-gS zqHaWLVWzgvh%W+>+5@HBEVQtFccauZOVj**??>HI>PAZlrLcqslu9YcQEHMA?cYi% z%IQQYmAuuI>emgWK7J%!+gmiU^-d`>{d$Er3^hvKpUInI6KXd+)nEysR3uHQ(-h<= zHO7ecZ>1FFbfT0>-Wp0tZ`09sw)LY76+~MXub1VQD|-F=-Zuh`?8$;Q0sgg@Nx4Y* z@Aj(1Q?a@G27j7R)FBF(P)xv4C>M~OD{nS_Ev4s4UXXaa^+VQM`JVSpIy2)g*ZedT zRP*E|pP9|D5${*fG*!6Yz@hH6Gl%vufXo4a{}C+A8BVcEObtH4`z)dDXLyw6C}XReROQ`TAGLo z3V=?h7uoYjx}InrknKW{U`tTPyQE~g^}RJR&;_t7x`R!ka{(JZ*8RvLp}Nw))c~Xk zJq$Rx*DVBBCp3}Hy-n|x|2D{bE@9{}x~Abnyy0aFQfq)b#vrfs@58lAcc?y1c|SGK zQDM#S)B@QgbhLM5e|TM*hTJ~baCD;ncB5}RxD@c~?(n%Q>&G9U-E%X_y8*V}=i8l_ zANKAs-l%;ZDpAp2c5Kp395G7PUx#$I8mz%$f*@S1HM;fF=*-vgXbY^+)Fm8Z`k3c3 z$CCX@Aln`z1+&c4)bA4y&38s$z==uzMNy^qQqUa)(sBs zrVIJ1E0#uEV;JEDif^vvQSg)#(;ZV}fFi2A{)9_qdtY}$$Wgi>PV-Ymc0w4*`bB$5BYw1>Ga9sq)7LaQohQG-5zMby;n; zm0{GSzdr1;6q24!9P6}%Kf`GOBg})J0~kmMOY3%+6z*m!Rq^YYv|iV=ND0a;{Mcq6 z#ci3ir)ARGt8eq1o>F`>Ngh%;>H#meNaj{HA~WWd2vYJj8bpeb>MP2hlVgNK(K|y$ zc;(mfxP<=?CwQ!b*nrk}a7d@{>CeJl-Dtm`%XX@=U7I1B?H>T#$G_x?Bw^*p-!blL zZ09(G`+K_Btf7{6R zO_c3h2#h5obI2aOKk_@i&P+yr&DR|g-*lPFmHB#FC9E&! z!^@wT9oBdEx2(R{d&=)85GKBh?1rF3%CS`J1_GEKM6ScF&K~J0M9BCZi6i?@N_B3gJGu23Q2yl8LO`r>=S>Ze62j>&!Qo9=&cc@)& zq;aJd4pNhP#RFXCU6gq${Un<-cZ0g?LEF5UCe8J#k5~D8h+s&XMFfa658~#M<_C>yvMSxLC%tfkbkL+* zSuN4N#SvOgWp$SwAMjW##U65VuP=?sMP^h1PJi;RL)@7^burfof9iGyL`U;p&N!^f zsUvFZ*-L!Eh-zCJogAx2ZlL(Y*1xO-BNM|I+BvJ*9{I)94ry&; zHRQ6Ebk(k3OZ81g=FUWlASG|d)t_E3(3+>D^!QliW`Zu-N#bl3bah=K#m)<{-9b75 zq~KWUT+*TlDMq4qCpx)Pl^|hS75Z=$s!-&Jpdj{irhR*ag)=lS03b+@1&1E@`g!HL z%~mul@h@F%y=I^|1w~t^zDFPP_jp4F{}mq9inh!sCYEu0nXmsGjq#ji@hA|8rNxt8&(>a_YBOEIw=y{7y_JUHUv03Dg@L- zl>T*f{!fs8VbNaXK2|6+CW^b@;}V=gDKRa!;i-vycn1;cKwKYO60*|YNUi5POHX;* z{jOFOpd+QOjWXR}NmZ99p;I8r=L89hl#sYdxb!TMfs5l>Z{J?CkaLWZt-oa`V<0c? zis09`2*Hz8Zm@Ioz@XggUUTK-vCP97Pwos4hg&X|mJrm5-T>ZnT_F zu7Gl(OfGyjrTLtte@$#s=f8=w$D`$8!Dbpz$wU7(E5 zKuJaRCK|+=K(@6FT?%%MuZY#ZLJy73(v4+AN<1_$)Ju)w@ABBMV(Y&^=tOT^7`^Y& zHGPsDsmLo=0;iqC*BB&tN|4%P*9E6VCn$Xg@cM25ZjMzfu8RKlk*er@?`sWa0>=5p zmf0y{>Ee%wRkTNcX{bqd-43k$Cu7V7)-PA1Ohoz!hdhTJUrp|7QS?66FE+3lwalk*&P4cjxe#qVPGwzBx&MPkI7D{rA{c@4WUT>gF`l=jLWwo$Wk z9ga&l9lBFL+u#+8j^5zU{)bp9ay~f;ZyX5N$L<8;##ab$kNlYMufb1v&%$e*#ayq6 zLSxB&>y)cKGCGWDkDM5Kk&ddH`ld@9IaZ02yB;hDs~h>gKN5 ztoOFQ5_H=!i^RhDAEJ{vmYWF!I*QB^<1|-Z1!|7vz90(H^#egj*NEd1J}ydSlkR1a z2>wt71D1=D*FSQFk?v^1cZOgPDuLHXSC5>Wn7M+V}R++Dn9=}VdIrwDOrNn@azk!(n|j@s*q)SJKQ+l?K&P{ z?Uvcrds4#IGrW6uosQjWI^0a7Vc*_QdJT1W^?7367A&F<^m)D9of& zE~ggKF_+-xXon}siVN>m7MXdDqe%>|J)wo$rb&WCKRyS3?X=B|r)v?p8skDZXiX5homeK%g z+2o9h|3Xt0k++AYQWS*@!U6E$u#l~5s!5rq+DJbQ8Y8Qz@)6}~sw3#uL2Oo2eRfNi zruvq{N4(VpyMS7E%6k=sg-vynBniD~^50!ky@{LERBx#T0kaNhA(xAuAxV4aRmTKs z`zo?2d!|>-X|krO0?}0DYJD(4cUZ?lDw3gu0>bjPq*sj~Zx2nSC<-~)6*4j`Wb2x$ zaB8|&eLt&L0gPfbRk-U<@^QW{(~wzBHRg|s&FNJ_i;8|lQ_V)$%|Ae;c;yF}6kX{* z^Nee%if410>agd&x~WVEQR)UDS`&JaU*7FdTctvBn(F;2)Y--rOUg}JThTBMI_p?e zQ!kQq5qC_z73I#BjgxolTI4tIP9W#TW@sKvw$&mB1ufDi(_UFEvfw7+mD3`JY*CB! zrALG<@}ddLmHrXSU5ng;o7H)4rGdVx^K{c98*QNLPR^Zl*}tJh>UwSwi*hY;dY2aA zMo=4h7W6do#Niiz2@DHaHRjZ$3jaEJC@Uh@^K1NorC&E?&s+qrjrP8m@6I7;TTZlW zVXCr;bhe*PyCj=P6R%&#l~ZmWUH?ohxtytDD>jC&`y&=uj(fzi) zF2HX<|7T` zqJIs>8}M8jhI=b%tMT|PFqlHg)YB(Ab1VeNr3Sc*8rQx9HS(W!)Hn;0*eg>*I<($r zwE1t+>6V$6$MJN;voW(bw}e=yH@Ds*s7Ly2lMSI!kA7_}gh!}LnmQN#D-fEqA=uMj zTZ=<=PxM^+7WBOPNk`8!GxU^nHF|m>Jr{|dpYfx&v>eMpjMdPtA(!3W=#89`{#^hx zZaIK8mvqT}(N^Rh)g|}ETb?_#zlK|CI7>iPZQg3rN)yyleZKdEi7d@mGPc`$GF@A? zTawMEQ`0Tam0+Y>%Jui6DJ0?NkXL{5-cCi`aFPjPMgi8M?4w2SP@Im1u4yGZ~1TiRqA;s#U5}^i^ z>}hLyXX%B?Sm7F2e1K?EdOP>>X=6Bgx$E0=(CGGr^#@qm{4bvBjE0?i$t`}M_<{Ay zFH3NW?^C|N!BU_vEOhSWbW{w^y*x<@ckZRWH*|8A+>I3g`vZYJw+lLU?j;u;XQwap z8#K5T@2Y&I8FYekFOL!HPV4#q|dyP5jf**x6Y#4M9V zU}BCqq+uwr5N6KSwg)Kz3$w4MC(@RtmeM9dyBeF=5H=zDTUmhDL;`-2g%fLV^v*}H zYtB<|;t!+Kvgj{m)%J#bEvZ%h^)JRa5IzH_m~STLRYh-X$3nfCFvy^=NqJKWWDjlK z+z_#95muLHmYU7K3Joxk#}Ei`PnB_xOvxAjT1{Nupc#Ny8DY+5nf=4*m(=@V5ztJ@ z$Fvhb%PT7pW=oy|VE^t%oRAqygfr%`VFthDtUp<2f3A1eKhndrea0g2PYV5P2*zHV zWl|x|&M}Mitq~($uW9y%{rkS!`V3t{%pux!VN4b_u>ig1Q^JgYa{gU{4Z^?l!@AOAu|n1GzvYt^!B>#inu*a&HT^hiDjG zWz`$Uf~`q(rp9Lj&aKu`>+!K+i`cUn30}CVTnuG%^l2L&y~=T~mgM;lLw7{PjH9-L zIve^-+0InPQIMfy1VQbQ!zMaO1mH;|oOuLYAhquhLeb!p?e4}dA_v3Kpp&Ta#%!*w ze@<_r4Ys%8bl=z5>f}Zpuqvx2N2^U(LtiQKea?jIW`-)7#~8u-!$39qjv^u^j{F=#YR@74jH{j4 zUr?ReCWngE-p_dUvS%uuaDfr1OpZ};M|_>Bc%dWpQ6Z^|55Sj0Me9sZQJpEEqPlVp z6;D_8ROAOi-ZT|^%iD#DA9to=vhuF;z}QL8WaJh;lKal)HxaaCf=3P|U=yjEOok`W zeI%yUNqBpX&6zss!1+2Xe+uOkhGb(wEPq3-&Zl_;Z8$Wl#-Y7&Fptc|y?zyG4oc*& zU{!a@o?Lnt_YR(xNG_VIc7#SX)4zlYebTRAF23wtUFsaq_v00tFPpDM8yo{gkxM8V z1wmaxPIn7PwyBTNt76yb)?o=Y%4HjNtS`9MdIPUWFeFW`&F6;VHp561)%AN7FHB}U z9MzmiK9)!>SA$)VgUiy(*2IAu&+n+MSkbspy4os1_X>XpLzw_{yOb6pp6QpZ+InoN zXHBZ0J#y%|j$5m}YQ@e>Qe$UdNa#$UJwp-0SC;DQYz%Evj*HiC;H=pf)m{v?d=&5F z-o*U*qE)PZ5ucAF@|VZF;UnYT@H;_xG+en13qjGqE28_gT@s1zxA3CAST3l>=sa%g zsQ9R{-I)xQHU27De)CU;@=Rah?{N%GQ)ncCusjGQsIyq@UKQh|!~AyImg9dPDhf_` zWy%5JO(SuyrZSHPzQSRq6JRUB#`t+g@M=el%Qx0!k*tB?DvM+@od9j^GayZ}qV`BX zFjHkm>m3oz9IL5BwKKQS%2l-Nw_G*6L4I6zaMg$N` zXNHZp&fcnFW5oYp*f>-5>>D{$jtRUy@pTq>3tgiB4ignO;iFnxH*EY(*;A35g1l*g zH&K18hasnn!0UF{7?G@;KS6@-c7EFDsoDYH%-Of@^+zOH^auy&&nD$Ci0Qo_Y{6LTvVxn z*e2Ecu%UIXG2Wp6$*{pSsaeAYa{8-=joSR>nPEf2g(=LS>V^$=iy7)$Hf+Q+Y$S4r z4KRvVe0=$Cac@+M4I3-eVBHQIwfWD)HEeY3hT=$n9*q7z2b$nb;Jpd2EEl)BAXzqU z$J^ODzX85A@sGM|9?28w@&r;B1|#%$^48Tt@GF-<^ZPTpO)$w4L|cCZ9 z6d_!coHM(}W;i%^W@?jL&FWMA-F!fr-d|}9O?HlS^ZI!G7w|aqtQxN>Sa0k*xwI;G zjz5p$P&2NSBMoBLN%&H%J662fcu+9KfBrN}^G7+RWz51CY8j@*=5Np%W4|lb?B%BO zuP7x~{oO`JBJ;^_LHGjTc>jF>o`jUzOx+-%7kWu~MNvHI<3tH)#c3;#V+ zrTCROM5?FXYIZqY@{`g>)TEdyz4RkTr2n9)(sw|KsnSt6!c$YF4f+2MdtU+`Rdv2U zGg+8nnM4d4*IqP8&;Vfx0*Vrnzyt$C2uKwTLo!(;$;8YgB#0VTiD3{oimg>@t)fN6 zx}iUcs0g%m!B#D;wotV=h!(Vp)Y8oVea|^}=4O~1LTmp|CC-zZv%Tj#-}jyGtoPn? zla{=Wek%5wDFth$KZ-TeBOGUtCwk2!mwp4jhQW%}UFG{{3=&wD_Y}@ zS&`Ow6%ty{dJHlDA6w%Elshir2uhW$@niU+TI05Rcl@n! z!&PjJkMaLm_u&7&OVCy6lZw-opVK$|VfcJXew#wn1!fSOZ4m5I09KMX9jp)$Jg9c8 za5u@R1`@||-of6Gxwe3$K5y9xKcYqaF1TVl6__1*d;l|9nmF=r5V$Seb!U)+AIWjL zrIRBqogAlZI=RDPa(BwPA|CbG!~CGbiLpMf6g08FD_HGdUdb|p2cL+{a4>_x?G!OI zB`vw16axvCg|Yw=1D_h4lQ2@i%NbZRK=8(T@NEJJKYywqk~MP~iR=z8UeCcv?N{qB zDz_mr@*=akllpxkk>f>?LoyXid%WEvKTki#w}D>zeqWC73sDlRtyl72G)&Qo(vrmo zTkimm9ZbW9M>hC)O4e~5>=pH0g?-nfsKsM4$&LRea^i%S2YDr1l2-QUG#`rhn9P`; z(iO$b;xQX$f{&yncToR|hnwM_X!sffHXjW;p4`Uan;!OpK!(stw%9JBT4H|FH3Q#t z-G^I~;+w96F=-0!MeT^;7KclzZ@P-FD{RN{O5Ey{-*kmOiE8ZdG_Y`mtay-_ucrCF2)BbcjIt1*5;ZjK0YA_m90YaAX_&6su3uQjx3`6|zI8Zdl~yfv%nS1KChp5SYMh)dt0;!pv4+8&)1n?o)&Bb zw``;8H7GLrW_BCma2I+T?m{2hpCF%BLF-5s+sH^0cgmCUcVOq5?~6vgZtxG@WYyZ= z3UAp#tJg4l+8*OZxb<_~W#wJ)1!*I}>y16cT~>Zt<|cW+Tis&qeZ9UuN<~Yd1;`r5 z+fX;JV-L9`tyw5cRyzRVR`!$g*&ZL1O=vAtqz{H0;3tJiC5Jd3ZbXnKvra|RzeD%q zMz)Lk!aqE0LL^KUHH?=IRbV6oYZyQmlaB7DCurx7+FE}S?_ZFyf>B>4Eujb9I%e8m z@U|-pm?vAm&L8!~4R7sx z91TaD6oLJLvFHrYrq0~1!NFQ5_(ybLnD{Pv5@e%5KL~@KRv@0Cj*+;b2@aKmAnIu? zoYz2?Egs%xT=4R63y2H+dUf;rK=79jV+LWs`iu!4}*g}b8| z&HBvRrorz|D-1q@?vQR)fj<%Ck{6ZaF>25rvPLiQB;J4#dqgh;SYgwVJ9Ul`Tzc6(!8;)V=1xb$|EEsjD153}Ln4lsoJ%D~4#D#`nJQi47!w`xLLwZTp7N)~U$d-D$n5`6lNIW*?L*$utUMUH}&_tDM2 zUC22*T1jv_x)&5J^bZw>$GoH^8Z^xM6g>m1e}kx^6{2ThJ6!U%P$4G2ObGZ-4xv5Q z_hrrD++N#uZ*$A@=Bp@@sw=b=9nNDin; zxu3a4y@cf}BKO_Kl;bH2x&@Dl|JVhpmvy5D`xTh*gsUAzu7!B);rCg~ zRWnd8V%m-TIz z^_BcU%6io^zH8DmzTCcN{0u$gd=wnj={>SV6J|9wxaA?)Gp;zg`~2ApI_O6Vgwy5O zGtTnEVPis&>VUJSgP!po)idr6{uI5S-ZQ>|p_VI--S<(syMq(f!i9RI6>kb#G3|$Y zz8oicSDyAV3083HPYt6>LCZV%2!t3yFkZdn!p)mN$`baUu2FB?bP}GCGYlRt%HFfU z`s;#G+iv{xzAFVGX>*)*vLw0vQgX6r5K2b9UtI@zg>}>V;O9?Hbf6Pfx+@T`4EMM4 zIlZLGFSVOXTtry`KK`D!~G-3sTVOVg|^T%Yb zpyeQ}=w%mfdRwU(VVWFNmq9O)M<&oa->{G4y2#6i0fRe5wV?aOep>e8f1qE#Ky){< z;qvY_OjVST-?AUN|1-)s%Q^{VWN&28pI@@WW!;xQ>d;N!!#ASva74j?KcHZ4!Q?JK zBJc1YcHzGD$Jyv+@<#2be{J8dpk3AFqyM}@j4bH##iU}%yA%uJZ4kAzLQZc2@u%b? z>lri;)au@@` zmiArDrekzxdhdd_2gn|tpK3q!;IRie&oRuS3b+G`X}e|LN{U9KLSA8DctEq`?lY>q zuYT)V{4x4!)rvS5)+biR#mlB2EAu0dG;X+&{_L8c8d5tw$kkp4TCII9-=qoCtPTGD zCm@4Cj^?=v1spZVUBVnKe4FWTzCOskkIn$?B1pz)&P(4FH!;qrML3YPbpf3*2{-7I z^xxe}R(A(4pbJ4*4u4$6Egos9@4auGFjf&tTH-^1OTNJ_Y*-Y!_+-dMh>}wfJo=Km z^avN!xi`ZuG31SU>4ts#P6q&#-_t2$shNqs4wG-b-XXLHSMM4&z%ObJgH0n_xaba$ zU+**cVJ6YI5XbIQ>`RH4!{mGm_RE=8Ai$~^=D%<`DsbFp)3GR}X z)X>ZWXZ`XG%_7g%5qm$#oxlAR7E};;N0>B*CUw66p(!uXEUk6CUz^FDJtgur)DqSYIQAqnd-}4e56~_(h}|`beDck zvoY{|P)%0b4Lp462Ru`!&A8x=Ovxhy&-pNr=g$;GvgX#4$nId--STMsvGQnqt{H;w zBQCNxrjEuRgGgrh8C)^2i*146gFnKNi^6s=V;f4Mttr^UXp;gS1{j>~g7(n>=!kxm zuIN`AksC*=`|(YhP;f2+`yC3mKZs*M7H;KEiP&FY^09PvY~v~NSVo8! z7;`3XZ9Q}kcpij_Jw*~r`fvok&Ll#qz115`Oi-qAZqs2cRcJZ6JU>Yf@I7~{r7}FiN z$<0WGn*x=?cJP%^uD|+{!weCVwbaL42ZC4sfc1MI_zGNP;6sY2EHn+=3&4&Tf{fv< zx!2+HaLL1nU}It$51FKnY51{UW05a}OlmnSb~S`huq+C6GD?Jz@MJ_Z{Fzeqv-v>9 zX*@%U90Ye0EFECHu4Rc<@oFIFoe=u$KL&MrC6H;z^yvI=a&YWA~AIH=i~sF>MbAq{R}Gt%G|$(qHty~O+x z_DiZHAdX#iVQxMSQi)?%T`f4`dv~zzE`(1Jq_ch@#-H86YY@k@ZEy|Edpi{(dgc{E zIv46&o_&gY1PB(2U9TG;!C<2VM>>*VDY}g3(^_u5j;O=DmOTY6`_!9U$yDRZ`?wL!p$f?f^#hGLA2-YS4%vTs|19u) zeT6~miI^UnYW+>r=kxs~&p+cR4c>Ywp6lTn6xy(wEN>FZ4DLgk=;mlt|0RR_6Ql^P zrQ%{5+&0-mM;Tmmxk2<-JF2dCXduxB_a@{r8l3fxh{0uhrG7rW9T}mg=}0r^XNKTZ zo|wkwbZmq3O9>(dm$ZblOH|`01awh(1>n`$J31&YC^=o*ZU<>^Mp3CeO1 zZfAVMP{lC5A4QDMR-a|0F!WdyK7$gJ5gzgwWO%nD846JB^8=(2x|9sdZ<9(s2-l$G z&!F?L5tc%}V;W%vN|wiJ=eN9tI~4JGE!%Tj;?wf5jDT)|iq<(}-ZtXy^HD z6GiucN85mO1!k#(r)gwkMIA;C%;s3*YWah((cm4h)?6(2L?osk9D#DNH;W@yFiW!s zb5^y5@|K2f?1hQA9|ht5pdg2L%AW5n^=%bXvfaT{Kp_!dZu~L4`f#4VQ;B)_R@6}s znP)eq93=K3;^-DIZy<8CG!?{3qHgnA4q_)P*hIUCXz6blvI+uYepdnqd-_64>w!L6 zOMLweMGRoOJV_QmR~7GJ@o2zOX_zsnVMFOO5tbvHGN!FU_~DA*d*FtPeKc0FDDhdg z{GPJJ?yAJUuVlu(Jb1eiG_r+ZF5QxiZM2q`#79_m2j2jO9A9WG?1z-B>X%*{PU#z zo$B=PWJSNxNPmL~{X0ls8B%ve|BZl>9|SP{V&}%6ZV$o75swXo$kC?&7zdCU+0(O& zrcZM%{6v^h%RgN$U!vuTDa$rj;8wA~P)AB92*Q1ap@phX;9Q4Fhn;a)#rW+-SL$`s zSk(+wDvjo@x` zykKt3;Gb!h;159s&yV>hVfN?m!R_^>Tx#xb_l=DQhotLGnq!}|*>ML%Ama^9kKVR zsF*1Bf?&hQUaDfR8SZ8|&l&TpQm}Uu%`wp0Q&g+$@cTTBvK3>qkE+(TD-Db-?})LY zSd2}HV(g}6Qg0u@)$Q#fGPV~$FqSMBQwd4sT+DD5>u zOGfRjTOzfWOeTBD)_TtzFqs4N}nY3#4hXmYC78&O+e2^Q^B`f zK)fkJycxuGfH3k_A!4862;^!)xKWQn@e><#VrEXM#zMjtJaM)=I072SV>1i4Qggaa zvx{Fg=#&#Le8DuoFwq|dijgk*5d)Xk2>nUL$x?b$S6|{T?#jO@ie0T6# zO1(rBrTDCvVc>IMM|^IkO+@qg+~W3p?prANyqtXEWEJw+jeHi8Pqne7^Czu_t?Vl? z#o8VGHL9#Ve>7Hw2DE_X4tM{QL#Sz9MTs>Jbhl1=+_xH=*-c5W| zDtr3`d{ruY+XQ@8YVpV2@&h+@+pHm5Fdtll+H&}DC>yEK8>SWz)IJIhCA9(kq?{s$ z+b^V-o2C<7kftbpb%UU|N>CL1(Ho|Ck)Zfha1Sb;{3R-a;|0C(I=LGawTC4&-m$d! z^T?mPd8wrRRLp}81aBv`^Rl<+SroZEK`u`xcY`8#r6jjjkQ3t4E11J0Bw6=zu)&VW z>|izt_UGND+1n+}?PEc5+gM4_6=+lx?ULfU2t|6s6blr^ir@hlk)&ABF~w&V(5NxC zqwreO8-gvoA^%1pio*S=655{FwZyQFffKj1#Z6qX8@3EBnY+Nv;46Eh9slLvJ5}@~ zVr2h2Y*uU(3rJ+}&lJOqfb3KdR;E0%OpZj)h*l&Zk17ajD0?G2GdbllKyFcxwF1I| zTwr%L+UXS$Ivxe0BC|Kj_FRCYnF4+8jDW@hB***l&={E@H;?QIPG0Pcw8Qkw&9xuZqx^3L23*G|rDMjerIMBvmr(`eUgC z-`8%#h8w;>ncecLt7J4EnkS2Rc#sd#+Y#P?2ioui{e_?<_OBZzqO$91Nk*;NZ#u}0cNq>m~b9m^;(j~C1PvB2pQnAtTiD^2E=9s-z>50 z`wIV%?Z!)66OxVDLj42{neA^fz-+AvpUJ?P2xM;}OZ%S0zolE6Qd<+=mT6*fx`~qQ z`vLx8J9f`yaHvvLc;=l*fvYtm4Q?9tPJyYyGsft=Mxg!bU%pHev)2Q`x_P?V1H;#- z@Aw=D9--W*aAvXxf|NaUUpjP)^r2dsJ`Zv8C9I}9%*jY{J zGZT*`4I0~X{uy{cKqXs)cnI>hNrP5VlX!iohk>|@DwHq5;bl9PFsbB2evH(`l#z^Z z1!V10;~HbrVZp+1(WKJWxGLWj!dmysJLUYW7-s&gYr_IE(z0ZGn$)rfcbNG6!%yc! zd5gCe;$ain$a0hNmWU73if?jq@yFTfCxC&06fA35Me->I`osq@Px=>L9u}QU)bfob zEQGdU(~QVp2+> z?y)Gx2n;EKZ~X&C41EN`senI0e#4k zi(cn5KO4VL9ACF-`B-0!ZES(9p4&iM?VWUU59Gj+SAjkYIZ~G3bRO$Vq4%?&<9=57 zE1s`$$O!cLD_W>}zU5qKUq6Sm*Yh&@H<9F0C^4LTpG$66QKzq6bGvR+HpLMQo%@?h{FV3~CK0 zpCyw+6T@ZQ%H-!b9SVbvTrL#zK?KzOXs*{w&=YVJ*MEif1=j(Zx~O6~&q6nT+LIb} zy*EPgS)g^0=pX{UzIarCiXx!f4WJ%i5tMj;2$XJ%fT{%uH6BsYILTZi=7owmmjJb^ zoW2rtBtHzI{Rjzu1M`$`#f9~LgmcV5pJyZJFVQHnpW~KVSWJ%uy%{NYCqa7UyeyL& zBQ#DzcN|V$CzIzyl0Sz*qTS@;(V(xc6Zb~t1PZpV7!%9nRhXM8IcE!|l8n_kU6M_S zkiAGY=lFde5GT&*56d}1qTg_ZN%lHg&Kpo5l(8>TZV(MKEXcbuc~ykQ0AtJAC6nhz zlDkLbOzJ?+b(lseIU8A?__Axb)TNSaMuhA%fLNdCQQ~84ghl4Y3qRR{mL~4JVs-g? zLCedNT3#(cA6A4uT!U$;xv_rij-mhN$DjjQ9+Vv{h52B3$dvsaZ1vf*aBLL%V0{1a zRt>%b!N1f}P3--Ue5XkM9LZm=l*un4dGSSfShomGNW2R(nLQ{zQrm*@f^g&cM zWWdv4@`>SnXOIC*Hdr1qqcpL<2~lP5J|HMM{L2Ct55h|~ay9+W8t#ySN8~kQL>MxZ zgZkt&C5S9wC@sQJo1E?yhZ*vpE}uA8gbl*)ZxS4m(=dlOBcEW3V~=F36lLt6To8Dm zLk%g$-bb~Zu}Xtc90*<}nA?QUUbWLX_2j}(Tgb^+xIRQ>$ReODDa2?Hz=I89)Xz=I z-@;r45O?Jnc#^#3kH7`DvkYuO9OOL8e?>vb18Jpdmt->)mLmoC$K;<5K#R zbD2Qao2N0~SHV}RFqcbs93d&r!}N7toY`bIS{xCnz6zqm=~##Y!3_7Jw{gU59a!8- zAuvxp5PXZB0ECF*|1^>1KrjLPv#JiGAk@z7O5Yt-1(nV@c&*?)*H9I$36G?Tg_TGW zx$78Zyub}URF+{NniZ)sGhhy}xsdC1r<&Ht*tO zBdhHc2#Y1fUZi(U0=%LTL*4g-4jQOPibyc)Sgo?0#RvKvo8{t@jmzRS?VBkxlUU66~EG+pPps*8h$|D*CM8}D^3{3L4 z1ChRiZhTrZAPB~zG+;goP9zx|!!7ckEAy9OCx-c1=Y^cHBcCO?eZD$K@Vp=r$ht`2 zKMFophB(P2>gl84y$I7yG?tNuG719yx+9NR(X$NFiBX1=Wn_`jK-T-{m<7Lz<}ZY+ z`0huV+#cwF*o$a}&kvNuUQ@*W<&g|}jKt3C1TnvX*ak&xgCdq{B-USQ^f`gS?lu^# z;$8}+ZRU)egPZJ?p97S}XMw$AjBZ-034!m1@?ydMJYK*aSt4O|Ca_HscG1lec9{w6 zhZ6RdqLv02SPfgr67~S7$%}=IO6y{40FQKYfvYjDe z_bP5yo50%gP;zUQS82*?0()P=8WlB{32d8$jan>u>uUmgM8f{43jG=yi6z2H37e*1 zzcYbdCt+I^Y&~E`z4t`_K)r7*p{w*hK-!d_W00=*?j7s>3|Y)wi==FMCfpp!6$&j= zDmdE&_9qDoDcDz~u~o2H!qzI-P7~OD5_X#6?O_vGvxNOt!4{do+!8id6?&BkY@CFZ zD%fxn*trsxr3&q30*jZhz0Fd+dr@1lY~rsuLcO~eO4th~uva8(q$+fc3G5*Wb1Q1s znZQ~k?0m)BL=)It3HyzrcCHC*l7tm3k|G?L6I;^35|*c^y=?+JNx}vx-X1f7{e7I! zTatp^Yyx{*!gRgOHi11WVc9oH5k{H7?v}8ZRH401VAo4ntCDoTyL|(`3>L!%95>t0 zfX}x=o25!fX(2@{!UXoJ zgl$)vN-}{xAz^E8kc9>zYAoJXOIVXC^hFcc^%7=NupgShW=q&*iZ`DLEKkBdRJ;|K zz|NPjK8jjD6Ihajou^=J#jz#*VysZ_%?kE=6WAXltX4_7!34Hh!roM{78BS{C2XRS zbdCvZxrF^wQMPW&%4?!gedzeI_ug zgf%KyqX}&9rJ@%0&6m7gZUXy_gx#-T=bOMbNSIHlH_ilhmxNU*g}irlY=z91u%!z2 zv}5p0TR}%U}H^SJtb^klhoU3Ca?pS2=y*fu+L}3mh`t0 z7N;crjS1{&3AY>m_WnqBg?>c8!Exs1!2T1ePsf>l&p(>?W}D zBy5x_^e^bZvs0wMyR({QM55vO3G6-z`?KQh zY!lcL342^MnXj&lEor5M&73Fow$lVQS;8DjgojOF!zAol1zThSJ4M2tRE1t;0y})M zP;Zf2TQoku2uZ2C0JAz8_mt3nlCs z1$)p0RxV-1s(NlRffYztP{C%Jz=lZJuM}(uU`7?(hRUZ3@~<$cAOk8m)OHul{2QZ@wj)?a7 zQShlEgHaBF3Mek6HtbpK1jE=@;|?14)r=3wE&OC7V#D`xu0&3G3nVax^(ZPfSje*Q z9yJf8cuqjL1IRtpz?i4*(iG}^!O@>zARssfZ1Hy5QwZ>W2eZ0b5)y%C@URSq?vz1t zhSb9<$j3$y{7eP;SPX(6s~{gtLhu6>)MW5I7332nNPSxcGiC5~6&xvp+f{I^3~oU% z>DeXXy~?tdgy)zVNT?f5N_egVs!TpaIRXjenS{96h^wHW-1z@Q2*byn;?tVPO4TC? zz>k8jOcPJU5`yD*Z(w=6X(`J6n^aYAK$dR#Kjuiv-<2EiIrB@}k5K zoMie%b+zWC(l6?&HAkagR8(tDI{l)ST5~e#7gf}nBaSf@_0yU&mhqx;T63_+E+2Du zwdPKjGCscw3Yl6Gs#Q=KUzrLD$yySMRZtn3G6fp zTT?5ktuujrHCPlnL{VD^7;8_L={jhi^8W$x;hGZnk^>22Rj1Z&i`qoCyJRu*y^|6<3T_p>>(FE2_!Y))ITwwy+ zKS(HagW@gI1opaw^;OgyfEo4vkEv4cZp4T6-d)<%n?q58Zd0r%4$~%jZ>LTZOToS@ zh%ITngl$%ZzHS2Bn<3PDbEV|%ArsgR2}@UnHk-g6k+6pq?E5CL6%uy8;%%r2tVY6G z6>mLEV1*J^rC=Xk7F!`hB}~`bFHK-65_WHeRLE)**r5xA-oB?q@S4DONmx+9T!0xH z@JP{cKMJlze7FJkkPY~B_9S`(*0-ol8t{Bs%)_dfzf6p+f?^4~yFc1b;VYQ zMZz9ZweW%o?5_hvEzDHZ)|kM4En%Y+wd+h^k4sp0kF5HMCa^mtY_5WxYXWPMu!~ip zM<&FU^co3!TTy%41ePOV<4YxPkD0*IB`j1TVK$#TTNigB60d~|C6vg6>NnG>|O~= zP=$I-V2dSewG!bH6Ig|Wz2KI5JJkd>Ny37P+QHn|k`9%y7Zq>6GJ%~cVZTt+?l*xQ zIZvqfB1P?b6WCuQtf!(@WCGhJVNcJNk`6S1{anJzRH2C`uvHSaUBPze#8!w;!jhGG zH=4kvOV|^N+HHUthwX)EkX-NVLwtDH?kR`uYpF|p*tT~(?>^j5D0HGy!TBcK{8_?I zR;CD<$ka1zQQ2Q3W@m2~q`n5g%58_&$9g;UuF9 z97YvTAMN*Uhsa_cSF-gN+#J1kn<8O{uaU-LAXfzRWku_? z)x*dt7RF>1Fn#~{hiRg=(%h1V1=+Fnd%c9cRxDxDO<=PmY`hYDkO^#zg#AEK>t+Hw zTf$~4{p=arzP5Iv)ldZ^kv&{nNs!I3ciSBT6O%$U;h9Km78#z2L>eC-UA)!)GH|he zQ^ap{Nokqi>#g$DHu)>OHG?WkJf)THa^3aeTse1Tm8VpztkFumH4UCRe`QU%Hmt5x zbJvyES9@yw+H8Nd+c&qr<}K5XK~3{}wVc7@y>6U0>y|6jq?A+JSvkR@cHlESBQzsZ+DRUz}Z-uT}cA8n0g~Y|5E3 z=UPvRU-Jq_T6MLzw7$v%~Z-T%+*)vtbW3&!@TlT3vmOzp~l`;wA2y{(dyuN~pN1a=s_bQM(4OrAKRC zYGr_>h{{q@^l#s;`%`D`dcSvIxu?cc=O#n*Dq)IcLu;F~bfvA)LkA4%KEA%D#E&ZQ zjqa{D`%#&LM`bC>h}JaK=V${54%Gd=^Z|n`rRryCU%Dlx1sUwc;1zaL=B=+OHAaH_ z$T3PKIa}|Q! zEj3=POlgz-XoKXIP+0)O;;Wp6#Yz=|EUOd5x#k;)QGj z=heX`0N1&w^VTEmp|q7He(=}Nrw!Eb-_pNdN&kTs(L&S7RR;eRm*{#^1f(US6j%WG z_0)(qS6z=rILD)vRW`yrz%cR(8!jhHRizxi_%q9AglB5$6r|Ks20lw+R>)Uh<7upw zjX`!HJ{b9Et;RF2n7%Q{pP{iVnJVlP-f*IpUhQrIe;EC=YIjYOR#xZnKx@!}$2Xw+ ze@tJOFHGOv=<$t4WoYT1GW5|kbI0^69gv}grBG3NJ~O?T=~GLu^SG-hfTxj^bvh<` zis;CwlnhOA0lvaaN=vLM1=S2zFbxu~sj+|1O-S0V-ci#u-E*qg3t5CMhGj$#RpoKR zFg#U~0fR}D3V3_GIm}?=v{GT{90T0`N|a1{V>Cz_`nO15$aY`jPp_S4Dm(+Ey<`~LPk5>#7>v*>fx`VX89__rUQkh4>KU-WTgyHVwIOT|jZrj)3U`A? zx8X=b@r4@&7R|@t*T|s&<6o(#3WEaVuNmlRtn{^O*>1nTt`Z|3YeH3(tf@gIqg9wa z+~_J#O?vHsG5zM3Ued2Loi#IHv}hPrUi1?{Xg&~vx6X52ePx{oc2HSE@qHeRXxbWP zr{br(=rdIh=^IowiqrG!03rP z8n93GD?)w+g<;c_Kvm3p-H@@mvdUej&2u-=vL;W<&&^Q;eRwQN{B%0P29w7E(eHQQwodnr%YCa6dh?{ z+SRBeI!RQ#sqT|Pa3YF@53KEEIj5-D1muul;H$-?PHkrXAHpf;M-VhQKbIrRa3)#Pbc z&kzQ$Y3V~UuNkFP57V%>X~c&!!b5yE8wP#~KlE7mJlTE>cup_8b9`RW@eIU`s}9S{ zYs7@0w8W4<7Jjle27Oo^EwaYYL=AFFIi>;UgRY}+G7;SrTD%*JQ&}7Ai?kwrfY%qS znElmy>MFe~(62Rl{HX3yPbqo@VcS<^Po11Uc|wK;Q`3rE`8k(O&YLz(%b%uA%PZ1~ zrl7f@w4(e;d0<6L*R%oJWSwzWxNlJm(V47jNUtDilnO9eREJ&{?UImF=pHi$S+zsk zB_pxDVv#yc*Gx=Crgg-~w2l~=))6B}jAjH)+FvmbW0I$+Zn!}eUC>*xs4X-TmkZZO zT=d$zOI=l^2~SyQ+EK zdd#ssjU^s*!`0{&>zXu_Qi;_x&P>2Gr5xQoN13uJ?>tS6ESRd5)K?)pI(7E=?rJQS zu)r?U^JBQfY>p+!=^RN}Jg>c${lmLYw_~-I{sqD z&BOosSiD;1qtRl)KYys40Or*+RMvTG#Lkjfxv^7ZQ^g8}KTVr~k(gtW-e9pcCHhHi zJcj^dio3M5*jrZS^Z0!b)KiR+*N@>*%bPlN%2d$RyHZW7aQiet-eR1Y^&O;5si|tx zhH1z(9AjNA_a-nH;Fo?*ZJl?Hr}&(V%He~CXPjg7xHHZfR8w+}=!j)m;Bj(ZQBLl7 zO|7;v*jM@MePgJv$$x4KHT?(IrBQjWMz|^}t|R*Yt@117q@bMLL2;&ZhLmcBP+XO# z8godk+~Y?jc!r7Dls29#b?&zKD^XvO>fxMknzyd5DFb#8Nyl0wjPZdQc0@RV8Z?L# zy9t$;8PTM%T`&iBj~%BvkFVB?1s-kPE7HOS(B!Sh><*TXgn8b&xpLCv!;HPkTRtSS z@o1i#<_n&ij!tQmDcXd*q8Zs!hv%wJ?=oy8T~;^|*OeLgSEL=Cb2z3kv`?9HSS~R5 zMKTs4<7F}O4J(!N+i=FHd{@TIBg(4BqR7{P{ejZr>dG4BaW`_}FSaXu6|i{W^VU>h z^3UL%@Rq{+zHlNeWJ+eH;~KdRVUS6PlF0~#U6XVKz|OVOvuak?05 z@9XM4H6_^Ln>;>$LQeLyJhlt=9GSBF5MDOZ@D77-Qrg z`zxA|S2r@uc0`R=dwdne^ULedFtvtZX#B7w35FhMc72hlllde|dOq2)b*4Ot)bkx* zd6{}P*>!eGJ^_v7t4IIq8POEMddrJFahRbCdHu%ClX1INGqJkg0^2*w|998xHoBcDV*b)lDZl4cpb8QHF ze(X)4uTF>ex?&P7mCF{3maT7EVB^6fcmBo3#vm;RZJ8S`Vm_lys`O#miUqwSCO0}X ze^V{DWF+}wJfhzzTuB92_grdMdA)NvK!|=AbRZQt9i&{1V?Kwj(JVj}X`DxlR#Oow zbTqb0{PkGQsKuz3sbPhPe7F;UPFMN$S&Y!OiVOG0?ZfUy6=v_ub*c)AK3a6WDngCB zDkM8@jUBg&Vb`taWuJ`OFC|>Pk~hqmF#Y44Nk_;*FcbTIm^?M9*zzjx9CsB0?B1CV zbr@A)hD5#N_gCVMh9N#W93FNI7{#n!j;=dBY#3hj8!TeVHCm%Jj)C&av9aqb=C-57 zG90%?D(*e;HlDch~+3O`>B_3jVr*Q$1FvVmzPGqaIeaT z&GZI+ZoKB%ycxRn7kDsv@XakBTs;h}W8AdL@@ls>2PP$^+u266Zmj#}>IZc&A>qd%oh(6Entcx)d!x7n-7tYUqBOCodHTFy8 zq)cCHV9~*WyD7Z*z_d``q3PexhmGBAY$anpq750AIh^Yiu>^=LI*jRA$4DR1VfyeP zBV(rvzBysc&C4z*n39uSl!unBOHhgp=yrS#A7w&E$}x24$e4Uswyc}*Y|itSTP)3& z!j7_GqL7lUU+$}x)D$;b@UMyg=JTJQ{~A!QSWyX|+pm1W6lAjS){AuEZHRd12`{U? zgg(_lp_9gNAd);oBn{6HNx(Bi=JpIJlj%cMIzFgP20TMm`cRcVOr;N#MU{!@@+x<= zh^I$nq(|hWM`CI#(EEdCIXn^rkHo+uF_cGO;1LB>=rQ!jBE76U-1;MXULU5vSX~PL zd~ZpeUnsP}3kB5qgc*&nKXa(`S9r>* zO1;uwRZ&(|Un~8-ITdBPziM6t;{!&=&vQrc^p}V_^?B(p6?7_vU(%WHt@f3nk(0jg zqni%$b!ozfGLx*xl}*eI7&MIV)E@K=WY*d&*J)Hv9rAC7p4MEF650pZ6T zDLynI{51_FWg-^NkRgn!#frrv7%3A=i)xRMP6p765@Spdeig44BQ-FN>q^mo5gYN9 zVKu^-vI^x^`{s&piB~X;BCsKeM{vY1-JRhcp!L<#-D-aqlQMJyRT!1Uy?FH2Tr^|1 zB63q68{vhxZ{yD?EhAQJaezdwS4_+Bqz^aY@!SvgtuX__IDk$VGZVRr<3tc81CJZ? zo&2F&!lY0BhrIAWUAQUkgAZXk`uYrXC+qz4o<;hmWM%lpH z91r~ZP>cLvzXUhua0`KxR1I4=@}~D_&a=Yfg%pQrK>Fu-Fv;r=!H}PKhkTw|H=kfI zz@atlGw95~!=)ql=v-4K9`OU) zLTPYk4Q~te#3bTXxEXNI%)(bC;8wx)!@c;zw$O)gGqT%4vl3Abo>5y5cRk##a5uqy zkMVfznE=7F3~p#{Z%%v;_PfdAcq11>Ek>pj_NQyy#ir;l8u6E%X%J zKF_y>K7spxFQXhh>KE7w`fy){8{gAnc@yrLaEEVi3*8B~`B$LR%VIhBYw!zq)T?cw zd*JSR9r8KB*KgZGufkpQHuz7nSa$y&^x?k!$F|UdWQ*lD*e~mOlErfAhX})M*xMF5 z0(TGGjNTT@n2(Vk?x}x+d$PrH#X-cUSS;SdkRR^NmQZL`AB$yhuTUuC6pQ7K)KKUM z+^^3Gh3-5R2r4=o9W z{BSdF4uw918@weH%00_siN6zgxL4j43Vi}M?uVh!@UyYc^<&V7d*!`|hx^ohCP#N*Or4n2W1hX)a_Q+8oj;6JWPUFFf@imd2-AP0I}6ty#G_imzo+2yHMrKs zUB%b~j2(~I@rWId*zwMFxHjP02-Fr_J8$QFe;Xq}Ycc3+ zwyE8n$=ObOc8|HjWg330n@zy)0lq&Y1m5k`>)=B~y@&LJNWUZ$5GD^ zbXj7q)bm)|BM^Q3QKDz}h-vQonvjQOkne4#^?5k8(~EXsx(Tc**$U* zpA#egYEj%(vbb3>$!7DZU;e0vt?1uegWE!tjDV)y-JSN!dR&A5**$27A0mAX(kC&! z$eG*-Em7Y`5Wf@gtXt}DnJw3ux;QS^srhC73AHm3{U0uVZT2AWTcKChf4~NPu87Na zYRlpw+~R}@&P?0w&XEPqv3X9{IA`HRgd6p6zO!(OGxPi1o#`kbTeqz29`oBrurU1C zM(#m*g+tmxLG+KZo#e6p^4iy*XeY2=TU-w+`e@_L?O{XHu+4C8uw^?p+VY%RY!eAz zWJT;%QLzOmDka`x*)h5;bd|F6TPde1H!r$MG<1Sl?iZl%!sF$} zav9HYZ!F@`y@!9)M;hXZU&xznqQ8o2N5=kYoh>f@bQ6w{eLZZ4nmC+n7GVxh1{IxfT&J(g$}O!f~_DhR+4qIG|9=aChL^nSKRQYYl1R z3~4YNkw)^&7b{JtX-q3*i6=W05BX6!=OQ&1X}O@9tI~48O)j{}b?!<>cbsmc5OEhL zc0gh>(h5O><>7?sHaJS1s~mBwZHS$MSli_Y+GZj&)qsKR1G@#+ z4qQ8N?ZUMOR}j}hM+IqEt;ki3Tty6ZZx{O97E|yH@LvkPyJ0^2TZ(iU=M6@=cgEW` zIqffRdzGnT-gPJN4+D=AHE3_zcuqz#$2muibB^_>3Zq?a0`6Jhggs!~%SW0Y@oypi zQN)*Ee4{O}!Kw?}waP7pk3)dc8L0kuM9mdrRGg^*oRh%t=p@J&dh*q=3 zcC`}?Co+z)+yczg*I>S0U|#N8mb(sgH{j}A`6w5;K1Qwrm>sNn*WzL0EgwE9b4m0u{w8Hi<~>H zSLp3%36hF{yK8e>=su-~j@yyV_If8Z5w3|_p$Oaisv_pZ$^jp(HF@5`gmCigjt#bmaaso&Wt1SlY;f)+1uJeS9gY=RW{plWk^s34C>gH z4U0yu&B#>%^ScrOQ+9-Y9soc4vA+FZ(a&&nIG1C6{lCCZ73ym%_<0uVd_VRbjyXTu z)6KTe8SI804%cB^&Gt&?o^Ek_;}BbbSXh0xxbsbhG0OrJF&z5^|A&19eh~PW|g+-J3ZFXdqWi6?y>!=7@Tvu!syE5zMF_Nx9Qk*aLq)73# z01K_3e$aWo-c&5K$nadUvXhPejBo7xxU`4IB_^APrlxgbAQ z{qIbSd(EaQ9#cUfS1sxj@Py4L$FeSecx+(ghKBgyPf4a zYpY}fhWao#tg`x?wKJTJGts2=7<66muf??v*9Kf0ac#l11J_P#g|oI=(kOG*#*MN{ zf4Q^PRua>Dbp#CAMeo6kX8yi0dll+`IQFwIKRFai?Tr4{cC)RI>U*&}&@FCpJYpxJ zN4}OJ3-+SIA*_cCfsYJmaVfxSD&R(r~TnRY_9sI*{v1QqE`4 zMarf@EP9Qp;a~%^j!r6j?;!9+6}pin zFS4u9H4N=C>oDJfs&jEaWAC(3XgtQ5W46b&$#D-PIM*dla&Abz&bc<(_89`$VZv6# zMqFEP?ZCA&xeSRDkp|OGu7yAD4{<7+2wiRKWIiq(ld+4G46{qd_UtR&YB=_|%w3%twGVI))gtmTY>s#sxGM?)BLeauuEV&R zF>z`?^TL=GZ)=X(7gmA4P2lhRvQX%{&hXcaDOr2!SobE_9zi5lAPL2sqM6Qm)&4i` zQ(aII3N8Jn%Dco||C|@ygYw2+8xr>`k8M{8v!kY@rI@?M%`oY&b3y+I=-*Qv3Z04l z64E!@H-l#49UbhO<>J0wZ9^zDqci&td$24HVkr>WU=hpg&tldx+7?)Q0QAe|g+dR< zcg*L(__*8RJK*yZ(Aj=H?js(1o{f2CT*zviXqIE<88TrKY!%@uIMZVJ`Hi8_$;Z|M z=ocHQmxB5ev8b=0{GeNg`=eKOhHfpoY%#X!!)Tqew$|C0cN_z&2SezTSj>PIKd#}p z@0!^h>fCy2Pkh|HHnek0>P*|YzL=VcUc*)yv*ZORcRkAOvp5u*${QEQn#b+2)koPG z6oMU^Rk)7cxfze0n+EQZJYh1GseGXh>q@S8D>g*J-oJ>0MQcqQxw^MBe)`+aBJ z4H$RwQTy!$fTn18&fxw~=q1c&k7;KI6XG81W5xyYfA{-N1K(-jI}LoNf$uc%od&+s zz;_z>P6OYd24*)%Vw!S~m-HTS(?z~F#k|Hamz#f$N;ihN4f1hRx-raU_5qd7Ee8IK zVJ_znt8~)h&lu)1Z}=pcLR$Pqhc8s=y!FYSF--o)M5PEx9^W0-M8DqZK_7$(nGsB|tV`7?(3xKnXd`NlBwc%tYV!_;|&O4s#o40HSXI+f0{ z_%nuiyQDEH-5BnP^qW+=F26C1+xC_vDxGz~pE1nmc9yDi>XJWW7`JULEh?R5@n;O< zwy7nMEA2z4Zwzxg_MxbBW7zndBWeFTzq=HFy8Rl%Bcbg+#Qu}4C^-25nsmg zh%<)2iSixerDS^hiVj~sp?$hB%<`{@N;ig?^N}d}#xUiNE-yN4EDvytG5lTm|GEB+ z`i#~u!^ZlI4paZe`eeE>EG>tz=D(e)edui=I{dq+bYqz18~bCHVhpqVcT|48|1ySI zW^{ScVPkouZw!AE<&y?~1=zdhPY+)e6`mUvz9}laDk}WLsPMX|@N+7x_q$rPET4Tk ze`5#B+QTgv@zWNaBV3iuqK{{|#UOs^Dji$d;-{zU{XXBh;qS|~keBXQ4o>*#^};Wx z@Td1ft2j8|r(l+ziZI74{%}i9{B*mqtdjgmu92<;OHnv|{KG3s;%9eDSC8M2ui~X+ znW=#KxT=@e7LxpDDtt(Vbv_QN@Q33ip?|3G5=Hkr=Q|C2r-AP@5Z1sgvfm1am1l

    VH#X=(}=hZ)0m3wZ{qa1sf?>6%vNH6X1MTl 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 -2U?jaa2Y!>3z%i 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 VLm4O@EIT773k)f#sJs}={{xh) Date: Tue, 4 Oct 2016 16:40:55 +0200 Subject: [PATCH 235/268] Fixed error message when linking a non-existing file --- earthdiagnostics/datamanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6e7a4f1..09607f8 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -324,7 +324,7 @@ class DataManager(object): if os.path.lexists(link_path): os.remove(link_path) if not os.path.exists(filepath): - raise ValueError('Original file {0} does not exists') + raise ValueError('Original file {0} does not exists'.format(filepath)) os.symlink(filepath, link_path) @staticmethod -- GitLab From 637193241b4733bf739e88951a3587d9f9f84780 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 5 Oct 2016 10:36:58 +0200 Subject: [PATCH 236/268] Fixed bug on automatic CMORization logic --- earthdiagnostics/datamanager.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 09607f8..6aab5fc 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -543,7 +543,7 @@ class CMORManager(DataManager): for startdate, member in self.experiment.get_member_list(): - if not self.config.cmor.force and self._is_cmorized(startdate, member): + if self._is_cmorized(startdate, member) and not self.config.cmor.force: continue member_str = self.experiment.get_member_str(member) if not self.config.cmor.force: @@ -573,15 +573,15 @@ class CMORManager(DataManager): self._correct_paths(startdate) self._create_links(startdate) continue - else: - start_time = datetime.now() - Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) - - cmorizer = Cmorizer(self, startdate, member) - cmorizer.cmorize_ocean() - cmorizer.cmorize_atmos() - Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, - datetime.now() - start_time) + + start_time = datetime.now() + Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) + + cmorizer = Cmorizer(self, startdate, member) + cmorizer.cmorize_ocean() + cmorizer.cmorize_atmos() + Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, + datetime.now() - start_time) def _correct_paths(self, startdate): bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) -- GitLab From 68637eb0a87a217eee97395e65d444048e5976a1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 5 Oct 2016 12:45:12 +0200 Subject: [PATCH 237/268] Fixed heatcontent to avoid appending a 0 to the name variable when computing all levels --- earthdiagnostics/ocean/heatcontent.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/earthdiagnostics/ocean/heatcontent.py b/earthdiagnostics/ocean/heatcontent.py index 672113c..dabc54f 100644 --- a/earthdiagnostics/ocean/heatcontent.py +++ b/earthdiagnostics/ocean/heatcontent.py @@ -158,9 +158,15 @@ class HeatContent(Diagnostic): ohcsum_handler.close() ohcvmean_handler.close() + if self.box.min_depth == 0: + # For cdftools, this is all levels + box_save = None + else: + box_save = self.box + Utils.setminmax(ohcsum_temp, 'ohcsum') self.data_manager.send_file(ohcsum_temp, 'ocean', 'ohcsum', self.startdate, self.member, self.chunk, - box=self.box, region=self.basin.fullname, rename_var='ohcsum') + box=box_save, region=self.basin.fullname, rename_var='ohcsum') Utils.setminmax(ohcvmean_temp, 'ohcvmean') self.data_manager.send_file(ohcvmean_temp, 'ocean', 'ohcvmean', self.startdate, self.member, self.chunk, - box=self.box, region=self.basin.fullname, rename_var='ohcvmean') + box=box_save, region=self.basin.fullname, rename_var='ohcvmean') -- GitLab From a061756b4cd1e4f5b489fa650e42804b07889bd4 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 5 Oct 2016 15:10:18 +0200 Subject: [PATCH 238/268] Changed way to create links to suit sd2v needs while avoiding unnecessary complexity --- earthdiagnostics/datamanager.py | 46 +++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6aab5fc..ea7942b 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -283,24 +283,48 @@ class DataManager(object): else: freq_str = 'monthly_mean' - if grid: - var = '{0}-{1}'.format(var, grid) + if not grid: + grid = 'original' + var_grid = '{0}-{1}'.format(var, grid) if domain in ['ocean', 'seaIce']: variable_folder = '{0}_f{1}h'.format(var, self.experiment.ocean_timestep) + vargrid_folder = '{0}_f{1}h'.format(var_grid, self.experiment.ocean_timestep) else: variable_folder = '{0}_f{1}h'.format(var, self.experiment.atmos_timestep) + vargrid_folder = '{0}_f{1}h'.format(var_grid, self.experiment.atmos_timestep) - link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) + if grid == 'original': + link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) + if os.path.islink(link_path): + link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, vargrid_folder) - if not os.path.exists(link_path): - # This can be a race condition - # noinspection PyBroadException - try: - os.makedirs(link_path) - except Exception: - pass - elif move_old: + if not os.path.exists(link_path): + # This can be a race condition + # noinspection PyBroadException + try: + os.makedirs(link_path) + except Exception: + pass + else: + link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, vargrid_folder) + if not os.path.exists(link_path): + # This can be a race condition + # noinspection PyBroadException + try: + os.makedirs(link_path) + except Exception: + pass + default_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) + original_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, + vargrid_folder.replace('-{0}_f'.format(grid), '-original_f')) + if os.path.isdir(default_path): + shutil.move(default_path, original_path) + elif os.path.islink(link_path) and os.path.realpath(default_path) != link_path: + os.remove(default_path) + os.symlink(link_path, default_path) + + if move_old: if self.lock.acquire(False): if link_path not in self._checked_vars: self._checked_vars.append(link_path) -- GitLab From 20a952656cba18f4526e71a07e84cdd217685e2c Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 5 Oct 2016 17:08:19 +0200 Subject: [PATCH 239/268] Added interpolation with CDO diagnostic --- earthdiagnostics/datamanager.py | 6 +- earthdiagnostics/earthdiags.py | 1 + earthdiagnostics/ocean/__init__.py | 1 + earthdiagnostics/ocean/interpolate.py | 2 +- earthdiagnostics/ocean/interpolatecdo.py | 111 +++++++++++++++++++++++ earthdiagnostics/utils.py | 43 +++++---- 6 files changed, 144 insertions(+), 20 deletions(-) create mode 100644 earthdiagnostics/ocean/interpolatecdo.py diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index ea7942b..25627e4 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -318,10 +318,10 @@ class DataManager(object): default_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) original_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, vargrid_folder.replace('-{0}_f'.format(grid), '-original_f')) - if os.path.isdir(default_path): - shutil.move(default_path, original_path) - elif os.path.islink(link_path) and os.path.realpath(default_path) != link_path: + if os.path.islink(default_path): os.remove(default_path) + elif os.path.isdir(default_path): + shutil.move(default_path, original_path) os.symlink(link_path, default_path) if move_old: diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 4d0e1cb..3eacf73 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -202,6 +202,7 @@ class EarthDiags(object): Diagnostic.register(VerticalMean) Diagnostic.register(VerticalMeanMeters) Diagnostic.register(Interpolate) + Diagnostic.register(InterpolateCDO) Diagnostic.register(Moc) Diagnostic.register(AreaMoc) Diagnostic.register(MaxMoc) diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index adc29cc..0628fb6 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -12,6 +12,7 @@ from earthdiagnostics.ocean.convectionsites import ConvectionSites from earthdiagnostics.ocean.cutsection import CutSection from earthdiagnostics.ocean.averagesection import AverageSection from earthdiagnostics.ocean.interpolate import Interpolate +from earthdiagnostics.ocean.interpolatecdo import InterpolateCDO from earthdiagnostics.ocean.verticalmeanmeters import VerticalMeanMeters from earthdiagnostics.ocean.verticalmean import VerticalMean from earthdiagnostics.ocean.mixedlayersaltcontent import MixedLayerSaltContent diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index b7cb998..4a1dab4 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -179,7 +179,7 @@ class Interpolate(Diagnostic): scrip_use_in.writelines("/\n") scrip_use_in.close() Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use ' - '{0}'.format(namelist_file), Log.NO_LOG) + '{0}'.format(namelist_file), Log.DEBUG) os.remove(namelist_file) nco.ncecat(input=temp, output=temp, options="-O -h") shutil.move(temp, self._get_level_file(lev)) diff --git a/earthdiagnostics/ocean/interpolatecdo.py b/earthdiagnostics/ocean/interpolatecdo.py new file mode 100644 index 0000000..e8c1f4a --- /dev/null +++ b/earthdiagnostics/ocean/interpolatecdo.py @@ -0,0 +1,111 @@ +# coding=utf-8 +from earthdiagnostics.constants import Basins +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile +import numpy as np + + +class InterpolateCDO(Diagnostic): + """ + 3-dimensional conservative interpolation to the regular atmospheric grid. + It can also be used for 2D (i,j) variables + + :original author: Javier Vegas-Regidor + + :created: October 2016 + + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: str + :param model_version: model version + :type model_version: str + """ + + alias = 'interpCDO' + "Diagnostic alias for the configuration file" + + def __init__(self, data_manager, startdate, member, chunk, domain, variable, target_grid, model_version): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.model_version = model_version + self.required_vars = [variable] + self.generated_vars = [variable] + self.tempTemplate = '' + self.grid = target_grid + + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.model_version == other.model_version and self.domain == other.domain and \ + self.variable == other.variable and self.grid == other.grid + + def __str__(self): + return 'Interpolate Startdate: {0} Member: {1} Chunk: {2} ' \ + 'Variable: {3}:{4} Target grid: {5} ' \ + 'Model: {6}' .format(self.startdate, self.member, self.chunk, self.domain, self.variable, self.grid, + self.model_version) + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: target_grid, variable, domain=ocean + :type options: list[str] + :return: + """ + num_options = len(options) - 1 + if num_options < 2: + raise Exception('You must specify the grid and variable to interpolate') + if num_options > 4: + raise Exception('You must specify between 2 and 3 parameters for the interpolation with CDO diagnostic') + target_grid = options[1] + variable = options[2] + if num_options >= 3: + domain = options[3] + else: + domain = 'ocean' + job_list = list() + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): + job_list.append( + InterpolateCDO(diags.data_manager, startdate, member, chunk, domain, variable, target_grid, + diags.config.experiment.model_version)) + return job_list + + def compute(self): + """ + Runs the diagnostic + """ + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + handler = Utils.openCdf(variable_file) + var = handler.variables[self.variable] + + mask = Utils.get_mask(Basins.Global).astype(float) + mask[mask == 0] = np.nan + var[:] = mask * var[:] + handler.close() + + cdo = Utils.cdo + temp = TempFile.get() + cdo.remapbil(self.grid, input=variable_file, output=temp) + Utils.setminmax(temp, self.variable) + self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, + grid=self.grid) + + + + diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 3d70738..d97efc9 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -35,6 +35,7 @@ class Utils(object): :return: mask :rtype: numpy.array """ + basin = Basins.parse(basin) if basin != Basins.Global: mask_handler = Utils.openCdf('mask_regions.nc') mask = mask_handler.variables[basin.fullname][:, 0, :] @@ -116,24 +117,33 @@ class Utils(object): shutil.copyfile(filepath, temp) handler = Utils.openCdf(temp) - for old_name, new_name in dic_names.items(): - if old_name in handler.variables: - if new_name not in handler.variables: - handler.renameVariable(old_name, new_name) - elif must_exist: - raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) - - if rename_dimension: - if old_name in handler.dimensions: - handler.renameDimension(old_name, new_name) + error = False + + try: + for old_name, new_name in dic_names.items(): + if rename_dimension: + if old_name in handler.dimensions: + handler.renameDimension(old_name, new_name) + elif must_exist: + raise Exception("Dimension {0} does not exist in file {1}".format(old_name, filepath)) + + if old_name in handler.variables: + if new_name not in handler.variables: + handler.renameVariable(old_name, new_name) elif must_exist: - raise Exception("Dimension {0} does not exist in file {1}".format(old_name, filepath)) - handler.sync() + raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) + handler.sync() + except RuntimeError as ex: + error = True handler.close() try: Utils.execute_shell_command(['ncdump', '-h', temp], log_level=Log.NO_LOG) except Utils.ExecutionError: + error = True + + if error: + Log.debug('Using secondary rename method for netCDF') original_handler = Utils.openCdf(filepath) new_handler = Utils.openCdf(temp, 'w') for attribute in original_handler.ncattrs(): @@ -338,23 +348,24 @@ class Utils(object): """ if not must_exist and variable not in source.variables.keys(): return - if variable in destiny.variables.keys(): - return if not new_names: new_names = dict() - if variable in new_names: new_name = new_names[variable] else: new_name = variable + + if new_name in destiny.variables.keys(): + return + translated_dimensions = Utils._translate(source.variables[variable].dimensions, new_names) if not set(translated_dimensions).issubset(destiny.dimensions): if not add_dimensions: raise Exception('Variable {0} can not be added because dimensions does not match'.format(variable)) for dimension in source.variables[variable].dimensions: Utils.copy_dimension(source, destiny, dimension, must_exist, new_names) - if variable in destiny.variables.keys(): + if new_name in destiny.variables.keys(): # Just in case the variable we are copying match a dimension name return original_var = source.variables[variable] -- GitLab From 92a231fac64498491de0efe9857ab3a2bf97fc55 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 5 Oct 2016 17:08:19 +0200 Subject: [PATCH 240/268] Added interpolation with CDO diagnostic --- earthdiagnostics/datamanager.py | 6 +- earthdiagnostics/earthdiags.py | 1 + earthdiagnostics/ocean/__init__.py | 1 + earthdiagnostics/ocean/interpolate.py | 2 +- earthdiagnostics/ocean/interpolatecdo.py | 111 +++++++++++++++++++++++ earthdiagnostics/utils.py | 43 +++++---- 6 files changed, 144 insertions(+), 20 deletions(-) create mode 100644 earthdiagnostics/ocean/interpolatecdo.py diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index ea7942b..25627e4 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -318,10 +318,10 @@ class DataManager(object): default_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) original_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, vargrid_folder.replace('-{0}_f'.format(grid), '-original_f')) - if os.path.isdir(default_path): - shutil.move(default_path, original_path) - elif os.path.islink(link_path) and os.path.realpath(default_path) != link_path: + if os.path.islink(default_path): os.remove(default_path) + elif os.path.isdir(default_path): + shutil.move(default_path, original_path) os.symlink(link_path, default_path) if move_old: diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 4d0e1cb..3eacf73 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -202,6 +202,7 @@ class EarthDiags(object): Diagnostic.register(VerticalMean) Diagnostic.register(VerticalMeanMeters) Diagnostic.register(Interpolate) + Diagnostic.register(InterpolateCDO) Diagnostic.register(Moc) Diagnostic.register(AreaMoc) Diagnostic.register(MaxMoc) diff --git a/earthdiagnostics/ocean/__init__.py b/earthdiagnostics/ocean/__init__.py index adc29cc..0628fb6 100644 --- a/earthdiagnostics/ocean/__init__.py +++ b/earthdiagnostics/ocean/__init__.py @@ -12,6 +12,7 @@ from earthdiagnostics.ocean.convectionsites import ConvectionSites from earthdiagnostics.ocean.cutsection import CutSection from earthdiagnostics.ocean.averagesection import AverageSection from earthdiagnostics.ocean.interpolate import Interpolate +from earthdiagnostics.ocean.interpolatecdo import InterpolateCDO from earthdiagnostics.ocean.verticalmeanmeters import VerticalMeanMeters from earthdiagnostics.ocean.verticalmean import VerticalMean from earthdiagnostics.ocean.mixedlayersaltcontent import MixedLayerSaltContent diff --git a/earthdiagnostics/ocean/interpolate.py b/earthdiagnostics/ocean/interpolate.py index b7cb998..4a1dab4 100644 --- a/earthdiagnostics/ocean/interpolate.py +++ b/earthdiagnostics/ocean/interpolate.py @@ -179,7 +179,7 @@ class Interpolate(Diagnostic): scrip_use_in.writelines("/\n") scrip_use_in.close() Utils.execute_shell_command('/home/Earth/jvegas/pyCharm/cfutools/interpolation/scrip_use ' - '{0}'.format(namelist_file), Log.NO_LOG) + '{0}'.format(namelist_file), Log.DEBUG) os.remove(namelist_file) nco.ncecat(input=temp, output=temp, options="-O -h") shutil.move(temp, self._get_level_file(lev)) diff --git a/earthdiagnostics/ocean/interpolatecdo.py b/earthdiagnostics/ocean/interpolatecdo.py new file mode 100644 index 0000000..330cb8f --- /dev/null +++ b/earthdiagnostics/ocean/interpolatecdo.py @@ -0,0 +1,111 @@ +# coding=utf-8 +from earthdiagnostics.constants import Basins +from earthdiagnostics.diagnostic import Diagnostic +from earthdiagnostics.utils import Utils, TempFile +import numpy as np + + +class InterpolateCDO(Diagnostic): + """ + 3-dimensional conservative interpolation to the regular atmospheric grid. + It can also be used for 2D (i,j) variables + + :original author: Javier Vegas-Regidor + + :created: October 2016 + + :param data_manager: data management object + :type data_manager: DataManager + :param startdate: startdate + :type startdate: str + :param member: member number + :type member: int + :param chunk: chunk's number + :type chunk: int + :param variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: str + :param model_version: model version + :type model_version: str + """ + + alias = 'interpCDO' + "Diagnostic alias for the configuration file" + + def __init__(self, data_manager, startdate, member, chunk, domain, variable, target_grid, model_version): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.variable = variable + self.domain = domain + self.model_version = model_version + self.required_vars = [variable] + self.generated_vars = [variable] + self.tempTemplate = '' + self.grid = target_grid + + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.model_version == other.model_version and self.domain == other.domain and \ + self.variable == other.variable and self.grid == other.grid + + def __str__(self): + return 'Interpolate Startdate: {0} Member: {1} Chunk: {2} ' \ + 'Variable: {3}:{4} Target grid: {5} ' \ + 'Model: {6}' .format(self.startdate, self.member, self.chunk, self.domain, self.variable, self.grid, + self.model_version) + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: target_grid, variable, domain=ocean + :type options: list[str] + :return: + """ + num_options = len(options) - 1 + if num_options < 2: + raise Exception('You must specify the grid and variable to interpolate') + if num_options > 3: + raise Exception('You must specify between 2 and 3 parameters for the interpolation with CDO diagnostic') + target_grid = options[1] + variable = options[2] + if num_options >= 3: + domain = options[3] + else: + domain = 'ocean' + job_list = list() + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): + job_list.append( + InterpolateCDO(diags.data_manager, startdate, member, chunk, domain, variable, target_grid, + diags.config.experiment.model_version)) + return job_list + + def compute(self): + """ + Runs the diagnostic + """ + variable_file = self.data_manager.get_file(self.domain, self.variable, self.startdate, self.member, self.chunk) + handler = Utils.openCdf(variable_file) + var = handler.variables[self.variable] + + mask = Utils.get_mask(Basins.Global).astype(float) + mask[mask == 0] = np.nan + var[:] = mask * var[:] + handler.close() + + cdo = Utils.cdo + temp = TempFile.get() + cdo.remapbil(self.grid, input=variable_file, output=temp) + Utils.setminmax(temp, self.variable) + self.data_manager.send_file(temp, self.domain, self.variable, self.startdate, self.member, self.chunk, + grid=self.grid) + + + + diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 3d70738..d97efc9 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -35,6 +35,7 @@ class Utils(object): :return: mask :rtype: numpy.array """ + basin = Basins.parse(basin) if basin != Basins.Global: mask_handler = Utils.openCdf('mask_regions.nc') mask = mask_handler.variables[basin.fullname][:, 0, :] @@ -116,24 +117,33 @@ class Utils(object): shutil.copyfile(filepath, temp) handler = Utils.openCdf(temp) - for old_name, new_name in dic_names.items(): - if old_name in handler.variables: - if new_name not in handler.variables: - handler.renameVariable(old_name, new_name) - elif must_exist: - raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) - - if rename_dimension: - if old_name in handler.dimensions: - handler.renameDimension(old_name, new_name) + error = False + + try: + for old_name, new_name in dic_names.items(): + if rename_dimension: + if old_name in handler.dimensions: + handler.renameDimension(old_name, new_name) + elif must_exist: + raise Exception("Dimension {0} does not exist in file {1}".format(old_name, filepath)) + + if old_name in handler.variables: + if new_name not in handler.variables: + handler.renameVariable(old_name, new_name) elif must_exist: - raise Exception("Dimension {0} does not exist in file {1}".format(old_name, filepath)) - handler.sync() + raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) + handler.sync() + except RuntimeError as ex: + error = True handler.close() try: Utils.execute_shell_command(['ncdump', '-h', temp], log_level=Log.NO_LOG) except Utils.ExecutionError: + error = True + + if error: + Log.debug('Using secondary rename method for netCDF') original_handler = Utils.openCdf(filepath) new_handler = Utils.openCdf(temp, 'w') for attribute in original_handler.ncattrs(): @@ -338,23 +348,24 @@ class Utils(object): """ if not must_exist and variable not in source.variables.keys(): return - if variable in destiny.variables.keys(): - return if not new_names: new_names = dict() - if variable in new_names: new_name = new_names[variable] else: new_name = variable + + if new_name in destiny.variables.keys(): + return + translated_dimensions = Utils._translate(source.variables[variable].dimensions, new_names) if not set(translated_dimensions).issubset(destiny.dimensions): if not add_dimensions: raise Exception('Variable {0} can not be added because dimensions does not match'.format(variable)) for dimension in source.variables[variable].dimensions: Utils.copy_dimension(source, destiny, dimension, must_exist, new_names) - if variable in destiny.variables.keys(): + if new_name in destiny.variables.keys(): # Just in case the variable we are copying match a dimension name return original_var = source.variables[variable] -- GitLab From 9394890898ed5a5ea89897a63602d53b9ec3cced Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 6 Oct 2016 10:39:31 +0200 Subject: [PATCH 241/268] Bumped version and updated doc --- VERSION | 2 +- doc/source/codedoc/ocean.rst | 6 ++++++ doc/source/conf.py | 2 +- doc/source/diagnostic_list.rst | 5 ++++- earthdiagnostics/EarthDiagnostics.pdf | Bin 239448 -> 241584 bytes 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index ee5d689..9215a4a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b13 +3.0.0b14 diff --git a/doc/source/codedoc/ocean.rst b/doc/source/codedoc/ocean.rst index 49d48c6..2da23ca 100644 --- a/doc/source/codedoc/ocean.rst +++ b/doc/source/codedoc/ocean.rst @@ -49,6 +49,12 @@ earthdiagnostics.ocean.interpolate :show-inheritance: :members: +earthdiagnostics.ocean.interpolatecdo +------------------------------------- +.. automodule:: earthdiagnostics.ocean.interpolatecdo + :show-inheritance: + :members: + earthdiagnostics.ocean.maxmoc ----------------------------- .. automodule:: earthdiagnostics.ocean.maxmoc diff --git a/doc/source/conf.py b/doc/source/conf.py index 5bfeca2..357ee36 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b13' +release = '3.0.0b14' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/diagnostic_list.rst b/doc/source/diagnostic_list.rst index e75b31f..def8e82 100644 --- a/doc/source/diagnostic_list.rst +++ b/doc/source/diagnostic_list.rst @@ -56,6 +56,9 @@ Ocean 3-dimensional conservative interpolation to the regular atmospheric grid. It can also be used for 2D (i,j) variables. See :class:`~earthdiagnostics.ocean.interpolate.Interpolate` +- interpolateCDO: + Bilinear interpolation to a given grid using CDO. See :class:`~earthdiagnostics.ocean.interpolatecdo.InterpolateCDO` + - maxmoc: Compute an Atlantic MOC index by finding the maximum of the annual mean meridional overturning in a latitude / depth region See :class:`~earthdiagnostics.ocean.maxmoc.MaxMoc` @@ -81,7 +84,7 @@ Ocean - verticalmean: Chooses vertical level in ocean, or vertically averages between 2 or more ocean levels. See :class:`~earthdiagnostics.ocean.verticalmean.VerticalMean` - +gia - verticalmeanmeters: Averages vertically any given variable. See :class:`~earthdiagnostics.ocean.verticalmeanmeters.VerticalMeanMeters` diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index 17bd255bb6896777abaf6905e11b0d00f20e479a..d829fe64273cce1e72a2734b06e2a14fa51dc497 100644 GIT binary patch delta 109433 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�HngMW_9~>&+5t~b~M!U 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 ANB{r; delta 107300 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 Date: Thu, 6 Oct 2016 10:42:36 +0200 Subject: [PATCH 242/268] Fixed typo in doc --- doc/source/diagnostic_list.rst | 2 +- earthdiagnostics/EarthDiagnostics.pdf | Bin 241584 -> 241604 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/diagnostic_list.rst b/doc/source/diagnostic_list.rst index def8e82..7539fc3 100644 --- a/doc/source/diagnostic_list.rst +++ b/doc/source/diagnostic_list.rst @@ -84,7 +84,7 @@ Ocean - verticalmean: Chooses vertical level in ocean, or vertically averages between 2 or more ocean levels. See :class:`~earthdiagnostics.ocean.verticalmean.VerticalMean` -gia + - verticalmeanmeters: Averages vertically any given variable. See :class:`~earthdiagnostics.ocean.verticalmeanmeters.VerticalMeanMeters` diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index d829fe64273cce1e72a2734b06e2a14fa51dc497..8578cfe0731d4d83a05481fa0c82b37f592b28a4 100644 GIT binary patch delta 5946 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 eU3a}u>U+Frx$2rw(V{b2 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 -- GitLab From 83f4fcc6e4e284b99e726ec706775d595209e0cf Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Thu, 6 Oct 2016 16:57:20 +0200 Subject: [PATCH 243/268] Added IFS grid to SSTK variable for cmorization to avoid overwriting NEMO outputs --- diags.conf | 2 +- earthdiagnostics/cmor_table.csv | 3 ++- earthdiagnostics/ocean/interpolatecdo.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/diags.conf b/diags.conf index 48355a3..bfbec56 100644 --- a/diags.conf +++ b/diags.conf @@ -28,7 +28,7 @@ OCEAN_FILES = True # If true, CMORizes atmosphere files. Default = True ATMOSPHERE_FILES = True # You can specify the variable to cmorize, in the way domain:var domain:var2 domain2:var -VARIABLE_LIST = +VARIABLE_LIST = ocean:tos # Variables to be CMORized from the grib atmospheric files, separated by comma. # You can also specify the levels to extract using the following syntax diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index ac70f8a..791c849 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -212,7 +212,8 @@ d2m,tdps,dew_point_temperature,2m dewpoint temperature,atmos,,K,,, votemper:mean_3Dsosstsst,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,K,,, sctemtot,thetaoga,sea_water_potential_temperature,Global average sea water potential temperature ,ocean,,K,,, iicesume,tmelt,tendency_of_sea_ice_amount_due_to_surface_melting,Rate of melt at upper surface of sea ice,seaIce,,,,, -sosstsst:sstk:mean_sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,,, +sosstsst:mean_sosstsst,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,,, +sstk,tos,sea_surface_temperature,Sea surface temperature ,ocean,,K,,,ifs tossq,tossq,square_of_sea_surface_temperature,Square of sea surface temperature ,ocean,,K2,,, zotematl,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Atl,K,,, zotemglo,toszmean,zonal_mean_temperature,Zonal mean temperature,ocean,Glob,K,,, diff --git a/earthdiagnostics/ocean/interpolatecdo.py b/earthdiagnostics/ocean/interpolatecdo.py index 330cb8f..7e9d61f 100644 --- a/earthdiagnostics/ocean/interpolatecdo.py +++ b/earthdiagnostics/ocean/interpolatecdo.py @@ -83,7 +83,7 @@ class InterpolateCDO(Diagnostic): for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append( InterpolateCDO(diags.data_manager, startdate, member, chunk, domain, variable, target_grid, - diags.config.experiment.model_version)) + diags.config.experiment.model_version)) return job_list def compute(self): -- GitLab From 20bf0de65be6ba0941c24d0c884f2123499550b3 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 10 Oct 2016 12:20:54 +0200 Subject: [PATCH 244/268] Added option to choose if cmorizar has to use or not the grib files for atmosphere --- earthdiagnostics/cmorizer.py | 13 +++++++++---- earthdiagnostics/config.py | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 03c34d3..4bb39cf 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -90,8 +90,12 @@ class Cmorizer(object): if not self.cmor.atmosphere: return - grb_path = os.path.join(self.original_files_path, '*.grb') - gribfiles = glob.glob(grb_path) + if self.cmor.use_grib: + grb_path = os.path.join(self.original_files_path, '*.grb') + gribfiles = glob.glob(grb_path) + else: + gribfiles = tuple() + if len(gribfiles) == 0: tar_files = glob.glob( os.path.join(self.original_files_path, 'MMA*')) @@ -102,8 +106,9 @@ class Cmorizer(object): self._unpack_tar(tarfile) Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) count += 1 - else: - self._cmorize_grib() + + self._cmorize_grib() + def _cmorize_grib(self): count = 1 diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index 166e6c0..1710d9b 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -94,6 +94,7 @@ class CMORConfig(object): self.force = parser.get_bool_option('CMOR', 'FORCE', False) self.ocean = parser.get_bool_option('CMOR', 'OCEAN_FILES', True) self.atmosphere = parser.get_bool_option('CMOR', 'ATMOSPHERE_FILES', True) + self.use_grib = parser.get_bool_option('CMOR', 'USE_GRIB', True) self.associated_experiment = parser.get_option('CMOR', 'ASSOCIATED_EXPERIMENT', 'to be filled') self.associated_model = parser.get_option('CMOR', 'ASSOCIATED_MODEL', 'to be filled') self.initialization_description = parser.get_option('CMOR', 'INITIALIZATION_DESCRIPTION', 'to be filled') -- GitLab From 85b782d56fc5bd19d791555de285ff4ca57a00e8 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 10 Oct 2016 13:22:58 +0200 Subject: [PATCH 245/268] Updated docstrings --- earthdiagnostics/cmorizer.py | 20 ++++- earthdiagnostics/datamanager.py | 128 ++++++++++++++++++++++---------- earthdiagnostics/utils.py | 26 ++++++- earthdiagnostics/variable.py | 3 +- test/unit/test_cdftools.py | 7 ++ test/unit/test_variable.py | 1 + 6 files changed, 140 insertions(+), 45 deletions(-) diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index 4bb39cf..dcced38 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -16,6 +16,17 @@ from earthdiagnostics.utils import TempFile, Utils class Cmorizer(object): + """ + Class to manage CMORization + + :param data_manager: experiment's data manager + :type data_manager: DataManager + :param startdate: startdate to cmorize + :type startdate: str + :param member: member to cmorize + :type member: int + + """ def __init__(self, data_manager, startdate, member): self.data_manager = data_manager @@ -29,6 +40,10 @@ class Cmorizer(object): self.startdate, self.member_str, 'outputs') def cmorize_ocean(self): + """ + CMORizes ocean files from MMO files + :return: + """ if not self.cmor.ocean: return self._unpack_ocean_files('MMO') @@ -87,6 +102,10 @@ class Cmorizer(object): return errors def cmorize_atmos(self): + """ + CMORizes atmospheric data, from grib or MMA files + :return: + """ if not self.cmor.atmosphere: return @@ -109,7 +128,6 @@ class Cmorizer(object): self._cmorize_grib() - def _cmorize_grib(self): count = 1 atmos_timestep = None diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 25627e4..ca6ffec 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -405,17 +405,92 @@ class DataManager(object): raise NotImplementedError() def get_year(self, domain, var, startdate, member, year, grid=None, box=None): + """ + Gets all the data corresponding to a given year from the CMOR repository to the scratch folder as one file and + returns the path to the scratch's copy. + + :param year: year to retrieve + :type year: int + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :return: path to the copy created on the scratch folder + :rtype: str + """ raise NotImplementedError() # Overridable methods (not mandatory) def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, frequency=None, year=None, date_str=None, move_old=False): + """ + Creates the link of a given file from the CMOR repository. + + :param move_old: + :param date_str: + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ pass class CMORManager(DataManager): + """ + Data manager class for CMORized experiments + """ def get_file_path(self, startdate, member, domain, var, chunk, frequency, box=None, grid=None, year=None, date_str=None): + """ + Returns the path to a concrete file + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param domain: file's domain + :type domain: str + :param var: file's var + :type var: str + :param chunk: file's chunk + :type chunk: int + :param frequency: file's frequency + :type frequency: str + :param box: file's box + :type box: Box + :param grid: file's grid + :type grid: str + :param year: file's year + :type year: int + :param date_str: date string to add directly. Overrides year or chunk configurations + :type date_str: str + :return: path to the file + :rtype: str + """ if not frequency: frequency = self.config.frequency var = self._get_final_var_name(box, var) @@ -452,32 +527,7 @@ class CMORManager(DataManager): def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, frequency=None, year=None, date_str=None, move_old=False): - """ - Creates the link of a given file from the CMOR repository. - :param move_old: - :param date_str: - :param year: if frequency is yearly, this parameter is used to give the corresponding year - :type year: int - :param domain: CMOR domain - :type domain: str - :param var: variable name - :type var: str - :param startdate: file's startdate - :type startdate: str - :param member: file's member - :type member: int - :param chunk: file's chunk - :type chunk: int - :param grid: file's grid (only needed if it is not the original) - :type grid: str - :param box: file's box (only needed to retrieve sections or averages) - :type box: Box - :param frequency: file's frequency (only needed if it is different from the default) - :type frequency: str - :return: path to the copy created on the scratch folder - :rtype: str - """ var = self._get_final_var_name(box, var) if not frequency: @@ -488,26 +538,24 @@ class CMORManager(DataManager): def get_year(self, domain, var, startdate, member, year, grid=None, box=None): """ - Gets all the data corresponding to a given year from the CMOR repository to the scratch folder as one file and - returns the path to the scratch's copy. - - :param year: year to retrieve - :type year: int - :param domain: CMOR domain + Ge a file containing all the data for one year for one variable + :param domain: variable's domain :type domain: str - :param var: variable name + :param var: variable's name :type var: str - :param startdate: file's startdate + :param startdate: startdate to retrieve :type startdate: str - :param member: file's member + :param member: member to retrieve :type member: int - :param grid: file's grid (only needed if it is not the original) + :param year: year to retrieve + :type year: int + :param grid: variable's grid :type grid: str - :param box: file's box (only needed to retrieve sections or averages) + :param box: variable's box :type box: Box - :return: path to the copy created on the scratch folder - :rtype: str + :return: """ + chunk_files = list() for chunk in self.experiment.get_year_chunks(startdate, year): chunk_files.append(self.get_file(domain, var, startdate, member, chunk, grid=grid, box=box)) @@ -625,8 +673,8 @@ class CMORManager(DataManager): filepath = os.path.join(dirpath, filename) good = filepath.replace('_{0}_output_'.format(self.experiment.model), '_{0}_{1}_S{2}_'.format(self.experiment.model, - self.experiment.experiment_name, - startdate)) + self.experiment.experiment_name, + startdate)) good = good.replace('/{0}/{0}'.format(self.experiment.model), '/{0}/{1}'.format(self.experiment.model, diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index d97efc9..3ac18e4 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -133,7 +133,7 @@ class Utils(object): elif must_exist: raise Exception("Variable {0} does not exist in file {1}".format(old_name, filepath)) handler.sync() - except RuntimeError as ex: + except RuntimeError: error = True handler.close() @@ -456,6 +456,9 @@ class Utils(object): return os.path.expandvars(os.path.expanduser(path)) class ExecutionError(Exception): + """ + Exception to raise when a command execution fails + """ pass @classmethod @@ -469,13 +472,27 @@ class Utils(object): return translated @staticmethod - def untar(files, member_path): + def untar(files, destiny_path): + """ + Untar files to a given destiny + :param files: files to unzip + :type files: list + :param destiny_path: path to destination folder + :type destiny_path: str + """ for filepath in files: Log.debug('Unpacking {0}', filepath) - Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, member_path)) + Utils.execute_shell_command('tar -xvf {0} -C {1}'.format(filepath, destiny_path)) @staticmethod def unzip(files, force=False): + """ + Unzip a list of files + :param files: files to unzip + :type files: list + :param force: if True, it will overwrite unzipped files + :type force: bool + """ for filepath in files: Log.debug('Unzipping {0}', filepath) if force: @@ -488,6 +505,9 @@ class Utils(object): raise Utils.UnzipException('Can not unzip {0}: {1}'.format(filepath, ex)) class UnzipException(Exception): + """ + Excpetion raised when unzip fails + """ pass diff --git a/earthdiagnostics/variable.py b/earthdiagnostics/variable.py index 0956355..fb68163 100644 --- a/earthdiagnostics/variable.py +++ b/earthdiagnostics/variable.py @@ -1,3 +1,4 @@ +# coding=utf-8 import csv import os @@ -32,7 +33,7 @@ class Variable(object): :param original_name: original variable's name :type original_name: str :param silent: if True, omits log warning when variable is not found - :type silent: str + :type silent: bool :return: CMOR variable :rtype: Variable """ diff --git a/test/unit/test_cdftools.py b/test/unit/test_cdftools.py index 266535c..9fd8bb3 100644 --- a/test/unit/test_cdftools.py +++ b/test/unit/test_cdftools.py @@ -13,6 +13,13 @@ class TestCDFTools(TestCase): def test_run(self): with mock.patch('os.path.exists') as exists_mock: def mock_exists(path): + """ + Function for os.path.exists mock + :param path: path to check + :type path: str + :return: true if path does not start with 'bad' + :rtype: bool + """ return not path.startswith('bad') exists_mock.side_effect = mock_exists with mock.patch('earthdiagnostics.utils.Utils.execute_shell_command') as execute_mock: diff --git a/test/unit/test_variable.py b/test/unit/test_variable.py index 2e172a9..67d68dc 100644 --- a/test/unit/test_variable.py +++ b/test/unit/test_variable.py @@ -1,3 +1,4 @@ +# coding=utf-8 from unittest import TestCase from earthdiagnostics.variable import Variable -- GitLab From df31dc2e3496bd920c23acd7d549679979aa4c6e Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 11 Oct 2016 11:13:58 +0200 Subject: [PATCH 246/268] Extracted cmormanager to its own file. Refactored datamanager, cmormanager and cmorizer. --- doc/source/codedoc/earthdiagnostics.rst | 7 + earthdiagnostics/cmormanager.py | 287 +++++++++++++++++ earthdiagnostics/datamanager.py | 406 ++++-------------------- earthdiagnostics/earthdiags.py | 2 +- earthdiagnostics/utils.py | 17 +- 5 files changed, 380 insertions(+), 339 deletions(-) create mode 100644 earthdiagnostics/cmormanager.py diff --git a/doc/source/codedoc/earthdiagnostics.rst b/doc/source/codedoc/earthdiagnostics.rst index 9c35e00..0bd7d03 100644 --- a/doc/source/codedoc/earthdiagnostics.rst +++ b/doc/source/codedoc/earthdiagnostics.rst @@ -22,6 +22,13 @@ earthdiagnostics.cmorizer :inherited-members: :members: +earthdiagnostics.cmormanager +---------------------------- +.. automodule:: earthdiagnostics.cmormanager + :show-inheritance: + :inherited-members: + :members: + earthdiagnostics.config ----------------------- .. automodule:: earthdiagnostics.config diff --git a/earthdiagnostics/cmormanager.py b/earthdiagnostics/cmormanager.py new file mode 100644 index 0000000..6fc1eca --- /dev/null +++ b/earthdiagnostics/cmormanager.py @@ -0,0 +1,287 @@ +import glob +from datetime import datetime + +import os +from autosubmit.config.log import Log +from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day + +from earthdiagnostics.cmorizer import Cmorizer +from earthdiagnostics.datamanager import DataManager +from earthdiagnostics.utils import TempFile, Utils + + +class CMORManager(DataManager): + """ + Data manager class for CMORized experiments + """ + def get_file_path(self, startdate, member, domain, var, chunk, frequency, + box=None, grid=None, year=None, date_str=None): + """ + Returns the path to a concrete file + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param domain: file's domain + :type domain: str + :param var: file's var + :type var: str + :param chunk: file's chunk + :type chunk: int + :param frequency: file's frequency + :type frequency: str + :param box: file's box + :type box: Box + :param grid: file's grid + :type grid: str + :param year: file's year + :type year: int + :param date_str: date string to add directly. Overrides year or chunk configurations + :type date_str: str + :return: path to the file + :rtype: str + """ + if not frequency: + frequency = self.config.frequency + var = self._get_final_var_name(box, var) + domain_abreviattion = self.get_domain_abbreviation(domain, frequency) + start = parse_date(startdate) + member_plus = str(member + 1) + + member_path = os.path.join(self._get_startdate_path(startdate), frequency, domain) + if chunk is not None: + chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') + chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') + chunk_end = previous_day(chunk_end, 'standard') + + time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, + chunk_end.month) + + elif year: + if frequency is not 'yr': + raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') + time_bound = str(year) + elif date_str: + time_bound = date_str + else: + raise ValueError('Chunk, year and date_str can not be None at the same time') + if grid: + var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) + else: + var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) + filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' + '{6}.nc'.format(var, domain_abreviattion, self.experiment.model, + self.experiment.experiment_name, + startdate, member_plus, time_bound)) + return filepath + + def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, + frequency=None, year=None, date_str=None, move_old=False): + """ + Creates the link of a given file from the CMOR repository. + + :param move_old: + :param date_str: + :param year: if frequency is yearly, this parameter is used to give the corresponding year + :type year: int + :param domain: CMOR domain + :type domain: str + :param var: variable name + :type var: str + :param startdate: file's startdate + :type startdate: str + :param member: file's member + :type member: int + :param chunk: file's chunk + :type chunk: int + :param grid: file's grid (only needed if it is not the original) + :type grid: str + :param box: file's box (only needed to retrieve sections or averages) + :type box: Box + :param frequency: file's frequency (only needed if it is different from the default) + :type frequency: str + :return: path to the copy created on the scratch folder + :rtype: str + """ + var = self._get_final_var_name(box, var) + + if not frequency: + frequency = self.config.frequency + domain = DataManager.correct_domain(domain) + filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, grid, year, date_str) + self._create_link(domain, filepath, frequency, var, grid, move_old) + + def get_year(self, domain, var, startdate, member, year, grid=None, box=None): + """ + Ge a file containing all the data for one year for one variable + :param domain: variable's domain + :type domain: str + :param var: variable's name + :type var: str + :param startdate: startdate to retrieve + :type startdate: str + :param member: member to retrieve + :type member: int + :param year: year to retrieve + :type year: int + :param grid: variable's grid + :type grid: str + :param box: variable's box + :type box: Box + :return: + """ + + chunk_files = list() + for chunk in self.experiment.get_year_chunks(startdate, year): + chunk_files.append(self.get_file(domain, var, startdate, member, chunk, grid=grid, box=box)) + + if len(chunk_files) > 1: + temp = TempFile.get() + Utils.nco.ncrcat(input=' '.join(chunk_files), output=temp) + for chunk_file in chunk_files: + os.remove(chunk_file) + else: + temp = chunk_files[0] + temp2 = TempFile.get() + handler = Utils.openCdf(temp) + time = Utils.get_datetime_from_netcdf(handler) + handler.close() + start = None + end = None + for x in range(0, len(time)): + date = time[x] + if date.year == year: + if date.month == 1: + start = x + elif date.month == 12: + end = x + + Utils.nco.ncks(input=temp, output=temp2, options='-O -d time,{0},{1}'.format(start, end)) + os.remove(temp) + return temp2 + + def _is_cmorized(self, startdate, member): + startdate_path = self._get_startdate_path(startdate) + if not os.path.exists(startdate_path): + return False + for freq in os.listdir(startdate_path): + freq_path = os.path.join(startdate_path, freq) + for domain in os.listdir(freq_path): + domain_path = os.path.join(freq_path, domain) + for var in os.listdir(domain_path): + member_path = os.path.join(domain_path, var, 'r{0}i1p1'.format(member + 1)) + if os.path.exists(member_path): + return True + return False + + # noinspection PyPep8Naming + def prepare_CMOR_files(self): + """ + Prepares the data to be used by the diagnostic. + + If CMOR data is not created, it show a warning and closes. In the future, an automatic cmorization procedure + will be launched + + If CMOR data is available but packed, the procedure will unpack it. + + :return: + """ + # Check if cmorized and convert if not + + for startdate, member in self.experiment.get_member_list(): + + if self._is_cmorized(startdate, member) and not self.config.cmor.force: + continue + member_str = self.experiment.get_member_str(member) + if not self.config.cmor.force: + tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') + tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, + 'cmorfiles') + file_name = 'CMOR?_{0}_{1}_*.tar.gz'.format(self.experiment.expid, startdate, member_str) + filepaths = glob.glob(os.path.join(tar_path, file_name)) + filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) + if len(filepaths) > 0: + Log.info('Unzipping cmorized data...') + Utils.unzip(filepaths, True) + + if not os.path.exists(self.cmor_path): + os.mkdir(self.cmor_path) + + file_name = 'CMOR?_{0}_{1}_*.tar'.format(self.experiment.expid, startdate, member_str) + filepaths = glob.glob(os.path.join(tar_path, file_name)) + filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, file_name)) + filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) + if len(filepaths) > 0: + Log.info('Unpacking cmorized data...') + Utils.untar(filepaths, self.cmor_path) + self._correct_paths(startdate) + self._create_links(startdate) + continue + + start_time = datetime.now() + Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) + + cmorizer = Cmorizer(self, startdate, member) + cmorizer.cmorize_ocean() + cmorizer.cmorize_atmos() + Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, + datetime.now() - start_time) + + def _correct_paths(self, startdate): + bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) + if os.path.exists(bad_path): + Log.debug('Moving CMOR files out of the output folder') + Utils.execute_shell_command(['mv', bad_path, os.path.join(bad_path, '..', '..')]) + os.rmdir(os.path.join(self.cmor_path, 'output')) + Log.debug('Done') + + if self.experiment.experiment_name != self.experiment.model: + bad_path = os.path.join(self.cmor_path, self.experiment.institute, self.experiment.model, + self.experiment.model) + Log.debug('Correcting double model appearance') + for (dirpath, dirnames, filenames) in os.walk(bad_path, False): + + for filename in filenames: + filepath = os.path.join(dirpath, filename) + good = filepath.replace('_{0}_output_'.format(self.experiment.model), + '_{0}_{1}_S{2}_'.format(self.experiment.model, + self.experiment.experiment_name, + startdate)) + + good = good.replace('/{0}/{0}'.format(self.experiment.model), + '/{0}/{1}'.format(self.experiment.model, + self.experiment.experiment_name)) + + Utils.move_file(filepath, good) + os.rmdir(dirpath) + Log.debug('Done') + + def _create_links(self, startdate): + Log.info('Creating links for CMOR files ()') + path = self._get_startdate_path(startdate) + for freq in os.listdir(path): + for domain in os.listdir(os.path.join(path, freq)): + for var in os.listdir(os.path.join(path, freq, domain)): + for member in os.listdir(os.path.join(path, freq, domain, var)): + for name in os.listdir(os.path.join(path, freq, domain, var, member)): + filepath = os.path.join(path, freq, domain, var, member, name) + if os.path.isfile(filepath): + self._create_link(domain, filepath, freq, var, "", False) + else: + for filename in os.listdir(filepath): + self._create_link(domain, os.path.join(filepath, filename), freq, var, "", False) + Log.info('Creating lings for CMOR files') + + def _get_startdate_path(self, startdate): + """ + Returns the path to the startdate's CMOR folder + :param startdate: target startdate + :type startdate: str + :return: path to the startdate's CMOR folder + :rtype: str + """ + return os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles', self.experiment.institute, + self.experiment.model, self.experiment.experiment_name, 'S' + startdate) \ No newline at end of file diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index ca6ffec..06a0f40 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,18 +1,13 @@ # coding: utf-8 import csv -import glob import shutil import threading -from datetime import datetime import numpy as np import os import re -from autosubmit.config.log import Log -from autosubmit.date.chunk_date_lib import parse_date, chunk_start_date, chunk_end_date, previous_day from cfunits import Units -from earthdiagnostics.cmorizer import Cmorizer from earthdiagnostics.utils import Utils, TempFile from earthdiagnostics.variable import Variable @@ -118,54 +113,15 @@ class DataManager(object): if region: self._prepare_region(filepath, filetosend, region, var) - - temp = TempFile.get() - Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetosend, temp]) - shutil.move(temp, filetosend) - + Utils.convert2netcdf4(filetosend, True) if cmor_var: - handler = Utils.openCdf(filetosend) - var_handler = handler.variables[var] - var_handler.standard_name = cmor_var.standard_name - var_handler.long_name = cmor_var.long_name - var_handler.short_name = cmor_var.short_name - var_type = var_handler.dtype - handler.modeling_realm = cmor_var.domain - handler.table_id = 'Table {0} (December 2013)'.format(self.get_domain_abbreviation(cmor_var.domain, - frequency)) - - if cmor_var.units: - self._fix_units(cmor_var, var_handler) - - handler.sync() - if 'lev' in handler.variables: - handler.variables['lev'].short_name = 'lev' - if domain == 'ocean': - handler.variables['lev'].standard_name = 'depth' - if 'lon' in handler.variables: - handler.variables['lon'].short_name = 'lon' - handler.variables['lon'].standard_name = 'longitude' - if 'lat' in handler.variables: - handler.variables['lat'].short_name = 'lat' - handler.variables['lat'].standard_name = 'latitude' - - handler.close() - - if cmor_var.valid_min != '': - valid_min = '-a valid_min, {0}, o, {1}, "{2}" '.format(var, var_type.char, cmor_var.valid_min) - else: - valid_min = '' + self._correct_metadata(cmor_var, domain, filetosend, frequency, var) + self._rename_coordinate_variables(filetosend) - if cmor_var.valid_max != '': - valid_max = '-a valid_max, {0}, o, {1}, "{2}" '.format(var, var_type.char, cmor_var.valid_max) - else: - valid_max = '' - - Utils.nco.ncatted(input=filetosend, output=filetosend, - options='-O -a _FillValue,{0},o,{1},"1.e20" ' - '-a missingValue,{0},o,{1},"1.e20" {2}{3}'.format(var, var_type.char, - valid_min, valid_max)) + Utils.move_file(filetosend, filepath) + self._create_link(domain, filepath, frequency, var, grid, move_old) + def _rename_coordinate_variables(self, filetosend): variables = dict() variables['x'] = 'i' variables['y'] = 'j' @@ -177,8 +133,48 @@ class DataManager(object): variables['nav_lon_grid_T'] = 'lon' Utils.rename_variables(filetosend, variables, False, True) - Utils.move_file(filetosend, filepath) - self._create_link(domain, filepath, frequency, var, grid, move_old) + def _correct_metadata(self, cmor_var, domain, filetosend, frequency, var): + handler = Utils.openCdf(filetosend) + var_handler = handler.variables[var] + var_handler.standard_name = cmor_var.standard_name + var_handler.long_name = cmor_var.long_name + var_handler.short_name = cmor_var.short_name + var_type = var_handler.dtype + handler.modeling_realm = cmor_var.domain + handler.table_id = 'Table {0} (December 2013)'.format(self.get_domain_abbreviation(cmor_var.domain, + frequency)) + if cmor_var.units: + self._fix_units(cmor_var, var_handler) + handler.sync() + self._fix_coordinate_variables_metadata(domain, handler) + handler.close() + self._fix_values_metadata(cmor_var, filetosend, var, var_type) + + def _fix_values_metadata(self, cmor_var, filetosend, var, var_type): + if cmor_var.valid_min != '': + valid_min = '-a valid_min, {0}, o, {1}, "{2}" '.format(var, var_type.char, cmor_var.valid_min) + else: + valid_min = '' + if cmor_var.valid_max != '': + valid_max = '-a valid_max, {0}, o, {1}, "{2}" '.format(var, var_type.char, cmor_var.valid_max) + else: + valid_max = '' + Utils.nco.ncatted(input=filetosend, output=filetosend, + options='-O -a _FillValue,{0},o,{1},"1.e20" ' + '-a missingValue,{0},o,{1},"1.e20" {2}{3}'.format(var, var_type.char, + valid_min, valid_max)) + + def _fix_coordinate_variables_metadata(self, domain, handler): + if 'lev' in handler.variables: + handler.variables['lev'].short_name = 'lev' + if domain == 'ocean': + handler.variables['lev'].standard_name = 'depth' + if 'lon' in handler.variables: + handler.variables['lon'].short_name = 'lon' + handler.variables['lon'].standard_name = 'longitude' + if 'lat' in handler.variables: + handler.variables['lat'].short_name = 'lat' + handler.variables['lat'].standard_name = 'latitude' @staticmethod def _fix_units(cmor_var, var_handler): @@ -275,46 +271,31 @@ class DataManager(object): return 'landIce' return domain - def _create_link(self, domain, filepath, frequency, var, grid, move_old): - if frequency in ('d', 'daily', 'day'): - freq_str = 'daily_mean' - elif frequency.endswith('hr'): - freq_str = frequency[:-2] + 'hourly' + def get_varfolder(self, domain, var): + if domain in ['ocean', 'seaIce']: + return '{0}_f{1}h'.format(var, self.experiment.ocean_timestep) else: - freq_str = 'monthly_mean' + return '{0}_f{1}h'.format(var, self.experiment.atmos_timestep) + + def _create_link(self, domain, filepath, frequency, var, grid, move_old): + freq_str = self.frequency_folder_name(frequency) if not grid: grid = 'original' var_grid = '{0}-{1}'.format(var, grid) - if domain in ['ocean', 'seaIce']: - variable_folder = '{0}_f{1}h'.format(var, self.experiment.ocean_timestep) - vargrid_folder = '{0}_f{1}h'.format(var_grid, self.experiment.ocean_timestep) - else: - variable_folder = '{0}_f{1}h'.format(var, self.experiment.atmos_timestep) - vargrid_folder = '{0}_f{1}h'.format(var_grid, self.experiment.atmos_timestep) + variable_folder = self.get_varfolder(domain, var) + vargrid_folder = self.get_varfolder(domain, var_grid) if grid == 'original': link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) if os.path.islink(link_path): link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, vargrid_folder) - if not os.path.exists(link_path): - # This can be a race condition - # noinspection PyBroadException - try: - os.makedirs(link_path) - except Exception: - pass + Utils.create_folder_tree(link_path) else: link_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, vargrid_folder) - if not os.path.exists(link_path): - # This can be a race condition - # noinspection PyBroadException - try: - os.makedirs(link_path) - except Exception: - pass + Utils.create_folder_tree(link_path) default_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, variable_folder) original_path = os.path.join(self.config.data_dir, self.experiment.expid, freq_str, vargrid_folder.replace('-{0}_f'.format(grid), '-original_f')) @@ -334,13 +315,7 @@ class DataManager(object): regex = re.compile(var + '_[0-9]{6,8}\.nc') for filename in os.listdir(link_path): if regex.match(filename): - if not os.path.exists(old_path): - # This can be a race condition - # noinspection PyBroadException - try: - os.makedirs(old_path) - except Exception: - pass + Utils.create_folder_tree(old_path) Utils.move_file(os.path.join(link_path, filename), os.path.join(old_path, filename)) @@ -351,6 +326,15 @@ class DataManager(object): raise ValueError('Original file {0} does not exists'.format(filepath)) os.symlink(filepath, link_path) + def frequency_folder_name(self, frequency): + if frequency in ('d', 'daily', 'day'): + freq_str = 'daily_mean' + elif frequency.endswith('hr'): + freq_str = frequency[:-2] + 'hourly' + else: + freq_str = 'monthly_mean' + return freq_str + @staticmethod def get_domain_abbreviation(domain, frequency): """ @@ -460,258 +444,6 @@ class DataManager(object): pass -class CMORManager(DataManager): - """ - Data manager class for CMORized experiments - """ - def get_file_path(self, startdate, member, domain, var, chunk, frequency, - box=None, grid=None, year=None, date_str=None): - """ - Returns the path to a concrete file - :param startdate: file's startdate - :type startdate: str - :param member: file's member - :type member: int - :param domain: file's domain - :type domain: str - :param var: file's var - :type var: str - :param chunk: file's chunk - :type chunk: int - :param frequency: file's frequency - :type frequency: str - :param box: file's box - :type box: Box - :param grid: file's grid - :type grid: str - :param year: file's year - :type year: int - :param date_str: date string to add directly. Overrides year or chunk configurations - :type date_str: str - :return: path to the file - :rtype: str - """ - if not frequency: - frequency = self.config.frequency - var = self._get_final_var_name(box, var) - domain_abreviattion = self.get_domain_abbreviation(domain, frequency) - start = parse_date(startdate) - member_plus = str(member + 1) - - member_path = os.path.join(self._get_startdate_path(startdate), frequency, domain) - if chunk is not None: - chunk_start = chunk_start_date(start, chunk, self.experiment.chunk_size, 'month', 'standard') - chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') - chunk_end = previous_day(chunk_end, 'standard') - - time_bound = "{0:04}{1:02}-{2:04}{3:02}".format(chunk_start.year, chunk_start.month, chunk_end.year, - chunk_end.month) - - elif year: - if frequency is not 'yr': - raise ValueError('Year may be provided instead of chunk only if frequency is "yr"') - time_bound = str(year) - elif date_str: - time_bound = date_str - else: - raise ValueError('Chunk, year and date_str can not be None at the same time') - if grid: - var_path = os.path.join(member_path, var, grid, 'r{0}i1p1'.format(member_plus)) - else: - var_path = os.path.join(member_path, var, 'r{0}i1p1'.format(member_plus)) - filepath = os.path.join(var_path, '{0}_{1}_{2}_{3}_S{4}_r{5}i1p1_' - '{6}.nc'.format(var, domain_abreviattion, self.experiment.model, - self.experiment.experiment_name, - startdate, member_plus, time_bound)) - return filepath - - def link_file(self, domain, var, startdate, member, chunk=None, grid=None, box=None, - frequency=None, year=None, date_str=None, move_old=False): - - var = self._get_final_var_name(box, var) - - if not frequency: - frequency = self.config.frequency - domain = DataManager.correct_domain(domain) - filepath = self.get_file_path(startdate, member, domain, var, chunk, frequency, grid, year, date_str) - self._create_link(domain, filepath, frequency, var, grid, move_old) - - def get_year(self, domain, var, startdate, member, year, grid=None, box=None): - """ - Ge a file containing all the data for one year for one variable - :param domain: variable's domain - :type domain: str - :param var: variable's name - :type var: str - :param startdate: startdate to retrieve - :type startdate: str - :param member: member to retrieve - :type member: int - :param year: year to retrieve - :type year: int - :param grid: variable's grid - :type grid: str - :param box: variable's box - :type box: Box - :return: - """ - - chunk_files = list() - for chunk in self.experiment.get_year_chunks(startdate, year): - chunk_files.append(self.get_file(domain, var, startdate, member, chunk, grid=grid, box=box)) - - if len(chunk_files) > 1: - temp = TempFile.get() - Utils.nco.ncrcat(input=' '.join(chunk_files), output=temp) - for chunk_file in chunk_files: - os.remove(chunk_file) - else: - temp = chunk_files[0] - temp2 = TempFile.get() - handler = Utils.openCdf(temp) - time = Utils.get_datetime_from_netcdf(handler) - handler.close() - start = None - end = None - for x in range(0, len(time)): - date = time[x] - if date.year == year: - if date.month == 1: - start = x - elif date.month == 12: - end = x - - Utils.nco.ncks(input=temp, output=temp2, options='-O -d time,{0},{1}'.format(start, end)) - os.remove(temp) - return temp2 - - def _is_cmorized(self, startdate, member): - startdate_path = self._get_startdate_path(startdate) - if not os.path.exists(startdate_path): - return False - for freq in os.listdir(startdate_path): - freq_path = os.path.join(startdate_path, freq) - for domain in os.listdir(freq_path): - domain_path = os.path.join(freq_path, domain) - for var in os.listdir(domain_path): - member_path = os.path.join(domain_path, var, 'r{0}i1p1'.format(member + 1)) - if os.path.exists(member_path): - return True - return False - - # noinspection PyPep8Naming - def prepare_CMOR_files(self): - """ - Prepares the data to be used by the diagnostic. - - If CMOR data is not created, it show a warning and closes. In the future, an automatic cmorization procedure - will be launched - - If CMOR data is available but packed, the procedure will unpack it. - - :return: - """ - # Check if cmorized and convert if not - - for startdate, member in self.experiment.get_member_list(): - - if self._is_cmorized(startdate, member) and not self.config.cmor.force: - continue - member_str = self.experiment.get_member_str(member) - if not self.config.cmor.force: - tar_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', 'cmorfiles') - tar_original_files = os.path.join(self.config.data_dir, 'original_files', self.experiment.expid, - 'cmorfiles') - file_name = 'CMOR?_{0}_{1}_*.tar.gz'.format(self.experiment.expid, startdate, member_str) - filepaths = glob.glob(os.path.join(tar_path, file_name)) - filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) - if len(filepaths) > 0: - Log.info('Unzipping cmorized data...') - Utils.unzip(filepaths, True) - - if not os.path.exists(self.cmor_path): - os.mkdir(self.cmor_path) - - file_name = 'CMOR?_{0}_{1}_*.tar'.format(self.experiment.expid, startdate, member_str) - filepaths = glob.glob(os.path.join(tar_path, file_name)) - filepaths += glob.glob(os.path.join(tar_path, 'outputs', file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, file_name)) - filepaths += glob.glob(os.path.join(tar_original_files, 'outputs', file_name)) - if len(filepaths) > 0: - Log.info('Unpacking cmorized data...') - Utils.untar(filepaths, self.cmor_path) - self._correct_paths(startdate) - self._create_links(startdate) - continue - - start_time = datetime.now() - Log.info('CMORizing startdate {0} member {1}. Starting at {0}', startdate, member_str, start_time) - - cmorizer = Cmorizer(self, startdate, member) - cmorizer.cmorize_ocean() - cmorizer.cmorize_atmos() - Log.result('CMORized startdate {0} member {1}!\n\n', startdate, member_str, - datetime.now() - start_time) - - def _correct_paths(self, startdate): - bad_path = os.path.join(self.cmor_path, 'output', self.experiment.institute) - if os.path.exists(bad_path): - Log.debug('Moving CMOR files out of the output folder') - Utils.execute_shell_command(['mv', bad_path, os.path.join(bad_path, '..', '..')]) - os.rmdir(os.path.join(self.cmor_path, 'output')) - Log.debug('Done') - - if self.experiment.experiment_name != self.experiment.model: - bad_path = os.path.join(self.cmor_path, self.experiment.institute, self.experiment.model, - self.experiment.model) - Log.debug('Correcting double model appearance') - for (dirpath, dirnames, filenames) in os.walk(bad_path, False): - - for filename in filenames: - filepath = os.path.join(dirpath, filename) - good = filepath.replace('_{0}_output_'.format(self.experiment.model), - '_{0}_{1}_S{2}_'.format(self.experiment.model, - self.experiment.experiment_name, - startdate)) - - good = good.replace('/{0}/{0}'.format(self.experiment.model), - '/{0}/{1}'.format(self.experiment.model, - self.experiment.experiment_name)) - - Utils.move_file(filepath, good) - os.rmdir(dirpath) - Log.debug('Done') - - def _create_links(self, startdate): - Log.info('Creating links for CMOR files ()') - path = self._get_startdate_path(startdate) - for freq in os.listdir(path): - for domain in os.listdir(os.path.join(path, freq)): - for var in os.listdir(os.path.join(path, freq, domain)): - for member in os.listdir(os.path.join(path, freq, domain, var)): - for name in os.listdir(os.path.join(path, freq, domain, var, member)): - filepath = os.path.join(path, freq, domain, var, member, name) - if os.path.isfile(filepath): - self._create_link(domain, filepath, freq, var, "", False) - else: - for filename in os.listdir(filepath): - self._create_link(domain, os.path.join(filepath, filename), freq, var, "", False) - Log.info('Creating lings for CMOR files') - - def _get_startdate_path(self, startdate): - """ - Returns the path to the startdate's CMOR folder - :param startdate: target startdate - :type startdate: str - :return: path to the startdate's CMOR folder - :rtype: str - """ - return os.path.join(self.config.data_dir, self.experiment.expid, 'cmorfiles', self.experiment.institute, - self.experiment.model, self.experiment.experiment_name, 'S' + startdate) - - class UnitConversion(object): """ Class to manage unit conversions diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 3eacf73..6021bb4 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -13,7 +13,7 @@ import os from autosubmit.date.chunk_date_lib import * from config import Config -from datamanager import CMORManager +from earthdiagnostics.cmormanager import CMORManager from earthdiagnostics import cdftools from earthdiagnostics.utils import TempFile from earthdiagnostics.diagnostic import Diagnostic diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 3ac18e4..0c79647 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -471,12 +471,27 @@ class Utils(object): translated.append(dim) return translated + @staticmethod + def create_folder_tree(path): + """ + Createas a fodle path will and parent directories if needed. + :param path: folder's path + :type path: str + """ + if not os.path.exists(path): + # This can be a race condition + # noinspection PyBroadException + try: + os.makedirs(path) + except Exception: + pass + @staticmethod def untar(files, destiny_path): """ Untar files to a given destiny :param files: files to unzip - :type files: list + :type files: list[Any] | Tuple[Any] :param destiny_path: path to destination folder :type destiny_path: str """ -- GitLab From c1a0b25a911ee3dcbe44ae8c21f1493cf379cbb1 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 11 Oct 2016 11:15:49 +0200 Subject: [PATCH 247/268] Refactored cmorizer. --- earthdiagnostics/cmorizer.py | 402 +++++++++++++++++++---------------- 1 file changed, 220 insertions(+), 182 deletions(-) diff --git a/earthdiagnostics/cmorizer.py b/earthdiagnostics/cmorizer.py index dcced38..57169c9 100644 --- a/earthdiagnostics/cmorizer.py +++ b/earthdiagnostics/cmorizer.py @@ -28,6 +28,14 @@ class Cmorizer(object): """ + NON_DATA_VARIABLES = ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', + 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', + 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', + 'time_counter_bounds', 'ncatice', 'nav_lat_grid_V', 'nav_lat_grid_U', + 'nav_lat_grid_T', 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T', + 'depth', 'depth_2', 'depth_3', 'depth_4', + 'mlev', 'hyai', 'hybi', 'hyam', 'hybm') + def __init__(self, data_manager, startdate, member): self.data_manager = data_manager self.startdate = startdate @@ -38,6 +46,8 @@ class Cmorizer(object): self.member_str = self.experiment.get_member_str(member) self.original_files_path = os.path.join(self.config.data_dir, self.experiment.expid, 'original_files', self.startdate, self.member_str, 'outputs') + self.atmos_timestep = None + self.cmor_scratch = os.path.join(self.config.scratch_dir, 'CMOR') def cmorize_ocean(self): """ @@ -46,60 +56,50 @@ class Cmorizer(object): """ if not self.cmor.ocean: return - self._unpack_ocean_files('MMO') - self._unpack_ocean_files('PPO') - self._unpack_ocean_files('diags') + self._cmorize_ocean_files('MMO') + self._cmorize_ocean_files('PPO') + self._cmorize_ocean_files('diags') - def _unpack_ocean_files(self, prefix): + def _cmorize_ocean_files(self, prefix): tar_folder = os.path.join(self.original_files_path, '{0}*'.format(prefix)) tar_files = glob.glob(tar_folder) tar_files.sort() - errors = list() count = 1 for tarfile in tar_files: Log.info('Unpacking oceanic file {0}/{1}'.format(count, len(tar_files))) - self._unpack_tar(tarfile) + self._unpack_tar_file(tarfile) + self._cmorize_nc_files() Log.result('Oceanic file {0}/{1} finished'.format(count, len(tar_files))) count += 1 - return errors - - def _unpack_tar(self, tarfile): - Log.info('Unpacking {0}', tarfile) - - scratch_dir = os.path.join(self.config.scratch_dir, 'CMOR') - - if os.path.exists(scratch_dir): - shutil.rmtree(scratch_dir) - os.makedirs(scratch_dir) - Utils.untar((tarfile,), scratch_dir) - errors = Utils.unzip(glob.glob(os.path.join(scratch_dir, '*.gz'))) - - if os.path.basename(tarfile).startswith('MMA'): - temp = TempFile.get() - for filename in glob.glob(os.path.join(scratch_dir, 'MMA_*_SH_*.nc')): - Utils.cdo.sp2gpl(options='-O', input=filename, output=temp) - shutil.move(temp, filename) - - sh_files = glob.glob(os.path.join(scratch_dir, 'MMA_*_SH_*.nc')) - Utils.cdo.mergetime(input=sh_files, output=os.path.join(scratch_dir, 'sh.nc')) - - gg_files = glob.glob(os.path.join(scratch_dir, 'MMA_*_GG_*.nc')) - Utils.cdo.mergetime(input=gg_files, output=os.path.join(scratch_dir, 'gg.nc')) - - for filename in sh_files + gg_files: - os.remove(filename) - Utils.nco.ncks(input=os.path.join(scratch_dir, 'sh.nc'), - output=os.path.join(scratch_dir, 'gg.nc'), options='-A') - os.remove(os.path.join(scratch_dir, 'sh.nc')) + def _cmorize_nc_files(self): + for filename in glob.glob(os.path.join(self.cmor_scratch, '*.nc')): + self._cmorize_nc_file(filename) - tar_startdate = tarfile[0:-4].split('_')[5].split('-') - new_name = 'MMA_1m_{0[0]}_{0[1]}.nc'.format(tar_startdate) - shutil.move(os.path.join(scratch_dir, 'gg.nc'), os.path.join(scratch_dir, new_name)) + def _unpack_tar_file(self, tarfile): + if os.path.exists(self.cmor_scratch): + shutil.rmtree(self.cmor_scratch) + os.makedirs(self.cmor_scratch) + Utils.untar((tarfile,), self.cmor_scratch) + Utils.unzip(glob.glob(os.path.join(self.cmor_scratch, '*.gz'))) - for filename in glob.glob(os.path.join(scratch_dir, '*.nc')): - self._cmorize_nc_file(filename) - return errors + def _merge_mma_files(self, tarfile): + temp = TempFile.get() + for filename in glob.glob(os.path.join(self.cmor_scratch, 'MMA_*_SH_*.nc')): + Utils.cdo.sp2gpl(options='-O', input=filename, output=temp) + shutil.move(temp, filename) + sh_files = glob.glob(os.path.join(self.cmor_scratch, 'MMA_*_SH_*.nc')) + Utils.cdo.mergetime(input=sh_files, output=os.path.join(self.cmor_scratch, 'sh.nc')) + gg_files = glob.glob(os.path.join(self.cmor_scratch, 'MMA_*_GG_*.nc')) + Utils.cdo.mergetime(input=gg_files, output=os.path.join(self.cmor_scratch, 'gg.nc')) + for filename in sh_files + gg_files: + os.remove(filename) + Utils.nco.ncks(input=os.path.join(self.cmor_scratch, 'sh.nc'), + output=os.path.join(self.cmor_scratch, 'gg.nc'), options='-A') + os.remove(os.path.join(self.cmor_scratch, 'sh.nc')) + tar_startdate = tarfile[0:-4].split('_')[5].split('-') + new_name = 'MMA_1m_{0[0]}_{0[1]}.nc'.format(tar_startdate) + shutil.move(os.path.join(self.cmor_scratch, 'gg.nc'), os.path.join(self.cmor_scratch, new_name)) def cmorize_atmos(self): """ @@ -109,32 +109,29 @@ class Cmorizer(object): if not self.cmor.atmosphere: return - if self.cmor.use_grib: - grb_path = os.path.join(self.original_files_path, '*.grb') - gribfiles = glob.glob(grb_path) + if self.cmor.use_grib and self.gribfiles_available(): + self._cmorize_grib_files() else: - gribfiles = tuple() - - if len(gribfiles) == 0: - tar_files = glob.glob( - os.path.join(self.original_files_path, 'MMA*')) - tar_files.sort() - count = 1 - for tarfile in tar_files: - Log.info('Unpacking atmospheric file {0}/{1}'.format(count, len(tar_files))) - self._unpack_tar(tarfile) - Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) - count += 1 - - self._cmorize_grib() - - def _cmorize_grib(self): + self._cmorize_mma_files() + + def _cmorize_mma_files(self): + tar_files = glob.glob(os.path.join(self.original_files_path, 'MMA*')) + tar_files.sort() + count = 1 + for tarfile in tar_files: + Log.info('Unpacking atmospheric file {0}/{1}'.format(count, len(tar_files))) + self._unpack_tar_file(tarfile) + self._merge_mma_files(tarfile) + self._cmorize_nc_files() + Log.result('Atmospheric file {0}/{1} finished'.format(count, len(tar_files))) + count += 1 + + def _cmorize_grib_files(self): count = 1 - atmos_timestep = None chunk_start = parse_date(self.startdate) - while os.path.exists(os.path.join(self.original_files_path, self._get_grib_filename('GG', chunk_start))) or \ - os.path.exists(os.path.join(self.original_files_path, self._get_grib_filename('SH', chunk_start))): + while os.path.exists(self.get_original_grib_path(chunk_start, 'GG')) or \ + os.path.exists(self.get_original_grib_path(chunk_start, 'SH')): chunk_end = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') chunk_end = previous_day(chunk_end, 'standard') @@ -142,69 +139,77 @@ class Cmorizer(object): for grid in ('SH', 'GG'): Log.info('Processing {0} variables', grid) - if not os.path.exists(os.path.join(self.original_files_path, - self._get_grib_filename(grid, chunk_start))): + if not os.path.exists(self.get_original_grib_path(chunk_start, grid)): continue - - for month in range(0, self.experiment.chunk_size): - current_month = add_months(chunk_start, month, 'standard') - original_gribfile = os.path.join(self.original_files_path, - self._get_grib_filename(grid, current_month)) - Log.info('Processing month {1}', grid, date2str(current_month)) - gribfile = os.path.join(self.config.scratch_dir, os.path.basename(original_gribfile)) - if not os.path.isfile(gribfile): - Log.info('Copying file...', grid, date2str(current_month)) - shutil.copy(original_gribfile, gribfile) - - if atmos_timestep is None: - atmos_timestep = self._get_atmos_timestep(gribfile) - - prev_gribfile = os.path.join(self.config.scratch_dir, - self._get_grib_filename(grid, - add_months(current_month, -1, 'standard'))) - if os.path.exists(prev_gribfile): - self._merge_grib_files(current_month, prev_gribfile, gribfile) - full_file = 'ICM' - else: - full_file = gribfile - - Log.info('Unpacking... ') - # remap on regular Gauss grid - if grid == 'SH': - Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_', - options='-f nc4') - else: - Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R -f nc4') - # total precipitation (remove negative values) - Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' - '{0}_{{142,143}}.128.nc'.format(gribfile), - output='{0}_228.128.nc'.format(gribfile)) - Utils.remove_file('ICM') - next_gribfile = os.path.join(self.original_files_path, - self._get_grib_filename(grid, - add_months(current_month, 1, 'standard'))) - - if not os.path.exists(next_gribfile): - os.remove(gribfile) - - cdo_reftime = parse_date(self.startdate).strftime('%Y-%m-%d,00:00') - - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '{0}hr'.format(atmos_timestep)) - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1d') - self._ungrib_vars(cdo_reftime, gribfile, current_month.month, '1m') - - for splited_file in glob.glob('{0}_*.128.nc'.format(gribfile)): - os.remove(splited_file) - - Log.result('Month {0}, {1} variables finished', date2str(current_month), grid) - count += 1 - - self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, '1m') - self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, '1d') - self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, - '{0}hr'.format(atmos_timestep)) + self.cmorize_grib_file(chunk_end, chunk_start, count, grid) chunk_start = chunk_end_date(chunk_start, self.experiment.chunk_size, 'month', 'standard') + def cmorize_grib_file(self, chunk_end, chunk_start, count, grid): + for month in range(0, self.experiment.chunk_size): + current_date = add_months(chunk_start, month, 'standard') + original_gribfile = self.get_original_grib_path(current_date, grid) + Log.info('Processing month {1}', grid, date2str(current_date)) + gribfile = self.get_scratch_grib_path(current_date, grid) + self._copy_gribfile(current_date, gribfile, grid, original_gribfile) + + self._obtain_atmos_timestep(gribfile) + + prev_gribfile = self.get_scratch_grib_path(add_months(current_date, -1, 'standard'), grid) + if os.path.exists(prev_gribfile): + self._merge_grib_files(current_date, prev_gribfile, gribfile) + full_file = 'ICM' + else: + full_file = gribfile + + Log.info('Unpacking... ') + # remap on regular Gauss grid + if grid == 'SH': + Utils.cdo.splitparam(input='-sp2gpl {0}'.format(full_file), output=gribfile + '_', + options='-f nc4') + else: + Utils.cdo.splitparam(input=full_file, output=gribfile + '_', options='-R -f nc4') + # total precipitation (remove negative values) + Utils.cdo.setcode(228, input='-setmisstoc,0 -setvrange,0,Inf -add ' + '{0}_{{142,143}}.128.nc'.format(gribfile), + output='{0}_228.128.nc'.format(gribfile)) + Utils.remove_file('ICM') + next_gribfile = self.get_original_grib_path(add_months(current_date, 1, 'standard'), grid) + + if not os.path.exists(next_gribfile): + os.remove(gribfile) + + cdo_reftime = parse_date(self.startdate).strftime('%Y-%m-%d,00:00') + + self._ungrib_vars(cdo_reftime, gribfile, current_date.month, '{0}hr'.format(self.atmos_timestep)) + self._ungrib_vars(cdo_reftime, gribfile, current_date.month, '1d') + self._ungrib_vars(cdo_reftime, gribfile, current_date.month, '1m') + + for splited_file in glob.glob('{0}_*.128.nc'.format(gribfile)): + os.remove(splited_file) + + Log.result('Month {0}, {1} variables finished', date2str(current_date), grid) + count += 1 + self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, '1m') + self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, '1d') + self._merge_and_cmorize_atmos(chunk_start, chunk_end, grid, + '{0}hr'.format(self.atmos_timestep)) + + def get_scratch_grib_path(self, current_date, grid): + return os.path.join(self.config.scratch_dir, self._get_grib_filename(grid, current_date)) + + def _obtain_atmos_timestep(self, gribfile): + if self.atmos_timestep is None: + self.atmos_timestep = self._get_atmos_timestep(gribfile) + + def _copy_gribfile(self, current_date, gribfile, grid, original_gribfile): + if not os.path.isfile(gribfile): + Log.info('Copying file...', grid, date2str(current_date)) + shutil.copy(original_gribfile, gribfile) + + def get_original_grib_path(self, current_date, grid): + return os.path.join(self.original_files_path, + self._get_grib_filename(grid, current_date)) + def _get_grib_filename(self, grid, month): return 'ICM{0}{1}+{2}.grb'.format(grid, self.experiment.expid, date2str(month)[:-2]) @@ -223,15 +228,28 @@ class Cmorizer(object): def _cmorize_nc_file(self, filename): Log.info('Processing file {0}', filename) - temp = TempFile.get() - handler = Utils.openCdf(filename) - variables = handler.variables.keys() - handler.close() - if not self.cmor.any_required(variables): + + if not self._contains_requested_variables(filename): os.remove(filename) return - Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filename, temp]) - shutil.move(temp, filename) + + Utils.convert2netcdf4(filename, True) + frequency = self._get_nc_file_frequency(filename) + self._rename_coordinate_variables(filename) + handler = Utils.openCdf(filename) + self._add_common_attributes(frequency, handler) + self._update_time_variables(handler) + handler.sync() + Log.info('Splitting file {0}', filename) + for variable in handler.variables.keys(): + if variable in Cmorizer.NON_DATA_VARIABLES: + continue + self.extract_variable(filename, handler, frequency, variable) + Log.result('File {0} cmorized!', filename) + handler.close() + os.remove(filename) + + def _get_nc_file_frequency(self, filename): file_parts = os.path.basename(filename).split('_') if self.experiment.expid in [file_parts[1], file_parts[2]]: frequency = 'm' @@ -243,6 +261,13 @@ class Cmorizer(object): frequency = file_parts[1][1].lower() else: frequency = file_parts[1][1].lower() + return frequency + + def _contains_requested_variables(self, filename): + variables = self._get_file_variables(filename) + return self.cmor.any_required(variables) + + def _rename_coordinate_variables(self, filename): variables = dict() variables['time_counter'] = 'time' variables['time_counter_bnds'] = 'time_bnds' @@ -252,28 +277,14 @@ class Cmorizer(object): variables['x'] = 'i' variables['y'] = 'j' Utils.rename_variables(filename, variables, False, True) + + def _get_file_variables(self, filename): handler = Utils.openCdf(filename) - self._add_common_attributes(frequency, handler) - self._update_time_variables(handler) - handler.sync() - temp = TempFile.get() - Log.info('Splitting file {0}', filename) - for variable in handler.variables.keys(): - if variable in ('lon', 'lat', 'time', 'time_bnds', 'leadtime', 'lev', 'icethi', - 'deptht', 'depthu', 'depthw', 'depthv', 'time_centered', 'time_centered_bounds', - 'deptht_bounds', 'depthu_bounds', 'depthv_bounds', 'depthw_bounds', - 'time_counter_bounds', 'ncatice', - 'nav_lat_grid_V', 'nav_lat_grid_U', 'nav_lat_grid_T', - 'nav_lon_grid_V', 'nav_lon_grid_U', 'nav_lon_grid_T', - 'depth', 'depth_2', 'depth_3', 'depth_4', - 'mlev', 'hyai', 'hybi', 'hyam', 'hybm'): - continue - self.extract_variable(filename, handler, frequency, temp, variable) - Log.result('File {0} cmorized!', filename) + variables = handler.variables.keys() handler.close() - os.remove(filename) + return variables - def extract_variable(self, file_path, handler, frequency, temp, variable): + def extract_variable(self, file_path, handler, frequency, variable): """ Extracts a variable from a file and creates the CMOR file @@ -283,41 +294,21 @@ class Cmorizer(object): :type handler: netCDF$.Dataset :param frequency: variable's frequency :type frequency: str - :param temp: temporal file to use - :type temp: str :param variable: variable's name :type variable: str """ + temp = TempFile.get() file_parts = os.path.basename(file_path).split('_') var_cmor = Variable.get_variable(variable) if var_cmor is None: return if not self.cmor.cmorize(var_cmor): return - if frequency == 'd': - frequency = 'day' - elif frequency == 'm': - frequency = 'mon' - elif frequency == 'h': - frequency = '6hr' - else: - raise Exception('Frequency {0} not supported'.format(frequency)) + frequency = self.translate_frequency(frequency) Utils.nco.ncks(input=file_path, output=temp, options='-v {0}'.format(variable)) - if var_cmor.domain == 'ocean': - Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev', - 'depth': 'lev'}, False, True) - elif var_cmor.domain in ('land', 'landIce'): - Utils.rename_variables(temp, {'depth': 'sdepth', 'depth_2': 'sdepth', 'depth_3': 'sdepth', - 'depth_4': 'sdepth'}, False, True) - elif var_cmor.domain == 'atmos': - Utils.rename_variables(temp, {'depth': 'plev'}, False, True) + self._rename_level_variables(temp, var_cmor) - handler_cmor = Utils.openCdf(temp) - Utils.copy_variable(handler, handler_cmor, 'lon', False) - Utils.copy_variable(handler, handler_cmor, 'lat', False) - if 'time' in handler_cmor.dimensions.keys(): - Utils.copy_variable(handler, handler_cmor, 'leadtime', False) - handler_cmor.close() + self._add_coordinate_variables(handler, temp) if var_cmor.basin is None: region = None @@ -334,12 +325,42 @@ class Cmorizer(object): else: Log.error('Variable {0} can not be cmorized. Original filename does not match a recognized pattern', var_cmor.short_name) - return + raise CMORException('Variable {0}:{1} can not be cmorized. Original filename does not match a recognized ' + 'pattern'.format(var_cmor.domain, var_cmor.short_name)) self.data_manager.send_file(temp, var_cmor.domain, var_cmor.short_name, self.startdate, self.member, frequency=frequency, rename_var=variable, date_str=date_str, region=region, move_old=True, grid=var_cmor.grid) + def _add_coordinate_variables(self, handler, temp): + handler_cmor = Utils.openCdf(temp) + Utils.copy_variable(handler, handler_cmor, 'lon', False) + Utils.copy_variable(handler, handler_cmor, 'lat', False) + if 'time' in handler_cmor.dimensions.keys(): + Utils.copy_variable(handler, handler_cmor, 'leadtime', False) + handler_cmor.close() + + def _rename_level_variables(self, temp, var_cmor): + if var_cmor.domain == 'ocean': + Utils.rename_variables(temp, {'deptht': 'lev', 'depthu': 'lev', 'depthw': 'lev', 'depthv': 'lev', + 'depth': 'lev'}, False, True) + if var_cmor.domain in ('land', 'landIce'): + Utils.rename_variables(temp, {'depth': 'sdepth', 'depth_2': 'sdepth', 'depth_3': 'sdepth', + 'depth_4': 'sdepth'}, False, True) + if var_cmor.domain == 'atmos': + Utils.rename_variables(temp, {'depth': 'plev'}, False, True) + + def translate_frequency(self, frequency): + if frequency == 'd': + frequency = 'day' + elif frequency == 'm': + frequency = 'mon' + elif frequency == 'h': + frequency = '6hr' + else: + raise Exception('Frequency {0} not supported'.format(frequency)) + return frequency + @staticmethod def _merge_grib_files(current_month, prev_gribfile, gribfile): Log.info('Merging data from different files...') @@ -371,7 +392,7 @@ class Cmorizer(object): cdo_operator = "-monmean -daymax {0}".format(cdo_operator) else: cdo_operator = "-monmean {0} ".format(cdo_operator) - elif frequency in ('day', 'daily', '1d'): + if frequency in ('day', 'daily', '1d'): if var_code == 201: cdo_operator = "-daymax {0} ".format(cdo_operator) elif var_code == 202: @@ -445,14 +466,26 @@ class Cmorizer(object): def _update_time_variables(self, handler): time_var = handler.variables['time'] times = Utils.get_datetime_from_netcdf(handler) + time_var.units = 'days since 1850-01-01' + time_var.time_origin = "1850-01-01" + time_var.calendar = 'standard' + time_var.long_name = "Verification time of the forecast" + time_var.standard_name = "time" + time_var.axis = "T" if type(times[0]) is not datetime: for x in range(0, times.shape[0]): # noinspection PyProtectedMember times[x] = times[x]._to_real_datetime() time_var[:] = netCDF4.date2num(times, 'days since 1850-01-01', 'standard') + if 'axis_nbounds' in handler.dimensions: handler.renameDimension('axis_nbounds', 'bnds') + self._set_time_bounds(handler, time_var) + + self._set_leadtime_var(handler) + + def _set_time_bounds(self, handler, time_var): if 'time_counter_bounds' in handler.variables: handler.renameVariable('time_counter_bounds', 'time_bnds') handler.sync() @@ -473,12 +506,8 @@ class Cmorizer(object): # noinspection PyProtectedMember time_bounds[x, y] = time_bounds[x, y]._to_real_datetime() time_bounds_var[:] = netCDF4.date2num(time_bounds, 'days since 1850-01-01', 'standard') - time_var.units = 'days since 1850-01-01' - time_var.time_origin = "1850-01-01" - time_var.calendar = 'standard' - time_var.long_name = "Verification time of the forecast" - time_var.standard_name = "time" - time_var.axis = "T" + + def _set_leadtime_var(self, handler): if 'leadtime' in handler.variables: var = handler.variables['leadtime'] else: @@ -519,3 +548,12 @@ class Cmorizer(object): handler.startdate = 'S{0}'.format(self.startdate) handler.tracking_id = str(uuid.uuid1()) handler.title = "{0} model output prepared for SPECS {1}".format(experiment.model, experiment.experiment_name) + + def gribfiles_available(self): + grb_path = os.path.join(self.original_files_path, '*.grb') + gribfiles = glob.glob(grb_path) + return len(gribfiles) > 0 + + +class CMORException(Exception): + pass -- GitLab From 0a00380a9c3e859588eee9343c202de09448d1c4 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 11 Oct 2016 12:19:31 +0200 Subject: [PATCH 248/268] Added ATMOS_GRID config option. Modified interpolatecdo to use it --- diags.conf | 4 ++-- earthdiagnostics/config.py | 1 + earthdiagnostics/ocean/interpolatecdo.py | 27 +++++++++++++++++++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/diags.conf b/diags.conf index bfbec56..f57f9c1 100644 --- a/diags.conf +++ b/diags.conf @@ -86,7 +86,7 @@ CHUNKS = 15 # This ALIAS section is a bit different # Inside this, you can provide alias for frequent diagnostics calls. # By default, there are some of the diagnostics available at the previous version. -# You can define an alias for one or more diagnostic calls +# You can define an alias for one or moraa90a1ee diagnostic calls [ALIAS] MAX_MOC = mocmax,38,50,500,2000 mocmax,40,40,0,10000 @@ -96,7 +96,7 @@ HEAT_SAL_MXL = mlotstsc mlotsthc LMSALC = vertmeanmeters,so,300,5400 USALC = vertmeanmeters,so,0,300 OHC = ohc,glob,0,1,10 -XOHC = ohc,glob,1,0,0< +XOHC = ohc,glob,1,0,0 LOHC = ohc,glob,0,23,46 MOHC = ohc,glob,0,18,22 UOHC = ohc,glob,0,1,17 diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index 1710d9b..cff5710 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -205,6 +205,7 @@ class ExperimentConfig(object): self.atmos_timestep = parser.get_int_option('EXPERIMENT', 'ATMOS_TIMESTEP', 6) self.ocean_timestep = parser.get_int_option('EXPERIMENT', 'OCEAN_TIMESTEP', 6) self.model_version = parser.get_option('EXPERIMENT', 'MODEL_VERSION') + self.atmos_grid = parser.get_option('EXPERIMENT', 'ATMOS_GRID') self.startdates = startdates self.members = members diff --git a/earthdiagnostics/ocean/interpolatecdo.py b/earthdiagnostics/ocean/interpolatecdo.py index 7e9d61f..58942ce 100644 --- a/earthdiagnostics/ocean/interpolatecdo.py +++ b/earthdiagnostics/ocean/interpolatecdo.py @@ -69,12 +69,19 @@ class InterpolateCDO(Diagnostic): :return: """ num_options = len(options) - 1 - if num_options < 2: - raise Exception('You must specify the grid and variable to interpolate') + if num_options < 1: + raise Exception('You must specify the variable to interpolate') if num_options > 3: - raise Exception('You must specify between 2 and 3 parameters for the interpolation with CDO diagnostic') - target_grid = options[1] - variable = options[2] + raise Exception('You must specify between 1 and 3 parameters for the interpolation with CDO diagnostic') + variable = options[1] + + if num_options >= 3: + target_grid = options[2] + else: + target_grid = diags.config.experiment.atmos_grid.lower() + + target_grid = cls.translate_ifs_grids_to_cdo_names(target_grid) + if num_options >= 3: domain = options[3] else: @@ -86,6 +93,16 @@ class InterpolateCDO(Diagnostic): diags.config.experiment.model_version)) return job_list + @classmethod + def translate_ifs_grids_to_cdo_names(cls, target_grid): + if target_grid.startswith('T159L'): + target_grid = 't106' + if target_grid.startswith('T255L'): + target_grid = 't170' + if target_grid.startswith('T511L'): + target_grid = 't340' + return target_grid + def compute(self): """ Runs the diagnostic -- GitLab From 77ea66ec798ad4854a12419a5ea4a3e6d1e9a08a Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Tue, 11 Oct 2016 12:22:32 +0200 Subject: [PATCH 249/268] Bumped version and updated doc --- VERSION | 2 +- doc/source/conf.py | 2 +- earthdiagnostics/EarthDiagnostics.pdf | Bin 241604 -> 254849 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 9215a4a..bf335c8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b14 +3.0.0b15 diff --git a/doc/source/conf.py b/doc/source/conf.py index 357ee36..c96fe16 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b14' +release = '3.0.0b15' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index 8578cfe0731d4d83a05481fa0c82b37f592b28a4..86a098403b2a4dad60c1e452a444157582137440 100644 GIT binary patch delta 126855 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 d5vzZZ3dY#IJh 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 G-M9cr%-gI0 diff --git a/VERSION b/VERSION index 005e92c..9414e12 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0b3 +3.0.0b4 diff --git a/doc/source/conf.py b/doc/source/conf.py index d725d7d..9db4018 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b3' +release = '3.0.0b4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 9283439..6350233 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -1,4 +1,4 @@ -# coding: latin-1 +# coding: utf-8 import csv import glob import shutil @@ -640,7 +640,7 @@ class DataManager(object): def _add_common_attributes(self, frequency, handler, member, startdate): handler.associated_experiment = self.associated_experiment handler.batch = '{0}{1}'.format(self.institution, datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)')) - handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ + handler.contact = 'Pierre-Antoine Bretonnière, pierre-antoine.bretonniere@bsc.es , ' \ 'Javier Vegas-Regidor, javier.vegas@bsc.es ' handler.Conventions = 'CF-1.6' handler.creation_date = datetime.now().strftime('%Y-%m-%d(T%H:%M:%SZ)') diff --git a/earthdiagnostics/ocean/heatcontentlayer.py b/earthdiagnostics/ocean/heatcontentlayer.py index 8fd383e..27b3088 100644 --- a/earthdiagnostics/ocean/heatcontentlayer.py +++ b/earthdiagnostics/ocean/heatcontentlayer.py @@ -13,6 +13,7 @@ class HeatContentLayer(Diagnostic): :original author: Isabel Andreu Burillo :contributor: Virginie Guemas + :contributor: Eleftheria Exarchou :contributor: Javier Vegas-Regidor :created: June 2012 @@ -46,8 +47,8 @@ class HeatContentLayer(Diagnostic): self.generated_vars = ['scvertsum'] def __str__(self): - return 'Heat content layer Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member, - self.chunk) + return 'Heat content layer Startdate: {0} Member: {1} Chunk: {2} Box: {3}'.format(self.startdate, self.member, + self.chunk, self.box) @classmethod def generate_jobs(cls, diags, options): -- GitLab From 1121a6f5e83272f96fb8841ffcf115af14e461c6 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 22 Jul 2016 12:51:00 +0200 Subject: [PATCH 152/268] Using cf_units --- earthdiagnostics/datamanager.py | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6350233..ed61fa0 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -4,6 +4,7 @@ import glob import shutil import threading import uuid +from cf_units import Unit from datetime import datetime import netCDF4 @@ -885,24 +886,14 @@ class DataManager(object): if cmor_var.units: if 'units' in var_handler.ncattrs(): if cmor_var.units != var_handler.units: - factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units, cmor_var.units) - if factor is not None: - if factor != 1 or offset != 0: - var_handler[:] = var_handler[:]*factor + offset - else: - if var_handler.units[-1] == '2' and cmor_var.units[-1] == 2: - factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units[:-1], - cmor_var.units[:-1]) - if factor is None: - Log.warning('Variable {0} can not be converted from {1} to {2}. ' - 'Please add conversion to table', - cmor_var.short_name, var_handler.units, cmor_var.units) - else: - var_handler[:] = np.square(np.sqrt(var_handler[:]) * factor + offset) + new_unit = Unit(cmor_var.units) + old_unit = Unit(var_handler.units) + var_handler[:] = new_unit.convert(var_handler[:], old_unit, inplace=True) + if 'valid_min' in var_handler.ncattrs(): - var_handler.valid_min = float(var_handler.valid_min) * factor + offset + var_handler.valid_min = new_unit.convert(float(var_handler.valid_min), old_unit) if 'valid_max' in var_handler.ncattrs(): - var_handler.valid_max = float(var_handler.valid_max) * factor + offset + var_handler.valid_max = new_unit.convert(float(var_handler.valid_max), old_unit) var_handler.units = cmor_var.units handler.sync() -- GitLab From 10bf89ad4b3d22c3dbc95b0ae87fde2d9ea9646f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Wed, 17 Aug 2016 16:14:29 +0200 Subject: [PATCH 153/268] Changed cmor files path to avoid redundant folders --- earthdiagnostics/datamanager.py | 53 +++++++++++++++++++++------------ earthdiagnostics/diags.conf | 4 +-- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6350233..5e0c334 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -89,8 +89,7 @@ class DataManager(object): errors = list() for startdate, member in self.exp_manager.get_member_list(): member_str = self.exp_manager.get_member_str(member) - if force_rebuild or not os.path.exists(os.path.join(self.data_dir, self.expid, 'cmorfiles', - startdate, member_str)): + if force_rebuild or not self._is_cmorized(startdate, member): created = True Log.info('CMORizing startdate {0} member {1}', startdate, member_str) if ocean: @@ -124,8 +123,7 @@ class DataManager(object): return for startdate, member in self.exp_manager.get_member_list(): - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, - self.exp_manager.get_member_str(member), 'outputs') + member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles') Log.info('Preparing CMOR files for startdate {0} and member {1}'.format(startdate, member)) filepaths = glob.glob(os.path.join(member_path, '*.gz')) @@ -423,7 +421,7 @@ class DataManager(object): for t in threads: t.join() if self.experiment_name != self.model: - bad_path = os.path.join(member_path, 'output', self.institution, self.model, self.model) + bad_path = os.path.join(member_path, self.institution, self.model, self.model) for (dirpath, dirnames, filenames) in os.walk(bad_path, False): for filename in filenames: filepath = os.path.join(dirpath, filename) @@ -436,7 +434,7 @@ class DataManager(object): Utils.move_file(filepath, good) os.rmdir(dirpath) - good_dir = os.path.join(member_path, 'output', self.institution, self.model, self.experiment_name) + good_dir = os.path.join(member_path, self.institution, self.model, self.experiment_name) for sdate in os.listdir(good_dir): for (dirpath, dirnames, filenames) in os.walk(os.path.join(good_dir, sdate), False): for filename in filenames: @@ -714,10 +712,7 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, - self.exp_manager.get_member_str(member), - 'outputs', 'output', self.institution, self.model, self.experiment_name, - 'S' + startdate, frequency, domain) + member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) chunk_start = chunk_start_date(start, chunk, self.exp_manager.chunk_size, 'month', 'standard') chunk_end = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') @@ -743,6 +738,10 @@ class DataManager(object): shutil.copyfile(filepath, temp_path) return temp_path + def get_startdate_path(self, startdate): + return os.path.join(self.data_dir, self.expid, 'cmorfiles', self.institution, self.model, + self.experiment_name, 'S' + startdate) + def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, rename_var=None, frequency=None, year=None, date_str=None): """ @@ -794,11 +793,7 @@ class DataManager(object): start = parse_date(startdate) member_plus = str(member + 1) - member_path = os.path.join(self.data_dir, self.expid, 'cmorfiles', startdate, - self.exp_manager.get_member_str(member), - 'outputs', 'output', self.institution, self.model, self.experiment_name, - 'S' + startdate, - frequency, domain) + member_path = os.path.join(self.get_startdate_path(startdate), frequency, domain) if chunk is not None: chunk_start = chunk_start_date(start, chunk, self.exp_manager.chunk_size, 'month', 'standard') @@ -889,6 +884,10 @@ class DataManager(object): if factor is not None: if factor != 1 or offset != 0: var_handler[:] = var_handler[:]*factor + offset + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = float(var_handler.valid_min) * factor + offset + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = float(var_handler.valid_max) * factor + offset else: if var_handler.units[-1] == '2' and cmor_var.units[-1] == 2: factor, offset = UnitConversion.get_conversion_factor_offset(var_handler.units[:-1], @@ -899,10 +898,13 @@ class DataManager(object): cmor_var.short_name, var_handler.units, cmor_var.units) else: var_handler[:] = np.square(np.sqrt(var_handler[:]) * factor + offset) - if 'valid_min' in var_handler.ncattrs(): - var_handler.valid_min = float(var_handler.valid_min) * factor + offset - if 'valid_max' in var_handler.ncattrs(): - var_handler.valid_max = float(var_handler.valid_max) * factor + offset + if 'valid_min' in var_handler.ncattrs(): + var_handler.valid_min = np.square(np.sqrt(float(var_handler.valid_min * factor + + offset))) + if 'valid_max' in var_handler.ncattrs(): + var_handler.valid_max = np.square(np.sqrt(float(var_handler.valid_max * factor + + offset))) + var_handler.units = cmor_var.units handler.sync() @@ -1049,6 +1051,19 @@ class DataManager(object): os.remove(temp) return temp2 + def _is_cmorized(self, startdate, member): + if not os.path.exists(self.get_startdate_path(startdate)): + return False + startdate_path = self.get_startdate_path(startdate) + for freq in os.listdir(startdate_path): + freq_path = os.path.join(startdate_path, freq) + for domain in os.listdir(freq_path): + domain_path = os.path.join(freq_path, domain) + for var in os.listdir(domain_path): + member_path = os.path.join(domain_path, var, 'r{0}i1p1'.format(member+1)) + if os.path.exists(member_path): + return True + return False class Variable(object): """ diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 9687488..7a4ba36 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -52,8 +52,8 @@ STARTDATES = 19580101 MEMBERS = 0 MEMBER_DIGITS = 2 CHUNK_SIZE = 12 -# CHUNKS = 58 -CHUNKS = 1 +CHUNKS = 58 +# CHUNKS = 1 -- GitLab From d123cab6af366bbeae76a45f8bf9a3cd21a6851c Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Fri, 19 Aug 2016 16:35:45 +0200 Subject: [PATCH 154/268] Improve cmorization peformance from GRIB Files --- earthdiagnostics/cmor_table.csv | 23 ++++---- earthdiagnostics/datamanager.py | 70 ++++++++++++++---------- earthdiagnostics/diags.conf | 12 ++-- earthdiagnostics/ocean/averagesection.py | 2 +- earthdiagnostics/ocean/maxmoc.py | 12 ++-- earthdiagnostics/utils.py | 49 +++++++++++++---- launch_diags.sh | 2 +- 7 files changed, 104 insertions(+), 66 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index b3b11f7..63d0991 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -15,8 +15,8 @@ iicebome:iocewflx,bmelt,tendency_of_sea_ice_amount_due_to_basal_melting,Rate of sobowlin,bowlin,bowl_index,Bowl index,ocean,,,, cc,cl,cloud_area_fraction_in_atmosphere_layer,Cloud area fraction,atmos,,,, hcc,clh,high_cloud_area_fraction,High cloud fraction,atmos,,,, -lcc,clh,low_cloud_area_fraction,Low cloud fraction,atmos,,,, -mcc,clh,medium_cloud_area_fraction,Medium cloud fraction,atmos,,,, +lcc,cll,low_cloud_area_fraction,Low cloud fraction,atmos,,,, +mcc,clm,medium_cloud_area_fraction,Medium cloud fraction,atmos,,,, ciwc,cli,mass_fraction_of_cloud_ice_in_air,Mass fraction of cloud ice,atmos,,,, tcc,clt,cloud_area_fraction,Total cloud fraction,atmos,,,, clwc,clw,mass_fraction_of_cloud_liquid_water_in_air,Mass fraction of cloud liquid water,atmos,,,, @@ -34,14 +34,13 @@ gwd,gwd,gravity_wave_dissipation,Gravity wave dissipation,atmos,,,, ibgheatco,hcicega,global mean ice heat content,Global mean ice heat content,seaIce,,,, sbgheatco,hcsnga,global mean snow heat content,Global mean snow heat content,seaIce,,,, heatc,heatc,integral_of_sea_water_potential_temperature_wrt_depth_expressed_as_heat_content,Heat content vertically integrated,ocean,,,, -sohtatl,hfbasin,sobarstf,Northward ocean heat transport,ocean,,,, -sohtind,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,,,, -sohtipc,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,,,, -sohtpac,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,,,, +sohtatl,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Atl,,, +sohtind,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Ind,,, +sohtipc,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,IndPac,,, +sohtpac,hfbasin,northward_ocean_heat_transport,Northward ocean heat transport,ocean,Pac,,, sophtadv,hfbasinadv,northward_ocean_heat_transport_due_to_advection,Northward ocean heat transport due to advection ,ocean,,,, sophteiv,hfbasinba,northward_ocean_heat_transport_due_to_bolus_advection,Northward ocean heat transport due to bolus advection ,ocean,,,, -qt_oce,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,, -sohefldo,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,, +qt_oce:sohefldo,hfds,surface_downward_heat_flux_in_sea_water,Downward heat flux at sea water surface,ocean,,,, slhf,hfls,surface_upward_latent_heat_flux,Surface upward latent heat flux,atmos,,,, sshf,hfss,surface_upward_sensible_heat_flux,Surface upward sensible heat flux,atmos,,,, sophtove,htovovrt,northward_ocean_heat_transport_due_to_overturning,Northward ocean heat transport due to overturning ,ocean,,,, @@ -122,8 +121,7 @@ msl,psl,air_pressure_at_sea_level,Sea level pressure,atmos,,,, qns_ice,qnsice,non_solar_heat_flux_at_ice_surface,Non-solar heat flux at ice surface: sum over categories,seaIce,,,, qt_ice,qtice,surface_downward_heat_flux_in_air,Surface downward heat flux in air,seaIce,,,, strd,rlds,surface_downwelling_longwave_flux_in_air,Surface downwelling longwave radiation,atmos,,,, -str,rls,surface_net_downward_longwave_flux,Net longwave surface radiation,atmos,,,, -strc,rls,surface_longwave_flux_in_air,Surface longwave radiation,atmos,,,, +strc:str,rls,surface_longwave_flux_in_air,Surface longwave radiation,atmos,,,, ttr,rlut,toa_outgoing_longwave_flux,Toa outgoing longwave radiation,atmos,,,, ttrc,rlutcs,toa_outgoing_longwave_flux_assuming_clear_sky,"Top net thermal radiation, clear sky",atmos,,,, ssrd,rsds,surface_downwelling_shortwave_flux_in_air,Surface downwelling shortwave radiation,atmos,,,, @@ -186,7 +184,6 @@ soleaeiw,soleaeiw,eddy_induced_velocity_coefficient,Eddy induced vel. coeff. at soleahtw,soleahtw,lateral_eddy_diffusivity,Lateral eddy diffusivity,ocean,,,, somixhgt,somixhgt,mixing_layer_depth_turbocline,Mixing layer depth (turbocline),ocean,,,, sosaline:isssalin,sos,sea_surface_salinity,Sea surface salinity ,ocean,,psu,, -tos,sosstsst,sea_surface_temperature,Sea surface temperature,ocean,,K,, sothedep,sothedep,thermocline_depth,Thermocline depth (max dt/dz),ocean,,,, src,src,skin_reservoir_content,Skin reservoir content,land,,,, zosrfatl,srfzmean,zonal_mean_surface,Zonal mean surface,ocean,Atl,,, @@ -205,10 +202,10 @@ t2m,tas,air_temperature,Near-surface air temperature,atmos,,K,, mx2t,tasmax,air_temperature,Daily maximum near-surface air temperature,atmos,,K,, mn2t,tasmin,air_temperature,Daily minimum near-surface air temperature,atmos,,K,, ewss,tauu,surface_downward_eastward_stress,Surface downward eastward wind stress,atmos,,,, -utau_ice:iocestru:iicestru,tauu,surface_downward_eastward_stress,Surface downward eastward wind stress,seaIce,,,, +utau_ice:iocestru:iicestru,tauuo,surface_downward_x_stress,Surface downward x stress ,seaIce,,,, sozotaux,tauuo,surface_downward_x_stress,Surface downward x stress ,ocean,,,, nsss,tauv,surface_downward_northward_stress,Surface downward northward wind stress,atmos,,,, -vtau_ice:iocestrv:iicestrv,tauv,surface_downward_northward_stress,Surface downward northward wind stress,seaIce,,,, +vtau_ice:iocestrv:iicestrv,tauvo,surface_downward_y_stress,Surface downward y stress ,seaIce,,,, sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface downward y stress ,ocean,,,, d2m,tdps,dew_point_temperature,2m dewpoint temperature,atmos,,K,, votemper,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,,, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 10bfb44..6936c28 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -4,6 +4,7 @@ import glob import shutil import threading import uuid +import pygrib from cf_units import Unit from datetime import datetime @@ -158,16 +159,18 @@ class DataManager(object): count = 1 for gribfile in copied_gribfiles: Log.info('Unpacking atmospheric grib file {0}/{1}'.format(count, len(copied_gribfiles))) - cdo = Utils.cdo start = parse_date(gribfile[-10:-4]) month = '{0:02}'.format(start.month) - times = cdo.showtimestamp(input=gribfile) - times = times[0].split()[0:2] - time_diff = datetime.strptime(times[1], '%Y-%m-%dT%H:%M:%S') - datetime.strptime(times[0], - '%Y-%m-%dT%H:%M:%S') - nfrp = (time_diff.seconds // 3600) - - param_6hr = (151, 167, 168, 164, 165, 166, 129,) + grib_handler = pygrib.open(gribfile) + mes1 = grib_handler.message(1) + mes2 = grib_handler.readline() + while mes2['name'] != mes1['name']: + mes2 = grib_handler.readline() + nfrp = mes2.analDate - mes1.analDate + nfrp = int(nfrp.total_seconds() / 3600) + grib_handler.close() + + param_6hr = (129, 130, 131, 132, 151, 167, 168, 164, 165, 166, 129,) param_day = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) param_mon = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, 177, 175, 212, 141, 180, 181, 179, 168, 243, 129, 130, 131, 132, 133) @@ -215,18 +218,18 @@ class DataManager(object): # radiation new_units = "W m-2" cdo_operator = "-divc,{0} -daymean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) elif param == 228: # precipitation new_units = "kg m-2 -s" cdo_operator = "-mulc,1000 -divc,{0} -daymean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) elif param == 201: # maximum - cdo_operator = "-daymax -selmon,{1} -shifttime,-{0}hours".format(nfrp, month) + cdo_operator = "-daymax -selmon,{1} -shifttime,-{0}hours".format(int(nfrp), month) elif param == 202: # minmimum - cdo_operator = "-daymin -selmon,{1} -shifttime,-{0}hours".format(nfrp, month) + cdo_operator = "-daymin -selmon,{1} -shifttime,-{0}hours".format(int(nfrp), month) elif param == 130: # 850 hPa cdo_operator = "-daymean -sellevel,85000 -selmon,{0}".format(month) @@ -239,18 +242,17 @@ class DataManager(object): '{2}_{3}_day.nc'.format(cdo_reftime, cdo_operator, gribfile, param)) + daily_variable_file = '{0}_{1}_day.nc'.format(gribfile, param) if new_units: - handler = Utils.openCdf('{0}_{1}_day.nc'.format(gribfile, param)) + handler = Utils.openCdf(daily_variable_file) for var in handler.variables.values(): if 'code' in var.ncattrs() and var.code == param: var.units = new_units break handler.close() # concat all vars in one file for day - Utils.nco.ncks(input='{0}_{1}_day.nc'.format(gribfile, param), - output='{0}_day.nc'.format(gribfile), options='-A') - os.remove('{0}_{1}_day.nc'.format(gribfile, param)) - + daily_file = '{0}_day.nc'.format(gribfile) + Utils.concat_variables(daily_variable_file, daily_file, True) # monthly variables for param in param_mon: if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): @@ -260,17 +262,17 @@ class DataManager(object): # radiation/heat new_units = "W m-2" cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) elif param in (180, 181): # momentum flux new_units = "N m-2" cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) elif param in (144, 228, 205, 182): # precipitation/evaporation/runoff new_units = "kg m-2 s-1" cdo_operator = "-mulc,1000 -divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, nfrp, month) + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) elif param == 201: # mean daily maximum cdo_operator = "-monmean -daymax -selmon,{1} " \ @@ -314,9 +316,7 @@ class DataManager(object): options='-O -v {0}'.format(var_name)) # concat all vars in one file for mon - Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), - output='{0}_mon.nc'.format(gribfile), options='-A') - os.remove('{0}_{1}_mon.nc'.format(gribfile, param)) + Utils.concat_variables('{0}_{1}_mon.nc'.format(gribfile, param), '{0}_mon.nc'.format(gribfile), True) # 6-hourly variables for param in param_6hr: @@ -326,7 +326,17 @@ class DataManager(object): if param == 129: # geopotential new_units = "m" - cdo_operator = "-divc,9.81 -sellevel,50000 -selmon,{0}".format(month) + cdo_operator = "-divc,9.81 -sellevel,{1} -selmon,{0}".format(month, + ' '.join(map(str, + range(300, 900, 50)))) + elif param == 129: + # upper air temperature + new_units = "m" + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ' '.join(map(str, range(300, 500, 50)))) + elif param in (131, 132): + # upper air wind + new_units = "m" + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ' '.join(map(str, (500, 700, 850)))) else: # default, plain monthly mean cdo_operator = "-selmon,{0}".format(month) @@ -335,17 +345,18 @@ class DataManager(object): '{1} {2}_{3}.128.grb ' '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, gribfile, param)) + h_var_file = '{0}_{1}_6hr.nc'.format(gribfile, param) if new_units: - handler = Utils.openCdf('{0}_{1}_6hr.nc'.format(gribfile, param)) + handler = Utils.openCdf(h_var_file) for var in handler.variables.values(): if 'code' in var.ncattrs() and var.code == param: var.units = new_units break handler.close() # concat all vars in one file for 6hr - Utils.nco.ncks(input='{0}_{1}_6hr.nc'.format(gribfile, param), - output='{0}_6hr.nc'.format(gribfile), options='-A') - os.remove('{0}_{1}_6hr.nc'.format(gribfile, param)) + + h_file = '{0}_6hr.nc'.format(gribfile) + Utils.concat_variables(h_var_file, h_file, True) for splited_file in glob.glob('{0}_???.128.grb'.format(gribfile)): os.remove(splited_file) @@ -741,7 +752,7 @@ class DataManager(object): def get_startdate_path(self, startdate): return os.path.join(self.data_dir, self.expid, 'cmorfiles', self.institution, self.model, - self.experiment_name, 'S' + startdate) + self.experiment_name, 'S' + startdate) def send_file(self, filetosend, domain, var, startdate, member, chunk=None, grid=None, region=None, box=None, rename_var=None, frequency=None, year=None, date_str=None): @@ -1049,6 +1060,7 @@ class DataManager(object): return True return False + class Variable(object): """ Class to characterize a CMOR variable. It also contains the static method to make the match between thje original diff --git a/earthdiagnostics/diags.conf b/earthdiagnostics/diags.conf index 7a4ba36..7628202 100644 --- a/earthdiagnostics/diags.conf +++ b/earthdiagnostics/diags.conf @@ -2,7 +2,7 @@ # Path to the folder where you want to create the temporary files SCRATCH_DIR = /scratch/Earth/jvegas # Root path for the cmorized data to use -DATA_DIR = /esnas/exp/nemo/ +DATA_DIR = /esnas/exp/ecearth/ # Path to NEMO's mask and grid files needed for CDFTools CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or @@ -47,12 +47,12 @@ MODEL_VERSION = N3.6_O1L75 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment -EXPID = a05p -STARTDATES = 19580101 +EXPID = a09i +STARTDATES = 19900101 MEMBERS = 0 -MEMBER_DIGITS = 2 -CHUNK_SIZE = 12 -CHUNKS = 58 +MEMBER_DIGITS = 1 +CHUNK_SIZE = 1 +CHUNKS = 1 # CHUNKS = 1 diff --git a/earthdiagnostics/ocean/averagesection.py b/earthdiagnostics/ocean/averagesection.py index 4b91a29..a002d82 100644 --- a/earthdiagnostics/ocean/averagesection.py +++ b/earthdiagnostics/ocean/averagesection.py @@ -55,7 +55,7 @@ class AverageSection(Diagnostic): :param diags: Diagnostics manager class :type diags: Diags - :param options: variable, minimun longitude, maximun longitude, minimum latitude, maximum latitude, domain=ocean + :param options: variable, minimum longitude, maximum longitude, minimum latitude, maximum latitude, domain=ocean :type options: list[str] :return: """ diff --git a/earthdiagnostics/ocean/maxmoc.py b/earthdiagnostics/ocean/maxmoc.py index 11beb3f..57f051a 100644 --- a/earthdiagnostics/ocean/maxmoc.py +++ b/earthdiagnostics/ocean/maxmoc.py @@ -146,7 +146,7 @@ class MaxMoc(Diagnostic): handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzmax', float, ('time',)) - var.long_name = 'Maximum_Overturing' + var.long_name = 'Maximum_Overturning' var.units = 'Sverdrup' var.valid_min = -1000. var.valid_max = 1000. @@ -157,7 +157,7 @@ class MaxMoc(Diagnostic): handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzmaxlat', float, ('time',)) - var.long_name = 'Latitude_of_Maximum_Overturing' + var.long_name = 'Latitude_of_Maximum_Overturning' var.units = 'Degrees' var.valid_min = -90. var.valid_max = 90. @@ -168,7 +168,7 @@ class MaxMoc(Diagnostic): handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzmaxlev', float, ('time',)) - var.long_name = 'Depth_of_Maximum_Overturing' + var.long_name = 'Depth_of_Maximum_Overturning' var.units = 'Meters' var.valid_min = 0. var.valid_max = 10000. @@ -179,7 +179,7 @@ class MaxMoc(Diagnostic): handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzmin', float, ('time',)) - var.long_name = 'Minimum_Overtuning' + var.long_name = 'Minimum_Overturning' var.units = 'Sverdrup' var.valid_min = -1000. var.valid_max = 1000. @@ -190,7 +190,7 @@ class MaxMoc(Diagnostic): handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzminlat', float, ('time',)) - var.long_name = 'Latitude_of_Minimum_Overtuning' + var.long_name = 'Latitude_of_Minimum_Overturning' var.units = 'Degrees' var.valid_min = -90. var.valid_max = 90. @@ -201,7 +201,7 @@ class MaxMoc(Diagnostic): handler = self._create_output_file(temp) var = handler.createVariable('vsftmyzminlev', float, ('time',)) - var.long_name = 'Depth_of_Minimum_Overtuning' + var.long_name = 'Depth_of_Minimum_Overturning' var.units = 'Meters' var.valid_min = 0. var.valid_max = 10000. diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 9eb62d5..8b185f8 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -215,20 +215,21 @@ class Utils(object): return Utils._cpu_count @staticmethod - def convert2netcdf4(filetoconvert): + def convert2netcdf4(filetoconvert, force=True): """ Checks if a file is in netCDF4 format and converts to netCDF4 if not :param filetoconvert: file to convert :type filetoconvert: str """ - temp = TempFile.get() - handler = Utils.openCdf(filetoconvert) - if handler.file_format == 'NETCDF4': + if not force: + handler = Utils.openCdf(filetoconvert) + if handler.file_format == 'NETCDF4': + handler.close() + return handler.close() - return - handler.close() Log.debug('Reformatting to netCDF-4') + temp = TempFile.get() Utils.execute_shell_command(["nccopy", "-4", "-d4", "-s", filetoconvert, temp]) shutil.move(temp, filetoconvert) @@ -269,7 +270,7 @@ class Utils(object): return netCDF4.num2date(nctime, units=units, calendar=cal_temps) @staticmethod - def copy_variable(source, destiny, variable, must_exist=True): + def copy_variable(source, destiny, variable, must_exist=True, add_dimensions=False): """ Copies the given variable from source to destiny @@ -280,20 +281,48 @@ class Utils(object): :param variable: variable to copy :type variable: str :param must_exist: if false, does not raise an error uf variable does not exist - :type must_exist: booº + :type must_exist: bool + :return: """ if not must_exist and variable not in source.variables.keys(): return if variable in destiny.variables.keys(): return - if not must_exist and not set(source.variables[variable].dimensions).issubset(destiny.dimensions): - return + if not set(source.variables[variable].dimensions).issubset(destiny.dimensions): + if not add_dimensions: + raise Exception('Variable {0} can not be added because dimensions does not match'.format(variable)) + for dimension in source.variables[variable].dimensions: + if dimension in destiny.dimensions: + continue + destiny.createDimension(dimension, source.dimensions[dimension].size) + if dimension in source.variables: + Utils.copy_variable(source, destiny, dimension) + if variable in destiny.variables.keys(): + # Just in case the variable we are copying match a dimension name + return original_var = source.variables[variable] new_var = destiny.createVariable(variable, original_var.datatype, original_var.dimensions) new_var.setncatts({k: original_var.getncattr(k) for k in original_var.ncattrs()}) new_var[:] = original_var[:] + @staticmethod + def concat_variables(source, destiny, remove_source=False): + if os.path.exists(destiny): + handler_total = Utils.openCdf(destiny) + handler_variable = Utils.openCdf(source) + for var in handler_variable.variables: + Utils.copy_variable(handler_variable, handler_total, var, add_dimensions=True) + handler_total.close() + handler_variable.close() + if remove_source: + os.remove(source) + else: + if remove_source: + Utils.move_file(source, destiny) + else: + shutil.copy(source, destiny) + Utils.convert2netcdf4(destiny, True) class TempFile(object): """ diff --git a/launch_diags.sh b/launch_diags.sh index 26380b9..5364683 100755 --- a/launch_diags.sh +++ b/launch_diags.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash #SBATCH -n 1 -#SBATCH --time 1:00:00 +#SBATCH --time 24:00:00 #SBATCH --error=job.%J.err #SBATCH --output=job.%J.out -- GitLab From 68ed923c74e615e3817b701804f4df0cfa0ace84 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 22 Aug 2016 10:48:42 +0200 Subject: [PATCH 155/268] Fixed bug in grib CMOR (sellevel) --- earthdiagnostics/cmor_table.csv | 4 ++-- earthdiagnostics/datamanager.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/earthdiagnostics/cmor_table.csv b/earthdiagnostics/cmor_table.csv index 63d0991..89c0b84 100644 --- a/earthdiagnostics/cmor_table.csv +++ b/earthdiagnostics/cmor_table.csv @@ -202,10 +202,10 @@ t2m,tas,air_temperature,Near-surface air temperature,atmos,,K,, mx2t,tasmax,air_temperature,Daily maximum near-surface air temperature,atmos,,K,, mn2t,tasmin,air_temperature,Daily minimum near-surface air temperature,atmos,,K,, ewss,tauu,surface_downward_eastward_stress,Surface downward eastward wind stress,atmos,,,, -utau_ice:iocestru:iicestru,tauuo,surface_downward_x_stress,Surface downward x stress ,seaIce,,,, +utau_ice:iocestru:iicestru,strairx,surface_downward_x_stress,X-Component of Atmospheric Stress On Sea Ice,seaIce,,N m-2,, sozotaux,tauuo,surface_downward_x_stress,Surface downward x stress ,ocean,,,, nsss,tauv,surface_downward_northward_stress,Surface downward northward wind stress,atmos,,,, -vtau_ice:iocestrv:iicestrv,tauvo,surface_downward_y_stress,Surface downward y stress ,seaIce,,,, +vtau_ice:iocestrv:iicestrv,strairy,surface_downward_y_stress,Y-Component of Atmospheric Stress On Sea Ice,seaIce,,N m-2,, sozotauy:sometauy,tauvo,surface_downward_y_stress,Surface downward y stress ,ocean,,,, d2m,tdps,dew_point_temperature,2m dewpoint temperature,atmos,,K,, votemper,thetao,sea_water_potential_temperature,Sea water potential temperature,ocean,,,, diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 6936c28..356c0d6 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -327,16 +327,16 @@ class DataManager(object): # geopotential new_units = "m" cdo_operator = "-divc,9.81 -sellevel,{1} -selmon,{0}".format(month, - ' '.join(map(str, + ','.join(map(str, range(300, 900, 50)))) elif param == 129: # upper air temperature new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ' '.join(map(str, range(300, 500, 50)))) + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, range(300, 500, 50)))) elif param in (131, 132): # upper air wind new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ' '.join(map(str, (500, 700, 850)))) + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, (500, 700, 850)))) else: # default, plain monthly mean cdo_operator = "-selmon,{0}".format(month) @@ -956,7 +956,7 @@ class DataManager(object): else: variable_folder = '{0}_f{1}h'.format(var, self.nfrp) - link_path = os.path.join(self.data_dir, self.expid, freq_str, variable_folder) + link_path = os.path.join(self.data_dir, self.expid, freq_str, domain.lower(), variable_folder) if not os.path.exists(link_path): # This can be a race condition -- GitLab From ec2c93883818983e3124ca3582413ff20a840288 Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 22 Aug 2016 11:58:38 +0200 Subject: [PATCH 156/268] Refactored cmorization. Diags arguments now will expand ~ and system variables on paths --- earthdiagnostics/datamanager.py | 316 ++++++++++++++++---------------- earthdiagnostics/diags.py | 4 +- earthdiagnostics/utils.py | 5 + 3 files changed, 169 insertions(+), 156 deletions(-) diff --git a/earthdiagnostics/datamanager.py b/earthdiagnostics/datamanager.py index 356c0d6..110f140 100644 --- a/earthdiagnostics/datamanager.py +++ b/earthdiagnostics/datamanager.py @@ -170,11 +170,6 @@ class DataManager(object): nfrp = int(nfrp.total_seconds() / 3600) grib_handler.close() - param_6hr = (129, 130, 131, 132, 151, 167, 168, 164, 165, 166, 129,) - param_day = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) - param_mon = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, - 177, 175, 212, 141, 180, 181, 179, 168, 243, 129, 130, 131, 132, 133) - grid = os.path.basename(gribfile)[3:5] if os.path.exists('ICM{0}{1}+{2.year}{2.month:02}.grb'.format(grid, self.expid, @@ -209,160 +204,15 @@ class DataManager(object): cdo_reftime = parse_date(startdate).strftime('%Y-%m-%d,00:00') - # daily variables - for param in param_day: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): - continue - new_units = None - if param in (169, 177, 179): - # radiation - new_units = "W m-2" - cdo_operator = "-divc,{0} -daymean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param == 228: - # precipitation - new_units = "kg m-2 -s" - cdo_operator = "-mulc,1000 -divc,{0} -daymean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param == 201: - # maximum - cdo_operator = "-daymax -selmon,{1} -shifttime,-{0}hours".format(int(nfrp), month) - elif param == 202: - # minmimum - cdo_operator = "-daymin -selmon,{1} -shifttime,-{0}hours".format(int(nfrp), month) - elif param == 130: - # 850 hPa - cdo_operator = "-daymean -sellevel,85000 -selmon,{0}".format(month) - else: - # default, plain daily mean - cdo_operator = "-daymean -selmon,{0}".format(month) - - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' - '{2}_{3}_day.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - - daily_variable_file = '{0}_{1}_day.nc'.format(gribfile, param) - if new_units: - handler = Utils.openCdf(daily_variable_file) - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: - var.units = new_units - break - handler.close() - # concat all vars in one file for day - daily_file = '{0}_day.nc'.format(gribfile) - Utils.concat_variables(daily_variable_file, daily_file, True) - # monthly variables - for param in param_mon: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): - continue - new_units = None - if param in (146, 147, 176, 169, 177, 175, 179, 212): - # radiation/heat - new_units = "W m-2" - cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param in (180, 181): - # momentum flux - new_units = "N m-2" - cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param in (144, 228, 205, 182): - # precipitation/evaporation/runoff - new_units = "kg m-2 s-1" - cdo_operator = "-mulc,1000 -divc,{0} -monmean -selmon,{2} " \ - "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) - elif param == 201: - # mean daily maximum - cdo_operator = "-monmean -daymax -selmon,{1} " \ - "-shifttime,-{0}hours".format(nfrp, month) - elif param == 202: - # mean daily minmimum - cdo_operator = "-monmean -daymin -selmon,{1} " \ - "-shifttime,-{0}hours".format(nfrp, month) - elif param in (130, 131, 132, 133): - # upper-air - cdo_operator = "-monmean -sellevel,5000,20000,50000,85000 " \ - "-selmon,{0}".format(month) - elif param == 129: - # upper-air geopotential - new_units = "m" - cdo_operator = "-divc,9.81 -timmean -sellevel,5000,20000,50000,85000 " \ - "-selmon,{0}".format(month) - else: - # default, plain monthly mean - cdo_operator = "-monmean -selmon,{0}".format(month) - - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' - '{2}_{3}_mon.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - handler = Utils.openCdf('{0}_{1}_mon.nc'.format(gribfile, param)) - if new_units: - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: - var.units = new_units - break - var_name = None - for key in handler.variables.keys(): - if key + '_2' in handler.variables and key not in handler.dimensions: - var_name = key - - handler.close() - if var_name is not None: - Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), - output='{0}_{1}_mon.nc'.format(gribfile, param), - options='-O -v {0}'.format(var_name)) - - # concat all vars in one file for mon - Utils.concat_variables('{0}_{1}_mon.nc'.format(gribfile, param), '{0}_mon.nc'.format(gribfile), True) - - # 6-hourly variables - for param in param_6hr: - if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): - continue - new_units = None - if param == 129: - # geopotential - new_units = "m" - cdo_operator = "-divc,9.81 -sellevel,{1} -selmon,{0}".format(month, - ','.join(map(str, - range(300, 900, 50)))) - elif param == 129: - # upper air temperature - new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, range(300, 500, 50)))) - elif param in (131, 132): - # upper air wind - new_units = "m" - cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, (500, 700, 850)))) - else: - # default, plain monthly mean - cdo_operator = "-selmon,{0}".format(month) - - Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' - '{1} {2}_{3}.128.grb ' - '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, - gribfile, param)) - h_var_file = '{0}_{1}_6hr.nc'.format(gribfile, param) - if new_units: - handler = Utils.openCdf(h_var_file) - for var in handler.variables.values(): - if 'code' in var.ncattrs() and var.code == param: - var.units = new_units - break - handler.close() - # concat all vars in one file for 6hr - - h_file = '{0}_6hr.nc'.format(gribfile) - Utils.concat_variables(h_var_file, h_file, True) + self._ungrib_6_hourly_vars(cdo_reftime, gribfile, month) + self._ungrib_daily_vars(cdo_reftime, gribfile, month, nfrp) + self._ungrib_monthly_files(cdo_reftime, gribfile, month, nfrp) for splited_file in glob.glob('{0}_???.128.grb'.format(gribfile)): os.remove(splited_file) - count += 1 Log.result('Atmospheric grib file {0}/{1} finished'.format(count, len(copied_gribfiles))) + count += 1 chunk_start = parse_date(startdate) while os.path.exists(os.path.join(self.scratch_dir, @@ -405,6 +255,164 @@ class DataManager(object): 'GG', '6hr') chunk_start = chunk_end_date(chunk_start, self.exp_manager.chunk_size, 'month', 'standard') + def _ungrib_6_hourly_vars(self, cdo_reftime, gribfile, month): + Log.info('Preparing 6-hourly variables') + var_codes = (129, 130, 131, 132, 151, 167, 168, 164, 165, 166, 129) + for param in var_codes: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param == 129: + # geopotential + new_units = "m" + cdo_operator = "-divc,9.81 -sellevel,{1} -selmon,{0}".format(month, + ','.join(map(str, + range(300, 900, 50)))) + elif param == 129: + # upper air temperature + new_units = "m" + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, range(300, 500, 50)))) + elif param in (131, 132): + # upper air wind + new_units = "m" + cdo_operator = "-sellevel,{1} -selmon,{0}".format(month, ','.join(map(str, (500, 700, 850)))) + else: + # default, plain monthly mean + cdo_operator = "-selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_6hr.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + h_var_file = '{0}_{1}_6hr.nc'.format(gribfile, param) + if new_units: + handler = Utils.openCdf(h_var_file) + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + handler.close() + # concat all vars in one file for 6hr + + h_file = '{0}_6hr.nc'.format(gribfile) + Utils.concat_variables(h_var_file, h_file, True) + + def _ungrib_daily_vars(self, cdo_reftime, gribfile, month, nfrp): + Log.info('Preparing daily variables') + var_codes = (167, 165, 166, 151, 164, 168, 169, 177, 179, 228, 201, 202, 130) + for param in var_codes: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param in (169, 177, 179): + # radiation + new_units = "W m-2" + cdo_operator = "-divc,{0} -daymean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) + elif param == 228: + # precipitation + new_units = "kg m-2 -s" + cdo_operator = "-mulc,1000 -divc,{0} -daymean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) + elif param == 201: + # maximum + cdo_operator = "-daymax -selmon,{1} -shifttime,-{0}hours".format(int(nfrp), month) + elif param == 202: + # minmimum + cdo_operator = "-daymin -selmon,{1} -shifttime,-{0}hours".format(int(nfrp), month) + elif param == 130: + # 850 hPa + cdo_operator = "-daymean -sellevel,85000 -selmon,{0}".format(month) + else: + # default, plain daily mean + cdo_operator = "-daymean -selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_day.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + + daily_variable_file = '{0}_{1}_day.nc'.format(gribfile, param) + if new_units: + handler = Utils.openCdf(daily_variable_file) + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + handler.close() + # concat all vars in one file for day + daily_file = '{0}_day.nc'.format(gribfile) + Utils.concat_variables(daily_variable_file, daily_file, True) + + def _ungrib_monthly_files(self, cdo_reftime, gribfile, month, nfrp): + Log.info('Preparing monthly variables') + + var_codes = (167, 201, 202, 165, 166, 151, 144, 228, 205, 182, 164, 146, 147, 176, 169, + 177, 175, 212, 141, 180, 181, 179, 168, 243, 129, 130, 131, 132, 133) + for param in var_codes: + if not os.path.exists('{0}_{1}.128.grb'.format(gribfile, param)): + continue + new_units = None + if param in (146, 147, 176, 169, 177, 175, 179, 212): + # radiation/heat + new_units = "W m-2" + cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) + elif param in (180, 181): + # momentum flux + new_units = "N m-2" + cdo_operator = "-divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) + elif param in (144, 228, 205, 182): + # precipitation/evaporation/runoff + new_units = "kg m-2 s-1" + cdo_operator = "-mulc,1000 -divc,{0} -monmean -selmon,{2} " \ + "-shifttime,-{1}hours".format(nfrp * 3600, int(nfrp), month) + elif param == 201: + # mean daily maximum + cdo_operator = "-monmean -daymax -selmon,{1} " \ + "-shifttime,-{0}hours".format(nfrp, month) + elif param == 202: + # mean daily minmimum + cdo_operator = "-monmean -daymin -selmon,{1} " \ + "-shifttime,-{0}hours".format(nfrp, month) + elif param in (130, 131, 132, 133): + # upper-air + cdo_operator = "-monmean -sellevel,5000,20000,50000,85000 " \ + "-selmon,{0}".format(month) + elif param == 129: + # upper-air geopotential + new_units = "m" + cdo_operator = "-divc,9.81 -timmean -sellevel,5000,20000,50000,85000 " \ + "-selmon,{0}".format(month) + else: + # default, plain monthly mean + cdo_operator = "-monmean -selmon,{0}".format(month) + + Utils.execute_shell_command('cdo -f nc -t ecmwf setreftime,{0} ' + '{1} {2}_{3}.128.grb ' + '{2}_{3}_mon.nc'.format(cdo_reftime, cdo_operator, + gribfile, param)) + handler = Utils.openCdf('{0}_{1}_mon.nc'.format(gribfile, param)) + if new_units: + for var in handler.variables.values(): + if 'code' in var.ncattrs() and var.code == param: + var.units = new_units + break + var_name = None + for key in handler.variables.keys(): + if key + '_2' in handler.variables and key not in handler.dimensions: + var_name = key + + handler.close() + if var_name is not None: + Utils.nco.ncks(input='{0}_{1}_mon.nc'.format(gribfile, param), + output='{0}_{1}_mon.nc'.format(gribfile, param), + options='-O -v {0}'.format(var_name)) + + # concat all vars in one file for mon + Utils.concat_variables('{0}_{1}_mon.nc'.format(gribfile, param), '{0}_mon.nc'.format(gribfile), True) + def _merge_and_cmorize_atmos(self, startdate, member, chunk_start, chunk_end, chunk_files, grid, frequency): merged_file = 'MMA_{0}_{1}_{2}_{3}.nc'.format(frequency, date2str(chunk_start), date2str(chunk_end), grid) for x in range(0, len(chunk_files)): diff --git a/earthdiagnostics/diags.py b/earthdiagnostics/diags.py index 033efc4..98f2836 100755 --- a/earthdiagnostics/diags.py +++ b/earthdiagnostics/diags.py @@ -333,9 +333,9 @@ def main(): Log.set_console_level(args.logconsole) Log.set_file_level(args.logfile) if args.logfilepath: - Log.set_file(args.logfilepath) + Log.set_file(Utils.expand_path(args.logfilepath)) - diags = Diags(args.configfile) + diags = Diags(Utils.expand_path(args.configfile)) diags.run() TempFile.clean() diff --git a/earthdiagnostics/utils.py b/earthdiagnostics/utils.py index 8b185f8..c10b1a5 100644 --- a/earthdiagnostics/utils.py +++ b/earthdiagnostics/utils.py @@ -324,6 +324,9 @@ class Utils(object): shutil.copy(source, destiny) Utils.convert2netcdf4(destiny, True) + def expand_path(self, path): + return os.path.expandvars(os.path.expanduser(path)) + class TempFile(object): """ Class to manage temporal files @@ -383,3 +386,5 @@ class TempFile(object): if os.path.exists(temp_file): os.remove(temp_file) TempFile.files = list() + + -- GitLab From 3d4dff9e78452f7f585f9dde9ea04052c1dffa5f Mon Sep 17 00:00:00 2001 From: Javier Vegas-Regidor Date: Mon, 22 Aug 2016 12:28:49 +0200 Subject: [PATCH 157/268] Updated doc and .gitignore file --- .gitignore | 8 ++++---- EarthDiagnostics.pdf | Bin 199946 -> 201103 bytes doc/source/errors.rst | 5 +++-- earthdiagnostics/datamanager.py | 16 +++++++++++++--- earthdiagnostics/utils.py | 25 ++++++++++++++++++++++++- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 92bfa24..4abe78e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -.*.sw* -.*.log* -.*.pyc +*.pyc .idea/* -doc/build/ +doc/build/* +*.err +*.out \ No newline at end of file diff --git a/EarthDiagnostics.pdf b/EarthDiagnostics.pdf index 076bd2cce44664cafd9e8595c1be14ae073d59e7..bea81421cda1ed54adb9e6aa4bdfbb2d5d77dc82 100644 GIT binary patch delta 97172 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