-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathdata_utils.py
110 lines (100 loc) · 4.54 KB
/
data_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Written in Aug 2018
Use a bad station screening file to eliminate the bad stations from stream
Right now removes all three components (maybe refined to remove certain
components in the future)
"""
import os,sys,subprocess
from obspy.core.stream import Stream
# add stats headers including trace.stats.distance/latitude/longitude
# figure out channel code number before select stream ...
def remove_station_from_stream(data_stream,inv,bad_station_file='bad-quality-station.txt',verbose=True):
if not os.path.isfile(bad_station_file):
sys.exit('No bad_quality_station_file: '+bad_station_file)
lines=open(bad_station_file,'r').readlines()
for i in range(len(lines)):
net_sta=lines[i].split()[0]
sta_info=net_sta.split('.')
if len(sta_info) == 2:
(net,sta)=sta_info[0:2]
elif len(sta_info) == 4:
(net,sta,loc,chan1)=sta_info[0:4]
else:
sys.exit('Incorrect format in bad_quality_station_file: net.sta or net.sta.chan.cmp')
if verbose:
print(net, sta)
# confirm this net.sta[.loc.chan1] indeed exist
found=False
for nt in inv:
for st in nt:
for ch in st:
if len(sta_info) == 2:
if nt.code == net and st.code==sta:
found=True; break
else:
if nt.code == net and st.code==sta and ch.location_code == loc and ch.code[0:2] == chan1:
found=True
break
if not found:
sys.exit('Check if '+net_sta+' exists in the inventory')
# screen out the bad traces
if len(sta_info) == 2:
str_bad=data_stream.select(network=net,station=sta)
elif len(sta_info) == 4:
str_bad=data_stream.select(network=net,station=sta,location=loc,channel=chan1+'?')
for trace in str_bad:
data_stream.remove(trace)
if verbose:
print('Remove trace ',trace)
return
# --------------------------------------------------------
def write_weight_file(weight_file,dist_list,model_dir,check_bad_fit=False,bad_fit_station_file='bad-fit-stations.txt',min_dist_pnl=0.,max_dist_pnl=300., max_dist=1000.):
# print('Write weight file '+ weight_file+'...')
if not os.path.isfile(dist_list):
sys.exit('No file: '+dist_list)
if not os.path.isdir(model_dir):
sys.exit('No greens function dir: '+model_dir)
if check_bad_fit:
print('Eliminate bad-fitting components based on '+bad_fit_station_file+'...')
if not os.path.isfile(bad_fit_station_file):
sys.exit('Check bad_fit_station_file '+bad_fit_station_file)
# step 1: read in bad_fit station/componentlist
tmp=open(bad_fit_station_file).readlines()
bad_fit_station_list=list(map(str.rstrip,tmp))
bad_fit={}
for fit in bad_fit_station_list:
[net_sta,cmps]=fit.split()
bad_fit[net_sta]=cmps
# step 2: write weight file based on dist.list and bad sta/comp file
fw=open(weight_file,'w')
for line in open(dist_list,'r'):
[file,dist]=line.split() #e.g., GS_OK035.z 22
file1=file[:-2] #e.g., GS_OK035
dist_km=int(round(float(dist)))
# check if greens function exist and obtain tp arrival
sac_grn=model_dir+'/'+dist+'.grn.0'
if not os.path.isfile(sac_grn):
sys.exit('No such greens function file '+sac_grn)
tp=subprocess.getoutput('saclst t1 t2 f '+sac_grn).split()[1]
#print(tp)
use_cmps={'P':1,'Z':1,'R':1,'T':1}
# eliminate bad fit station (only used in a second run)
if check_bad_fit:
if file1 in bad_fit.keys():
cmps=bad_fit[file1]
for cmp in list(cmps):
if cmp not in ['P','Z','R','T']:
sys.exit('Error component names in '+bad_fit_station_file)
use_cmps[cmp]=0
# adjust based on distance
if dist_km < min_dist_pnl or dist_km > max_dist_pnl:
use_cmps['P'] = 0
if dist_km > max_dist:
use_cmps={'P':0,'Z':0,'R':0,'T':0}
# note the gcap c code is very finicky about the format of the weight input
# need to read the source code to understand why
fw.write("%-10s %5d %.0f %.0f %.0f %.0f %.0f %.1f %.0f\n" %
(file1, dist_km, use_cmps['P'], use_cmps['P'], use_cmps['Z'], use_cmps['R'], use_cmps['T'], float(tp), 0))
fw.close()