Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/fomosto/elastic10_to_rotational8.py: 0%
84 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-03-07 11:54 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-03-07 11:54 +0000
1import os
2import logging
3import shutil
4from pyrocko import gf, guts, util
5import numpy as num
8logger = logging.getLogger('main')
11def a(*args):
12 return num.array(args, dtype=float)
15def ai(*args):
16 return num.array(args, dtype=int)
19def almost_equal(a, b, eps):
20 return abs(a - b < eps)
23def configure_diff(x, xmin, xmax, dx):
24 if almost_equal(x, xmin, 1e-6*dx):
25 return dx, 0.
26 elif almost_equal(x, xmax, 1e-6*dx):
27 return 0., dx
28 else:
29 return dx, dx
32def sindex(args):
33 return '(%s)' % ', '.join('%g' % x for x in args)
36def elastic10_to_rotational8(
37 source_store_dir,
38 dest_store_dir,
39 show_progress=True):
41 def _raise(message):
42 raise gf.StoreError('elastic10_to_rotational8: %s' % message)
44 source = gf.Store(source_store_dir)
46 if source.config.component_scheme not in ('elastic10', 'elastic10_fd'):
47 _raise(
48 'Only `elastic10` and `elastic10_fd` component schemes supported '
49 'for input store.')
51 have_fd_components = source.config.component_scheme == 'elastic10_fd'
53 if source.config.effective_stored_quantity != 'displacement':
54 _raise('Stored quantity of input store must be displacement.')
56 if not os.path.exists(dest_store_dir):
57 config = guts.clone(source.config)
58 config.id += '_rotfd'
59 config.__dict__['ncomponents'] = 8
60 config.__dict__['component_scheme'] = 'rotational8'
61 config.stored_quantity = 'rotation_displacement'
62 config.fd_distance_delta = None
63 if config.short_type == 'B':
64 config.fd_receiver_depth_delta = None
66 util.ensuredirs(dest_store_dir)
67 gf.Store.create(dest_store_dir, config=config)
68 shutil.copytree(
69 os.path.join(source_store_dir, 'phases'),
70 os.path.join(dest_store_dir, 'phases'))
72 try:
73 gf.store.Store.create_dependants(dest_store_dir)
74 except gf.StoreError:
75 pass
77 dest = gf.Store(dest_store_dir, 'w')
79 ta = source.config.short_type
80 tb = dest.config.short_type
82 if have_fd_components and not (ta, tb) == ('A', 'A'):
83 _raise(
84 'For input stores with component scheme `elastic10_fd`, only '
85 'conversion from store type A to A is currently supported.')
87 if (ta, tb) not in (('A', 'A'), ('B', 'B'), ('B', 'A')):
88 _raise('Cannot convert type %s to type %s.' % (ta, tb))
90 if source.config.distance_delta > dest.config.distance_delta:
91 _raise(
92 'Distance spacing of output store must be equal to or larger '
93 'distance spacing of input store.')
95 if (ta, tb) == ('B', 'B'):
96 if source.config.receiver_depth_delta \
97 > dest.config.receiver_depth_delta:
98 _raise(
99 'Depth spacing of output store must be equal to or larger '
100 'depth spacing of input store.')
102 if ta == 'A':
103 if source.config.receiver_depth \
104 != source.config.earthmodel_1d.discontinuity('surface').z:
105 _raise(
106 'When input store is of type A, receivers must be at the '
107 'surface.')
109 if have_fd_components:
110 dx = source.config.fd_distance_delta
111 else:
112 dx = source.config.distance_delta
114 if ta == 'B':
115 dz = source.config.receiver_depth_delta
116 else:
117 dz = None
119 if show_progress:
120 pbar = util.progressbar(
121 'elastic10_to_rotational8',
122 source.config.nrecords/source.config.ncomponents)
124 try:
125 for i, args in enumerate(dest.config.iter_nodes(level=-1)):
126 if ta == 'A':
127 sz, x = args
129 if have_fd_components:
130 dx1 = dx2 = dx
131 else:
132 dx1, dx2 = configure_diff(
133 x,
134 source.config.distance_min,
135 source.config.distance_max,
136 dx)
138 odx = dx1+dx2
140 for ig, (sum_args, weights) in enumerate(zip(
141 [
142 (a(), a(), ai()),
143 (a(), a(), ai()),
144 (a(sz, sz), a(x, x), ai(25, 5)),
145 (a(sz, sz), a(x, x), ai(26, 6)),
146 (a(sz, sz), a(x, x), ai(27, 7)),
147 (a(sz, sz), a(x, x), ai(23, 3)),
148 (a(sz, sz), a(x, x), ai(24, 4)),
149 (a(sz, sz), a(x, x), ai(29, 9)),
150 ] if have_fd_components else [
151 (a(), a(), ai()),
152 (a(), a(), ai()),
153 (a(sz, sz), a(x+dx1, x-dx2), ai(5, 5)),
154 (a(sz, sz), a(x+dx1, x-dx2), ai(6, 6)),
155 (a(sz, sz), a(x+dx1, x-dx2), ai(7, 7)),
156 (a(sz, sz), a(x+dx1, x-dx2), ai(3, 3)),
157 (a(sz, sz), a(x+dx1, x-dx2), ai(4, 4)),
158 (a(sz, sz), a(x+dx1, x-dx2), ai(9, 9)),
159 ],
160 [
161 a(),
162 a(),
163 1.0 / a(-odx, odx),
164 1.0 / a(-odx, odx),
165 1.0 / a(-odx, odx),
166 0.5 / a(odx, -odx),
167 0.5 / a(odx, -odx),
168 1.0 / a(-odx, odx),
169 ])):
171 if weights.size == 0:
172 h = gf.GFTrace(is_zero=True, itmin=0)
173 else:
174 h = source.sum(
175 sum_args,
176 num.zeros_like(weights),
177 weights,
178 optimization='disable')
180 dest.put(args + (ig,), h)
181 else:
182 rz, sz, x = args
184 dx1, dx2 = configure_diff(
185 x,
186 source.config.distance_min,
187 source.config.distance_max,
188 dx)
190 dz1, dz2 = configure_diff(
191 rz,
192 source.config.receiver_depth_min,
193 source.config.receiver_depth_max,
194 dz)
196 odx = dx1+dx2
197 odz = dz1+dz2
199 for ig, (sum_args, weights) in enumerate(zip(
200 [
201 (a(rz+dz1, rz-dz2), a(sz, sz), a(x, x), ai(3, 3)),
202 (a(rz+dz1, rz-dz2), a(sz, sz), a(x, x), ai(4, 4)),
203 (a(rz+dz1, rz-dz2, rz, rz), a(sz, sz, sz, sz), a(x, x, x+dx1, x-dx2), ai(0, 0, 5, 5)), # noqa
204 (a(rz+dz1, rz-dz2, rz, rz), a(sz, sz, sz, sz), a(x, x, x+dx1, x-dx2), ai(1, 1, 6, 6)), # noqa
205 (a(rz+dz1, rz-dz2, rz, rz), a(sz, sz, sz, sz), a(x, x, x+dx1, x-dx2), ai(2, 2, 7, 7)), # noqa
206 (a(rz, rz), a(sz, sz), a(x+dx1, x-dx2), ai(3, 3)),
207 (a(rz, rz), a(sz, sz), a(x+dx1, x-dx2), ai(4, 4)),
208 (a(rz+dz1, rz-dz2, rz, rz), a(sz, sz, sz, sz), a(x, x, x+dx1, x-dx2), ai(8, 8, 9, 9)), # noqa
209 ],
210 [
211 0.5 / a(-odz, odz),
212 0.5 / a(-odz, odz),
213 0.5 / a(odz, -odz, -odx, odx),
214 0.5 / a(odz, -odz, -odx, odx),
215 0.5 / a(odz, -odz, -odx, odx),
216 0.5 / a(odx, -odx),
217 0.5 / a(odx, -odx),
218 0.5 / a(odz, -odz, -odx, odx),
219 ])):
221 h = source.sum(
222 sum_args,
223 num.zeros_like(weights),
224 weights,
225 optimization='disable')
227 dest.put(args + (ig,), h)
229 if show_progress:
230 pbar.update(i+1)
232 finally:
233 if show_progress:
234 pbar.finish()