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.
@@ -0,0 +1,5 @@
1
+ <!-- Feel free to remove check-list items aren't relevant to your change -->
2
+
3
+ - [ ] Closes #xxxx
4
+ - [ ] Tests added
5
+ - [ ] Passes `pre-commit run --all-files`
@@ -17,7 +17,7 @@ concurrency:
17
17
  jobs:
18
18
  build-artifacts:
19
19
  runs-on: ubuntu-latest
20
- if: github.repository == 'CWorthy-ocean/roms_tools'
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 datatree; print(roms_tools.__version__)"
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
- user: ${{ secrets.PYPI_USERNAME }}
82
- password: ${{ secrets.PYPI_PASSWORD }}
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.2
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 "UCLA" version of ROMS._
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
- For now this package must be installed by clone the source code and installing locally.
39
+ Install via pip
40
40
 
41
41
  ```bash
42
- git clone <repo-URL>
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
+ ![iceland_grid](https://github.com/CWorthy-ocean/roms-tools/assets/35968931/de8c03ab-3c61-4ba5-a9b7-65592fd9280f)
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 "UCLA" version of ROMS._
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
- For now this package must be installed by clone the source code and installing locally.
11
+ Install via pip
12
12
 
13
13
  ```bash
14
- git clone <repo-URL>
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
+ ![iceland_grid](https://github.com/CWorthy-ocean/roms-tools/assets/35968931/de8c03ab-3c61-4ba5-a9b7-65592fd9280f)
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"
2
+ __version__ = "0.0.6"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: roms-tools
3
- Version: 0.0.2
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 "UCLA" version of ROMS._
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
- For now this package must be installed by clone the source code and installing locally.
39
+ Install via pip
40
40
 
41
41
  ```bash
42
- git clone <repo-URL>
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
+ ![iceland_grid](https://github.com/CWorthy-ocean/roms-tools/assets/35968931/de8c03ab-3c61-4ba5-a9b7-65592fd9280f)
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