CAMMAC https://cammac.readthedocs.io

S.Sénési for Météo-France - sept 2019 to march 2021

Build a figure showing long-term change for 9 water cycle variables for one SSP

Parameters stand in first cell, are either commented here or in the doc (see above)

A few commands below are specific to the Notebook environment, and can be safely commented out

Default settings (some may be overriden by Papermill - this would show in next cell in the execution output notebook)

In [ ]:
import os
do_test              = True

figure_name          = "FigTS-2-10"
# Version number will be a suffix for automatic figure filename. Use e.g. "_V1" for legibility
version              = ""
scheme               = "AR5"  # Hatching scheme
confidence_factor    = 1.645  # For AR6 comprehensive scheme : Multiplicative factor applied to control run 
                              # variability for deciding a change is significant (besides sqrt(2))
sign_threshold       = 0.66   # For AR6 simple scheme : threshold on cross-model change sign agreeement fraction
same_models_for_var  = False
manual_title         = None  # Will replace automatic title if not None

#See doc for data_versions in sibling directory data_versions
data_versions_tag   = "20200918"
data_versions_dir   = os.getenv("CAMMAC")+"/data"
excluded_models     = { }
included_models     = None
variability_excluded_models = {}
variability_models  = None
#
experiment          = "ssp245"
proj_period         = "2081-2100"
#
ref_experiment      = "historical"
ref_period          = "1995-2014" 
#
season              = "ANN"        # Other choices do not make sense for some variables (yet)
field_type          = "means_rchange" # Ranges in figures are not tuned for other choices ...

# Next value is used as a floor value of reference field for computing relative changes 
# of some variables
z1=0.1/(24*3600) # 0.1 mm/day, in kg m2 s-1
#
# If pre-computed fields for this SSP, season and projection_period are available, should we use it ?
# Set it to False for recomputing and printing fields and field changes statistics
# No problem if set to True and pre-computed fields does not exist
use_cached_proj_fields = True   
drop_old_figures       = False
#
outdir              = "./figures"
cache_dir           = "./cache"
variab_sampling_args= {"house_keeping":True,"compute":True,"detrend":True,"shift":100,"nyears":20,"number":20}
figure_details      = {"page_width":2450,"page_height":3444,"pt":48, "ybox":133,"y":52}
common_grid         = "r360x180"
antarctic_mask      = os.getenv("CAMMAC")+"/data/mask_hide_antarctic_360x180.nc"

# If some basic fields are to be plotted for each model :

#   - which fields should be actually plotted
# plot_for_each_model    = [ "reference", "projection", "change", "rchange", "schange", "variability" ]
plot_for_each_model    = [ ]
#   - and with which common plot_parameters
custom_plot_all_fields = { "proj" : "Robinson", "mpCenterLonF" : 0., "options" : "lbBoxEndCapStyle=TriangleBothEnds", "focus":"land"}
#   - and which range should be used
ranges = {}   # The baseline value !
# Values below fit the case of mrso
#ranges={ "reference" : { "min" : 0., "max" : 3000. , "delta" : 200. } ,
#        "projection" : { "min" : 0., "max" : 3000. , "delta" : 200. } ,
#        "change"     : { "min" :1000.,"max":-1000. , "delta":200.} , 
#        "rchange"    : { "min" : -25., "max" : 25. , "delta" : 5. } ,
#        "schange"    : { "colors": "-5 -2 -1 -0.5 -0.25 0. 0.25 0.5 1 2 5"  , "units":"-", "color":"AR6_Precip_12s" } , 
#        "variability": { "min" : 0., "max" : 1. , "delta" : 0.1 } ,
#       }

variables_for_each_model = [ ("pr","plain"), ]
In [ ]:
if do_test :
    version             = "_test"
    proj_period         = "2099-2100"
    ref_period          = "2012-2014" 
    included_models     = ["CNRM-CM6-1"]

Loading libraries

In [ ]:
import sys, os

