Skip to content

Commit 9c0d3fc

Browse files
committed
update according to pytomo3d
1 parent 763d2c8 commit 9c0d3fc

File tree

4 files changed

+87
-228
lines changed

4 files changed

+87
-228
lines changed
Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,53 @@
1-
# adjoint source type
2-
adj_src_type: "multitaper_misfit"
3-
4-
# min and max period(unit: second)
5-
min_period: 50.0
6-
max_period: 100.0
7-
8-
# adjoint config parameter
9-
lnpt: 15
10-
transfunc_waterlevel: 1.0E-10
11-
water_threshold: 0.02
12-
ipower_costaper: 10
13-
min_cycle_in_window: 3
14-
taper_percentage: 0.3
15-
mt_nw: 4.0
16-
num_taper: 5
17-
phase_step: 1.5
18-
dt_fac: 2.0
19-
err_fac: 2.5
20-
dt_max_scale: 3.5
21-
measure_type: 'dt'
22-
taper_type: 'hann'
23-
dt_sigma_min: 1.0
24-
dlna_sigma_min: 0.5
25-
use_cc_error: True
26-
use_mt_error: False
27-
28-
---
29-
# for postprocessing adjoint sources
30-
# interpolation. Starttime will be automatically set as cmt_time - 1.5 * hdur
31-
# to fit the SPECFEM behaviour
32-
interp_flag: True
33-
interp_delta: 0.1425
34-
interp_npts: 42000
35-
36-
# for sum multiple insturments, like "II.AAK.00.BHZ" and "II.AAK.10.BHZ". if you turn
37-
# the weight_flag to be true, then you need also provide the weight_dict in the code
38-
sum_over_comp_flag: False
39-
weight_flag: True
40-
41-
# filter the adjoint source
42-
filter_flag: True
43-
pre_filt: [0.0067, 0.01, 0.02, 0.025]
44-
45-
# add missing components with zero trace(to prepare rotate)
46-
# If set to False, only rotate those with Both "R" and "T"
47-
# components. Set to True highly recommended unless you are
48-
# sreu what you are doing
49-
add_missing_comp_flag: False
50-
51-
# rotate the adjoint source
52-
rotate_flag: False
1+
adjoint_config:
2+
# adjoint source type
3+
adj_src_type: "multitaper_misfit"
4+
5+
# min and max period(unit: second)
6+
min_period: 50.0
7+
max_period: 100.0
8+
9+
# adjoint config parameter
10+
lnpt: 15
11+
transfunc_waterlevel: 1.0E-10
12+
water_threshold: 0.02
13+
ipower_costaper: 10
14+
min_cycle_in_window: 3
15+
taper_percentage: 0.3
16+
mt_nw: 4.0
17+
num_taper: 5
18+
phase_step: 1.5
19+
dt_fac: 2.0
20+
err_fac: 2.5
21+
dt_max_scale: 3.5
22+
measure_type: 'dt'
23+
taper_type: 'hann'
24+
dt_sigma_min: 1.0
25+
dlna_sigma_min: 0.5
26+
use_cc_error: True
27+
use_mt_error: False
28+
29+
process_config:
30+
# for postprocessing adjoint sources
31+
# interpolation. Starttime will be automatically set as cmt_time - 1.5 * hdur
32+
# to fit the SPECFEM behaviour
33+
interp_flag: True
34+
interp_delta: 0.1425
35+
interp_npts: 42000
36+
37+
# for sum multiple insturments, like "II.AAK.00.BHZ" and "II.AAK.10.BHZ". if you turn
38+
# the weight_flag to be true, then you need also provide the weight_dict in the code
39+
sum_over_comp_flag: False
40+
weight_flag: True
41+
42+
# filter the adjoint source
43+
filter_flag: True
44+
pre_filt: [0.0067, 0.01, 0.02, 0.025]
45+
46+
# add missing components with zero trace(to prepare rotate)
47+
# If set to False, only rotate those with Both "R" and "T"
48+
# components. Set to True highly recommended unless you are
49+
# sreu what you are doing
50+
add_missing_comp_flag: False
51+
52+
# rotate the adjoint source
53+
rotate_flag: False

pypaw/bins/filter_windows.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,11 @@
1616
from __future__ import (absolute_import, division, print_function)
1717
import os
1818
import argparse
19-
from pytomo3d.window import filter_windows
19+
from pytomo3d.window.filter_windows import filter_windows, count_windows
2020
from .utils import load_json, dump_json, load_yaml
2121

2222

23-
def main():
24-
25-
parser = argparse.ArgumentParser()
26-
parser.add_argument('-f', action='store', dest='path_file', required=True,
27-
help="path file")
28-
parser.add_argument('-p', action='store', dest='param_file', required=True,
29-
help="param file")
30-
parser.add_argument('-v', action='store_true', dest='verbose',
31-
help="verbose flag")
32-
args = parser.parse_args()
33-
34-
paths = load_json(args.path_file)
35-
params = load_yaml(args.param_file)
36-
23+
def run_window_filter(paths, params, verbose=False):
3724
window_file = paths["window_file"]
3825
station_file = paths["station_file"]
3926
output_file = paths["output_file"]
@@ -45,12 +32,15 @@ def main():
4532
print("output filtered window file: %s" % output_file)
4633

