1+ from pathlib import Path
2+
3+ import matplotlib .pyplot as plt
4+ import numpy as np
5+ import xarray as xr
6+ from cartopy import crs as ccrs
7+
8+ import detclim .results_plot as rplt
9+
10+
11+ def main ():
12+ scratch_dir = Path ("/lustre/storm/nwp501/proj-shared/mkelleher/e3sm_scratch" )
13+ ctl = "ctl"
14+ test = "clubb_c1-5p0pct"
15+ params_hum = {
16+ "effgw_oro" : "GW Orog" ,
17+ "clubb_c1" : "CLUBB C1" ,
18+ "zmconv_c0_ocn" : "ZM Conv C0-Ocean" ,
19+ "ctl" : "Control" ,
20+ }
21+
22+ cases = {
23+ ctl : "2025-09-16.F2010.ne30pg2_r05_oECv3_control" ,
24+ test : "2025-09-16.F2010.ne30pg2_r05_oECv3_clubb_c1_2p520000" ,
25+ }
26+
27+ ens_dirs = {_ens : Path (scratch_dir , _name , "run" ) for _ens , _name in cases .items ()}
28+
29+ file_pattern = "{case}.eam.h0.aavg.nc"
30+ ens_file = {
31+ _ens : Path (ens_dirs [_ens ], file_pattern .format (case = _name ))
32+ for _ens , _name in cases .items ()
33+ }
34+
35+ files_2d = {
36+ _ens : Path (
37+ ens_file [_ens ].parent ,
38+ f"{ cases [_ens ]} .eam.h0.0001-03_0002-02_climo_ANN_r05_ensavg.nc" ,
39+ )
40+ for _ens in cases
41+ }
42+
43+ data_2d = {_ens : xr .open_dataset (_file ) for _ens , _file in files_2d .items ()}
44+
45+ proj = ccrs .Robinson ()
46+ src_crs = ccrs .PlateCarree ()
47+
48+ dvar = "CLDLIQ"
49+ title_props = {"fontsize" : 8 }
50+ _figwidth = 12.5 / 2.54
51+ plot_3panel = False
52+
53+ cbar_props = {"location" : "right" , "pad" : 0.01 , "shrink" : 0.8 }
54+ _figheight = _figwidth * 1.1
55+ fig = plt .figure (
56+ figsize = (_figwidth , _figheight ),
57+ dpi = 300 ,
58+ )
59+ axes = [
60+ fig .add_subplot (
61+ 2 ,
62+ 1 ,
63+ idx + 1 ,
64+ projection = proj ,
65+ )
66+ for idx in range (2 )
67+ ]
68+
69+ diff_data = {}
70+ for _ens , _data in data_2d .items ():
71+ _pltdata = _data .isel (time = 0 )
72+ if "lev" in _pltdata .coords :
73+ _pltdata = _pltdata .isel (lev = - 1 )
74+ else :
75+ _pltdata = _pltdata .squeeze ()
76+ _pltdata = _pltdata .eval (dvar )
77+ if dvar in _data :
78+ _name = _data [dvar ].long_name
79+ _units = _data [dvar ].units
80+ diff_data [_ens ] = _pltdata
81+
82+ _cf = axes [0 ].pcolormesh (
83+ _data ["lon" ],
84+ _data ["lat" ],
85+ diff_data [ctl ],
86+ transform = src_crs ,
87+ cmap = "plasma" ,
88+ rasterized = True ,
89+ )
90+ axes [0 ].set_title (f"{ rplt .fmt_case (ctl )} mean" , fontsize = title_props ["fontsize" ])
91+ _cax = fig .colorbar (_cf , ax = axes [0 ], ** cbar_props )
92+
93+ _cax .set_label (_units , fontsize = title_props ["fontsize" ])
94+
95+ diff_2d = diff_data [test ] - diff_data [ctl ]
96+ _absmax = np .max (np .abs (diff_2d .quantile ([0.01 , 0.99 ])))
97+ _cf = axes [1 ].pcolormesh (
98+ data_2d [test ]["lon" ],
99+ data_2d [test ]["lat" ],
100+ diff_2d ,
101+ vmin = - _absmax ,
102+ vmax = _absmax ,
103+ cmap = "BrBG" ,
104+ transform = src_crs ,
105+ rasterized = True ,
106+ )
107+ axes [1 ].set_title (
108+ f"Difference { rplt .fmt_case (test )} - { rplt .fmt_case (ctl )} " ,
109+ fontsize = title_props ["fontsize" ],
110+ )
111+ _cax = fig .colorbar (_cf , ax = axes [1 ], ** cbar_props )
112+ _cax .set_label (_units , fontsize = title_props ["fontsize" ])
113+ for axis in axes :
114+ axis .coastlines (linewidth = 0.5 )
115+ axis .gridlines (linestyle = "--" , linewidth = 0.5 , color = "k" )
116+
117+ fig .suptitle (f"{ _name } [{ _units } ]" , fontsize = 12 )
118+ plt .tight_layout ()
119+ plt .savefig (
120+ f"test_diff_{ _name .replace (' ' , '_' ).replace ('(' , '' ).replace (')' , '' )} _"
121+ f"{ ctl } -{ test } .png"
122+ )
123+ plt .savefig (
124+ f"test_diff_{ _name .replace (' ' , '_' ).replace ('(' , '' ).replace (')' , '' )} _"
125+ f"{ ctl } -{ test } .pdf"
126+ )
127+
128+
129+ if __name__ == "__main__" :
130+ main ()
0 commit comments