3
3
General comparison of 2-d model fields against data. Currently only supports
4
4
mixed layer depths (mld) and sea surface temperature (sst)
5
5
6
- Author: Luke Van Roekel, Milena Veneziani
7
- Last Modified: 10/24 /2016
6
+ Author: Luke Van Roekel, Milena Veneziani, Xylar Asay-Davis
7
+ Last Modified: 12/06 /2016
8
8
"""
9
9
10
10
import matplotlib .pyplot as plt
14
14
import xarray as xr
15
15
import datetime
16
16
from netCDF4 import Dataset as netcdf_dataset
17
- import os .path
18
17
19
- from ..shared .mpas_xarray .mpas_xarray import preprocess_mpas , remove_repeated_time_index
18
+ from ..shared .mpas_xarray .mpas_xarray import preprocess_mpas , \
19
+ remove_repeated_time_index
20
20
from ..shared .plot .plotting import plot_global_comparison
21
21
from ..shared .interpolation .interpolate import interp_fields , init_tree
22
22
from ..shared .constants import constants
23
23
24
24
from ..shared .io import StreamsFile
25
25
26
- def ocn_modelvsobs (config , field ):
26
+
27
+ def ocn_modelvsobs (config , field , streamMap = None , variableMap = None ):
27
28
28
29
"""
29
30
Plots a comparison of ACME/MPAS output to SST or MLD observations
30
31
32
+ If present, streamMap is a dictionary of MPAS-O stream names that map to
33
+ their mpas_analysis counterparts.
34
+
35
+ If present, variableMap is a dictionary of MPAS-O variable names that map
36
+ to their mpas_analysis counterparts.
37
+
31
38
Authors: Luke Van Roekel, Milena Veneziani, Xylar Asay-Davis
32
- Modified: 10/27 /2016
39
+ Modified: 12/07 /2016
33
40
"""
34
41
42
+ field = field .lower ()
43
+
35
44
# read parameters from config file
36
45
indir = config .get ('paths' , 'archive_dir_ocn' )
37
46
@@ -42,9 +51,10 @@ def ocn_modelvsobs(config, field):
42
51
# reading only those that are between the start and end dates
43
52
startDate = config .get ('time' , 'climo_start_date' )
44
53
endDate = config .get ('time' , 'climo_end_date' )
45
- infiles = streams .readpath ('timeSeriesStatsOutput' ,
46
- startDate = startDate , endDate = endDate )
47
- print 'Reading files {} through {}' .format (infiles [0 ],infiles [- 1 ])
54
+ streamName = streams .find_stream (streamMap ['timeSeriesStats' ])
55
+ infiles = streams .readpath (streamName , startDate = startDate ,
56
+ endDate = endDate )
57
+ print 'Reading files {} through {}' .format (infiles [0 ], infiles [- 1 ])
48
58
49
59
plots_dir = config .get ('paths' , 'plots_dir' )
50
60
obsdir = config .get ('paths' , 'obs_' + field .lower () + 'dir' )
@@ -57,55 +67,46 @@ def ocn_modelvsobs(config, field):
57
67
outputTimes = config .getExpression (field .lower () + '_modelvsobs' ,
58
68
'comparisonTimes' )
59
69
60
- f = netcdf_dataset (meshfile ,mode = 'r' )
70
+ f = netcdf_dataset (meshfile , mode = 'r' )
61
71
lonCell = f .variables ["lonCell" ][:]
62
72
latCell = f .variables ["latCell" ][:]
63
73
64
- if field .lower () == 'mld' :
65
- obs_filename = "%s/holtetalley_mld_climatology.nc" % obsdir
74
+ varList = [field ]
66
75
67
- ds = xr .open_mfdataset (infiles , preprocess = lambda x :
68
- preprocess_mpas (x , yearoffset = yr_offset ,
69
- timestr = ['xtime_start' , 'xtime_end' ],
70
- onlyvars = ['time_avg_dThreshMLD' ]))
71
- ds = remove_repeated_time_index (ds )
72
- ds .rename ({'time_avg_dThreshMLD' :'mpasData' }, inplace = True )
76
+ if field == 'mld' :
73
77
74
- #Load MLD observational data
78
+ selvals = None
79
+
80
+ # Load MLD observational data
81
+ obs_filename = "{}/holtetalley_mld_climatology.nc" .format (obsdir )
75
82
dsData = xr .open_mfdataset (obs_filename )
76
83
77
- #Increment month value to be consistent with the model output
84
+ # Increment month value to be consistent with the model output
78
85
dsData .iMONTH .values += 1
79
86
80
- #Rename the time dimension to be consistent with the SST dataset
81
- dsData .rename ({'month' :'calmonth' }, inplace = True )
82
- dsData .rename ({'iMONTH' :'month' }, inplace = True )
87
+ # Rename the time dimension to be consistent with the SST dataset
88
+ dsData .rename ({'month' : 'calmonth' }, inplace = True )
89
+ dsData .rename ({'iMONTH' : 'month' }, inplace = True )
83
90
84
- #rename appropriate observational data for compactness
85
- dsData .rename ({'mld_dt_mean' :'observationData' }, inplace = True )
91
+ obsFieldName = 'mld_dt_mean'
86
92
87
- #Reorder dataset for consistence
93
+ # Reorder dataset for consistence
88
94
dsData = dsData .transpose ('month' , 'iLON' , 'iLAT' )
89
95
90
- #Set appropriate MLD figure labels
96
+ # Set appropriate MLD figure labels
91
97
obsTitleLabel = "Observations (HolteTalley density threshold MLD)"
92
98
fileOutLabel = "mldHolteTalleyARGO"
93
99
unitsLabel = 'm'
94
100
95
- elif field . lower () == 'sst' :
101
+ elif field == 'sst' :
96
102
97
- ds = xr .open_mfdataset (infiles , preprocess = lambda x :
98
- preprocess_mpas (x , yearoffset = yr_offset ,
99
- timestr = ['xtime_start' , 'xtime_end' ],
100
- onlyvars = ['time_avg_activeTracers_temperature' ],
101
- selvals = {'nVertLevels' :1 }))
102
- ds = remove_repeated_time_index (ds )
103
- ds .rename ({'time_avg_activeTracers_temperature' :'mpasData' }, inplace = True )
103
+ selvals = {'nVertLevels' : 1 }
104
104
105
- obs_filename = "%s/MODEL.SST.HAD187001-198110.OI198111-201203.nc" % obsdir
105
+ obs_filename = \
106
+ "{}/MODEL.SST.HAD187001-198110.OI198111-201203.nc" .format (obsdir )
106
107
dsData = xr .open_mfdataset (obs_filename )
107
- #Select years for averaging (pre-industrial or present-day)
108
- #This seems fragile as definitions can change
108
+ # Select years for averaging (pre-industrial or present-day)
109
+ # This seems fragile as definitions can change
109
110
if yr_offset < 1900 :
110
111
time_start = datetime .datetime (1870 , 1 , 1 )
111
112
time_end = datetime .datetime (1900 , 12 , 31 )
@@ -118,15 +119,25 @@ def ocn_modelvsobs(config, field):
118
119
ds_tslice = dsData .sel (time = slice (time_start , time_end ))
119
120
monthly_clim_data = ds_tslice .groupby ('time.month' ).mean ('time' )
120
121
121
- #Rename the observation data for code compactness
122
+ # Rename the observation data for code compactness
122
123
dsData = monthly_clim_data .transpose ('month' , 'lon' , 'lat' )
123
- dsData . rename ({ 'SST' : 'observationData' }, inplace = True )
124
+ obsFieldName = 'SST'
124
125
125
- #Set appropriate figure labels for SST
126
- obsTitleLabel = "Observations (Hadley/OI, %s)" % preIndustrial_txt
126
+ # Set appropriate figure labels for SST
127
+ obsTitleLabel = \
128
+ "Observations (Hadley/OI, {})" .format (preIndustrial_txt )
127
129
fileOutLabel = "sstHADOI"
128
130
unitsLabel = r'$^o$C'
129
131
132
+ ds = xr .open_mfdataset (
133
+ infiles ,
134
+ preprocess = lambda x : preprocess_mpas (x , yearoffset = yr_offset ,
135
+ timestr = 'Time' ,
136
+ onlyvars = varList ,
137
+ selvals = selvals ,
138
+ variable_map = variableMap ))
139
+ ds = remove_repeated_time_index (ds )
140
+
130
141
time_start = datetime .datetime (yr_offset + climo_yr1 , 1 , 1 )
131
142
time_end = datetime .datetime (yr_offset + climo_yr2 , 12 , 31 )
132
143
ds_tslice = ds .sel (Time = slice (time_start , time_end ))
@@ -136,21 +147,30 @@ def ocn_modelvsobs(config, field):
136
147
latData = latData .flatten ()
137
148
lonData = lonData .flatten ()
138
149
139
- daysarray = np .ones ((12 , dsData .observationData .values .shape [1 ], dsData .observationData .values .shape [2 ]))
150
+ daysarray = np .ones ((12 , dsData [obsFieldName ].values .shape [1 ],
151
+ dsData [obsFieldName ].values .shape [2 ]))
140
152
141
153
for i , dval in enumerate (constants .dinmonth ):
142
154
daysarray [i , :, :] = dval
143
- inds = np .where (np .isnan (dsData . observationData [i , :, :].values ))
155
+ inds = np .where (np .isnan (dsData [ obsFieldName ] [i , :, :].values ))
144
156
daysarray [i , inds [0 ], inds [1 ]] = np .NaN
145
157
146
-
147
158
# initialize interpolation variables
148
- d2 , inds2 , lonTarg , latTarg = init_tree (np .rad2deg (lonCell ), np .rad2deg (latCell ), constants .lonmin ,
149
- constants .lonmax , constants .latmin , constants .latmax ,
150
- constants .dLongitude , constants .dLatitude )
151
- d , inds , lonTargD , latTargD = init_tree (lonData , latData , constants .lonmin , constants .lonmax ,
152
- constants .latmin , constants .latmax , constants .dLongitude ,
153
- constants .dLatitude )
159
+ d2 , inds2 , lonTarg , latTarg = init_tree (np .rad2deg (lonCell ),
160
+ np .rad2deg (latCell ),
161
+ constants .lonmin ,
162
+ constants .lonmax ,
163
+ constants .latmin ,
164
+ constants .latmax ,
165
+ constants .dLongitude ,
166
+ constants .dLatitude )
167
+ d , inds , lonTargD , latTargD = init_tree (lonData , latData ,
168
+ constants .lonmin ,
169
+ constants .lonmax ,
170
+ constants .latmin ,
171
+ constants .latmax ,
172
+ constants .dLongitude ,
173
+ constants .dLatitude )
154
174
nLon = lonTarg .shape [0 ]
155
175
nLat = lonTarg .shape [1 ]
156
176
@@ -163,50 +183,59 @@ def ocn_modelvsobs(config, field):
163
183
monthsvalue = constants .monthdictionary [timestring ]
164
184
165
185
if isinstance (monthsvalue , (int , long )):
166
- modeldata = monthly_clim .sel (month = monthsvalue ). mpasData .values
167
- obsdata = dsData .sel (month = monthsvalue ). observationData .values
186
+ modeldata = monthly_clim .sel (month = monthsvalue )[ field ] .values
187
+ obsdata = dsData .sel (month = monthsvalue )[ obsFieldName ] .values
168
188
else :
169
- modeldata = np .sum (constants .dinmonth [monthsvalue - 1 ]* monthly_clim .sel (month = monthsvalue ).
170
- mpasData .values .T , axis = 1 ) / np .sum (constants .dinmonth [monthsvalue - 1 ])
171
- obsdata = np .nansum (daysarray [monthsvalue - 1 , :, :]* dsData .sel (month = monthsvalue ).
172
- observationData .values , axis = 0 ) / np .nansum (daysarray [monthsvalue - 1 , :, :],
173
- axis = 0 )
189
+
190
+ modeldata = np .sum (
191
+ constants .dinmonth [monthsvalue - 1 ] *
192
+ monthly_clim .sel (month = monthsvalue )[field ].values .T ,
193
+ axis = 1 ) / np .sum (constants .dinmonth [monthsvalue - 1 ])
194
+ obsdata = np .nansum (
195
+ daysarray [monthsvalue - 1 , :, :] *
196
+ dsData .sel (month = monthsvalue )[obsFieldName ].values ,
197
+ axis = 0 ) / np .nansum (daysarray [monthsvalue - 1 , :, :], axis = 0 )
174
198
175
199
modelOutput [i , :, :] = interp_fields (modeldata , d2 , inds2 , lonTarg )
176
- observations [i , :, :] = interp_fields (obsdata .flatten (), d , inds , lonTargD )
200
+ observations [i , :, :] = interp_fields (obsdata .flatten (), d , inds ,
201
+ lonTargD )
177
202
178
203
for i in range (len (outputTimes )):
179
204
bias [i , :, :] = modelOutput [i , :, :] - observations [i , :, :]
180
205
181
- clevsModelObs = config .getExpression (field . lower () + '_modelvsobs' ,
206
+ clevsModelObs = config .getExpression (field + '_modelvsobs' ,
182
207
'clevsModelObs' )
183
- cmap = plt .get_cmap (config .get (field . lower () + '_modelvsobs' ,
208
+ cmap = plt .get_cmap (config .get (field + '_modelvsobs' ,
184
209
'cmapModelObs' ))
185
- cmapIndices = config .getExpression (field . lower () + '_modelvsobs' ,
210
+ cmapIndices = config .getExpression (field + '_modelvsobs' ,
186
211
'cmapIndicesModelObs' )
187
212
cmapModelObs = cols .ListedColormap (cmap (cmapIndices ), "cmapModelObs" )
188
- clevsDiff = config .getExpression (field . lower () + '_modelvsobs' ,
213
+ clevsDiff = config .getExpression (field + '_modelvsobs' ,
189
214
'clevsDiff' )
190
- cmap = plt .get_cmap (config .get (field . lower () + '_modelvsobs' , 'cmapDiff' ))
191
- cmapIndices = config .getExpression (field . lower () + '_modelvsobs' ,
215
+ cmap = plt .get_cmap (config .get (field + '_modelvsobs' , 'cmapDiff' ))
216
+ cmapIndices = config .getExpression (field + '_modelvsobs' ,
192
217
'cmapIndicesDiff' )
193
218
cmapDiff = cols .ListedColormap (cmap (cmapIndices ), "cmapDiff" )
194
219
195
220
for i in range (len (outputTimes )):
221
+ fileout = "{}/{}_{}_{}_years{:04d}-{:04d}.png" .format (
222
+ plots_dir , fileOutLabel , casename , outputTimes [i ], climo_yr1 ,
223
+ climo_yr2 )
224
+ title = "{} ({}, years {:04d}-{:04d})" .format (
225
+ field .upper (), outputTimes [i ], climo_yr1 , climo_yr2 )
196
226
plot_global_comparison (config ,
197
227
lonTarg ,
198
228
latTarg ,
199
229
modelOutput [i , :, :],
200
230
observations [i , :, :],
201
- bias [i , :,:],
231
+ bias [i , :, :],
202
232
cmapModelObs ,
203
233
clevsModelObs ,
204
234
cmapDiff ,
205
235
clevsDiff ,
206
- fileout = "%s/%s_%s_%s_years%04d-%04d.png" % (plots_dir , fileOutLabel ,
207
- casename , outputTimes [i ], climo_yr1 , climo_yr2 ),
208
- title = "%s (%s, years %04d-%04d)" % (field .upper (), outputTimes [i ], climo_yr1 , climo_yr2 ),
209
- modelTitle = "%s" % casename ,
210
- obsTitle = obsTitleLabel ,
211
- diffTitle = "Model-Observations" ,
212
- cbarlabel = unitsLabel )
236
+ fileout = fileout ,
237
+ title = title ,
238
+ modelTitle = "{}" .format (casename ),
239
+ obsTitle = obsTitleLabel ,
240
+ diffTitle = "Model-Observations" ,
241
+ cbarlabel = unitsLabel )
0 commit comments