4734
windows = load_json(window_file)
35+
nchans_old, nwins_old = count_windows(windows)
4836
stations = load_json(station_file)
4937
measurements = load_json(measurement_file)
5038

5139
# filter the window based on given sensor types
5240
windows_new, log = filter_windows(
53-
windows, stations, measurements, params, verbose=args.verbose)
41+
windows, stations, measurements, params, verbose=verbose)
42+
43+
nchans_new, nwins_new = count_windows(windows_new)
5444
# dump the new windows file to replace the original one
5545
dump_json(windows_new, output_file)
5646

@@ -59,6 +49,27 @@ def main():
5949
print("Log file located at: %s" % logfile)
6050
dump_json(log, logfile)
6151

52+
print("=" * 10 + " Summary " + "=" * 10)
53+
print("channels: %d --> %d" % (nchans_old, nchans_new))
54+
print("windows: %d -- > %d" % (nwins_old, nwins_new))
55+
56+
57+
def main():
58+
59+
parser = argparse.ArgumentParser()
60+
parser.add_argument('-f', action='store', dest='path_file', required=True,
61+
help="path file")
62+
parser.add_argument('-p', action='store', dest='param_file', required=True,
63+
help="param file")
64+
parser.add_argument('-v', action='store_true', dest='verbose',
65+
help="verbose flag")
66+
args = parser.parse_args()
67+
68+
paths = load_json(args.path_file)
69+
params = load_yaml(args.param_file)
70+
71+
run_window_filter(paths, params, verbose=args.verbose)
72+
6273

6374
if __name__ == "__main__":
6475
main()

pypaw/sum_adjoint.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,7 @@ def check_event_information_in_asdf_files(asdf_files):
103103
ds = ASDFDataSet(asdf_fn, mode='r')
104104
asdf_events[asdf_fn] = ds.events
105105

106-
diffs = check_events_consistent(asdf_events)
107-
if len(diffs) != 0:
108-
raise ValueError("Event information in %s not the same as others: %s"
109-
% (diffs, asdf_events.keys()))
106+
check_events_consistent(asdf_events)
110107

111108
event_base = asdf_events[asdf_events.keys()[0]]
112109
origin = event_base[0].preferred_origin()
@@ -164,6 +161,7 @@ def attach_station_to_db(self, station_info):
164161
def add_adjoint_dataset_on_channel_weight(self, ds, weights):
165162
"""
166163
Add adjoint source based on channel window weight
164+
The adjoint source's channel should be renamed to "MX"
167165
"""
168166
misfits = {}
169167
adjsrc_group = ds.auxiliary_data.AdjointSources

pypaw/window_weights.py

Lines changed: 5 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
plt.switch_backend('agg') # NOQA
2121

2222
from pyasdf import ASDFDataSet
23-
from spaceweight import SpherePoint
24-
from spaceweight import SphereDistRel
2523
from pytomo3d.adjoint.sum_adjoint import check_events_consistent
24+
from pytomo3d.window.window_weights import determine_receiver_weighting, \
25+
determine_category_weighting
2626
from pypaw.bins.utils import load_json, dump_json, load_yaml
2727

2828

@@ -147,125 +147,6 @@ def extract_source_location(input_info):
147147
return src_info
148148

149149

