DASPy-toolbox 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- DASPy_toolbox-1.0.0.dist-info/LICENSE.txt +1 -0
- DASPy_toolbox-1.0.0.dist-info/METADATA +85 -0
- DASPy_toolbox-1.0.0.dist-info/RECORD +49 -0
- DASPy_toolbox-1.0.0.dist-info/WHEEL +5 -0
- DASPy_toolbox-1.0.0.dist-info/entry_points.txt +2 -0
- DASPy_toolbox-1.0.0.dist-info/top_level.txt +1 -0
- daspy/__init__.py +4 -0
- daspy/advanced_tools/__init__.py +0 -0
- daspy/advanced_tools/channel.py +354 -0
- daspy/advanced_tools/decomposition.py +165 -0
- daspy/advanced_tools/denoising.py +276 -0
- daspy/advanced_tools/fdct.py +789 -0
- daspy/advanced_tools/strain2vel.py +245 -0
- daspy/basic_tools/__init__.py +0 -0
- daspy/basic_tools/filter.py +257 -0
- daspy/basic_tools/freqattributes.py +117 -0
- daspy/basic_tools/preprocessing.py +238 -0
- daspy/basic_tools/visualization.py +186 -0
- daspy/core/__init__.py +4 -0
- daspy/core/collection.py +279 -0
- daspy/core/dasdatetime.py +72 -0
- daspy/core/example.pkl +0 -0
- daspy/core/make_example.py +32 -0
- daspy/core/read.py +544 -0
- daspy/core/section.py +1319 -0
- daspy/core/write.py +282 -0
- daspy/seismic_detection/__init__.py +1 -0
- daspy/seismic_detection/calc_travel_time.py +23 -0
- daspy/seismic_detection/core.py +119 -0
- daspy/seismic_detection/detection.py +12 -0
- daspy/seismic_detection/gamma/__init__.py +13 -0
- daspy/seismic_detection/gamma/_base.py +549 -0
- daspy/seismic_detection/gamma/_bayesian_mixture.py +875 -0
- daspy/seismic_detection/gamma/_gaussian_mixture.py +866 -0
- daspy/seismic_detection/gamma/app.py +192 -0
- daspy/seismic_detection/gamma/seismic_ops.py +478 -0
- daspy/seismic_detection/gamma/utils.py +512 -0
- daspy/seismic_detection/location.py +266 -0
- daspy/seismic_detection/magnitude.py +43 -0
- daspy/seismic_detection/phase_picking.py +67 -0
- daspy/structure_imaging/__init__.py +0 -0
- daspy/structure_imaging/ambient_noise.py +4 -0
- daspy/structure_imaging/dispersion.py +27 -0
- daspy/structure_imaging/fault_zone.py +59 -0
- daspy/structure_imaging/inversion.py +6 -0
- daspy/traffic_monitoring/JamDetection.py +6 -0
- daspy/traffic_monitoring/SpeedMeasurement.py +6 -0
- daspy/traffic_monitoring/VehicleDetection.py +6 -0
- daspy/traffic_monitoring/__init__.py +0 -0
daspy/core/write.py
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# Purpose: Module for writing DAS data.
|
|
2
|
+
# Author: Minzhe Hu
|
|
3
|
+
# Date: 2024.11.1
|
|
4
|
+
# Email: hmz2018@mail.ustc.edu.cn
|
|
5
|
+
import os
|
|
6
|
+
import warnings
|
|
7
|
+
import pickle
|
|
8
|
+
import numpy as np
|
|
9
|
+
import h5py
|
|
10
|
+
import segyio
|
|
11
|
+
from shutil import copyfile
|
|
12
|
+
from nptdms import TdmsFile, TdmsWriter, RootObject, GroupObject, ChannelObject
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def write(sec, fname, ftype=None, raw_fname=None):
|
|
17
|
+
fun_map = {'tdms': _write_tdms, 'h5': _write_h5, 'sgy': _write_segy}
|
|
18
|
+
if ftype is None:
|
|
19
|
+
ftype = str(fname).lower().split('.')[-1]
|
|
20
|
+
ftype.replace('hdf5', 'h5')
|
|
21
|
+
ftype.replace('segy', 'sgy')
|
|
22
|
+
if ftype == 'pkl':
|
|
23
|
+
write_pkl(sec, fname)
|
|
24
|
+
elif ftype == 'npy':
|
|
25
|
+
np.save(fname, sec.data)
|
|
26
|
+
else:
|
|
27
|
+
fun_map[ftype](sec, fname, raw_fname=raw_fname)
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def write_pkl(sec, fname):
|
|
32
|
+
with open(fname, 'wb') as f:
|
|
33
|
+
pickle.dump(sec.__dict__, f)
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _write_tdms(sec, fname, raw_fname=None):
|
|
38
|
+
if raw_fname is None:
|
|
39
|
+
key = 'Measurement'
|
|
40
|
+
file_prop = {}
|
|
41
|
+
group_prop = {}
|
|
42
|
+
else:
|
|
43
|
+
original_file = TdmsFile(raw_fname)
|
|
44
|
+
group_name = [group.name for group in original_file.groups()]
|
|
45
|
+
if 'Measurement' in group_name:
|
|
46
|
+
key = 'Measurement'
|
|
47
|
+
elif 'DAS' in group_name:
|
|
48
|
+
key = 'DAS'
|
|
49
|
+
else:
|
|
50
|
+
key = group_name[0]
|
|
51
|
+
file_prop = original_file.properties
|
|
52
|
+
group_prop = original_file[key].properties
|
|
53
|
+
|
|
54
|
+
if 'Spatial Resolution' in group_prop.keys():
|
|
55
|
+
group_prop['Spatial Resolution'] = sec.dx
|
|
56
|
+
else:
|
|
57
|
+
file_prop['SpatialResolution[m]'] = sec.dx
|
|
58
|
+
|
|
59
|
+
if 'Time Base' in group_prop.keys():
|
|
60
|
+
group_prop['Time Base'] = 1. / sec.fs
|
|
61
|
+
else:
|
|
62
|
+
file_prop['SamplingFrequency[Hz]'] = sec.fs
|
|
63
|
+
|
|
64
|
+
if 'Total Channels' in group_prop.keys():
|
|
65
|
+
group_prop['Total Channels'] = sec.nch
|
|
66
|
+
|
|
67
|
+
if 'Initial Channel' in group_prop.keys():
|
|
68
|
+
group_prop['Initial Channel'] = sec.start_channel
|
|
69
|
+
|
|
70
|
+
file_prop['Start Distance (m)'] = sec.start_distance
|
|
71
|
+
if isinstance(sec.start_time, datetime):
|
|
72
|
+
start_time = sec.start_time
|
|
73
|
+
else:
|
|
74
|
+
start_time = datetime.fromtimestamp(sec.start_time)
|
|
75
|
+
|
|
76
|
+
if raw_fname is None:
|
|
77
|
+
file_prop['ISO8601 Timestamp'] = start_time.strftime(
|
|
78
|
+
'%Y-%m-%dT%H:%M:%S.%f%z')
|
|
79
|
+
group_prop['Trigger Time'] = np.datetime64(start_time.remove_tz())
|
|
80
|
+
else:
|
|
81
|
+
if 'ISO8601 Timestamp' in file_prop.keys():
|
|
82
|
+
file_prop['ISO8601 Timestamp'] = start_time.strftime(
|
|
83
|
+
'%Y-%m-%dT%H:%M:%S.%f%z')
|
|
84
|
+
else:
|
|
85
|
+
for s in ['GPSTimeStamp', 'CPUTimeStamp', 'Trigger Time']:
|
|
86
|
+
if s in group_prop.keys():
|
|
87
|
+
group_prop[s] = np.datetime64(start_time.remove_tz())
|
|
88
|
+
break
|
|
89
|
+
|
|
90
|
+
if hasattr(sec, 'gauge_length'):
|
|
91
|
+
file_prop['GaugeLength'] = sec.gauge_length
|
|
92
|
+
|
|
93
|
+
with TdmsWriter(fname) as tdms_file:
|
|
94
|
+
root_object = RootObject(file_prop)
|
|
95
|
+
group_object = GroupObject(key, properties=group_prop)
|
|
96
|
+
if raw_fname and len(original_file[key]) == 1:
|
|
97
|
+
channel = ChannelObject(key, original_file[key].channels()[0].name,
|
|
98
|
+
sec.data.T.flatten(), properties={})
|
|
99
|
+
tdms_file.write_segment([root_object, group_object, channel])
|
|
100
|
+
else:
|
|
101
|
+
channel_list = []
|
|
102
|
+
for ch, d in enumerate(sec.data):
|
|
103
|
+
channel_list.append(ChannelObject(key,
|
|
104
|
+
str(ch + sec.start_channel),
|
|
105
|
+
d, properties={}))
|
|
106
|
+
|
|
107
|
+
tdms_file.write_segment([root_object, group_object] + channel_list)
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _update_h5_dataset(h5_file, path, name, data):
|
|
112
|
+
attrs = h5_file[path + name].attrs
|
|
113
|
+
del h5_file[path + name]
|
|
114
|
+
h5_file.get(path).create_dataset(name, data=data)
|
|
115
|
+
for key, value in attrs.items():
|
|
116
|
+
h5_file[path + name].attrs[key] = value
|
|
117
|
+
return None
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _write_h5(sec, fname, raw_fname=None):
|
|
121
|
+
if raw_fname is None:
|
|
122
|
+
with h5py.File(fname, 'w') as h5_file:
|
|
123
|
+
h5_file.create_group('Acquisition/Raw[0]')
|
|
124
|
+
h5_file.get('Acquisition/Raw[0]/').\
|
|
125
|
+
create_dataset('RawData', data=sec.data)
|
|
126
|
+
if isinstance(sec.start_time, datetime):
|
|
127
|
+
h5_file['Acquisition/Raw[0]/RawData'].attrs['PartStartTime'] = \
|
|
128
|
+
np.bytes_(
|
|
129
|
+
sec.start_time.strftime('%Y-%m-%dT%H:%M:%S.%f%z'))
|
|
130
|
+
stime = sec.start_time.timestamp() * 1e6
|
|
131
|
+
DataTime = np.arange(
|
|
132
|
+
stime, stime + sec.nt / sec.fs, 1 / sec.fs)
|
|
133
|
+
else:
|
|
134
|
+
h5_file['Acquisition/Raw[0]/RawData'].attrs['PartStartTime'] = \
|
|
135
|
+
np.bytes_(str(sec.start_time))
|
|
136
|
+
DataTime = sec.start_time + np.arange(0, sec.nt / sec.fs,
|
|
137
|
+
1 / sec.fs)
|
|
138
|
+
|
|
139
|
+
h5_file.get('Acquisition/Raw[0]/').\
|
|
140
|
+
create_dataset('RawDataTime', data=DataTime)
|
|
141
|
+
h5_file['Acquisition/Raw[0]'].attrs['OutputDataRate'] = sec.fs
|
|
142
|
+
h5_file['Acquisition'].attrs['SpatialSamplingInterval'] = sec.dx
|
|
143
|
+
if hasattr(sec, 'gauge_length'):
|
|
144
|
+
h5_file['Acquisition'].attrs['GaugeLength'] = sec.gauge_length
|
|
145
|
+
else:
|
|
146
|
+
h5_file['Acquisition'].attrs['GaugeLength'] = np.nan
|
|
147
|
+
else:
|
|
148
|
+
if not os.path.exists(fname) or not os.path.samefile(raw_fname, fname):
|
|
149
|
+
copyfile(raw_fname, fname)
|
|
150
|
+
with h5py.File(fname, 'r+') as h5_file:
|
|
151
|
+
group = list(h5_file.keys())[0]
|
|
152
|
+
if len(h5_file.keys()) == 10:
|
|
153
|
+
if h5_file['header/dimensionNames'][0] == b'time':
|
|
154
|
+
_update_h5_dataset(h5_file, '/', 'data', sec.data.T)
|
|
155
|
+
elif h5_file['header/dimensionNames'][0] == b'distance':
|
|
156
|
+
_update_h5_dataset(h5_file, '/', 'data', sec.data)
|
|
157
|
+
|
|
158
|
+
_update_h5_dataset(h5_file, 'header', 'dx', sec.dx)
|
|
159
|
+
_update_h5_dataset(h5_file, 'header', 'dt', 1 / sec.fs)
|
|
160
|
+
if isinstance(sec.start_time, datetime):
|
|
161
|
+
_update_h5_dataset(h5_file, 'header', 'time',
|
|
162
|
+
sec.start_time.timestamp())
|
|
163
|
+
else:
|
|
164
|
+
_update_h5_dataset(h5_file, 'header', 'time',
|
|
165
|
+
sec.start_time)
|
|
166
|
+
if hasattr(sec, 'gauge_length'):
|
|
167
|
+
_update_h5_dataset(h5_file, '/', 'gaugeLength',
|
|
168
|
+
sec.gauge_length)
|
|
169
|
+
if hasattr(sec, 'scale'):
|
|
170
|
+
_update_h5_dataset(h5_file, '/', 'dataScale', sec.scale)
|
|
171
|
+
elif len(h5_file.keys()) == 5:
|
|
172
|
+
_update_h5_dataset(h5_file, '/', 'strain', sec.data.T)
|
|
173
|
+
_update_h5_dataset(h5_file, '/', 'spatialsampling', sec.dx)
|
|
174
|
+
_update_h5_dataset(h5_file, '/', 'RepetitionFrequency', sec.fs)
|
|
175
|
+
if hasattr(sec, 'gauge_length'):
|
|
176
|
+
_update_h5_dataset(h5_file, '/', 'GaugeLength',
|
|
177
|
+
sec.gauge_length)
|
|
178
|
+
elif group == 'Acquisition':
|
|
179
|
+
h5_file['Acquisition'].attrs['NumberOfLoci'] = sec.nch
|
|
180
|
+
_update_h5_dataset(h5_file, 'Acquisition/Raw[0]/', 'RawData',
|
|
181
|
+
sec.data)
|
|
182
|
+
if isinstance(sec.start_time, datetime):
|
|
183
|
+
h5_file['Acquisition/Raw[0]/RawData'].\
|
|
184
|
+
attrs['PartStartTime'] = np.bytes_(
|
|
185
|
+
sec.start_time.strftime('%Y-%m-%dT%H:%M:%S.%f%z'))
|
|
186
|
+
stime = sec.start_time.timestamp() * 1e6
|
|
187
|
+
DataTime = np.arange(
|
|
188
|
+
stime, stime + sec.nt / sec.fs, 1 / sec.fs)
|
|
189
|
+
else:
|
|
190
|
+
h5_file['Acquisition/Raw[0]/RawData'].\
|
|
191
|
+
attrs['PartStartTime'] = np.bytes_(str(sec.start_time))
|
|
192
|
+
DataTime = sec.start_time + np.arange(0, sec.nt / sec.fs,
|
|
193
|
+
1 / sec.fs)
|
|
194
|
+
_update_h5_dataset(h5_file, 'Acquisition/Raw[0]/',
|
|
195
|
+
'RawDataTime', DataTime)
|
|
196
|
+
h5_file['Acquisition/Raw[0]'].attrs['OutputDataRate'] = sec.fs
|
|
197
|
+
h5_file['Acquisition'].attrs['SpatialSamplingInterval'] = sec.dx
|
|
198
|
+
if hasattr(sec, 'gauge_length'):
|
|
199
|
+
h5_file['Acquisition'].attrs['GaugeLength'] = \
|
|
200
|
+
sec.gauge_length
|
|
201
|
+
elif group == 'raw':
|
|
202
|
+
_update_h5_dataset(h5_file, '/', 'raw', sec.data)
|
|
203
|
+
DataTime = sec.start_time.timestamp() + \
|
|
204
|
+
np.arange(0, sec.nt / sec.fs, 1 / sec.fs)
|
|
205
|
+
_update_h5_dataset(h5_file, '/', 'timestamp', DataTime)
|
|
206
|
+
elif group == 'data_product':
|
|
207
|
+
_update_h5_dataset(h5_file, 'data_product/', 'data', sec.data)
|
|
208
|
+
h5_file.attrs['dt_computer'] = 1 / sec.fs
|
|
209
|
+
h5_file.attrs['dx'] = sec.dx
|
|
210
|
+
h5_file.attrs['gauge_length'] = sec.gauge_length
|
|
211
|
+
DataTime = sec.start_time.timestamp() + \
|
|
212
|
+
np.arange(0, sec.nt / sec.fs, 1 / sec.fs)
|
|
213
|
+
if h5_file.attrs['saving_start_gps_time'] > 0:
|
|
214
|
+
h5_file.attrs['file_start_gps_time'] = \
|
|
215
|
+
sec.start_time.timestamp()
|
|
216
|
+
_update_h5_dataset(h5_file, 'data_product/', 'gps_time',
|
|
217
|
+
DataTime)
|
|
218
|
+
del h5_file['data_product/posix_time']
|
|
219
|
+
else:
|
|
220
|
+
h5_file.attrs['file_start_computer_time'] = \
|
|
221
|
+
sec.start_time.timestamp()
|
|
222
|
+
_update_h5_dataset(h5_file, 'data_product/', 'posix_time',
|
|
223
|
+
DataTime)
|
|
224
|
+
del h5_file['data_product/gps_time']
|
|
225
|
+
h5_file.attrs['data_product'] = sec.data_type
|
|
226
|
+
else:
|
|
227
|
+
acquisition = list(h5_file[f'{group}/Source1/Zone1'].keys())[0]
|
|
228
|
+
data = sec.data
|
|
229
|
+
fs = int(sec.fs)
|
|
230
|
+
d = len(h5_file[f'{group}/Source1/Zone1/{acquisition}'].shape)
|
|
231
|
+
if d == 3:
|
|
232
|
+
mod = sec.nt % fs
|
|
233
|
+
if mod:
|
|
234
|
+
data = np.hstack((data, np.zeros((sec.nch, fs - mod))))
|
|
235
|
+
data = data.reshape((sec.nch, fs, sec.nt//fs)).T
|
|
236
|
+
elif d == 2:
|
|
237
|
+
data = data.T
|
|
238
|
+
_update_h5_dataset(h5_file, f'{group}/Source1/Zone1/',
|
|
239
|
+
acquisition, data)
|
|
240
|
+
|
|
241
|
+
h5_file[f'{group}/Source1/Zone1'].attrs['Spacing'][0] = sec.dx
|
|
242
|
+
h5_file[f'{group}/Source1/Zone1'].attrs['FreqRes'] = \
|
|
243
|
+
np.bytes_(sec.fs)
|
|
244
|
+
h5_file[f'{group}/Source1/Zone1'].attrs['SamplingRate'][0] = \
|
|
245
|
+
sec.fs
|
|
246
|
+
h5_file[f'{group}/Source1/Zone1'].attrs['Extent'][0] = \
|
|
247
|
+
sec.start_channel
|
|
248
|
+
h5_file[f'{group}/Source1/Zone1'].attrs['Origin'][0] = \
|
|
249
|
+
sec.start_distance
|
|
250
|
+
h5_file[f'{group}/Source1/Zone1'].attrs['GaugeLength'][0] = \
|
|
251
|
+
sec.gauge_length
|
|
252
|
+
DataTime = sec.start_time.timestamp() + \
|
|
253
|
+
np.arange(0, sec.nt / sec.fs, 1 / sec.fs)
|
|
254
|
+
_update_h5_dataset(h5_file, f'{group}/Source1/',
|
|
255
|
+
'time', DataTime.reshape((1, -1)))
|
|
256
|
+
|
|
257
|
+
return None
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def _write_segy(sec, fname, raw_fname=None):
|
|
261
|
+
spec = segyio.spec()
|
|
262
|
+
spec.samples = np.arange(sec.nt) / sec.fs * 1e3
|
|
263
|
+
spec.tracecount = sec.nch
|
|
264
|
+
if raw_fname is None:
|
|
265
|
+
spec.format = 1
|
|
266
|
+
with segyio.create(fname, spec) as new_file:
|
|
267
|
+
new_file.header.length = sec.nch
|
|
268
|
+
new_file.header.segy._filename = fname
|
|
269
|
+
new_file.trace = sec.data.astype(np.float32)
|
|
270
|
+
else:
|
|
271
|
+
with segyio.open(raw_fname, ignore_geometry=True) as raw_file:
|
|
272
|
+
spec.sorting = raw_file.sorting
|
|
273
|
+
spec.format = raw_file.format
|
|
274
|
+
raw_file.header.length = sec.nch
|
|
275
|
+
raw_file.header.segy._filename = fname
|
|
276
|
+
with segyio.create(fname, spec) as new_file:
|
|
277
|
+
new_file.text[0] = raw_file.text[0]
|
|
278
|
+
new_file.header = raw_file.header
|
|
279
|
+
new_file.trace = sec.data.astype(raw_file.trace.dtype)
|
|
280
|
+
|
|
281
|
+
warnings.warn('This data format doesn\'t include channel interval.')
|
|
282
|
+
return None
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from daspy.seismic_detection.core import DetectSection
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import multiprocessing
|
|
4
|
+
import numpy as np
|
|
5
|
+
from obspy.taup.tau_model import TauModel
|
|
6
|
+
from obspy.taup import TauPyModel
|
|
7
|
+
from daspy.seismic_detection.location import calc_travel_time
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
cores = multiprocessing.cpu_count() - 1
|
|
11
|
+
pool = multiprocessing.Pool(processes=cores)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
filepath, elo, ela, edep, savefile = sys.argv[1:6]
|
|
15
|
+
|
|
16
|
+
elo, ela, edep = map(float, (elo, ela, edep))
|
|
17
|
+
model = TauPyModel()
|
|
18
|
+
model.model = TauModel.from_file(os.path.join(filepath, 'model.npz'))
|
|
19
|
+
geometry = np.load(os.path.join(filepath, 'geometry.npy'))
|
|
20
|
+
tasks = [(model, elo, ela, edep, *geo) for geo in geometry]
|
|
21
|
+
delay = pool.starmap(calc_travel_time, tasks)
|
|
22
|
+
delay = np.array(delay)
|
|
23
|
+
np.save(os.path.join(filepath, savefile), delay)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import daspy.basic_tools.visualization as DBV
|
|
3
|
+
from daspy.core import Section, DASDateTime
|
|
4
|
+
from daspy.seismic_detection.phase_picking import *
|
|
5
|
+
|
|
6
|
+
def plot(data, obj='waveform', title=None, cmap=None, vmax=None, vmin=None,
|
|
7
|
+
**kwargs):
|
|
8
|
+
if obj == 'pickmap':
|
|
9
|
+
cmap = 'hot' if cmap is None else cmap
|
|
10
|
+
vmax = np.percentile(abs(data), 99) if vmax is None else vmax
|
|
11
|
+
vmin = np.percentile(abs(data), 80) if vmin is None else vmin
|
|
12
|
+
title = obj
|
|
13
|
+
obj = 'waveform'
|
|
14
|
+
|
|
15
|
+
return DBV.plot(data, title=title, cmap=cmap, vmin=vmin, vmax=vmax,
|
|
16
|
+
**kwargs)
|
|
17
|
+
|
|
18
|
+
class DetectSection(Section):
|
|
19
|
+
|
|
20
|
+
def __str__(self):
|
|
21
|
+
describe = ''
|
|
22
|
+
n = max(map(len, self.__dict__.keys()))
|
|
23
|
+
for key, value in self.__dict__.items():
|
|
24
|
+
if key in ['data', 'geometry', 'pickmap']:
|
|
25
|
+
describe = '{}: shape{}\n'.format(key.rjust(n), value.shape) \
|
|
26
|
+
+ describe
|
|
27
|
+
elif key in ['dx', 'start_distance', 'gauge_length']:
|
|
28
|
+
describe += '{}: {} m\n'.format(key.rjust(n), value)
|
|
29
|
+
elif key == 'fs':
|
|
30
|
+
describe += '{}: {} Hz\n'.format(key.rjust(n), value)
|
|
31
|
+
elif key == 'start_time':
|
|
32
|
+
if isinstance(value, DASDateTime):
|
|
33
|
+
describe += '{}: {}\n'.format(key.rjust(n), value)
|
|
34
|
+
else:
|
|
35
|
+
describe += '{}: {} s\n'.format(key.rjust(n), value)
|
|
36
|
+
elif key == 'pick':
|
|
37
|
+
describe += '{}: {}\n'.format(key.rjust(n), len(value))
|
|
38
|
+
else:
|
|
39
|
+
describe += '{}: {}\n'.format(key.rjust(n), value)
|
|
40
|
+
return describe
|
|
41
|
+
|
|
42
|
+
__repr__ = __str__
|
|
43
|
+
|
|
44
|
+
def plot(self, obj='waveform', kwargs_pro={}, **kwargs):
|
|
45
|
+
if obj == 'pickmap':
|
|
46
|
+
if 'data' not in kwargs.keys():
|
|
47
|
+
if not hasattr(self, 'pick_map') or len(kwargs_pro):
|
|
48
|
+
self.calc_pickmap(**kwargs_pro)
|
|
49
|
+
kwargs['data']= self.pickmap
|
|
50
|
+
if 'cmap' not in kwargs.keys():
|
|
51
|
+
kwargs['cmap'] = 'hot'
|
|
52
|
+
if 'vmax' not in kwargs.keys():
|
|
53
|
+
kwargs['vmax'] = np.percentile(abs(kwargs['data']), 99.9)
|
|
54
|
+
if 'vmin' not in kwargs.keys():
|
|
55
|
+
kwargs['vmin'] = np.percentile(abs(kwargs['data']), 95)
|
|
56
|
+
if 'title' not in kwargs.keys():
|
|
57
|
+
kwargs['title'] = obj
|
|
58
|
+
obj = 'waveform'
|
|
59
|
+
elif obj == 'phasepick':
|
|
60
|
+
if 'data' not in kwargs.keys():
|
|
61
|
+
kwargs['data']= self.data
|
|
62
|
+
if 'pick' not in kwargs.keys():
|
|
63
|
+
if not hasattr(self, 'pick') or len(kwargs_pro):
|
|
64
|
+
self.map_picking(**kwargs_pro)
|
|
65
|
+
kwargs['pick'] = self.pick
|
|
66
|
+
if len(kwargs['pick']):
|
|
67
|
+
kwargs['pick'][:, 0] -= self.start_channel
|
|
68
|
+
|
|
69
|
+
super().plot(obj=obj, kwargs_pro=kwargs_pro, **kwargs)
|
|
70
|
+
|
|
71
|
+
def calc_pickmap(self, method='sta_lta', **kwargs):
|
|
72
|
+
if isinstance(method, str):
|
|
73
|
+
method = [method]
|
|
74
|
+
self.pickmap = np.zeros_like(self.data)
|
|
75
|
+
for m in method:
|
|
76
|
+
if m == 'sta_lta':
|
|
77
|
+
self.pickmap += sta_lta_map(self.data, self.fs, **kwargs)
|
|
78
|
+
elif m == 'kurto':
|
|
79
|
+
self.pickmap += kurto_map(self.data, self.fs, **kwargs)
|
|
80
|
+
elif m == 'skew':
|
|
81
|
+
self.pickmap += skew_map(self.data, self.fs, **kwargs)
|
|
82
|
+
|
|
83
|
+
return self.pickmap
|
|
84
|
+
|
|
85
|
+
def map_picking(self, thres1=5, thres2=5, choose_max=False, min_dt=None,
|
|
86
|
+
**kwargs):
|
|
87
|
+
if not hasattr(self, 'pick_map') or len(kwargs):
|
|
88
|
+
self.calc_pickmap(**kwargs)
|
|
89
|
+
|
|
90
|
+
pick = map_picking(self.pickmap, thres1=thres1, thres2=thres2,
|
|
91
|
+
choose_max=choose_max,
|
|
92
|
+
min_dsp=min_dt*self.fs).astype(float)
|
|
93
|
+
if len(pick):
|
|
94
|
+
pick[:, 0] += self.start_channel
|
|
95
|
+
pick[:, 1] = pick[:, 1] / self.fs
|
|
96
|
+
|
|
97
|
+
self.pick = pick
|
|
98
|
+
return pick
|
|
99
|
+
|
|
100
|
+
def symmetry_detection(self, win=5000):
|
|
101
|
+
sec = self.copy()
|
|
102
|
+
sec.normalization()
|
|
103
|
+
win_ch = round(win / self.dx)
|
|
104
|
+
cc = np.zeros(self.nch)
|
|
105
|
+
for sch in range(self.nch):
|
|
106
|
+
win_ch_use = min(win_ch, sch, sec.nch-sch-1)
|
|
107
|
+
if win_ch_use > 0:
|
|
108
|
+
panel1 = sec.data[sch-win_ch_use:sch]
|
|
109
|
+
panel1 = panel1[::-1]
|
|
110
|
+
panel2 = sec.data[sch+1:sch+win_ch_use+1]
|
|
111
|
+
cc[sch] = np.sum(panel1 * panel2) / win_ch
|
|
112
|
+
self.signal_channel = self.start_channel + np.argmax(cc)
|
|
113
|
+
return cc / sec.nt
|
|
114
|
+
|
|
115
|
+
@classmethod
|
|
116
|
+
def from_section(clc, raw_sec):
|
|
117
|
+
raw_dict = raw_sec.__dict__
|
|
118
|
+
data = raw_dict.pop('data')
|
|
119
|
+
return clc(data, **raw_dict)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The :mod:`sklearn.mixture` module implements mixture modeling algorithms.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from ._gaussian_mixture import GaussianMixture
|
|
6
|
+
from ._bayesian_mixture import BayesianGaussianMixture
|
|
7
|
+
# from .seismic_ops import *
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
__all__ = ['GaussianMixture',
|
|
11
|
+
'BayesianGaussianMixture',
|
|
12
|
+
'seismic_ops',
|
|
13
|
+
'utils']
|