roms-tools 0.0.2__tar.gz → 0.0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- roms-tools-0.0.6/.github/pull_request_template.md +5 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/.github/workflows/pypipublish.yaml +5 -5
- {roms-tools-0.0.2 → roms-tools-0.0.6}/PKG-INFO +6 -6
- {roms-tools-0.0.2 → roms-tools-0.0.6}/README.md +5 -5
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools/_version.py +1 -1
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools.egg-info/PKG-INFO +6 -6
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools.egg-info/SOURCES.txt +1 -1
- roms-tools-0.0.2/roms_tools/setup/old_grid_script.py +0 -438
- {roms-tools-0.0.2 → roms-tools-0.0.6}/.gitignore +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/.pre-commit-config.yaml +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/LICENSE +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/pyproject.toml +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools/__init__.py +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools/setup/__init__.py +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools/setup/grid.py +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools/tests/test_setup.py +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools.egg-info/dependency_links.txt +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools.egg-info/requires.txt +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/roms_tools.egg-info/top_level.txt +0 -0
- {roms-tools-0.0.2 → roms-tools-0.0.6}/setup.cfg +0 -0
|
@@ -17,7 +17,7 @@ concurrency:
|
|
|
17
17
|
jobs:
|
|
18
18
|
build-artifacts:
|
|
19
19
|
runs-on: ubuntu-latest
|
|
20
|
-
if: github.repository == 'CWorthy-ocean/
|
|
20
|
+
if: github.repository == 'CWorthy-ocean/roms-tools'
|
|
21
21
|
steps:
|
|
22
22
|
- uses: actions/checkout@v4
|
|
23
23
|
with:
|
|
@@ -64,7 +64,7 @@ jobs:
|
|
|
64
64
|
run: |
|
|
65
65
|
python -m pip install --upgrade pip
|
|
66
66
|
python -m pip install dist/roms_tools*.whl
|
|
67
|
-
python -c "import
|
|
67
|
+
python -c "import roms_tools; print(roms_tools.__version__)"
|
|
68
68
|
|
|
69
69
|
upload-to-pypi:
|
|
70
70
|
needs: test-built-dist
|
|
@@ -78,6 +78,6 @@ jobs:
|
|
|
78
78
|
- name: Publish package to PyPI
|
|
79
79
|
uses: pypa/gh-action-pypi-publish@v1.8.10
|
|
80
80
|
with:
|
|
81
|
-
|
|
82
|
-
password: ${{ secrets.
|
|
83
|
-
verbose: true
|
|
81
|
+
username: "__token__"
|
|
82
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
83
|
+
verbose: true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: roms-tools
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
4
4
|
Summary: Tools for running and analysing UCLA-ROMS simulations
|
|
5
5
|
Author-email: Thomas Nicholas <tom@cworthy.org>
|
|
6
6
|
License: Apache-2
|
|
@@ -32,16 +32,14 @@ Requires-Dist: packaging
|
|
|
32
32
|
|
|
33
33
|
A suite of python tools for setting up a [ROMS](https://github.com/CESR-lab/ucla-roms) simulation.
|
|
34
34
|
|
|
35
|
-
_Note these tools are for the
|
|
35
|
+
_Note these tools are for the [Center for Earth Systems Research Group](http://research.atmos.ucla.edu/cesr/) at UCLA's version of ROMS._
|
|
36
36
|
|
|
37
37
|
## Installation instructions
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Install via pip
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
|
|
43
|
-
cd roms-tools
|
|
44
|
-
pip install .
|
|
42
|
+
pip install roms-tools
|
|
45
43
|
```
|
|
46
44
|
|
|
47
45
|
Check the installation has worked by running the tests (you will need to also install pytest to run these)
|
|
@@ -82,6 +80,8 @@ To visualize the grid we have just created, use the `.plot` method:
|
|
|
82
80
|
grid.plot()
|
|
83
81
|
```
|
|
84
82
|
|
|
83
|
+

|
|
84
|
+
|
|
85
85
|
To see the values of the grid variables you can examine the `xarray.Dataset` object returned by the `.ds` property
|
|
86
86
|
|
|
87
87
|
```python
|
|
@@ -4,16 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
A suite of python tools for setting up a [ROMS](https://github.com/CESR-lab/ucla-roms) simulation.
|
|
6
6
|
|
|
7
|
-
_Note these tools are for the
|
|
7
|
+
_Note these tools are for the [Center for Earth Systems Research Group](http://research.atmos.ucla.edu/cesr/) at UCLA's version of ROMS._
|
|
8
8
|
|
|
9
9
|
## Installation instructions
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Install via pip
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
15
|
-
cd roms-tools
|
|
16
|
-
pip install .
|
|
14
|
+
pip install roms-tools
|
|
17
15
|
```
|
|
18
16
|
|
|
19
17
|
Check the installation has worked by running the tests (you will need to also install pytest to run these)
|
|
@@ -54,6 +52,8 @@ To visualize the grid we have just created, use the `.plot` method:
|
|
|
54
52
|
grid.plot()
|
|
55
53
|
```
|
|
56
54
|
|
|
55
|
+

|
|
56
|
+
|
|
57
57
|
To see the values of the grid variables you can examine the `xarray.Dataset` object returned by the `.ds` property
|
|
58
58
|
|
|
59
59
|
```python
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# Do not change! Do not track in version control!
|
|
2
|
-
__version__ = "0.0.
|
|
2
|
+
__version__ = "0.0.6"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: roms-tools
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
4
4
|
Summary: Tools for running and analysing UCLA-ROMS simulations
|
|
5
5
|
Author-email: Thomas Nicholas <tom@cworthy.org>
|
|
6
6
|
License: Apache-2
|
|
@@ -32,16 +32,14 @@ Requires-Dist: packaging
|
|
|
32
32
|
|
|
33
33
|
A suite of python tools for setting up a [ROMS](https://github.com/CESR-lab/ucla-roms) simulation.
|
|
34
34
|
|
|
35
|
-
_Note these tools are for the
|
|
35
|
+
_Note these tools are for the [Center for Earth Systems Research Group](http://research.atmos.ucla.edu/cesr/) at UCLA's version of ROMS._
|
|
36
36
|
|
|
37
37
|
## Installation instructions
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Install via pip
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
|
|
43
|
-
cd roms-tools
|
|
44
|
-
pip install .
|
|
42
|
+
pip install roms-tools
|
|
45
43
|
```
|
|
46
44
|
|
|
47
45
|
Check the installation has worked by running the tests (you will need to also install pytest to run these)
|
|
@@ -82,6 +80,8 @@ To visualize the grid we have just created, use the `.plot` method:
|
|
|
82
80
|
grid.plot()
|
|
83
81
|
```
|
|
84
82
|
|
|
83
|
+

|
|
84
|
+
|
|
85
85
|
To see the values of the grid variables you can examine the `xarray.Dataset` object returned by the `.ds` property
|
|
86
86
|
|
|
87
87
|
```python
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
LICENSE
|
|
4
4
|
README.md
|
|
5
5
|
pyproject.toml
|
|
6
|
+
.github/pull_request_template.md
|
|
6
7
|
.github/workflows/pypipublish.yaml
|
|
7
8
|
roms_tools/__init__.py
|
|
8
9
|
roms_tools/_version.py
|
|
@@ -13,5 +14,4 @@ roms_tools.egg-info/requires.txt
|
|
|
13
14
|
roms_tools.egg-info/top_level.txt
|
|
14
15
|
roms_tools/setup/__init__.py
|
|
15
16
|
roms_tools/setup/grid.py
|
|
16
|
-
roms_tools/setup/old_grid_script.py
|
|
17
17
|
roms_tools/tests/test_setup.py
|
|
@@ -1,438 +0,0 @@
|
|
|
1
|
-
import netCDF4
|
|
2
|
-
import numpy as np
|
|
3
|
-
|
|
4
|
-
import matplotlib.pyplot as plt
|
|
5
|
-
import copy
|
|
6
|
-
from scipy.interpolate import RegularGridInterpolator
|
|
7
|
-
|
|
8
|
-
import cartopy.crs as ccrs
|
|
9
|
-
import matplotlib.pyplot as plt
|
|
10
|
-
|
|
11
|
-
from datetime import date
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def generate_grid(grdname, nx, ny, size_x, size_y, tra_lon, tra_lat, rot):
|
|
16
|
-
|
|
17
|
-
r_earth = 6371315.0
|
|
18
|
-
|
|
19
|
-
## Mercator projection around the equator
|
|
20
|
-
|
|
21
|
-
if (size_y>size_x):
|
|
22
|
-
length = size_y * 1e3
|
|
23
|
-
nl = ny
|
|
24
|
-
width = size_x * 1e3
|
|
25
|
-
nw = nx
|
|
26
|
-
else:
|
|
27
|
-
length = size_x * 1e3
|
|
28
|
-
nl = nx
|
|
29
|
-
width = size_y * 1e3
|
|
30
|
-
nw = ny
|
|
31
|
-
|
|
32
|
-
dlon = length/r_earth
|
|
33
|
-
lon1d = dlon*np.arange(-0.5,nl+1.5,1)/nl - dlon/2
|
|
34
|
-
mul = 1.0
|
|
35
|
-
dlat = width/r_earth
|
|
36
|
-
for it in range(1,101):
|
|
37
|
-
y1 = np.log(np.tan(np.pi/4-dlat/4))
|
|
38
|
-
y2 = np.log(np.tan(np.pi/4+dlat/4))
|
|
39
|
-
y = (y2-y1)*np.arange(-0.5,nw+1.5,1)/nw + y1
|
|
40
|
-
lat1d = 2*np.arctan(np.exp(y)) - np.pi/2
|
|
41
|
-
lat1d = np.arctan(np.sinh(y))
|
|
42
|
-
dlat_cen = 0.5*(lat1d[int(np.round(nw/2)+1)]-lat1d[int(np.round(nw/2)-1)])
|
|
43
|
-
dlon_cen = dlon/nl
|
|
44
|
-
mul = dlat_cen/dlon_cen*length/width*nw/nl
|
|
45
|
-
dlat = dlat/mul
|
|
46
|
-
|
|
47
|
-
lon1de = dlon*np.arange(-1,nl+2,1)/nl - dlon/2
|
|
48
|
-
ye = (y2-y1)*np.arange(-1,nw+2)/nw + y1
|
|
49
|
-
lat1de = 2*np.arctan(np.exp(ye)) - np.pi/2
|
|
50
|
-
lat1de = np.arctan(np.sinh(ye))
|
|
51
|
-
lat1de= lat1de/mul
|
|
52
|
-
|
|
53
|
-
(lon1,lat1) = np.meshgrid(lon1d,lat1d)
|
|
54
|
-
(lone,late) = np.meshgrid(lon1de,lat1de)
|
|
55
|
-
lonu = 0.5*(lon1[:,:-1]+lon1[:,1:])
|
|
56
|
-
latu = 0.5*(lat1[:,:-1]+lat1[:,1:])
|
|
57
|
-
lonv = 0.5*(lon1[:-1,:]+lon1[1:,:])
|
|
58
|
-
latv = 0.5*(lat1[:-1,:]+lat1[1:,:])
|
|
59
|
-
|
|
60
|
-
if (size_y>size_x):
|
|
61
|
-
(lon1,lat1) = rot_sphere(lon1,lat1,90)
|
|
62
|
-
(lonu,latu) = rot_sphere(lonu,latu,90)
|
|
63
|
-
(lonv,latv) = rot_sphere(lonv,latv,90)
|
|
64
|
-
(lone,late) = rot_sphere(lone,late,90)
|
|
65
|
-
|
|
66
|
-
lon1 = np.transpose(np.flip(lon1,0))
|
|
67
|
-
lat1 = np.transpose(np.flip(lat1,0))
|
|
68
|
-
lone = np.transpose(np.flip(lone,0))
|
|
69
|
-
late = np.transpose(np.flip(late,1))
|
|
70
|
-
|
|
71
|
-
lonu_tmp= np.transpose(np.flip(lonv,0))
|
|
72
|
-
latu_tmp = np.transpose(np.flip(latv,0))
|
|
73
|
-
lonv = np.transpose(np.flip(lonu,0))
|
|
74
|
-
latv = np.transpose(np.flip(latu,0))
|
|
75
|
-
lonu = lonu_tmp
|
|
76
|
-
latu = latu_tmp
|
|
77
|
-
|
|
78
|
-
(lon2,lat2) = rot_sphere(lon1,lat1,rot)
|
|
79
|
-
(lonu,latu) = rot_sphere(lonu,latu,rot)
|
|
80
|
-
(lonv,latv) = rot_sphere(lonv,latv,rot)
|
|
81
|
-
(lone,late) = rot_sphere(lone,late,rot)
|
|
82
|
-
|
|
83
|
-
(lon3,lat3) = tra_sphere(lon2,lat2,tra_lat)
|
|
84
|
-
(lonu,latu) = tra_sphere(lonu,latu,tra_lat)
|
|
85
|
-
(lonv,latv) = tra_sphere(lonv,latv,tra_lat)
|
|
86
|
-
(lone,late) = tra_sphere(lone,late,tra_lat)
|
|
87
|
-
|
|
88
|
-
lon4 = lon3 + tra_lon*np.pi/180
|
|
89
|
-
lonu = lonu + tra_lon*np.pi/180
|
|
90
|
-
lonv = lonv + tra_lon*np.pi/180
|
|
91
|
-
lone = lone + tra_lon*np.pi/180
|
|
92
|
-
lon4[lon4<-np.pi] = lon4[lon4<-np.pi] + 2*np.pi
|
|
93
|
-
lonu[lonu<-np.pi] = lonu[lonu<-np.pi] + 2*np.pi
|
|
94
|
-
lonv[lonv<-np.pi] = lonv[lonv<-np.pi] + 2*np.pi
|
|
95
|
-
lone[lone<-np.pi] = lone[lone<-np.pi] + 2*np.pi
|
|
96
|
-
lat4 = lat3
|
|
97
|
-
|
|
98
|
-
# Compute pn and pm
|
|
99
|
-
# pm = 1/dx
|
|
100
|
-
pmu = gc_dist(lonu[:,:-1],latu[:,:-1],lonu[:,1:],latu[:,1:])
|
|
101
|
-
pm = 0*lon4
|
|
102
|
-
pm[:,1:-1] = pmu
|
|
103
|
-
pm[:,0] = pm[:,1]
|
|
104
|
-
pm[:,-1] = pm[:,-2]
|
|
105
|
-
pm = 1/pm
|
|
106
|
-
|
|
107
|
-
# pn = 1/dy
|
|
108
|
-
pnv = gc_dist(lonv[:-1,:],latv[:-1,:],lonv[1:,:],latv[1:,:])
|
|
109
|
-
pn = 0*lon4
|
|
110
|
-
pn[1:-1,:] = pnv
|
|
111
|
-
pn[0,:] = pn[1,:]
|
|
112
|
-
pn[-1,:] = pn[-2,:]
|
|
113
|
-
pn = 1/pn
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
## Compute angles of local grid positive x-axis relative to east
|
|
117
|
-
dellat = latu[:,1:]-latu[:,:-1]
|
|
118
|
-
dellon = lonu[:,1:]-lonu[:,:-1]
|
|
119
|
-
dellon[dellon > np.pi] = dellon[dellon > np.pi] - 2*np.pi
|
|
120
|
-
dellon[dellon < -np.pi] = dellon[dellon < -np.pi] + 2*np.pi
|
|
121
|
-
dellon = dellon * np.cos(0.5*(latu[:,1:]+latu[:,:-1]))
|
|
122
|
-
|
|
123
|
-
ang = copy.copy(lon4);
|
|
124
|
-
ang_s = np.arctan(dellat/(dellon+1e-16))
|
|
125
|
-
ang_s[(dellon<0) & (dellat<0)] = ang_s[(dellon<0) & (dellat<0)] - np.pi
|
|
126
|
-
ang_s[(dellon<0) & (dellat>=0)] = ang_s[(dellon<0) & (dellat>=0)] + np.pi
|
|
127
|
-
ang_s[ang_s > np.pi] = ang_s[ang_s > np.pi] - np.pi
|
|
128
|
-
ang_s[ang_s < -np.pi] = ang_s[ang_s < -np.pi] + np.pi
|
|
129
|
-
|
|
130
|
-
ang[:,1:-1] = ang_s
|
|
131
|
-
ang[:,0] = ang[:,1]
|
|
132
|
-
ang[:,-1] = ang[:,-2]
|
|
133
|
-
|
|
134
|
-
lon4[lon4<0] = lon4[lon4<0] + 2*np.pi
|
|
135
|
-
lone[lone<0] = lone[lone<0] + 2*np.pi
|
|
136
|
-
|
|
137
|
-
plot_grid(lon4,lat4)
|
|
138
|
-
save_grid(grdname,nx,ny,lon4,lat4,pm,pn,ang,size_x,size_y,rot,tra_lon,tra_lat,lone,late)
|
|
139
|
-
|
|
140
|
-
#return (lon4,lat4,pm,pn,ang,lone,late)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def save_grid(grdname,nx,ny,lon,lat,pm,pn,angle,xsize,ysize,rot,tra_lon,tra_lat,lone,late):
|
|
144
|
-
|
|
145
|
-
# This is part of Easy Grid
|
|
146
|
-
# (c) 2008, Jeroen Molemaker, UCLA
|
|
147
|
-
|
|
148
|
-
ROMS_title = 'ROMS grid by Easy Grid. Settings:' + \
|
|
149
|
-
' nx: ' + str(nx) + ' ny: ' + str(ny) + \
|
|
150
|
-
' xsize: ' + str(xsize/1e3) + ' ysize: ' + str(ysize/1e3) + \
|
|
151
|
-
' rotate: ' + str(rot) + ' Lon: ' + str(tra_lon) + ' Lat: ' + str(tra_lat)
|
|
152
|
-
|
|
153
|
-
nxp= nx+2
|
|
154
|
-
nyp= ny+2
|
|
155
|
-
|
|
156
|
-
# Create the grid file
|
|
157
|
-
create_grid(nxp,nyp,grdname,ROMS_title)
|
|
158
|
-
|
|
159
|
-
f0=4*np.pi*np.sin(lat)/(24*3600)
|
|
160
|
-
|
|
161
|
-
# Make bathymetry
|
|
162
|
-
hraw = make_topo(lon,lat)
|
|
163
|
-
|
|
164
|
-
# Compute the mask
|
|
165
|
-
mask = 0*hraw + 1
|
|
166
|
-
mask[hraw > 0] = 0
|
|
167
|
-
|
|
168
|
-
# Fill the grid file
|
|
169
|
-
f = netCDF4.Dataset(grdname, 'r+', format='NETCDF4')
|
|
170
|
-
f['pm'][:,:] = pm
|
|
171
|
-
f['pn'][:,:] = pn
|
|
172
|
-
f['angle'][:,:] = angle
|
|
173
|
-
f['hraw'][:,:] = hraw
|
|
174
|
-
f['f'][:,:] = f0
|
|
175
|
-
f['mask_rho'][:,:] = mask
|
|
176
|
-
f['lon_rho'][:,:] = lon*180/np.pi
|
|
177
|
-
f['lat_rho'][:,:] = lat*180/np.pi
|
|
178
|
-
f['spherical'][:] = 'T'
|
|
179
|
-
f['tra_lon'][:] = tra_lon
|
|
180
|
-
f['tra_lat'][:] = tra_lat
|
|
181
|
-
f['rotate'][:] = rot
|
|
182
|
-
|
|
183
|
-
f.close()
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
def rot_sphere(lon1, lat1, rot):
|
|
187
|
-
|
|
188
|
-
(n,m) = np.shape(lon1)
|
|
189
|
-
rot = rot*np.pi/180
|
|
190
|
-
|
|
191
|
-
# translate into x,y,z
|
|
192
|
-
# conventions: (lon,lat) = (0,0) corresponds to (x,y,z) = ( 0,-r, 0)
|
|
193
|
-
# (lon,lat) = (0,90) corresponds to (x,y,z) = ( 0, 0, r)
|
|
194
|
-
x1 = np.sin(lon1) * np.cos(lat1)
|
|
195
|
-
y1 = np.cos(lon1) * np.cos(lat1)
|
|
196
|
-
z1 = np.sin(lat1)
|
|
197
|
-
|
|
198
|
-
# We will rotate these points around the small circle defined by
|
|
199
|
-
# the intersection of the sphere and the plane that
|
|
200
|
-
# is orthogonal to the line through (lon,lat) (0,0) and (180,0)
|
|
201
|
-
|
|
202
|
-
# The rotation is in that plane around its intersection with
|
|
203
|
-
# aforementioned line.
|
|
204
|
-
|
|
205
|
-
# Since the plane is orthogonal to the y-axis (in my definition at least),
|
|
206
|
-
# Rotations in the plane of the small circle maintain constant y and are around
|
|
207
|
-
# (x,y,z) = (0,y1,0)
|
|
208
|
-
|
|
209
|
-
rp1 = np.sqrt(x1**2 + z1**2)
|
|
210
|
-
|
|
211
|
-
ap1 = np.pi/2*np.ones((n,m))
|
|
212
|
-
ap1[np.abs(x1)>1e-7] = np.arctan(np.abs(z1[np.abs(x1)>1e-7] / x1[np.abs(x1)>1e-7]))
|
|
213
|
-
ap1[x1<0] = np.pi - ap1[x1<0]
|
|
214
|
-
ap1[z1<0] = -ap1[z1<0]
|
|
215
|
-
|
|
216
|
-
ap2 = ap1 + rot
|
|
217
|
-
x2 = rp1 * np.cos(ap2)
|
|
218
|
-
y2 = y1
|
|
219
|
-
z2 = rp1 * np.sin(ap2)
|
|
220
|
-
|
|
221
|
-
lon2 = np.pi/2*np.ones((n,m))
|
|
222
|
-
lon2[abs(y2)>1e-7] = np.arctan(np.abs(x2[np.abs(y2)>1e-7] / y2[np.abs(y2)>1e-7]))
|
|
223
|
-
lon2[y2<0] = np.pi - lon2[y2<0]
|
|
224
|
-
lon2[x2<0] = -lon2[x2<0]
|
|
225
|
-
|
|
226
|
-
pr2 = np.sqrt(x2**2 + y2**2)
|
|
227
|
-
lat2 = np.pi/2 * np.ones((n,m))
|
|
228
|
-
lat2[np.abs(pr2)>1e-7] = np.arctan(np.abs(z2[np.abs(pr2)>1e-7] / pr2[np.abs(pr2)>1e-7]))
|
|
229
|
-
lat2[z2<0] = -lat2[z2<0]
|
|
230
|
-
|
|
231
|
-
return (lon2,lat2)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
def tra_sphere(lon1,lat1,tra):
|
|
235
|
-
|
|
236
|
-
# Rotate sphere around its y-axis
|
|
237
|
-
# Part of easy grid
|
|
238
|
-
# (c) 2008, Jeroen Molemaker, UCLA
|
|
239
|
-
|
|
240
|
-
(n,m) = np.shape(lon1)
|
|
241
|
-
tra = tra*np.pi/180 # translation in latitude direction
|
|
242
|
-
|
|
243
|
-
# translate into x,y,z
|
|
244
|
-
# conventions: (lon,lat) = (0,0) corresponds to (x,y,z) = ( 0,-r, 0)
|
|
245
|
-
# (lon,lat) = (0,90) corresponds to (x,y,z) = ( 0, 0, r)
|
|
246
|
-
x1 = np.sin(lon1) * np.cos(lat1)
|
|
247
|
-
y1 = np.cos(lon1) * np.cos(lat1)
|
|
248
|
-
z1 = np.sin(lat1)
|
|
249
|
-
|
|
250
|
-
# We will rotate these points around the small circle defined by
|
|
251
|
-
# the intersection of the sphere and the plane that
|
|
252
|
-
# is orthogonal to the line through (lon,lat) (90,0) and (-90,0)
|
|
253
|
-
|
|
254
|
-
# The rotation is in that plane around its intersection with
|
|
255
|
-
# aforementioned line.
|
|
256
|
-
|
|
257
|
-
# Since the plane is orthogonal to the x-axis (in my definition at least),
|
|
258
|
-
# Rotations in the plane of the small circle maintain constant x and are around
|
|
259
|
-
# (x,y,z) = (x1,0,0)
|
|
260
|
-
|
|
261
|
-
rp1 = np.sqrt(y1**2 + z1**2)
|
|
262
|
-
|
|
263
|
-
ap1 = np.pi/2 * np.ones((n,m))
|
|
264
|
-
ap1[np.abs(y1)>1e-7] = np.arctan(np.abs(z1[np.abs(y1)>1e-7] / y1[np.abs(y1)>1e-7]))
|
|
265
|
-
ap1[y1<0] = np.pi - ap1[y1<0]
|
|
266
|
-
ap1[z1<0] = -ap1[z1<0]
|
|
267
|
-
|
|
268
|
-
ap2 = ap1 + tra
|
|
269
|
-
x2 = x1
|
|
270
|
-
y2 = rp1 * np.cos(ap2)
|
|
271
|
-
z2 = rp1 * np.sin(ap2)
|
|
272
|
-
|
|
273
|
-
## transformation from (x,y,z) to (lat,lon)
|
|
274
|
-
lon2 = np.pi/2* np.ones((n,m))
|
|
275
|
-
lon2[np.abs(y2)>1e-7] = np.arctan(np.abs(x2[np.abs(y2)>1e-7] / y2[np.abs(y2)>1e-7]))
|
|
276
|
-
lon2[y2<0] = np.pi - lon2[y2<0]
|
|
277
|
-
lon2[x2<0] = -lon2[x2<0]
|
|
278
|
-
|
|
279
|
-
pr2 = np.sqrt(x2**2 + y2**2)
|
|
280
|
-
lat2 = np.pi / (2*np.ones((n,m)))
|
|
281
|
-
lat2[np.abs(pr2)>1e-7] = np.arctan(np.abs(z2[np.abs(pr2)>1e-7] / pr2[np.abs(pr2)>1e-7]))
|
|
282
|
-
lat2[z2<0] = -lat2[z2<0]
|
|
283
|
-
|
|
284
|
-
return (lon2,lat2)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
def gc_dist(lon1,lat1,lon2,lat2):
|
|
288
|
-
|
|
289
|
-
# Distance between 2 points along a great circle
|
|
290
|
-
# lat and lon in radians!!
|
|
291
|
-
# 2008, Jeroen Molaker, UCLA
|
|
292
|
-
|
|
293
|
-
dlat = lat2-lat1
|
|
294
|
-
dlon = lon2-lon1
|
|
295
|
-
|
|
296
|
-
dang = 2*np.arcsin( np.sqrt( np.sin(dlat/2)**2 + np.cos(lat2) * np.cos(lat1) * np.sin(dlon/2)**2 ) ) # haversine function
|
|
297
|
-
|
|
298
|
-
r_earth = 6371315.0
|
|
299
|
-
|
|
300
|
-
dis = r_earth*dang
|
|
301
|
-
|
|
302
|
-
return dis
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
def create_grid(nx, ny, grdname, title):
|
|
306
|
-
|
|
307
|
-
f = netCDF4.Dataset(grdname, 'w', format='NETCDF4')
|
|
308
|
-
|
|
309
|
-
one = f.createDimension('one', 1)
|
|
310
|
-
xi_rho = f.createDimension('xi_rho', nx)
|
|
311
|
-
eta_rho = f.createDimension('eta_rho', ny)
|
|
312
|
-
|
|
313
|
-
spherical = f.createVariable('spherical','c', ('one'));
|
|
314
|
-
setattr(spherical, 'long_name', "Grid type logical switch")
|
|
315
|
-
setattr(spherical, 'option_T', "spherical")
|
|
316
|
-
|
|
317
|
-
angle = f.createVariable('angle','f8', ('eta_rho', 'xi_rho'));
|
|
318
|
-
setattr(angle, 'long_name', "Angle between xi axis and east")
|
|
319
|
-
setattr(angle, 'units', "radians")
|
|
320
|
-
|
|
321
|
-
h = f.createVariable('h','f8', ('eta_rho', 'xi_rho'));
|
|
322
|
-
setattr(h, 'long_name', "Final bathymetry at rho-points")
|
|
323
|
-
setattr(h, 'units', "meter")
|
|
324
|
-
|
|
325
|
-
hraw = f.createVariable('hraw','f8', ('eta_rho', 'xi_rho'));
|
|
326
|
-
setattr(hraw, 'long_name', "Working bathymetry at rho-points")
|
|
327
|
-
setattr(hraw, 'units', "meter")
|
|
328
|
-
|
|
329
|
-
f0 = f.createVariable('f','f8', ('eta_rho', 'xi_rho'));
|
|
330
|
-
setattr(f0, 'long_name', "Coriolis parameter at rho-points")
|
|
331
|
-
setattr(f0, 'units', "second-1")
|
|
332
|
-
|
|
333
|
-
pm = f.createVariable('pm','f8', ('eta_rho', 'xi_rho'));
|
|
334
|
-
setattr(pm, 'long_name', "Curvilinear coordinate metric in xi-direction")
|
|
335
|
-
setattr(pm, 'units', "meter-1")
|
|
336
|
-
|
|
337
|
-
pn = f.createVariable('pn','f8', ('eta_rho', 'xi_rho'));
|
|
338
|
-
setattr(pn, 'long_name', "Curvilinear coordinate metric in eta-direction")
|
|
339
|
-
setattr(pn, 'units', "meter-1")
|
|
340
|
-
|
|
341
|
-
lon_rho = f.createVariable('lon_rho','f8', ('eta_rho', 'xi_rho'));
|
|
342
|
-
setattr(lon_rho, 'long_name', "longitude of rho-points")
|
|
343
|
-
setattr(lon_rho, 'units', "degrees East")
|
|
344
|
-
|
|
345
|
-
lat_rho = f.createVariable('lat_rho','f8', ('eta_rho', 'xi_rho'));
|
|
346
|
-
setattr(lat_rho, 'long_name', "latitude of rho-points")
|
|
347
|
-
setattr(lat_rho, 'units', "degrees North")
|
|
348
|
-
|
|
349
|
-
mask_rho = f.createVariable('mask_rho','f8', ('eta_rho', 'xi_rho'));
|
|
350
|
-
setattr(mask_rho, 'long_name', "Mask at rho-points")
|
|
351
|
-
setattr(mask_rho, 'units', "land/water (0/1)")
|
|
352
|
-
|
|
353
|
-
tra_lon = f.createVariable('tra_lon','f8', ('one'));
|
|
354
|
-
setattr(tra_lon, 'long_name', "Easy grid: Longitudinal translation of base grid")
|
|
355
|
-
setattr(tra_lon, 'units', "degrees East")
|
|
356
|
-
|
|
357
|
-
tra_lat = f.createVariable('tra_lat','f8', ('one'));
|
|
358
|
-
setattr(tra_lat, 'long_name', "Easy grid: Latitudinal translation of base grid")
|
|
359
|
-
setattr(tra_lat, 'units', "degrees North")
|
|
360
|
-
|
|
361
|
-
rotate = f.createVariable('rotate','f8', ('one'));
|
|
362
|
-
setattr(rotate, 'long_name', "Easy grid: Rotation of base grid")
|
|
363
|
-
setattr(rotate, 'units', "degrees")
|
|
364
|
-
|
|
365
|
-
xy_flip = f.createVariable('xy_flip','f8', ('one'));
|
|
366
|
-
setattr(xy_flip, 'long_name', "Easy grid: XY flip of base grid")
|
|
367
|
-
setattr(xy_flip, 'units', "True/False (0/1)")
|
|
368
|
-
|
|
369
|
-
f.Title = title
|
|
370
|
-
today = date.today()
|
|
371
|
-
f.Date = today.strftime("%m/%d/%y")
|
|
372
|
-
f.Type = "ROMS grid produced by Easy Grid"
|
|
373
|
-
|
|
374
|
-
f.close()
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
def make_topo(lon, lat):
|
|
378
|
-
|
|
379
|
-
toponame = 'etopo5.nc'
|
|
380
|
-
g = netCDF4.Dataset(toponame, 'r')
|
|
381
|
-
|
|
382
|
-
topo_lon = g['topo_lon'][:]
|
|
383
|
-
topo_lat = g['topo_lat'][:]
|
|
384
|
-
d = np.transpose(g['topo'][:,:].astype('float64'))
|
|
385
|
-
topo_lon[topo_lon<0] = topo_lon[topo_lon<0] + 360
|
|
386
|
-
topo_lonm = topo_lon-360
|
|
387
|
-
|
|
388
|
-
topo_loncat = np.concatenate((topo_lonm, topo_lon), axis=0)
|
|
389
|
-
d_loncat = np.concatenate((d, d), axis=0)
|
|
390
|
-
|
|
391
|
-
interp = RegularGridInterpolator((topo_loncat, topo_lat), d_loncat)
|
|
392
|
-
|
|
393
|
-
di = interp((lon*180/np.pi,lat*180/np.pi))
|
|
394
|
-
|
|
395
|
-
return di
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
def plot_grid(lon, lat):
|
|
399
|
-
|
|
400
|
-
# Define projections
|
|
401
|
-
geodetic = ccrs.Geodetic()
|
|
402
|
-
trans = ccrs.NearsidePerspective(central_longitude=np.mean(lon*180/np.pi), central_latitude=np.mean(lat*180/np.pi))
|
|
403
|
-
|
|
404
|
-
lon_deg = lon*180/np.pi - 360
|
|
405
|
-
lat_deg = lat*180/np.pi
|
|
406
|
-
|
|
407
|
-
(lo1,la1) = (lon_deg[0,0], lat_deg[0,0])
|
|
408
|
-
(lo2,la2) = (lon_deg[0,-1], lat_deg[0,-1])
|
|
409
|
-
(lo3,la3) = (lon_deg[-1,-1], lat_deg[-1,-1])
|
|
410
|
-
(lo4,la4) = (lon_deg[-1,0], lat_deg[-1,0])
|
|
411
|
-
|
|
412
|
-
(min_lo, max_lo) = (np.min(lon_deg), np.max(lon_deg))
|
|
413
|
-
(min_la, max_la) = (np.min(lat_deg), np.max(lat_deg))
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
lo1t, la1t = trans.transform_point(lo1, la1, geodetic)
|
|
417
|
-
lo2t, la2t = trans.transform_point(lo2, la2, geodetic)
|
|
418
|
-
lo3t, la3t = trans.transform_point(lo3, la3, geodetic)
|
|
419
|
-
lo4t, la4t = trans.transform_point(lo4, la4, geodetic)
|
|
420
|
-
|
|
421
|
-
min_lot, min_lat = trans.transform_point(min_lo, min_la, geodetic)
|
|
422
|
-
max_lot, max_lat = trans.transform_point(max_lo, max_la, geodetic)
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
fig = plt.figure(figsize=(10, 10))
|
|
427
|
-
ax = plt.axes(projection=trans)
|
|
428
|
-
|
|
429
|
-
ax.plot(
|
|
430
|
-
[lo1t, lo2t, lo3t, lo4t, lo1t],
|
|
431
|
-
[la1t, la2t, la3t, la4t, la1t],
|
|
432
|
-
"ro-"
|
|
433
|
-
)
|
|
434
|
-
|
|
435
|
-
ax.coastlines(resolution='50m', linewidth=.5, color='black') # add map
|
|
436
|
-
ax.gridlines()
|
|
437
|
-
|
|
438
|
-
plt.show()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|