150-
def _receiver_validator(weights, rec_wcounts, cat_wcounts):
151-
152-
for comp in weights:
153-
wsum = 0
154-
for trace_id, trace_weight in weights[comp].iteritems():
155-
nwin = rec_wcounts[trace_id]
156-
wsum += trace_weight * nwin
157-
158-
if not np.isclose(wsum, cat_wcounts[comp]):
159-
raise ValueError("receiver validator fails: %f, %f" %
160-
(wsum, cat_wcounts[comp]))
161-
162-
163-
def determine_receiver_weighting(src, stations, windows, max_ratio=0.35,
164-
flag=True, plot=False,
165-
figname_prefix=None):
166-
"""
167-
Given one station and window information, determine the receiver
168-
weighting
169-
In one asdf file, there are still 3 components, for example,
170-
["BHR", "BHT", "BHZ"]. These three components should be treated
171-
indepandently and weights will be calculated independantly.
172-
173-
:return: dict of weights which contains 3 components. Each components
174-
contains weights values
175-
"""
176-
center = SpherePoint(src["latitude"], src["longitude"],
177-
tag="source")
178-
179-
# extract window information
180-
weights = {}
181-
rec_wcounts = {}
182-
cat_wcounts = defaultdict(lambda: 0)
183-
for sta, sta_window in windows.iteritems():
184-
for chan, chan_win in sta_window.iteritems():
185-
comp = chan.split(".")[-1]
186-
_nwin = len(chan_win)
187-
if _nwin == 0:
188-
continue
189-
weights.setdefault(comp, {}).update({chan: 0.0})
190-
rec_wcounts[chan] = _nwin
191-
cat_wcounts[comp] += _nwin
192-
193-
# in each components, calculate weight
194-
ref_dists = {}
195-
cond_nums = {}
196-
for comp, comp_info in weights.iteritems():
197-
points = []
198-
logger.info("Components:%s" % comp)
199-
for chan in comp_info:
200-
_comp = chan[-1]
201-
if _comp == "Z":
202-
point = SpherePoint(stations[chan]["latitude"],
203-
stations[chan]["longitude"],
204-
tag=chan, weight=1.0)
205-
else:
206-
# for R and T component. In station file, there
207-
# are only E and N component. So we need transfer
208-
echan = chan[:-1] + "E"
209-
chan1 = chan[:-1] + "1"
210-
zchan = chan[:-1] + "Z"
211-
if echan in stations:
212-
point = SpherePoint(stations[echan]["latitude"],
213-
stations[echan]["longitude"],
214-
tag=chan, weight=1.0)
215-
elif chan1 in stations:
216-
point = SpherePoint(stations[chan1]["latitude"],
217-
stations[chan1]["longitude"],
218-
tag=chan, weight=1.0)
219-
elif zchan in stations:
220-
point = SpherePoint(stations[zchan]["latitude"],
221-
stations[zchan]["longitude"],
222-
tag=chan, weight=1.0)
223-
points.append(point)
224-
225-
if flag:
226-
# calculate weight; otherwise, leave it as default value(1)
227-
weightobj = SphereDistRel(points, center=center)
228-
scan_figname = figname_prefix + ".%s.smart_scan.png" % comp
229-
ref_dists[comp], cond_nums[comp] = weightobj.smart_scan(
230-
max_ratio=max_ratio, start=0.5, gap=0.5,
231-
drop_ratio=0.95, plot=plot,
232-
figname=scan_figname)
233-
if plot:
234-
figname = figname_prefix + ".%s.weight.png" % comp
235-
weightobj.plot_global_map(figname=figname, lon0=180.0)
236-
else:
237-
ref_dists[comp] = None
238-
cond_nums[comp] = None
239-
240-
wsum = 0
241-
for point in points:
242-
nwin = rec_wcounts[point.tag]
243-
wsum += point.weight * nwin
244-
norm_factor = cat_wcounts[comp] / wsum
245-
246-
for point in points:
247-
weights[comp][point.tag] = point.weight * norm_factor
248-
249-
_receiver_validator(weights, rec_wcounts, cat_wcounts)
250-
251-
return {"rec_weights": weights, "rec_wcounts": rec_wcounts,
252-
"cat_wcounts": cat_wcounts, "rec_ref_dists": ref_dists,
253-
"rec_cond_nums": cond_nums}
254-
255-
256-
def _category_validator(weights, counts):
257-
wsum = 0.0
258-
nwins = 0
259-
for p, pinfo in weights.iteritems():
260-
for c in pinfo:
261-
wsum += weights[p][c] * counts[p][c]
262-
nwins += counts[p][c]
263-
264-
if not np.isclose(wsum, nwins):
265-
raise ValueError("Category validator fails: %f, %f" %
266-
(wsum, nwins))
267-
268-
269150
def check_cat_consistency(cat_ratio, cat_wcounts):
270151
err = 0
271152
# check consistency
@@ -281,38 +162,6 @@ def check_cat_consistency(cat_ratio, cat_wcounts):
281162
"consistent with window information")
282163

283164

284-
def determine_category_weighting(weight_param, cat_wcounts):
285-
"""
286-
determine the category weighting based on window counts in each category
287-
"""
288-
logger_block("Category Weighting")
289-
weights = {}
290-
291-
cat_ratio = weight_param["ratio"]
292-
293-
print("cat_ratio: %s" % cat_ratio)
294-
print("cat_wcounts: %s" % cat_wcounts)
295-
sumv = 0
296-
nwins = 0
297-
for p, pinfo in cat_wcounts.iteritems():
298-
for c in pinfo:
299-
sumv += cat_wcounts[p][c] / cat_ratio[p][c]
300-
nwins += cat_wcounts[p][c]
301-
302-
normc = nwins / sumv
303-
logger.info("Total number of windows: %d" % nwins)
304-
305-
weights = {}
306-
for p, pinfo in cat_wcounts.iteritems():
307-
weights[p] = {}
308-
for c in pinfo:
309-
weights[p][c] = normc / cat_ratio[p][c]
310-
311-
logger.info("Category weights: %s" % weights)
312-
_category_validator(weights, cat_wcounts)
313-
return weights
314-
315-
316165
def plot_histogram(figname, array, nbins=50):
317166
# plot histogram of weights
318167
plt.hist(array, nbins)
@@ -529,9 +378,9 @@ def calculate_receiver_weights_asdf(self, period_info, weighting_param):
529378

530379
_results = determine_receiver_weighting(
531380
self.src_info, station_info, window_info,
532-
max_ratio=search_ratio,
533-
flag=weight_flag,
534-
plot=plot_flag, figname_prefix=figname_prefix)
381+
search_ratio=search_ratio,
382+
weight_flag=weight_flag,
383+
plot_flag=plot_flag, figname_prefix=figname_prefix)
535384

536385
return _results
537386

0 commit comments

Comments
 (0)