Skip to content

Commit 4fbb942

Browse files
committed
Refactor lon lat to x y
Update particle definition and all related code - particle.py particle variables - ParticleSet args - all internal mentions of .lon and .lat - test suite code
1 parent 5c1b8cb commit 4fbb942

34 files changed

Lines changed: 471 additions & 465 deletions

docs/user_guide/examples_v3/example_brownian.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ def test_brownian_example(mesh, npart=3000):
3636
pset = parcels.ParticleSet(
3737
fieldset=fieldset,
3838
pclass=parcels.Particle,
39-
lon=np.zeros(npart),
40-
lat=np.zeros(npart),
39+
x=np.zeros(npart),
40+
y=np.zeros(npart),
4141
)
4242
pset.execute(
4343
pset.Kernel(parcels.kernels.DiffusionUniformKh),

docs/user_guide/examples_v3/example_decaying_moving_eddy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def true_values(
6969

7070
def decaying_moving_example(fieldset, outfile, method=parcels.kernels.AdvectionRK4):
7171
pset = parcels.ParticleSet(
72-
fieldset, pclass=parcels.Particle, lon=start_lon, lat=start_lat
72+
fieldset, pclass=parcels.Particle, x=start_lon, y=start_lat
7373
)
7474

7575
dt = timedelta(minutes=5)

docs/user_guide/examples_v3/example_globcurrent.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def test_globcurrent_particles():
7070
latstart = [-35]
7171

7272
pset = parcels.ParticleSet(
73-
fieldset, pclass=parcels.Particle, lon=lonstart, lat=latstart
73+
fieldset, pclass=parcels.Particle, x=lonstart, y=latstart
7474
)
7575

7676
pset.execute(
@@ -91,29 +91,29 @@ def test__particles_init_time():
9191
pset = parcels.ParticleSet(
9292
fieldset,
9393
pclass=parcels.Particle,
94-
lon=lonstart,
95-
lat=latstart,
94+
x=lonstart,
95+
y=latstart,
9696
time=np.datetime64("2002-01-15"),
9797
)
9898
pset2 = parcels.ParticleSet(
9999
fieldset,
100100
pclass=parcels.Particle,
101-
lon=lonstart,
102-
lat=latstart,
101+
x=lonstart,
102+
y=latstart,
103103
time=14 * 86400,
104104
)
105105
pset3 = parcels.ParticleSet(
106106
fieldset,
107107
pclass=parcels.Particle,
108-
lon=lonstart,
109-
lat=latstart,
108+
x=lonstart,
109+
y=latstart,
110110
time=np.array([np.datetime64("2002-01-15")]),
111111
)
112112
pset4 = parcels.ParticleSet(
113113
fieldset,
114114
pclass=parcels.Particle,
115-
lon=lonstart,
116-
lat=latstart,
115+
x=lonstart,
116+
y=latstart,
117117
time=[np.datetime64("2002-01-15")],
118118
)
119119
assert pset[0].time - pset2[0].time == 0
@@ -126,8 +126,8 @@ def test_globcurrent_outside_time_interval_error():
126126
pset = parcels.ParticleSet(
127127
fieldset,
128128
pclass=parcels.Particle,
129-
lon=[25],
130-
lat=[-35],
129+
x=[25],
130+
y=[-35],
131131
time=fieldset.U.grid.time[0] - timedelta(days=1).total_seconds(),
132132
)
133133
with pytest.raises(parcels.OutsideTimeInterval):
@@ -173,10 +173,10 @@ def SampleP(particle, fieldset, time): # pragma: no cover
173173
if with_starttime:
174174
time = fieldset.U.grid.time[0] if dt > 0 else fieldset.U.grid.time[-1]
175175
pset = parcels.ParticleSet(
176-
fieldset, pclass=MyParticle, lon=[25], lat=[-35], time=time
176+
fieldset, pclass=MyParticle, x=[25], y=[-35], time=time
177177
)
178178
else:
179-
pset = parcels.ParticleSet(fieldset, pclass=MyParticle, lon=[25], lat=[-35])
179+
pset = parcels.ParticleSet(fieldset, pclass=MyParticle, x=[25], y=[-35])
180180

181181
if with_starttime:
182182
with pytest.raises(parcels.OutsideTimeInterval):
@@ -202,7 +202,7 @@ def DeleteP0(particle, fieldset, time): # pragma: no cover
202202
particle.delete()
203203

204204
pset0 = parcels.ParticleSet(
205-
fieldset, pclass=parcels.Particle, lon=[25, 25], lat=[-35, -35], time=time0
205+
fieldset, pclass=parcels.Particle, x=[25, 25], y=[-35, -35], time=time0
206206
)
207207

208208
pset0.execute(
@@ -212,7 +212,7 @@ def DeleteP0(particle, fieldset, time): # pragma: no cover
212212
)
213213

214214
pset1 = parcels.ParticleSet(
215-
fieldset, pclass=parcels.Particle, lon=[25, 25], lat=[-35, -35], time=time0
215+
fieldset, pclass=parcels.Particle, x=[25, 25], y=[-35, -35], time=time0
216216
)
217217

218218
pset1.execute(
@@ -231,7 +231,7 @@ def test_globcurrent_pset_fromfile(dt, pid_offset, tmpdir):
231231
fieldset = set_globcurrent_fieldset()
232232

233233
parcels.Particle.setLastID(pid_offset)
234-
pset = parcels.ParticleSet(fieldset, pclass=parcels.Particle, lon=25, lat=-35)
234+
pset = parcels.ParticleSet(fieldset, pclass=parcels.Particle, x=25, y=-35)
235235
pfile = pset.ParticleFile(filename, outputdt=timedelta(hours=6))
236236
pset.execute(
237237
parcels.kernels.AdvectionRK4,
@@ -265,7 +265,7 @@ def test_error_outputdt_not_multiple_dt(tmpdir):
265265

266266
dt = 81.2584344538292 # number for which output writing fails
267267

268-
pset = parcels.ParticleSet(fieldset, pclass=parcels.Particle, lon=[0], lat=[0])
268+
pset = parcels.ParticleSet(fieldset, pclass=parcels.Particle, x=[0], y=[0])
269269
ofile = pset.ParticleFile(name=filepath, outputdt=timedelta(days=1))
270270

271271
def DoNothing(particle, fieldset, time): # pragma: no cover

docs/user_guide/examples_v3/example_moving_eddies.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def test_moving_eddies_fwdbwd(mesh, tmpdir, npart=2):
166166
lons = [3.3, 3.3] if fieldset.U.grid.mesh == "spherical" else [3.3e5, 3.3e5]
167167
lats = [46.0, 47.8] if fieldset.U.grid.mesh == "spherical" else [1e5, 2.8e5]
168168
pset = parcels.ParticleSet(
169-
fieldset=fieldset, pclass=parcels.Particle, lon=lons, lat=lats
169+
fieldset=fieldset, pclass=parcels.Particle, x=lons, y=lats
170170
)
171171

172172
# Execte for 14 days, with 30sec timesteps and hourly output

docs/user_guide/examples_v3/example_ofam.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ def test_ofam_xarray_vs_netcdf(dt):
4949
lonstart, latstart, runtime = (180, 10, timedelta(days=7))
5050

5151
psetN = parcels.ParticleSet(
52-
fieldsetNetcdf, pclass=parcels.Particle, lon=lonstart, lat=latstart
52+
fieldsetNetcdf, pclass=parcels.Particle, x=lonstart, y=latstart
5353
)
5454
psetN.execute(parcels.kernels.AdvectionRK4, runtime=runtime, dt=dt)
5555

5656
psetX = parcels.ParticleSet(
57-
fieldsetxarray, pclass=parcels.Particle, lon=lonstart, lat=latstart
57+
fieldsetxarray, pclass=parcels.Particle, x=lonstart, y=latstart
5858
)
5959
psetX.execute(parcels.kernels.AdvectionRK4, runtime=runtime, dt=dt)
6060

@@ -74,8 +74,8 @@ def test_ofam_particles(use_xarray):
7474
pset = parcels.ParticleSet(
7575
fieldset,
7676
pclass=parcels.Particle,
77-
lon=lonstart,
78-
lat=latstart,
77+
x=lonstart,
78+
y=latstart,
7979
depth=depstart,
8080
)
8181

src/parcels/_core/field.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def __getitem__(self, key):
184184
self._check_velocitysampling()
185185
try:
186186
if isinstance(key, ParticleSetView):
187-
return self.eval(key.time, key.z, key.lat, key.lon, key)
187+
return self.eval(key.time, key.z, key.y, key.x, key)
188188
else:
189189
return self.eval(*key)
190190
except tuple(AllParcelsErrorCodes.keys()) as error:
@@ -293,7 +293,7 @@ def eval(self, time: datetime, z, y, x, particles=None):
293293
def __getitem__(self, key):
294294
try:
295295
if isinstance(key, ParticleSetView):
296-
return self.eval(key.time, key.z, key.lat, key.lon, key)
296+
return self.eval(key.time, key.z, key.y, key.x, key)
297297
else:
298298
return self.eval(*key)
299299
except tuple(AllParcelsErrorCodes.keys()) as error:

src/parcels/_core/kernel.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ def remove_deleted(self, pset):
106106
pset.remove_indices(indices)
107107

108108
def _position_update(self, particles, fieldset):
109-
particles.lon += particles.dlon
110-
particles.lat += particles.dlat
109+
particles.x += particles.dx
110+
particles.y += particles.dy
111111
particles.z += particles.dz
112112
particles.time += particles.dt
113113

114-
particles.dlon = 0
115-
particles.dlat = 0
114+
particles.dx = 0
115+
particles.dy = 0
116116
particles.dz = 0
117117

118118
if hasattr(self.fieldset, "RK45_tol"):
@@ -244,6 +244,6 @@ def execute(self, pset, endtime, dt):
244244
if error_code == StatusCode.ErrorOutsideTimeInterval:
245245
error_func(pset[inds].time)
246246
else:
247-
error_func(pset[inds].z, pset[inds].lat, pset[inds].lon)
247+
error_func(pset[inds].z, pset[inds].y, pset[inds].x)
248248

249249
return pset

src/parcels/_core/particle.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,18 +141,26 @@ def get_default_particle(spatial_dtype: type[np.float32] | type[np.float64]) ->
141141
attrs={"standard_name": "vertical coordinate", "units": "m", "positive": "down"},
142142
),
143143
Variable(
144-
"lat",
144+
"y",
145145
dtype=spatial_dtype,
146-
attrs={"standard_name": "latitude", "units": "degrees_north", "axis": "Y"},
146+
attrs={
147+
"standard_name": "latitude",
148+
"units": "degrees_north",
149+
"axis": "Y",
150+
}, # TODO v4: Update to ensure that units come from the model
147151
),
148152
Variable(
149-
"lon",
153+
"x",
150154
dtype=spatial_dtype,
151-
attrs={"standard_name": "longitude", "units": "degrees_east", "axis": "X"},
155+
attrs={
156+
"standard_name": "longitude",
157+
"units": "degrees_east",
158+
"axis": "X",
159+
}, # TODO v4: Update to ensure that units come from the model
152160
),
153161
Variable("dz", dtype=spatial_dtype, to_write=False),
154-
Variable("dlat", dtype=spatial_dtype, to_write=False),
155-
Variable("dlon", dtype=spatial_dtype, to_write=False),
162+
Variable("dy", dtype=spatial_dtype, to_write=False),
163+
Variable("dx", dtype=spatial_dtype, to_write=False),
156164
Variable(
157165
"particle_id",
158166
dtype=np.int64,

src/parcels/_core/particleset.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ def __init__(
6060
pclass=Particle,
6161
time=None,
6262
z=None,
63-
lat=None,
64-
lon=None,
63+
y=None,
64+
x=None,
6565
particle_ids=None,
6666
**kwargs,
6767
):
@@ -70,21 +70,21 @@ def __init__(
7070

7171
self.fieldset = fieldset
7272
time = np.empty(shape=0) if time is None else np.array(time).flatten()
73-
lat = np.empty(shape=0) if lat is None else np.array(lat).flatten()
74-
lon = np.empty(shape=0) if lon is None else np.array(lon).flatten()
73+
y = np.empty(shape=0) if y is None else np.array(y).flatten()
74+
x = np.empty(shape=0) if x is None else np.array(x).flatten()
7575

7676
if particle_ids is None:
77-
particle_ids = np.arange(lon.size)
77+
particle_ids = np.arange(x.size)
7878

7979
if z is None:
8080
minz = 0
8181
for field in self.fieldset.fields.values():
8282
if field.grid.depth is not None:
8383
minz = min(minz, field.grid.depth[0])
84-
z = np.ones(lon.size) * minz
84+
z = np.ones(x.size) * minz
8585
else:
8686
z = np.array(z).flatten()
87-
assert lon.size == lat.size and lon.size == z.size, "lon, lat, z don't all have the same lenghts"
87+
assert x.size == y.size and x.size == z.size, "lon, lat, z don't all have the same lenghts"
8888

8989
if time is None or len(time) == 0:
9090
# do not set a time yet (because sign_dt not known)
@@ -95,26 +95,26 @@ def __init__(
9595
time = timedelta_to_float(time)
9696
else:
9797
raise TypeError("particle time must be a datetime, timedelta, or date object")
98-
time = np.repeat(time, lon.size) if time.size == 1 else time
98+
time = np.repeat(time, x.size) if time.size == 1 else time
9999

100-
assert lon.size == time.size, "time and positions (lon, lat, z) do not have the same lengths."
100+
assert x.size == time.size, "time and positions (lon, lat, z) do not have the same lengths."
101101

102102
if fieldset.time_interval:
103103
_warn_particle_times_outside_fieldset_time_bounds(time, fieldset.time_interval)
104104

105105
for kwvar in kwargs:
106106
kwargs[kwvar] = np.array(kwargs[kwvar]).flatten()
107-
assert lon.size == kwargs[kwvar].size, f"{kwvar} and positions (lon, lat, z) don't have the same lengths."
107+
assert x.size == kwargs[kwvar].size, f"{kwvar} and positions (lon, lat, z) don't have the same lengths."
108108

109109
self._data = create_particle_data(
110110
pclass=pclass,
111-
nparticles=lon.size,
111+
nparticles=x.size,
112112
ngrids=len(fieldset.gridset),
113113
initial=dict(
114114
time=time,
115115
z=z,
116-
lat=lat,
117-
lon=lon,
116+
y=y,
117+
x=x,
118118
particle_id=particle_ids,
119119
),
120120
)
@@ -245,7 +245,7 @@ def remove_indices(self, indices):
245245
def populate_indices(self):
246246
"""Pre-populate guesses of particle ei (element id) indices"""
247247
for i, grid in enumerate(self.fieldset.gridset):
248-
grid_positions = grid.search(self.z, self.lat, self.lon)
248+
grid_positions = grid.search(self.z, self.y, self.x)
249249
self._data["ei"][:, i] = grid.ravel_index(
250250
{
251251
"X": grid_positions["X"]["index"],

0 commit comments

Comments
 (0)