Skip to content

Commit 09f2d9e

Browse files
committed
First implementation
1 parent c8f5dc6 commit 09f2d9e

File tree

3 files changed

+63
-37
lines changed

3 files changed

+63
-37
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ v2.2.x
1313
latest
1414
------
1515

16-
- Modelling routines: The definition of the coordinates for ``dipole``,
17-
``dipole_k``, and ``analytical`` is now more flexible (``x`` and ``y``
18-
coordinate can now have different dimension, as long as one is a scalar).
16+
- Modelling routines: The definition of the coordinates (and, where it applies,
17+
azimuths and dips/elevations) is now more flexible (see corresponding
18+
function docstrings).
1919

2020
- Bug fixes, small improvements and maintenance
2121

empymod/model.py

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,8 @@ def bipole(src, rec, depth, res, freqtime, signal=None, aniso=None,
9696
- [x0, x1, y0, y1, z0, z1] (bipole of finite length)
9797
- [x, y, z, azimuth, dip] (dipole, infinitesimal small)
9898
99-
Dimensions:
100-
101-
- The coordinates x, y, and z (dipole) or x0, x1, y0, y1, z0, and z1
102-
(bipole) can be single values or arrays.
103-
- The variables x and y (dipole) or x0, x1, y0, and y1 (bipole) must
104-
have the same dimensions.
105-
- The variables z, azimuth, and dip (dipole) or z0 and z1 (bipole) must
106-
either be single values or having the same dimension as the other
107-
coordinates.
99+
For `N` sources or receivers, all variables must be of size `N` or 1
100+
(in the latter case it will be expanded to `N`).
108101
109102
Angles (coordinate system is either left-handed with positive z down or
110103
right-handed with positive z up; East-North-Depth):
@@ -835,15 +828,8 @@ def loop(src, rec, depth, res, freqtime, signal=None, aniso=None, epermH=None,
835828
- [x0, x1, y0, y1, z0, z1] (bipole of finite length)
836829
- [x, y, z, azimuth, dip] (dipole, infinitesimal small)
837830
838-
Dimensions:
839-
840-
- The coordinates x, y, and z (dipole) or x0, x1, y0, y1, z0, and z1
841-
(bipole) can be single values or arrays.
842-
- The variables x and y (dipole) or x0, x1, y0, and y1 (bipole) must
843-
have the same dimensions.
844-
- The variables z, azimuth, and dip (dipole) or z0 and z1 (bipole) must
845-
either be single values or having the same dimension as the other
846-
coordinates.
831+
For `N` sources or receivers, all variables must be of size `N` or 1
832+
(in the latter case it will be expanded to `N`).
847833
848834
Angles (coordinate system is either left-handed with positive z down or
849835
right-handed with positive z up; East-North-Depth):

empymod/utils.py

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -258,14 +258,32 @@ def check_bipole(inp, name):
258258

259259
def chck_dipole(inp, name):
260260
r"""Check inp for shape and type."""
261-
# Check x
261+
# Check x, y, and z
262262
inp_x = _check_var(inp[0], float, 1, name+'-x')
263-
264-
# Check y and ensure it has same dimension as x
265-
inp_y = _check_var(inp[1], float, 1, name+'-y', inp_x.shape)
266-
267-
# Check z
268-
inp_z = _check_var(inp[2], float, 1, name+'-z', (1,), inp_x.shape)
263+
inp_y = _check_var(inp[1], float, 1, name+'-y')
264+
inp_z = _check_var(inp[2], float, 1, name+'-z')
265+
266+
# Expand x or y coordinate if necessary.
267+
if inp_x.size != inp_y.size:
268+
if inp_x.size == 1:
269+
inp_x = np.repeat(inp_x, inp_y.size)
270+
elif inp_y.size == 1:
271+
inp_y = np.repeat(inp_y, inp_x.size)
272+
else:
273+
raise ValueError(
274+
f"Parameters {name}-x and {name}-y must be of same size "
275+
"or be a single value; provided: "
276+
f"{inp_x.shape}; {inp_y.shape}."
277+
)
278+
279+
# If x/y=1, but z not => expand
280+
if inp_z.size > 1 and inp_x.size == 1:
281+
inp_x = np.repeat(inp_x, inp_z.size)
282+
inp_y = np.repeat(inp_y, inp_z.size)
283+
284+
# If x/y!=1 and z!=1, check!
285+
else:
286+
_check_shape(inp_z, name+'-z', (1,), inp_x.shape)
269287

270288
# Check if all depths are the same, if so replace by one value
271289
if np.all(np.isclose(inp_z-inp_z[0], 0)):
@@ -287,18 +305,32 @@ def chck_dipole(inp, name):
287305
out = chck_dipole(inp, name)
288306

289307
# Check azimuth and dip
290-
inp_a = _check_var(inp[3], float, 1, 'azimuth', (1,), out[0].shape)
291-
inp_d = _check_var(inp[4], float, 1, 'dip', (1,), out[0].shape)
308+
inp_a = _check_var(inp[3], float, 1, 'azimuth')
309+
inp_d = _check_var(inp[4], float, 1, 'dip')
310+
311+
# Expand x/y coordinate or azm/dip if necessary.
312+
# THINK ABOUT IT!
313+
for inp_ad, ad_name in ([inp_a, 'azimuth'], [inp_d, 'dip']):
314+
if inp_ad.size != 1 and out[0].shape != inp_ad.shape:
315+
if out[0].size == 1:
316+
out[0] = np.repeat(out[0], inp_ad.size)
317+
out[1] = np.repeat(out[1], inp_ad.size)
318+
else:
319+
raise ValueError(
320+
f"Parameter {name}-x and {name}-y must be of same size "
321+
"or be a single value; provided: "
322+
f"{inp_x.shape}; {inp_y.shape}."
323+
)
292324

293325
# How many different depths
294326
nz = out[2].size
295327

296328
# Expand azimuth and dip to match number of depths
297329
if nz > 1:
298330
if inp_a.size == 1:
299-
inp_a = np.ones(nz)*inp_a
331+
inp_a = np.repeat(inp_a, nz)
300332
if inp_d.size == 1:
301-
inp_d = np.ones(nz)*inp_d
333+
inp_d = np.repeat(inp_d, nz)
302334

303335
out = [*out, inp_a, inp_d]
304336

@@ -310,11 +342,19 @@ def chck_dipole(inp, name):
310342
# If one pole has a single depth, but the other has various
311343
# depths, we have to repeat the single depth, as we will have
312344
# to loop over them.
313-
if out0[2].size != out1[2].size:
314-
if out0[2].size == 1:
315-
out0[2] = np.repeat(out0[2], out1[2].size)
316-
else:
317-
out1[2] = np.repeat(out1[2], out0[2].size)
345+
for i in range(3):
346+
if out0[i].size != out1[i].size:
347+
if out0[i].size == 1:
348+
out0[i] = np.repeat(out0[i], out1[i].size)
349+
elif out1[i].size == 1:
350+
out1[i] = np.repeat(out1[i], out0[i].size)
351+
else:
352+
raise ValueError("TODO")
353+
354+
# Think about it. Same as above, but for the coordinates.
355+
# 1. Test that x0, x1 have same dimension
356+
# 2. If x0.shape != 1 and z0.shape != 1: check
357+
# 3. if z.shape > x0.shape -> expand
318358

319359
# Check if inp is a dipole instead of a bipole
320360
# (This is a problem, as we would could not define the angles then.)

0 commit comments

Comments
 (0)