Skip to content

Commit 3444789

Browse files
authored
Merge pull request #132 from valeriupredoi/dev_amoc_reverse
Several developments for the AMOC analysis
2 parents 823f0b0 + 41e61d8 commit 3444789

35 files changed

+1425
-327
lines changed

bgcval2/analysis_compare.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def apply_timerange(times, datas, jobID, timeranges):
175175
print('apply_timerange:', jobID, ti, da)
176176

177177
if not len(n_times):
178-
print('apply_timerange: WARNING: No times made the cut?', len(times),
178+
print('apply_timerange: WARNING: No times made the cut?', jobID, len(times),
179179
'original times', [np.min(times), np.max(times)],
180180
'timerange:', timerange)
181181
assert 0
@@ -401,7 +401,7 @@ def timeseries_compare(jobs,
401401
title = titleify([region, layer, metric, name])
402402

403403
times, datas = apply_shifttimes(mdata, jobID, shifttimes)
404-
print('post apply_shifttimes:', len(times), len(datas))
404+
print('post apply_shifttimes:', jobID, len(times), len(datas))
405405
times, datas = apply_timerange(times, datas, jobID, timeranges)
406406
timesD[jobID] = times
407407
arrD[jobID] = datas

bgcval2/bgcval2_make_report.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,7 @@ def newImageLocation(fn):
14881488
'SouthernTotalIceExtent',
14891489
'Temperature_Global_Surface',
14901490
'Salinty_Global_Surface',
1491+
'AtlanticSubtropicalSalinity',
14911492
'FreshwaterFlux_Global',
14921493
'TotalHeatFlux',
14931494
'MA_SST',
@@ -1524,7 +1525,6 @@ def newImageLocation(fn):
15241525
'BGC Key Metrics': [],
15251526
'Other Plots': [],
15261527
}
1527-
15281528

15291529
for fn in files:
15301530
found = False
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
#!/usr/bin/ipython
2+
#
3+
# Copyright 2024, Plymouth Marine Laboratory
4+
#
5+
# This file is part of the bgc-val library.
6+
#
7+
# bgc-val is free software: you can redistribute it and/or modify it
8+
# under the terms of the Revised Berkeley Software Distribution (BSD) 3-clause license.
9+
10+
# bgc-val is distributed in the hope that it will be useful, but
11+
# without any warranty; without even the implied warranty of merchantability
12+
# or fitness for a particular purpose. See the revised BSD license for more details.
13+
# You should have received a copy of the revised BSD license along with bgc-val.
14+
# If not, see <http://opensource.org/licenses/BSD-3-Clause>.
15+
#
16+
# Address:
17+
# Plymouth Marine Laboratory
18+
# Prospect Place, The Hoe
19+
# Plymouth, PL1 3DH, UK
20+
#
21+
# Email:
22+
# ledm@pml.ac.uk
23+
#
24+
"""
25+
.. module:: generic_map_legend
26+
:platform: Unix
27+
:synopsis: Tool to make a plot showing a regions.
28+
.. moduleauthor:: Lee de Mora <ledm@pml.ac.uk>
29+
.. active:: No
30+
"""
31+
32+
# implement correct import of params if module in use
33+
# from ..Paths.paths import orcaGridfn, WOAFolder_annual
34+
import matplotlib
35+
matplotlib.use('Agg')
36+
import os
37+
from netCDF4 import Dataset
38+
import numpy as np
39+
from bgcval2.bgcvaltools import bv2tools as bvt
40+
from bgcval2.bgcvaltools.pftnames import getLongName
41+
from bgcval2.bgcvaltools.makeMask import makeMask
42+
from matplotlib import pyplot
43+
import cartopy
44+
import cartopy.crs as ccrs
45+
from cartopy import img_transform, feature as cfeature
46+
from bgcval2._runtime_config import get_run_configuration
47+
from bgcval2.Paths.paths import paths_setter
48+
49+
50+
51+
52+
# Functions#
53+
# Make a single plot for each region.
54+
# one pane for global map centered on the middle of the region.
55+
# One pane zoomed in on center of region
56+
# One pane global map.
57+
58+
59+
def plot_globe(ax):
60+
pyplot.sca(ax)
61+
62+
# if quick:
63+
ax.add_feature(cfeature.OCEAN, zorder=0)
64+
ax.add_feature(cfeature.LAND, zorder=0, edgecolor='black')
65+
# else:
66+
# nc = Dataset(bathy_fn, 'r')
67+
# lats = nc.variables['lat'][::binning]
68+
# lons = nc.variables['lon'][::binning]
69+
70+
# data = nc.variables['elevation'][::binning, ::binning]
71+
# nc.close()
72+
73+
# data = np.ma.masked_where(data>0., data)
74+
75+
# pyplot.pcolormesh(
76+
# lons,
77+
# lats,
78+
# data,
79+
# #transform=proj,
80+
# transform=ccrs.PlateCarree(),
81+
# cmap=cmap,
82+
# vmin=vmin, vmax=vmax,
83+
# )
84+
# ax.coastlines()
85+
# ax.add_feature(cfeature.LAND, edgecolor='black', facecolor=land_color, linewidth=0.5, zorder=9)
86+
87+
ax.set_global()
88+
ax.gridlines()
89+
return ax
90+
91+
92+
def plot_platcarre(ax):
93+
pyplot.sca(ax)
94+
95+
# if quick:
96+
ax.add_feature(cfeature.OCEAN, zorder=0)
97+
# else:
98+
# nc = Dataset(bathy_fn, 'r')
99+
# lats = nc.variables['lat'][::binning]
100+
# lons = nc.variables['lon'][::binning]
101+
102+
# data = nc.variables['elevation'][::binning, ::binning]
103+
# nc.close()
104+
105+
# data = np.ma.masked_where(data>0., data)
106+
107+
# pyplot.pcolormesh(
108+
# lons,
109+
# lats,
110+
# data,
111+
# #transform=proj,
112+
# transform=ccrs.PlateCarree(),
113+
# cmap=cmap,
114+
# vmin=vmin, vmax=vmax,
115+
# )
116+
# ax.coastlines()
117+
# ax.add_feature(cfeature.LAND, edgecolor='black', facecolor=land_color, linewidth=0.5, zorder=9)
118+
119+
ax.set_global()
120+
ax.gridlines()
121+
return ax
122+
123+
124+
def add_region(fig, ax, lons, lats, data):
125+
#im = ax.scatter(lons, lats, c=data)
126+
pyplot.sca(ax)
127+
#im = ax.contourf(lons, lats, data, zorder=1000)
128+
im = ax.pcolormesh(lons, lats, data, zorder=1, transform=ccrs.PlateCarree(),)
129+
130+
#pyplot.colorbar()
131+
132+
ax.add_feature(cfeature.LAND, zorder=10, edgecolor='black')
133+
return fig, ax, im
134+
135+
136+
def make_figure(region):
137+
fig_fn = bvt.folder('images/regions')+region+'.png'
138+
#if os.path.exists(fig_fn): return
139+
140+
fig = pyplot.figure()
141+
142+
paths_dict, config_user = get_run_configuration("defaults")
143+
# filter paths dict into an object that's usable below
144+
paths = paths_setter(paths_dict)
145+
#ncfn = paths.orcaGridfn
146+
ncfn = 'mesh_mask_eORCA1_wrk.nc'
147+
148+
nc = Dataset(ncfn, 'r')
149+
print(ncfn)
150+
151+
dat = nc.variables['mbathy'][:].squeeze()
152+
lats = nc.variables['nav_lat'][:].squeeze()
153+
lons = nc.variables['nav_lon'][:].squeeze()
154+
lons = bvt.makeLonSafeArr(lons)
155+
156+
old_mask = np.ma.masked_where(dat.mask + dat ==0, dat).mask
157+
158+
xd = np.ma.masked_where(old_mask, dat).flatten()
159+
xt = np.ones_like(xd)
160+
xz = xt
161+
xy = np.ma.masked_where(old_mask, lats).flatten()
162+
xx = np.ma.masked_where(old_mask, lons).flatten()
163+
old_mask_flat = old_mask.flatten()
164+
165+
region_mask = makeMask('bathy', region, xt, xz, xy, xx, xd, debug=True)
166+
#print('done makeMask')
167+
#assert 0
168+
new_dat = np.ma.masked_where(region_mask + old_mask_flat, xd)
169+
new_lon = np.ma.masked_where(region_mask+ old_mask_flat, xx)
170+
new_lat = np.ma.masked_where(region_mask+ old_mask_flat, xy)
171+
172+
new_dat = new_dat.reshape(dat.shape)
173+
#new_lat = lats # new_lat.reshape(lats.shape)
174+
#new_lon = lons # new_lon.reshape(lons.shape)
175+
176+
177+
fig.set_size_inches(12, 8)
178+
widths = [1, 1, 1]
179+
heights = [1, 1.75]
180+
spec2 = matplotlib.gridspec.GridSpec(
181+
ncols=len(widths),
182+
nrows=len(heights),
183+
figure=fig,
184+
width_ratios=widths,
185+
height_ratios=heights,
186+
hspace=0.30,
187+
wspace=0.30,)
188+
189+
print('lats:', new_lat.mean(), 'lon:', new_lon.mean(), 'data:', new_dat.min(), new_dat.max())
190+
191+
ortho_pro=ccrs.Orthographic(new_lon.mean(), new_lat.mean(),)
192+
ax_globe = fig.add_subplot(spec2[0, 0], projection=ortho_pro)
193+
ax_globe = plot_globe(ax_globe)
194+
fig, ax_globe, im = add_region(fig, ax_globe, lons, lats, new_dat)
195+
196+
ortho_pro=ccrs.Orthographic(new_lon.mean()+120., new_lat.mean(),)
197+
ax_globe1 = fig.add_subplot(spec2[0, 1], projection=ortho_pro)
198+
ax_globe1 = plot_globe(ax_globe1)
199+
fig, ax_globe1, im1 = add_region(fig, ax_globe1, lons, lats, new_dat)
200+
201+
202+
ortho_pro=ccrs.Orthographic(new_lon.mean()-120., new_lat.mean(),)
203+
ax_globe2 = fig.add_subplot(spec2[0, 2], projection=ortho_pro)
204+
ax_globe2 = plot_globe(ax_globe2)
205+
fig, ax_globe2, im2 = add_region(fig, ax_globe2, lons, lats, new_dat)
206+
207+
pc_proj=cartopy.crs.PlateCarree(central_longitude=new_lon.mean())
208+
ax_pc = fig.add_subplot(spec2[1, :], projection=pc_proj)
209+
ax_pc = plot_platcarre(ax_pc)
210+
fig, ax_pc, im3 = add_region(fig, ax_pc, lons, lats, new_dat)
211+
#cbar = pyplot.colorbar(ax=ax_pc, cax=im3)
212+
213+
pyplot.suptitle(region+': '+getLongName(region))
214+
print('saving:', fig_fn)
215+
pyplot.savefig(fig_fn,dpi=300.)
216+
pyplot.savefig(fig_fn.replace('.png', '_trans.png'), transparent=True)
217+
pyplot.close()
218+
219+
220+
def main():
221+
regions = [
222+
'Ascension',
223+
'ITCZ',
224+
'TristandaCunha',
225+
'Pitcairn',
226+
'Cornwall',
227+
'SubtropicNorthAtlantic',
228+
'SPNA',
229+
'STNA',
230+
'SouthernOcean',
231+
'ArcticOcean',
232+
'Equator10',
233+
'NorthPacificOcean',
234+
'SouthPacificOcean',
235+
'NorthAtlanticOcean',
236+
'SouthAtlanticOcean',
237+
'GINseas',
238+
'LabradorSea',
239+
'EquatorialAtlanticOcean',
240+
'Global',
241+
'ignoreInlandSeas',
242+
]
243+
for region in regions[:]:
244+
make_figure(region)
245+
246+
if __name__ == "__main__":
247+
main()

bgcval2/bgcvaltools/makeMask.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,20 +216,20 @@ def makeMask(name, newSlice, xt, xz, xy, xx, xd, debug=False):
216216
if newSlice == 'ignoreExtraArtics':
217217
return np.ma.masked_outside(xy, -50., 50.).mask
218218
if newSlice == 'NorthAtlanticOcean':
219-
return np.ma.masked_outside(bvt.makeLonSafeArr(xx), -80.,
219+
print('NorthAtlanticOcean - pre')
220+
#xx = bvt.makeLonSafeArr(xx)
221+
print('NorthAtlanticOcean', len(xx))
222+
return np.ma.masked_outside(xx, -80.,
220223
0.).mask + np.ma.masked_outside(
221224
xy, 10., 60.).mask
222225
if newSlice == 'SouthAtlanticOcean':
223-
return np.ma.masked_outside(bvt.makeLonSafeArr(xx), -65.,
224-
20.).mask + np.ma.masked_outside(
226+
return np.ma.masked_outside(xx, -65., 20.).mask + np.ma.masked_outside(
225227
xy, -50., -10.).mask
226228
if newSlice == 'EquatorialAtlanticOcean':
227-
return np.ma.masked_outside(bvt.makeLonSafeArr(xx), -65.,
228-
20.).mask + np.ma.masked_outside(
229+
return np.ma.masked_outside(xx, -65., 20.).mask + np.ma.masked_outside(
229230
xy, -15., 15.).mask
230231
if newSlice == 'ITCZ': #Inter‐Tropical Convergence Zone (johns 2020 Sargassum) in the region 0-15N, 15-55W
231-
return np.ma.masked_outside(bvt.makeLonSafeArr(xx), -55.,
232-
15.).mask + np.ma.masked_outside(
232+
return np.ma.masked_outside(xx, -55., 15.).mask + np.ma.masked_outside(
233233
xy, 0., 15.).mask
234234

235235
if newSlice == 'ArcticOcean':
@@ -246,11 +246,36 @@ def makeMask(name, newSlice, xt, xz, xy, xx, xd, debug=False):
246246
xy, 60., 80.).mask
247247
return mx
248248

249+
if newSlice in ['SubtropicNorthAtlantic', 'STNA']:
250+
mx = np.ma.masked_outside(xx, -80., -10.).mask + np.ma.masked_outside(
251+
xy, 10., 40.).mask
252+
# mx *= np.ma.masked_outside(xx, -45., 15.).mask + np.ma.masked_outside(
253+
# xy, 60., 80.).mask
254+
return mx
255+
256+
if newSlice in ['SubtropicSouthAtlantic', 'STSA']:
257+
mx = np.ma.masked_outside(xx, -80., -10.).mask + np.ma.masked_outside(
258+
xy, 10., 40.).mask
259+
# mx *= np.ma.masked_outside(xx, -45., 15.).mask + np.ma.masked_outside(
260+
# xy, 60., 80.).mask
261+
return mx
262+
263+
249264
if newSlice in ['SubpolarNorthAtlantic', 'SPNA',]:
250265
# Based on SPNA region here: https://www.nature.com/articles/s43247-021-00120-y#citeas
251266
mx = np.ma.masked_outside(xx, -35., -10.).mask + np.ma.masked_outside(
252267
xy, 40., 65.).mask
253268
return mx
269+
270+
# if newSlice in ['WesternSubpolarNorthAtlantic', 'WSPNA',]:
271+
272+
273+
if newSlice in ['GINseas',]: #Greenland, icveland and norwegean seas
274+
mx = np.ma.masked_outside(xx, -20., 15.).mask + np.ma.masked_outside(
275+
xy, 65., 75.).mask
276+
return mx
277+
#65-75:20W-15E
278+
254279

255280
if newSlice == 'AtlanticSOcean':
256281
mx = np.ma.masked_outside(xx, -40., 20.).mask + np.ma.masked_outside(
@@ -292,7 +317,7 @@ def makeMask(name, newSlice, xt, xz, xy, xx, xd, debug=False):
292317
if newSlice == 'Pitcairn': # MPA covers several islands. This is very approximate
293318
# Ducie Island: 24.66 S 124.75 W (Eastern most)
294319
# Oeno island: 23.9 S 130.74 W (western most) (Western boundary is not the full EEZ)
295-
mx = np.ma.masked_outside(xx, -130.74 - 1.5, 124.75 + 3.).mask # longitude # West
320+
mx = np.ma.masked_outside(xx, -130.74 - 1.5, -124.75 + 3.).mask # longitude # West
296321
mx += np.ma.masked_outside(xy, -24.66 -3, -23.9 + 3.).mask # Lattitue # South
297322
return mx
298323

0 commit comments

Comments
 (0)