from climaf.api import *
# Climaf settings
from climaf.cache import stamping
climaf.cache.stamping=False

from CAMMAClib.changes     import change_figure_with_caching
from CAMMAClib.ancillary   import prettier_label
from CAMMAClib.mips_et_al  import TSU_metadata, read_versions_dictionnary

# Load some user settings, if available
settings_file=os.getenv("CAMMAC_USER_PYTHON_CODE_DIR",".")+'/cammac_user_settings.py'
if os.path.exists(settings_file) :
    exec(compile(open(settings_file).read(),settings_file,'exec'))

If using a notebook, use wide display

In [ ]:
from IPython.core.display import display, HTML, Image
display(HTML("<style>.container { width:100% !important; }</style>"))

Next function combines global variables and its own arguments for calling change_figure_with_caching

In [ ]:
def afigure(variable, title, panel, plot_args,  derivation_label = "plain",field_type = field_type, 
            mask = None, table = "Amon", data_versions_tag = data_versions_tag, threshold=None, deep=None,
            read = use_cached_proj_fields ):

    global metadata
    
    key=variable
    if table=="day" :
        key=variable+"_day"
    exclude=excluded_models.get(key,[])
    vexclude=variability_excluded_models.get(key,[])
    #
    fig_file,fig,dic,variab_models,models = change_figure_with_caching(
        ref_period = ref_period, proj_period = proj_period, 
        variable = variable, table = table, ref_experiment = ref_experiment,
        experiment = experiment, season = season,
        derivation_label = derivation_label, 
        field_type = field_type,
        title = panel+") "+ title,
        custom_plot = plot_args, labelbar = "True", 
        data_versions_tag = data_versions_tag, data_versions_dir = data_versions_dir,
        excluded_models = exclude, models = included_models,
        variability_excluded_models = vexclude, 
        variability_models = variability_models,
        outdir = outdir, 
        #
        common_grid = common_grid, mask=mask,
        variab_sampling_args = variab_sampling_args,
        cache_dir = cache_dir, read = read, write = True, 
        print_statistics = True , deep = deep,  drop=drop_old_figures,
        threshold = threshold,
        same_models_for_variability_and_changes=same_models_for_var,
        scheme=scheme,
        low_change_agree_threshold=confidence_factor,
        change_sign_agree_threshold = sign_threshold
        )
    metadata += TSU_metadata([ref_experiment,experiment],models       ,variable,table,data_versions,panel)
    metadata += TSU_metadata(["piControl"]              ,variab_models,variable,table,data_versions,panel)
    return fig,dic

Compute figures for the nine variables

In [ ]:
col100={"colors":"-100 -75 -50 -25 -10   0   10 25 50 75 100 "}
col40={"colors":"-40 -30 -20 -10 -5   0   5   10  20 30 40 "}
col20={"colors":"-20 -15 -10  -5 -2.5 0 2.5    5  10 15 20 "}
col10={"colors":"-10 -8 -6 -4 -2 0 2 4 6 8 10"}


data_versions=read_versions_dictionnary(data_versions_tag, data_versions_dir)
dic=dict()

