AirNow and WRF-Chem
Our first example will demonstrate the basics available in MELODIES MONET to compare WRF-Chem model results against AirNow surface observations for ozone and PM2.5.
This example shows how one can compare results from two different model simulations against observations. This particular example compares WRF-Chem results using two different chemical mechanisms (RACM_ESRL and RACM_ESRL_VCP). Simulated surface ozone is slightly improved in WRF-Chem using the RACM_ESRL_VCP mechanism as compared to the AirNow observations.
First, we import the melodies_monet.driver
module.
from melodies_monet import driver
Please install h5py to open files from the Amazon S3 servers.
Please install h5netcdf to open files from the Amazon S3 servers.
Analysis driver class
Now, lets create an instance of the analysis driver class, melodies_monet.driver.analysis
.
It consists of these main parts:
model instances
observation instances
a paired instance of both
an = driver.analysis()
Initially, most of our analysis
object’s attributes
are set to None
, though some have meaningful defaults:
an
analysis(
control='control.yaml',
control_dict=None,
models={},
obs={},
paired={},
start_time=None,
end_time=None,
download_maps=True,
output_dir=None,
debug=False,
)
Control file
We set the YAML control file and begin by reading the file.
Note
Check out the Description of All YAML Options for info on how to create and modify these files.
an.control = "control_wrfchem_mech-0905_2.yaml"
an.read_control()
an.control_dict
{'analysis': {'start_time': '2019-09-05-06:00:00',
'end_time': '2019-09-06-06:00:00',
'output_dir': './output/airnow_wrfchem',
'debug': True},
'model': {'RACM_ESRL': {'files': 'example:wrfchem:racm_esrl',
'mod_type': 'wrfchem',
'mod_kwargs': {'mech': 'racm_esrl_vcp', 'surf_only_nc': True},
'radius_of_influence': 12000,
'mapping': {'airnow': {'PM2_5_DRY': 'PM2.5', 'o3': 'OZONE'}},
'projection': 'None',
'plot_kwargs': {'color': 'magenta', 'marker': 's', 'linestyle': '-'}},
'RACM_ESRL_VCP': {'files': 'example:wrfchem:racm_esrl_vcp',
'mod_type': 'wrfchem',
'mod_kwargs': {'mech': 'racm_esrl_vcp', 'surf_only_nc': True},
'radius_of_influence': 12000,
'mapping': {'airnow': {'PM2_5_DRY': 'PM2.5', 'o3': 'OZONE'}},
'projection': 'None',
'plot_kwargs': {'color': 'gold', 'marker': 'o', 'linestyle': '-'}}},
'obs': {'airnow': {'use_airnow': True,
'filename': 'example:airnow:2019-09',
'obs_type': 'pt_sfc',
'variables': {'OZONE': {'unit_scale': 1,
'unit_scale_method': '*',
'nan_value': -1.0,
'ylabel_plot': 'Ozone (ppbv)',
'vmin_plot': 15.0,
'vmax_plot': 55.0,
'vdiff_plot': 20.0,
'nlevels_plot': 21},
'PM2.5': {'unit_scale': 1,
'unit_scale_method': '*',
'nan_value': -1.0,
'ylabel_plot': 'PM2.5 (ug/m3)',
'ty_scale': 2.0,
'vmin_plot': 0.0,
'vmax_plot': 22.0,
'vdiff_plot': 15.0,
'nlevels_plot': 23}}}},
'plots': {'plot_grp1': {'type': 'timeseries',
'fig_kwargs': {'figsize': [12, 6]},
'default_plot_kwargs': {'linewidth': 2.0, 'markersize': 10.0},
'text_kwargs': {'fontsize': 24.0},
'domain_type': ['all', 'state_name', 'epa_region'],
'domain_name': ['CONUS', 'CA', 'R9'],
'data': ['airnow_RACM_ESRL', 'airnow_RACM_ESRL_VCP'],
'data_proc': {'rem_obs_nan': True,
'ts_select_time': 'time_local',
'ts_avg_window': 'H',
'set_axis': True}},
'plot_grp2': {'type': 'taylor',
'fig_kwargs': {'figsize': [8, 8]},
'default_plot_kwargs': {'linewidth': 2.0, 'markersize': 10.0},
'text_kwargs': {'fontsize': 16.0},
'domain_type': ['all'],
'domain_name': ['CONUS'],
'data': ['airnow_RACM_ESRL', 'airnow_RACM_ESRL_VCP'],
'data_proc': {'rem_obs_nan': True, 'set_axis': True}},
'plot_grp3': {'type': 'spatial_bias',
'fig_kwargs': {'states': True, 'figsize': [10, 5]},
'text_kwargs': {'fontsize': 16.0},
'domain_type': ['all'],
'domain_name': ['CONUS'],
'data': ['airnow_RACM_ESRL', 'airnow_RACM_ESRL_VCP'],
'data_proc': {'rem_obs_nan': True, 'set_axis': True}},
'plot_grp4': {'type': 'spatial_overlay',
'fig_kwargs': {'states': True, 'figsize': [10, 5]},
'text_kwargs': {'fontsize': 16.0},
'domain_type': ['all', 'epa_region'],
'domain_name': ['CONUS', 'R9'],
'data': ['airnow_RACM_ESRL', 'airnow_RACM_ESRL_VCP'],
'data_proc': {'rem_obs_nan': True, 'set_axis': True}},
'plot_grp5': {'type': 'boxplot',
'fig_kwargs': {'figsize': [8, 6]},
'text_kwargs': {'fontsize': 20.0},
'domain_type': ['all'],
'domain_name': ['CONUS'],
'data': ['airnow_RACM_ESRL', 'airnow_RACM_ESRL_VCP'],
'data_proc': {'rem_obs_nan': True, 'set_axis': False}}},
'stats': {'stat_list': ['MB', 'MdnB', 'R2', 'RMSE'],
'round_output': 2,
'output_table': False,
'output_table_kwargs': {'figsize': [7, 3],
'fontsize': 12.0,
'xscale': 1.4,
'yscale': 1.4,
'edges': 'horizontal'},
'domain_type': ['all'],
'domain_name': ['CONUS'],
'data': ['airnow_RACM_ESRL', 'airnow_RACM_ESRL_VCP']}}
Note: This is the complete file that was loaded.
1# General Description:
2# - Any key that is specific for a plot type will begin with `ts` for timeseries, `ty` for taylor.
3# - Some keys/groups are optional.
4# - For now, all plots except time series average over the analysis window.
5# - Seting axis values
6# - If set_axis = True in data_proc section of each plot_grp,
7# the yaxis for the plot will be set based on the values
8# specified in the obs section for each variable.
9# - If set_axis is set to False, then defaults will be used.
10# - 'vmin_plot' and 'vmax_plot' are needed for
11# 'timeseries', 'spatial_overlay', and 'boxplot'.
12# - 'vdiff_plot' is needed for 'spatial_bias' plots
13# - 'ty_scale' is needed for 'taylor' plots.
14# - 'nlevels' or the number of levels used in the contour plot can also optionally be provided for spatial_overlay plot.
15# - If set_axis = True and the proper limits are not provided in the obs section,
16# a warning will print, and the plot will be created using the default limits.
17analysis:
18 start_time: "2019-09-05-06:00:00" # UTC
19 end_time: "2019-09-06-06:00:00" # UTC
20 output_dir: ./output/airnow_wrfchem # relative to the program using this control file
21 # ^ optional; if not specified, plots are stored in code directory (??)
22 # Currently, the directory must exist or plot saving will error and fail.
23 debug: True
24
25model:
26 RACM_ESRL: # model label
27 files: example:wrfchem:racm_esrl
28 mod_type: "wrfchem"
29 mod_kwargs:
30 mech: "racm_esrl_vcp"
31 surf_only_nc: True # specify that we have only one vertical level; WRF-Chem specific
32 radius_of_influence: 12000 # meters
33 mapping: # of _model_ species name to _obs_ species name
34 airnow: # specifically for the obs labeled 'airnow'
35 PM2_5_DRY: "PM2.5"
36 o3: "OZONE"
37 projection: None
38 plot_kwargs: # optional
39 color: "magenta"
40 marker: "s"
41 linestyle: "-"
42 RACM_ESRL_VCP:
43 files: example:wrfchem:racm_esrl_vcp
44 mod_type: "wrfchem"
45 mod_kwargs:
46 mech: "racm_esrl_vcp"
47 surf_only_nc: True
48 radius_of_influence: 12000
49 mapping:
50 airnow:
51 PM2_5_DRY: "PM2.5"
52 o3: "OZONE"
53 projection: None
54 plot_kwargs:
55 color: "gold"
56 marker: "o"
57 linestyle: "-"
58
59obs:
60 airnow: # obs label
61 use_airnow: True
62 filename: example:airnow:2019-09
63 obs_type: pt_sfc
64 variables: # optional
65 OZONE:
66 unit_scale: 1
67 # ^ optional; Scaling factor
68 unit_scale_method: "*"
69 # ^ optional; Multiply = '*' , Add = '+', subtract = '-', divide = '/'
70 nan_value: -1.0
71 # ^ optional; When loading data, set this value to NaN
72 ylabel_plot: "Ozone (ppbv)"
73 # optional; set ylabel in order to include units and/or other info
74 vmin_plot: 15.0
75 # ^ optional; Min for y-axis during plotting.
76 # To apply to a plot, change restrict_yaxis = True.
77 vmax_plot: 55.0
78 # ^ optional; Max for y-axis during plotting.
79 # To apply to a plot, change restrict_yaxis = True.
80 vdiff_plot: 20.0
81 # ^ optional; +/- range to use in bias plots.
82 # To apply to a plot, change restrict_yaxis = True.
83 nlevels_plot: 21
84 # ^ optional; number of levels used in colorbar for contourf plot.
85 PM2.5:
86 unit_scale: 1
87 unit_scale_method: "*"
88 # obs_min: 0
89 # ^ optional; set all values less than this value to NaN
90 # obs_max: 100
91 # ^ optional; set all values greater than this value to NaN
92 nan_value: -1.0
93 # Note: The obs_min, obs_max, and nan_values are set to NaN first
94 # and then the unit conversion is applied.
95 ylabel_plot: "PM2.5 (ug/m3)"
96 ty_scale: 2.0 # optional; `ty_` indicates for Taylor diagram plot
97 vmin_plot: 0.0
98 vmax_plot: 22.0
99 vdiff_plot: 15.0
100 nlevels_plot: 23
101
102plots:
103 plot_grp1:
104 type: "timeseries" # plot type
105 fig_kwargs: # optional; to define figure options
106 figsize: [12, 6] # figure size (width, height) in inches
107 default_plot_kwargs:
108 # ^ optional; Define defaults for all plots.
109 # Important: Model kwargs overwrite these.
110 linewidth: 2.0
111 markersize: 10.
112 text_kwargs: # optional
113 fontsize: 24.
114 domain_type: ["all", "state_name", "epa_region"]
115 # ^ List of domain types: 'all' or any domain in obs file.
116 # (e.g., airnow: epa_region, state_name, siteid, etc.)
117 domain_name: ["CONUS", "CA", "R9"]
118 # ^ List of domain names. If domain_type = all,
119 # the domain name is used in the plot title.
120 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
121 # ^ make this a list of pairs in obs_model
122 # where the obs is the obs label and model is the model_label
123 data_proc: # optional??
124 rem_obs_nan: True
125 # ^ True: Remove all points where model or obs variable is NaN.
126 # False: Remove only points where model variable is NaN.
127 ts_select_time: "time_local" # `ts_` indicates this is time series plot-specific
128 # ^ Time used for avg and plotting
129 # Options: 'time' for UTC or 'time_local'
130 ts_avg_window: "H"
131 # ^ Options: None for no averaging, pandas resample rule (e.g., 'H', 'D')
132 set_axis: True
133 # ^ If true, add `vmin_plot` and `vmax_plot` for each variable in obs.
134
135 plot_grp2:
136 type: "taylor"
137 fig_kwargs:
138 figsize: [8, 8]
139 default_plot_kwargs:
140 linewidth: 2.0
141 markersize: 10.
142 text_kwargs:
143 fontsize: 16.
144 domain_type: ["all"]
145 domain_name: ["CONUS"]
146 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
147 data_proc:
148 rem_obs_nan: True
149 set_axis: True
150
151 plot_grp3:
152 type: "spatial_bias"
153 fig_kwargs: # optional; For all spatial plots, specify map_kwargs here too.
154 states: True # such as whether to show the state boundaries
155 figsize: [10, 5]
156 text_kwargs:
157 fontsize: 16.
158 domain_type: ["all",]
159 domain_name: ["CONUS"]
160 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
161 data_proc:
162 rem_obs_nan: True
163 set_axis: True
164
165 plot_grp4:
166 type: "spatial_overlay"
167 fig_kwargs:
168 states: True
169 figsize: [10, 5]
170 text_kwargs:
171 fontsize: 16.
172 domain_type: ["all", "epa_region"]
173 domain_name: ["CONUS", "R9"]
174 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
175 data_proc:
176 rem_obs_nan: True
177 set_axis: True
178
179 plot_grp5:
180 type: "boxplot"
181 fig_kwargs:
182 figsize: [8, 6]
183 text_kwargs:
184 fontsize: 20.
185 domain_type: ["all"]
186 domain_name: ["CONUS"]
187 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
188 data_proc:
189 rem_obs_nan: True
190 set_axis: False
191
192stats:
193 # Stats require positive numbers, so if you want to calculate temperature use Kelvin!
194 # Wind direction has special calculations for AirNow if obs name is 'WD'
195 stat_list: ["MB", "MdnB", "R2", "RMSE"]
196 # ^ List stats to calculate. Dictionary of definitions included
197 # in submodule `plots/proc_stats`. Only stats listed below are currently working.
198 # Full calc list:
199 # ['STDO', 'STDP', 'MdnNB','MdnNE','NMdnGE',
200 # 'NO', 'NOP', 'NP', 'MO', 'MP', 'MdnO', 'MdnP',
201 # 'RM', 'RMdn', 'MB', 'MdnB', 'NMB', 'NMdnB', 'FB',
202 # 'ME','MdnE','NME', 'NMdnE', 'FE', 'R2', 'RMSE','d1',
203 # 'E1', 'IOA', 'AC']
204 round_output: 2 # optional; defaults to rounding to 3rd decimal place
205 output_table: False
206 # ^ Always outputs a .txt file.
207 # Optional to also output a Matplotlib figure table (image).
208 output_table_kwargs: # optional
209 figsize: [7, 3]
210 fontsize: 12.
211 xscale: 1.4
212 yscale: 1.4
213 edges: "horizontal"
214 domain_type: ["all"]
215 domain_name: ["CONUS"]
216 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
Now, some of our analysis
object’s attributes are populated:
an
analysis(
control='control_wrfchem_mech-0905_2.yaml',
control_dict=...,
models={},
obs={},
paired={},
start_time=Timestamp('2019-09-05 06:00:00'),
end_time=Timestamp('2019-09-06 06:00:00'),
download_maps=True,
output_dir='./output/airnow_wrfchem',
debug=True,
)
Load the model data
The driver will automatically loop through the “models” found in the model
section
of the YAML file and create an instance of melodies_monet.driver.model
for each
that includes the
label
mapping information
file names (can be expressed using a glob expression)
xarray object
Note: Relevant control file section.
1model:
2 RACM_ESRL: # model label
3 files: example:wrfchem:racm_esrl
4 mod_type: "wrfchem"
5 mod_kwargs:
6 mech: "racm_esrl_vcp"
7 surf_only_nc: True # specify that we have only one vertical level; WRF-Chem specific
8 radius_of_influence: 12000 # meters
9 mapping: # of _model_ species name to _obs_ species name
10 airnow: # specifically for the obs labeled 'airnow'
11 PM2_5_DRY: "PM2.5"
12 o3: "OZONE"
13 projection: None
14 plot_kwargs: # optional
15 color: "magenta"
16 marker: "s"
17 linestyle: "-"
18 RACM_ESRL_VCP:
19 files: example:wrfchem:racm_esrl_vcp
20 mod_type: "wrfchem"
21 mod_kwargs:
22 mech: "racm_esrl_vcp"
23 surf_only_nc: True
24 radius_of_influence: 12000
25 mapping:
26 airnow:
27 PM2_5_DRY: "PM2.5"
28 o3: "OZONE"
29 projection: None
30 plot_kwargs:
31 color: "gold"
32 marker: "o"
33 linestyle: "-"
an.open_models()
RACM_ESRL
{'files': 'example:wrfchem:racm_esrl', 'mod_type': 'wrfchem', 'mod_kwargs': {'mech': 'racm_esrl_vcp', 'surf_only_nc': True}, 'radius_of_influence': 12000, 'mapping': {'airnow': {'PM2_5_DRY': 'PM2.5', 'o3': 'OZONE'}}, 'projection': 'None', 'plot_kwargs': {'color': 'magenta', 'marker': 's', 'linestyle': '-'}}
example:wrfchem:racm_esrl
**** Reading WRF-Chem model output...
RACM_ESRL_VCP
{'files': 'example:wrfchem:racm_esrl_vcp', 'mod_type': 'wrfchem', 'mod_kwargs': {'mech': 'racm_esrl_vcp', 'surf_only_nc': True}, 'radius_of_influence': 12000, 'mapping': {'airnow': {'PM2_5_DRY': 'PM2.5', 'o3': 'OZONE'}}, 'projection': 'None', 'plot_kwargs': {'color': 'gold', 'marker': 'o', 'linestyle': '-'}}
example:wrfchem:racm_esrl_vcp
**** Reading WRF-Chem model output...
Applying open_models()
populates the models
attribute.
an.models
{'RACM_ESRL': model(
model='wrfchem',
radius_of_influence=12000,
mod_kwargs={'mech': 'racm_esrl_vcp', 'surf_only_nc': True, 'var_list': ['o3', 'PM2_5_DRY']},
file_str='example:wrfchem:racm_esrl',
label='RACM_ESRL',
obj=...,
mapping={'airnow': {'PM2_5_DRY': 'PM2.5', 'o3': 'OZONE'}},
label='RACM_ESRL',
...
),
'RACM_ESRL_VCP': model(
model='wrfchem',
radius_of_influence=12000,
mod_kwargs={'mech': 'racm_esrl_vcp', 'surf_only_nc': True, 'var_list': ['o3', 'PM2_5_DRY']},
file_str='example:wrfchem:racm_esrl_vcp',
label='RACM_ESRL_VCP',
obj=...,
mapping={'airnow': {'PM2_5_DRY': 'PM2.5', 'o3': 'OZONE'}},
label='RACM_ESRL_VCP',
...
)}
We can access the underlying dataset with the
obj
attribute.
an.models['RACM_ESRL'].obj
<xarray.Dataset> Dimensions: (y: 284, x: 440, time: 31, z: 1) Coordinates: longitude (y, x) float32 -122.3 -122.2 -122.1 ... -60.68 -60.52 -60.37 latitude (y, x) float32 21.19 21.22 21.24 21.27 ... 50.33 50.28 50.24 50.2 * time (time) datetime64[ns] 2019-09-05 ... 2019-09-06T06:00:00 Dimensions without coordinates: y, x, z Data variables: o3 (time, z, y, x) float32 30.0 30.0 30.0 30.0 ... 34.72 36.87 37.13 PM2_5_DRY (time, z, y, x) float32 3.046 3.048 2.84 ... 0.45 0.4506 0.4512 Attributes: (12/17) FieldType: 104 MemoryOrder: XYZ description: O3 mixing ratio units: ppmv stagger: coordinates: XLONG XLAT XTIME ... ... MOAD_CEN_LAT: 39.617638 STAND_LON: -97.0 MAP_PROJ: 1 CEN_LAT: 39.617638 CEN_LON: -97.77487 mapping_tables_to_airnow: {'OZONE': 'o3', 'PM2.5':...
Load the observational data
As with the model data, the driver will loop through the “observations” found in
the obs
section of the YAML file and create an instance of
melodies_monet.driver.observation
for each.
Note: Relevant control file section.
1obs:
2 airnow: # obs label
3 use_airnow: True
4 filename: example:airnow:2019-09
5 obs_type: pt_sfc
6 variables: # optional
7 OZONE:
8 unit_scale: 1
9 # ^ optional; Scaling factor
10 unit_scale_method: "*"
11 # ^ optional; Multiply = '*' , Add = '+', subtract = '-', divide = '/'
12 nan_value: -1.0
13 # ^ optional; When loading data, set this value to NaN
14 ylabel_plot: "Ozone (ppbv)"
15 # optional; set ylabel in order to include units and/or other info
16 vmin_plot: 15.0
17 # ^ optional; Min for y-axis during plotting.
18 # To apply to a plot, change restrict_yaxis = True.
19 vmax_plot: 55.0
20 # ^ optional; Max for y-axis during plotting.
21 # To apply to a plot, change restrict_yaxis = True.
22 vdiff_plot: 20.0
23 # ^ optional; +/- range to use in bias plots.
24 # To apply to a plot, change restrict_yaxis = True.
25 nlevels_plot: 21
26 # ^ optional; number of levels used in colorbar for contourf plot.
27 PM2.5:
28 unit_scale: 1
29 unit_scale_method: "*"
30 # obs_min: 0
31 # ^ optional; set all values less than this value to NaN
32 # obs_max: 100
33 # ^ optional; set all values greater than this value to NaN
34 nan_value: -1.0
35 # Note: The obs_min, obs_max, and nan_values are set to NaN first
36 # and then the unit conversion is applied.
37 ylabel_plot: "PM2.5 (ug/m3)"
38 ty_scale: 2.0 # optional; `ty_` indicates for Taylor diagram plot
39 vmin_plot: 0.0
40 vmax_plot: 22.0
41 vdiff_plot: 15.0
42 nlevels_plot: 23
an.open_obs()
an.obs
{'airnow': observation(
obs='airnow',
label='airnow',
file='example:airnow:2019-09',
obj=...,
type='pt_src',
variable_dict={'OZONE': {'unit_scale': 1, 'unit_scale_method': '*', 'nan_value': -1.0, 'ylabel_plot': 'Ozone (ppbv)', 'vmin_plot': 15.0, 'vmax_plot': 55.0, 'vdiff_plot': 20.0, 'nlevels_plot': 21}, 'PM2.5': {'unit_scale': 1, 'unit_scale_method': '*', 'nan_value': -1.0, 'ylabel_plot': 'PM2.5 (ug/m3)', 'ty_scale': 2.0, 'vmin_plot': 0.0, 'vmax_plot': 22.0, 'vdiff_plot': 15.0, 'nlevels_plot': 23}},
)}
an.obs['airnow'].obj
<xarray.Dataset> Dimensions: (x: 3786, time: 2091, y: 1) Coordinates: * x (x) int64 0 1 2 3 4 5 6 7 ... 3779 3780 3781 3782 3783 3784 3785 * time (time) datetime64[ns] 2019-09-01 ... 2019-09-30T00:30:00 latitude (y, x) float64 47.65 47.51 49.02 53.3 ... 36.92 47.93 41.37 longitude (y, x) float64 -52.82 -52.79 -55.8 -60.36 ... -94.84 106.9 69.27 siteid (y, x) object '000010102' '000010401' ... 'UZB010001' Dimensions without coordinates: y Data variables: (12/30) BARPR (time, y, x) float64 ... BC (time, y, x) float64 ... CO (time, y, x) float64 ... NO (time, y, x) float64 ... NO2 (time, y, x) float64 ... NO2Y (time, y, x) float64 ... ... ... cmsa_name (y, x) float64 -1.0 -1.0 -1.0 -1.0 -1.0 ... -1.0 -1.0 -1.0 -1.0 msa_code (y, x) float64 -1.0 -1.0 -1.0 -1.0 ... -1.0 3.306e+04 -1.0 -1.0 msa_name (y, x) object '' '' '' '' '' '' ... '' '' '' ' Miami, OK ' '' '' state_name (y, x) object 'CC' 'CC' 'CC' 'CC' 'CC' 'CC' ... '' '' '' '' '' epa_region (y, x) object 'CA' 'CA' 'CA' 'CA' 'CA' ... '' 'R6' 'DSMG' 'DSUZ' time_local (time, y, x) datetime64[ns] ... Attributes: title: format: NetCDF-4 date_created: 2021-06-07
Pair model and observational data
Now, we create a melodies_monet.driver.pair
for each model–obs pair
using the pair_data()
routine.
%%time
an.pair_data()
[########################################] | 100% Completed | 0.1s
[########################################] | 100% Completed | 0.1s
[########################################] | 100% Completed | 0.1s
[########################################] | 100% Completed | 0.2s
[########################################] | 100% Completed | 0.1s
[########################################] | 100% Completed | 0.2s
[########################################] | 100% Completed | 0.2s
[########################################] | 100% Completed | 0.2s
Wall time: 47.5 s
an.paired
{'airnow_RACM_ESRL': pair(
type='pt_sfc',
radius_of_influence=1000000.0,
obs='airnow',
model='RACM_ESRL',
model_vars=['PM2_5_DRY', 'o3'],
obs_vars=['PM2.5', 'OZONE'],
filename='airnow_RACM_ESRL.nc',
),
'airnow_RACM_ESRL_VCP': pair(
type='pt_sfc',
radius_of_influence=1000000.0,
obs='airnow',
model='RACM_ESRL_VCP',
model_vars=['PM2_5_DRY', 'o3'],
obs_vars=['PM2.5', 'OZONE'],
filename='airnow_RACM_ESRL_VCP.nc',
)}
an.paired['airnow_RACM_ESRL']
pair(
type='pt_sfc',
radius_of_influence=1000000.0,
obs='airnow',
model='RACM_ESRL',
model_vars=['PM2_5_DRY', 'o3'],
obs_vars=['PM2.5', 'OZONE'],
filename='airnow_RACM_ESRL.nc',
)
Plot
The plotting()
routine produces plots.
Note: Relevant control file section.
1plots:
2 plot_grp1:
3 type: "timeseries" # plot type
4 fig_kwargs: # optional; to define figure options
5 figsize: [12, 6] # figure size (width, height) in inches
6 default_plot_kwargs:
7 # ^ optional; Define defaults for all plots.
8 # Important: Model kwargs overwrite these.
9 linewidth: 2.0
10 markersize: 10.
11 text_kwargs: # optional
12 fontsize: 24.
13 domain_type: ["all", "state_name", "epa_region"]
14 # ^ List of domain types: 'all' or any domain in obs file.
15 # (e.g., airnow: epa_region, state_name, siteid, etc.)
16 domain_name: ["CONUS", "CA", "R9"]
17 # ^ List of domain names. If domain_type = all,
18 # the domain name is used in the plot title.
19 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
20 # ^ make this a list of pairs in obs_model
21 # where the obs is the obs label and model is the model_label
22 data_proc: # optional??
23 rem_obs_nan: True
24 # ^ True: Remove all points where model or obs variable is NaN.
25 # False: Remove only points where model variable is NaN.
26 ts_select_time: "time_local" # `ts_` indicates this is time series plot-specific
27 # ^ Time used for avg and plotting
28 # Options: 'time' for UTC or 'time_local'
29 ts_avg_window: "H"
30 # ^ Options: None for no averaging, pandas resample rule (e.g., 'H', 'D')
31 set_axis: True
32 # ^ If true, add `vmin_plot` and `vmax_plot` for each variable in obs.
33
34 plot_grp2:
35 type: "taylor"
36 fig_kwargs:
37 figsize: [8, 8]
38 default_plot_kwargs:
39 linewidth: 2.0
40 markersize: 10.
41 text_kwargs:
42 fontsize: 16.
43 domain_type: ["all"]
44 domain_name: ["CONUS"]
45 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
46 data_proc:
47 rem_obs_nan: True
48 set_axis: True
49
50 plot_grp3:
51 type: "spatial_bias"
52 fig_kwargs: # optional; For all spatial plots, specify map_kwargs here too.
53 states: True # such as whether to show the state boundaries
54 figsize: [10, 5]
55 text_kwargs:
56 fontsize: 16.
57 domain_type: ["all",]
58 domain_name: ["CONUS"]
59 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
60 data_proc:
61 rem_obs_nan: True
62 set_axis: True
63
64 plot_grp4:
65 type: "spatial_overlay"
66 fig_kwargs:
67 states: True
68 figsize: [10, 5]
69 text_kwargs:
70 fontsize: 16.
71 domain_type: ["all", "epa_region"]
72 domain_name: ["CONUS", "R9"]
73 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
74 data_proc:
75 rem_obs_nan: True
76 set_axis: True
77
78 plot_grp5:
79 type: "boxplot"
80 fig_kwargs:
81 figsize: [8, 6]
82 text_kwargs:
83 fontsize: 20.
84 domain_type: ["all"]
85 domain_name: ["CONUS"]
86 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
87 data_proc:
88 rem_obs_nan: True
89 set_axis: False
%%time
an.plotting()
Reference std: 5.409628418207226
Warning: ty_scale not specified for OZONE, so default used.
Reference std: 16.454896847070792
Warning: ty_scale not specified for OZONE, so default used.
c:\users\zmoon\git\melodies-monet\melodies_monet\plots\surfplots.py:734: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
f,ax = plt.subplots(**fig_dict)
Wall time: 2min 33s






















The figures are saved in the directory specified by the
analysis
instance’s
output_dir
attribute.
Statistics
The stats()
routine produces tables of statistics.
Note: Relevant control file section.
1stats:
2 # Stats require positive numbers, so if you want to calculate temperature use Kelvin!
3 # Wind direction has special calculations for AirNow if obs name is 'WD'
4 stat_list: ["MB", "MdnB", "R2", "RMSE"]
5 # ^ List stats to calculate. Dictionary of definitions included
6 # in submodule `plots/proc_stats`. Only stats listed below are currently working.
7 # Full calc list:
8 # ['STDO', 'STDP', 'MdnNB','MdnNE','NMdnGE',
9 # 'NO', 'NOP', 'NP', 'MO', 'MP', 'MdnO', 'MdnP',
10 # 'RM', 'RMdn', 'MB', 'MdnB', 'NMB', 'NMdnB', 'FB',
11 # 'ME','MdnE','NME', 'NMdnE', 'FE', 'R2', 'RMSE','d1',
12 # 'E1', 'IOA', 'AC']
13 round_output: 2 # optional; defaults to rounding to 3rd decimal place
14 output_table: False
15 # ^ Always outputs a .txt file.
16 # Optional to also output a Matplotlib figure table (image).
17 output_table_kwargs: # optional
18 figsize: [7, 3]
19 fontsize: 12.
20 xscale: 1.4
21 yscale: 1.4
22 edges: "horizontal"
23 domain_type: ["all"]
24 domain_name: ["CONUS"]
25 data: ["airnow_RACM_ESRL", "airnow_RACM_ESRL_VCP"]
%%time
an.stats()
Wall time: 32.9 s
The stats routine has produced two files (one for each data variable). This is one of them:
Stat_ID,Stat_FullName,airnow_RACM_ESRL,airnow_RACM_ESRL_VCP
MB,Mean_Bias,3.93,3.23
MdnB,Median_Bias,3.86,3.27
R2,Coefficient_of_Determination_(R2),0.56,0.54
RMSE,Root_Mean_Square_Error,11.64,11.59