if True :
    metadata=""
    #
    l1c1,dic[("pr","plain")]      = afigure("pr"     ,"Precipitation"               ,"a",col40, threshold=z1)
    
    l1c2,dic[("evspsbl","plain")] = afigure("evspsbl","Evapotranspiration"          ,"b",col40, threshold=z1)
    
    colP_E= {  "min"   : -1, "max"   : 1 , "delta" : 0.2 }
    l1c3,dic[("P-scr","plain")]     = afigure("P-E"    ,"P-E"                         ,"c",colP_E, field_type="mean_change")#, threshold=z1)
    #
    #
    l2c1,dic[("mrro","plain")]    = afigure("mrro"   ,"Runoff"                      ,"d",col40, table="Lmon",mask=antarctic_mask, threshold=z1)
    
    l2c2,dic[("mrsos","plain")]   = afigure("mrsos"  ,"Surface soil moisture"       ,"e",col10, table="Lmon",mask=antarctic_mask)
    
    colsos={"focus":"ocean","colors":"-2.5 -2. -1.5 -1.0 -0.5 0 0.5 1.0 1.5 2.0 2.5 ","color":"AR6_MiscDiv_12"}
    l2c3,dic[("sos","plain")]     = afigure("sos"    ,"Sea surface salinity"        ,"f",colsos, table="Omon")
              #"colors":"-0.15 -0.1 -0.05 -0.025 -0.01 0 0.01 0.025 0.05 0.1 0.15 
    #
    #
    coldry={"color":"AR6_Temp_12" , "colors":"-20 -15 -10  -5 -2.5 0 2.5    5  10 15 20 "}
    #l3c1,dic[("pr","day")]  = afigure("pr"     ,"Number of dry days"          ,"g",coldry, table="day", derivation_label="dry")
    l3c1,dic[("dday","plain")]  = afigure("dday"     ,"Number of dry days"          ,"g",coldry, table="yr", derivation_label="plain")
    
    col_seas={"color":"AR6_Temp_12" , "colors":"-20 -15 -10  -5 -2.5 0 2.5  5  10 15 20"}
    l3c2,dic[("pr","seasonality")] = afigure("pr"     ,"Precipitation seasonality",   "h",col_seas, derivation_label="seasonality")
    
    #use_cached_proj_fields=False
    l3c3,dic[("pr","iav")]         = afigure("pr"     ,"Precip. inter-annual variab."   ,"i",col40   , derivation_label="iav")
    #
    #gini_plot={"color":"AR6_Precip_12"}
    #gini_plot.update(col40)
    #l3c3=afigure("pr"     ,"Precipitation Gini index"   ,gini_plot, derivation_label="gini" )
    #
    import os.path
    if not os.path.exists(outdir):
        os.makedirs(outdir)
    with open("%s/%s%s_md.txt"%(outdir,figure_name,version),"w") as f:
        f.write(metadata)

Assemble plots

In [ ]:
if manual_title is None :
    title="Long term water cycle variables changes for %s (%s vs %s)"%(prettier_label.get(experiment,experiment),proj_period,ref_period)
else:
    title=manual_title
    
page=cpage([[l1c1,l1c2,l1c3],
            [l2c1,l2c2,l2c3],
            [l3c1,l3c2,l3c3]], 
    title=title,insert=CAMMAC+"/CAMMAClib/captions/AR6_hatching_legend.png",**figure_details)

outfile="change_map_9vars_1SSP_%s_%s_%s%s.png"%(experiment,proj_period,data_versions_tag,version)
if drop_old_figures :
    cdrop(page)
cfile(page,outdir+"/"+outfile)
os.system("cd %s ; ln -sf %s %s%s.png"%(outdir,outfile,figure_name,version))
#
small=outfile.replace(".png",".small.png")
os.system("cd %s ; convert -geometry 50%% %s %s"%(outdir,outfile,small))
os.system("cd %s ; ln -sf %s %s%s_small.png"%(outdir,small,figure_name,version))

If using a notebook , display result

In [ ]:
Image(outfile,width=800)

Plotting all models for all field types and all variables

In [ ]:
for field_type in plot_for_each_model :
    #
    for variable,derivation_label in variables_for_each_model : 
        #
        plotargs=custom_plot_all_fields.copy()
        plotargs.update(ranges[variable].get(field_type,{}))
        allplots=plot(cens(dic[(variable,derivation_label)][experiment][season][field_type][derivation_label]),**plotargs)
        page=cpage(allplots,page_width=1200,page_height=1700,title="%s_%s_%s_%s_%s"%(variable,derivation_label,field_type,experiment,season))
        pagename="%s/all_models_%s_%s_%s_%s_%s_%s.png"%(outdir,variable,derivation_label,field_type,experiment,season,data_versions_tag)
        cfile(page,pagename)