Compare commits

..

1 Commits

Author SHA1 Message Date
053b1ce397 [initial] first implementation of residual plotting (WIP) 2024-09-16 16:29:14 +02:00
10 changed files with 205 additions and 221 deletions

10
PyLoT.py Executable file → Normal file
View File

@ -1537,8 +1537,8 @@ class MainWindow(QMainWindow):
return True
return not bool(os.listdir(wf_path))
def filename_from_action(self, action):
if action.data() is None:
def filename_from_action(self, action=None):
if not action or action.data() is None:
filt = "Supported file formats" \
" (*.mat *.qml *.xml *.kor *.evt)"
caption = "Open an event file"
@ -3590,7 +3590,7 @@ class MainWindow(QMainWindow):
def calc_magnitude(self):
self.init_metadata()
if not self.metadata:
return []
return None
wf_copy = self.get_data().getWFData().copy()
@ -3599,10 +3599,6 @@ class MainWindow(QMainWindow):
for station in np.unique(list(self.getPicks('manual').keys()) + list(self.getPicks('auto').keys())):
wf_select += wf_copy.select(station=station)
if not wf_select:
logging.warning('Empty Stream in calc_magnitude. Return.')
return []
corr_wf = restitute_data(wf_select, self.metadata)
# calculate moment magnitude
moment_mag = MomentMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('vp'),

View File

@ -63,9 +63,6 @@ You may need to do some modifications to these files. Especially folder names sh
PyLoT has been tested on Mac OSX (10.11), Debian Linux 8 and on Windows 10/11.
## Example Dataset
An example dataset with waveform data, metadata and automatic picks in the obspy-dmt dataset format for testing the teleseismic picking can be found at https://zenodo.org/doi/10.5281/zenodo.13759803
## Release notes
#### Features:

View File

@ -1,77 +0,0 @@
# Pick-Correlation Correction
## Introduction
Currently, the pick-correlation correction algorithm is not accessible from they PyLoT GUI. The main file *pick_correlation_correction.py* is located in the directory *pylot\correlation*.
The program only works for an obspy dmt database structure.
The basic workflow of the algorithm is shown in the following diagram. The first step **(1)** is the normal (automatic) picking procedure in PyLoT. Everything from step **(2)** to **(5)** is part of the correlation correction algorithm.
*Note: The first step is not required in case theoretical onsets are used instead of external picks when the parameter use_taupy_onsets is set to True. However, an existing event quakeML (.xml) file generated by PyLoT might be required for each event in case not external picks are used.*
![images/workflow_stacking.png](images/workflow_stacking.png)
A detailed description of the algorithm can be found in the corresponding publication:
*Paffrath, M., Friederich, W., and the AlpArray and AlpArray-SWATH D Working Groups: Teleseismic P waves at the AlpArray seismic network: wave fronts, absolute travel times and travel-time residuals, Solid Earth, 12, 16351660, https://doi.org/10.5194/se-12-1635-2021, 2021.*
## How to use
To use the program you have to call the main program providing two mandatory arguments: a path to the obspy dmt database folder *dmt_database_path* and the path to the PyLoT infile *pylot.in* for picking of the beam trace:
```python pick_correlation_correction.py dmt_database_path pylot.in```
By default, the parameter file *parameters.yaml* is used. You can use the command line option *--params* to specify a different parameter file and other optional arguments such as *-pd* for plotting detailed information or *-n 4* to use 4 cores for parallel processing:
```python pick_correlation_correction.py dmt_database_path pylot.in --params parameters_adriaarray.yaml -pd -n 4```
## Cross-Correlation Parameters
The program uses the parameters in the file *parameters.yaml* by default. You can use the command line option *--params* to specify a different parameter file. An example of the parameter file is provided in the *correlation\parameters.yaml* file.
In the top level of the parameter file the logging level *logging* can be set, as well as a list of pick phases *pick_phases* (e.g. ['P', 'S']).
For each pick phase the different parameters can be set in the first sub-level of the parameter file, e.g.:
```yaml
logging: info
pick_phases: ['P', 'S']
P:
min_corr_stacking: 0.8
min_corr_export: 0.6
[...]
S:
min_corr_stacking: 0.7
[...]
```
The following parameters are available:
| Parameter Name | Description | Parameter Type |
|--------------------------------|----------------------------------------------------------------------------------------------------|----------------|
| min_corr_stacking | Minimum correlation coefficient for building beam trace | float |
| min_corr_export | Minimum correlation coefficient for pick export | float |
| min_stack | Minimum number of stations for building beam trace | int |
| t_before | Correlation window before reference pick | float |
| t_after | Correlation window after reference pick | float |
| cc_maxlag | Maximum shift for initial correlation | float |
| cc_maxlag2 | Maximum shift for second (final) correlation (also for calculating pick uncertainty) | float |
| initial_pick_outlier_threshold | Threshold for excluding large outliers of initial (AIC) picks | float |
| export_threshold | Automatically exclude all onsets which deviate more than this threshold from corrected taup onsets | float |
| min_picks_export | Minimum number of correlated picks for export | int |
| min_picks_autopylot | Minimum number of reference auto picks to continue with event | int |
| check_RMS | Do RMS check to search for restitution errors (very experimental) | bool |
| use_taupy_onsets | Use taupy onsets as reference picks instead of external picks | bool |
| station_list | Use the following stations as reference for stacking | list[str] |
| use_stacked_trace | Use existing stacked trace if found (spare re-computation) | bool |
| data_dir | obspyDMT data subdirectory (e.g. 'raw', 'processed') | str |
| pickfile_extension | Use quakeML files (PyLoT output) with the following extension | str |
| dt_stacking | Time difference for stacking window (in seconds) | list[float] |
| filter_options | Filter for first correlation (rough) | dict |
| filter_options_final | Filter for second correlation (fine) | dict |
| filter_type | Filter type (e.g. bandpass) | str |
| sampfreq | Sampling frequency (in Hz) | float |
## Example Dataset
An example dataset with waveform data, metadata and automatic picks in the obspy-dmt dataset format for testing can be found at https://zenodo.org/doi/10.5281/zenodo.13759803

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

View File

@ -6,123 +6,122 @@ A description of the parameters used for determining automatic picks.
Parameters applied to the traces before picking algorithm starts.
| Name | Description |
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| *P Start*, *P | |
| Stop* | Define time interval relative to trace start time for CF calculation on vertical trace. Value is relative to theoretical onset time if 'Use TauPy' option is enabled in main settings of 'Tune Autopicker' dialogue. |
| *S Start*, *S | |
| Stop* | Define time interval relative to trace start time for CF calculation on horizontal traces. Value is relative to theoretical onset time if 'Use TauPy' option is enabled in main settings of 'Tune Autopicker' dialogue. |
| *Bandpass | |
| Z1* | Filter settings for Butterworth bandpass applied to vertical trace for calculation of initial P pick. |
| *Bandpass | |
| Z2* | Filter settings for Butterworth bandpass applied to vertical trace for calculation of precise P pick. |
| *Bandpass | |
| H1* | Filter settings for Butterworth bandpass applied to horizontal traces for calculation of initial S pick. |
| *Bandpass | |
| H2* | Filter settings for Butterworth bandpass applied to horizontal traces for calculation of precise S pick. |
| Name | Description |
|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| *P Start*, *P
Stop* | Define time interval relative to trace start time for CF calculation on vertical trace. Value is relative to theoretical onset time if 'Use TauPy' option is enabled in main settings of 'Tune Autopicker' dialogue. |
| *S Start*, *S
Stop* | Define time interval relative to trace start time for CF calculation on horizontal traces. Value is relative to theoretical onset time if 'Use TauPy' option is enabled in main settings of 'Tune Autopicker' dialogue. |
| *Bandpass
Z1* | Filter settings for Butterworth bandpass applied to vertical trace for calculation of initial P pick. |
| *Bandpass
Z2* | Filter settings for Butterworth bandpass applied to vertical trace for calculation of precise P pick. |
| *Bandpass
H1* | Filter settings for Butterworth bandpass applied to horizontal traces for calculation of initial S pick. |
| *Bandpass
H2* | Filter settings for Butterworth bandpass applied to horizontal traces for calculation of precise S pick. |
## Inital P pick
Parameters used for determination of initial P pick.
| Name | Description |
|-------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
| * | |
| tLTA* | Size of gliding LTA window in seconds used for calculation of HOS-CF. |
| *pickwin | |
| P* | Size of time window in seconds in which the minimum of the AIC-CF in front of the maximum of the HOS-CF is determined. |
| * | |
| AICtsmooth* | Average of samples in this time window will be used for smoothing of the AIC-CF. |
| * | |
| checkwinP* | Time in front of the global maximum of the HOS-CF in which to search for a second local extrema. |
| *minfactorP* | Used with * |
| checkwinP*. If a second local maximum is found, it has to be at least as big as the first maximum * *minfactorP*. | |
| * | |
| tsignal* | Time window in seconds after the initial P pick used for determining signal amplitude. |
| * | |
| tnoise* | Time window in seconds in front of initial P pick used for determining noise amplitude. |
| *tsafetey* | Time in seconds between *tsignal* and * |
| tnoise*. | |
| * | |
| tslope* | Time window in seconds after initial P pick in which the slope of the onset is calculated. |
| Name | Description |
|--------------|------------------------------------------------------------------------------------------------------------------------------|
| *
tLTA* | Size of gliding LTA window in seconds used for calculation of HOS-CF. |
| *pickwin
P* | Size of time window in seconds in which the minimum of the AIC-CF in front of the maximum of the HOS-CF is determined. |
| *
AICtsmooth* | Average of samples in this time window will be used for smoothing of the AIC-CF. |
| *
checkwinP* | Time in front of the global maximum of the HOS-CF in which to search for a second local extrema. |
| *minfactorP* | Used with *
checkwinP*. If a second local maximum is found, it has to be at least as big as the first maximum * *minfactorP*. |
| *
tsignal* | Time window in seconds after the initial P pick used for determining signal amplitude. |
| *
tnoise* | Time window in seconds in front of initial P pick used for determining noise amplitude. |
| *tsafetey* | Time in seconds between *tsignal* and *
tnoise*. |
| *
tslope* | Time window in seconds after initial P pick in which the slope of the onset is calculated. |
## Inital S pick
Parameters used for determination of initial S pick
| Name | Description |
|-------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------|
| * | |
| tdet1h* | Length of time window in seconds in which AR params of the waveform are determined. |
| * | |
| tpred1h* | Length of time window in seconds in which the waveform is predicted using the AR model. |
| * | |
| AICtsmoothS* | Average of samples in this time window is used for smoothing the AIC-CF. |
| * | |
| pickwinS* | Time window in which the minimum in the AIC-CF in front of the maximum in the ARH-CF is determined. |
| * | |
| checkwinS* | Time in front of the global maximum of the ARH-CF in which to search for a second local extrema. |
| *minfactorP* | Used with * |
| checkwinS*. If a second local maximum is found, it has to be at least as big as the first maximum * *minfactorS*. | |
| * | |
| tsignal* | Time window in seconds after the initial P pick used for determining signal amplitude. |
| * | |
| tnoise* | Time window in seconds in front of initial P pick used for determining noise amplitude. |
| *tsafetey* | Time in seconds between *tsignal* and * |
| tnoise*. | |
| * | |
| tslope* | Time window in seconds after initial P pick in which the slope of the onset is calculated. |
| Name | Description |
|---------------|------------------------------------------------------------------------------------------------------------------------------|
| *
tdet1h* | Length of time window in seconds in which AR params of the waveform are determined. |
| *
tpred1h* | Length of time window in seconds in which the waveform is predicted using the AR model. |
| *
AICtsmoothS* | Average of samples in this time window is used for smoothing the AIC-CF. |
| *
pickwinS* | Time window in which the minimum in the AIC-CF in front of the maximum in the ARH-CF is determined. |
| *
checkwinS* | Time in front of the global maximum of the ARH-CF in which to search for a second local extrema. |
| *minfactorP* | Used with *
checkwinS*. If a second local maximum is found, it has to be at least as big as the first maximum * *minfactorS*. |
| *
tsignal* | Time window in seconds after the initial P pick used for determining signal amplitude. |
| *
tnoise* | Time window in seconds in front of initial P pick used for determining noise amplitude. |
| *tsafetey* | Time in seconds between *tsignal* and *
tnoise*. |
| *
tslope* | Time window in seconds after initial P pick in which the slope of the onset is calculated. |
## Precise P pick
Parameters used for determination of precise P pick.
| Name | Description |
|-------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| *Precalcwin* | Time window in seconds for recalculation of the HOS-CF. The new CF will be two times the size of * |
| Precalcwin*, since it will be calculated from the initial pick to +/- *Precalcwin*. | |
| * | |
| tsmoothP* | Average of samples in this time window will be used for smoothing the second HOS-CF. |
| * | |
| ausP* | Controls artificial uplift of samples during precise picking. A common local minimum of the smoothed and unsmoothed HOS-CF is found when the previous sample is larger or equal to the current sample times (1+* |
| ausP*). | |
| Name | Description |
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| *Precalcwin* | Time window in seconds for recalculation of the HOS-CF. The new CF will be two times the size of *
Precalcwin*, since it will be calculated from the initial pick to +/- *Precalcwin*. |
| *
tsmoothP* | Average of samples in this time window will be used for smoothing the second HOS-CF. |
| *
ausP* | Controls artificial uplift of samples during precise picking. A common local minimum of the smoothed and unsmoothed HOS-CF is found when the previous sample is larger or equal to the current sample times (1+*
ausP*). |
## Precise S pick
Parameters used for determination of precise S pick.
| Name | Description |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| * | |
| tdet2h* | Time window for determination of AR coefficients. |
| * | |
| tpred2h* | Time window in which the waveform is predicted using the determined AR parameters. |
| *Srecalcwin* | Time window for recalculation of ARH-CF. New CF will be calculated from initial pick +/- * |
| Srecalcwin*. | |
| * | |
| tsmoothS* | Average of samples in this time window will be used for smoothing the second ARH-CF. |
| * | |
| ausS* | Controls artificial uplift of samples during precise picking. A common local minimum of the smoothed and unsmoothed ARH-CF is found when the previous sample is larger or equal to the current sample times (1+* |
| ausS*). | |
| * | |
| pickwinS* | Time window around initial pick in which to look for a precise pick. |
| Name | Description |
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| *
tdet2h* | Time window for determination of AR coefficients. |
| *
tpred2h* | Time window in which the waveform is predicted using the determined AR parameters. |
| *Srecalcwin* | Time window for recalculation of ARH-CF. New CF will be calculated from initial pick +/- *
Srecalcwin*. |
| *
tsmoothS* | Average of samples in this time window will be used for smoothing the second ARH-CF. |
| *
ausS* | Controls artificial uplift of samples during precise picking. A common local minimum of the smoothed and unsmoothed ARH-CF is found when the previous sample is larger or equal to the current sample times (1+*
ausS*). |
| *
pickwinS* | Time window around initial pick in which to look for a precise pick. |
## Pick quality control
Parameters used for checking quality and integrity of automatic picks.
| Name | Description |
|--------------------------------------------|-----------------------------------------------------------------------|
| * | |
| minAICPslope* | Initial P picks with a slope lower than this value will be discared. |
| * | |
| minAICPSNR* | Initial P picks with a SNR below this value will be discarded. |
| * | |
| minAICSslope* | Initial S picks with a slope lower than this value will be discarded. |
| * | |
| minAICSSNR* | Initial S picks with a SNR below this value will be discarded. |
| *minsiglength*, *noisefacor*. *minpercent* | Parameters for checking signal length. In the time window of size * |
| Name | Description |
|--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| *
minAICPslope* | Initial P picks with a slope lower than this value will be discared. |
| *
minAICPSNR* | Initial P picks with a SNR below this value will be discarded. |
| *
minAICSslope* | Initial S picks with a slope lower than this value will be discarded. |
| *
minAICSSNR* | Initial S picks with a SNR below this value will be discarded. |
| *minsiglength*, *noisefacor*. *minpercent* | Parameters for checking signal length. In the time window of size *
minsiglength* after the initial P pick *
minpercent* of samples have to be larger than the RMS value. |
| *
@ -140,12 +139,12 @@ wdttolerance* | Maximum allowed deviation of S onset
Parameters for discrete quality classes.
| Name | Description |
|--------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| * | |
| timeerrorsP* | Width of the time windows in seconds between earliest and latest possible pick which represent the quality classes 0, 1, 2, 3 for P onsets. |
| * | |
| timeerrorsS* | Width of the time windows in seconds between earliest and latest possible pick which represent the quality classes 0, 1, 2, 3 for S onsets. |
| *nfacP*, *nfacS* | For determination of latest possible onset time. The time when the signal reaches an amplitude of * |
| nfac* * mean value of the RMS amplitude in the time window *tnoise* corresponds to the latest possible onset time. | |
| Name | Description |
|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| *
timeerrorsP* | Width of the time windows in seconds between earliest and latest possible pick which represent the quality classes 0, 1, 2, 3 for P onsets. |
| *
timeerrorsS* | Width of the time windows in seconds between earliest and latest possible pick which represent the quality classes 0, 1, 2, 3 for S onsets. |
| *nfacP*, *nfacS* | For determination of latest possible onset time. The time when the signal reaches an amplitude of *
nfac* * mean value of the RMS amplitude in the time window *tnoise* corresponds to the latest possible onset time. |

View File

@ -218,12 +218,14 @@ def picksdict_from_obs(fn):
return picks
def picksdict_from_picks(evt, parameter=None):
def picksdict_from_picks(evt, parameter=None, nwst_id: bool = False):
"""
Takes an Event object and return the pick dictionary commonly used within
PyLoT
:param evt: Event object contain all available information
:type evt: `~obspy.core.event.Event`
:param nwst_id: determines if network and station id are used or only station id
:type nwst_id: bool
:return: pick dictionary (auto and manual)
"""
picksdict = {
@ -233,7 +235,10 @@ def picksdict_from_picks(evt, parameter=None):
for pick in evt.picks:
errors = None
phase = {}
station = pick.waveform_id.station_code
if not nwst_id:
station_or_nwst = pick.waveform_id.station_code
else:
station_or_nwst = f'{pick.waveform_id.station_code}.{pick.waveform_id.network_code}'
if pick.waveform_id.channel_code is None:
channel = ''
else:
@ -254,7 +259,7 @@ def picksdict_from_picks(evt, parameter=None):
if pick_method == 'None':
pick_method = 'manual'
try:
onsets = picksdict[pick_method][station]
onsets = picksdict[pick_method][station_or_nwst]
except KeyError as e:
# print(e)
onsets = {}
@ -301,7 +306,7 @@ def picksdict_from_picks(evt, parameter=None):
phase['filter_id'] = filter_id if filter_id is not None else ''
onsets[pick.phase_hint] = phase.copy()
picksdict[pick_method][station] = onsets.copy()
picksdict[pick_method][station_or_nwst] = onsets.copy()
return picksdict

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import copy
import traceback
import cartopy.crs as ccrs
@ -16,6 +16,8 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from obspy import UTCDateTime
from pylot.core.io.data import Data
from pylot.core.io.phases import picksdict_from_picks
from pylot.core.util.utils import identifyPhaseID
from scipy.interpolate import griddata
@ -41,6 +43,7 @@ class MplCanvas(FigureCanvas):
class Array_map(QtWidgets.QWidget):
def __init__(self, parent, metadata, parameter=None, axes=None, annotate=True, pointsize=25.,
linewidth=1.5, width=5e6, height=2e6):
QtWidgets.QWidget.__init__(self, parent=parent)
assert (parameter is not None or parent is not None), 'either parent or parameter has to be set'
@ -58,6 +61,8 @@ class Array_map(QtWidgets.QWidget):
self.uncertainties = None
self.autopicks_dict = None
self.hybrids_dict = None
self.picks_dict_ref = None
self.autopicks_dict_ref = None
self.eventLoc = None
self.parameter = parameter if parameter else parent._inputs
@ -108,8 +113,10 @@ class Array_map(QtWidgets.QWidget):
self.status_label = QtWidgets.QLabel()
self.map_reset_button = QtWidgets.QPushButton('Reset Map View')
self.save_map_button = QtWidgets.QPushButton('Save Map')
self.load_reference_picks_button = QtWidgets.QPushButton('Load reference picks.')
self.go2eq_button = QtWidgets.QPushButton('Go to Event Location')
self.subtract_mean_cb = QtWidgets.QCheckBox('Subtract mean')
self.subtract_ref_cb = QtWidgets.QCheckBox('Subtract reference onsets')
self.main_box = QtWidgets.QVBoxLayout()
self.setLayout(self.main_box)
@ -134,8 +141,8 @@ class Array_map(QtWidgets.QWidget):
self.cmaps_box = QtWidgets.QComboBox()
self.cmaps_box.setMaxVisibleItems(20)
[self.cmaps_box.addItem(map_name) for map_name in sorted(plt.colormaps())]
# try to set to plasma as default
self.cmaps_box.setCurrentIndex(self.cmaps_box.findText('plasma'))
# try to set to viridis as default
self.cmaps_box.setCurrentIndex(self.cmaps_box.findText('viridis'))
self.top_row.addWidget(QtWidgets.QLabel('Select a phase: '))
self.top_row.addWidget(self.comboBox_phase)
@ -156,7 +163,9 @@ class Array_map(QtWidgets.QWidget):
self.bot_row.addWidget(self.map_reset_button, 2)
self.bot_row.addWidget(self.go2eq_button, 2)
self.bot_row.addWidget(self.save_map_button, 2)
self.bot_row.addWidget(self.load_reference_picks_button, 2)
self.bot_row.addWidget(self.subtract_mean_cb, 0)
self.bot_row.addWidget(self.subtract_ref_cb, 0)
self.bot_row.addWidget(self.status_label, 5)
def init_colormap(self):
@ -217,7 +226,9 @@ class Array_map(QtWidgets.QWidget):
self.map_reset_button.clicked.connect(self.org_map_view)
self.go2eq_button.clicked.connect(self.go2eq)
self.save_map_button.clicked.connect(self.saveFigure)
self.load_reference_picks_button.clicked.connect(self.load_reference_picks)
self.subtract_mean_cb.stateChanged.connect(self.toggle_subtract_mean)
self.subtract_ref_cb.stateChanged.connect(self.toggle_subtract_ref)
self.plotWidget.mpl_connect('motion_notify_event', self.mouse_moved)
self.plotWidget.mpl_connect('scroll_event', self.mouse_scroll)
@ -374,8 +385,11 @@ class Array_map(QtWidgets.QWidget):
def get_max_from_stations(self, key):
return self._from_dict(max, key)
def get_selected_pick_type(self):
return self.comboBox_am.currentText().split(' ')[0]
def current_picks_dict(self):
picktype = self.comboBox_am.currentText().split(' ')[0]
picktype = self.get_selected_pick_type()
auto_manu = {'auto': self.autopicks_dict,
'manual': self.picks_dict,
'hybrid': self.hybrids_dict}
@ -447,6 +461,9 @@ class Array_map(QtWidgets.QWidget):
self.cmaps_box.setCurrentIndex(self.cmaps_box.findText(cmap))
self._refresh_drawings()
def toggle_subtract_ref(self):
self._refresh_drawings()
def init_lat_lon_dimensions(self):
# init minimum and maximum lon and lat dimensions
self.londim = self.lonmax - self.lonmin
@ -459,7 +476,10 @@ class Array_map(QtWidgets.QWidget):
self.longrid, self.latgrid = np.meshgrid(lonaxis, lataxis)
def init_picksgrid(self):
picks, uncertainties, lats, lons = self.get_picks_lat_lon()
rval = self.get_picks_lat_lon()
if not rval:
return
picks, uncertainties, lats, lons = rval
try:
self.picksgrid_active = griddata((lats, lons), picks, (self.latgrid, self.longrid), method='linear')
except Exception as e:
@ -477,15 +497,20 @@ class Array_map(QtWidgets.QWidget):
def get_picks_lat_lon(self):
picks_rel = self.picks_rel_mean_corrected if self.subtract_mean_cb.isChecked() else self.picks_rel
picks_rel = self.picks_rel_ref_corrected if self.subtract_ref_cb.isChecked() else picks_rel
if not picks_rel:
return
picks = []
uncertainties = []
latitudes = []
longitudes = []
for st_id, pick in picks_rel.items():
for nwst_id, pick in picks_rel.items():
if nwst_id not in self.uncertainties or nwst_id not in self.stations_dict:
continue
picks.append(pick)
uncertainties.append(self.uncertainties.get(st_id))
latitudes.append(self.stations_dict[st_id]['latitude'])
longitudes.append(self.stations_dict[st_id]['longitude'])
uncertainties.append(self.uncertainties.get(nwst_id))
latitudes.append(self.stations_dict[nwst_id]['latitude'])
longitudes.append(self.stations_dict[nwst_id]['longitude'])
return picks, uncertainties, latitudes, longitudes
# plotting -----------------------------------------------------
@ -582,7 +607,10 @@ class Array_map(QtWidgets.QWidget):
transform=ccrs.PlateCarree())
def scatter_picked_stations(self):
picks, uncertainties, lats, lons = self.get_picks_lat_lon()
rval = self.get_picks_lat_lon()
if not rval:
return
picks, uncertainties, lats, lons = rval
if len(lons) < 1 and len(lats) < 1:
return
@ -737,6 +765,52 @@ class Array_map(QtWidgets.QWidget):
fname += '.png'
self.canvas.fig.savefig(fname)
def load_reference_picks(self):
fname = self._parent.filename_from_action()
data_ref = Data(parent=self._parent, evtdata=str(fname))
evt_ref = data_ref.get_evt_data()
if not evt_ref:
return
picks_ref = evt_ref.picks
if not picks_ref:
return
picksdict_ref = picksdict_from_picks(evt_ref, nwst_id=False)
self.autopicks_dict = picksdict_ref['manual']
self.autopicks_dict_ref = picksdict_ref['auto']
return True
@property
def picks_rel_ref_corrected(self):
picktype = self.get_selected_pick_type()
if picktype in ['auto', 'hybrid']:
picks_dict = self.autopicks_dict_ref
elif picktype == 'manual':
picks_dict = self.autopicks_dict
else:
return
if picks_dict:
return self.subtract_picks(picks_dict)
else:
if self.load_reference_picks():
return self.picks_rel_ref_corrected
def subtract_picks(self, picks_dict):
current_picks = self.current_picks_dict()
subtracted_picks = {}
for station, ps_dict in current_picks.items():
for phase, pick in ps_dict.items():
pick_ref_ps = picks_dict.get(station)
if not pick_ref_ps:
continue
pick_ref = pick_ref_ps.get(phase)
if not pick_ref:
continue
mpp = pick['mpp'] - pick_ref['mpp']
nwst_id = f'{pick["network"]}.{station}'
subtracted_picks[nwst_id] = mpp
return subtracted_picks
def _warn(self, message):
self.qmb = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Icon.Warning, 'Warning', message)
self.qmb.show()

View File

@ -268,6 +268,9 @@ class Metadata(object):
if not fnames:
# search for station name in filename
fnames = glob.glob(os.path.join(path_to_inventory, '*' + station + '*'))
if not fnames:
# search for network name in filename
fnames = glob.glob(os.path.join(path_to_inventory, '*' + network + '*'))
if not fnames:
if self.verbosity:
print('Could not find filenames matching station name, network name or seed id')
@ -279,7 +282,7 @@ class Metadata(object):
continue
invtype, robj = self._read_metadata_file(os.path.join(path_to_inventory, fname))
try:
robj.get_coordinates(station_seed_id)
# robj.get_coordinates(station_seed_id) # TODO: Commented out, failed with Parser, is this needed?
self.inventory_files[fname] = {'invtype': invtype,
'data': robj}
if station_seed_id in self.seed_ids.keys():
@ -287,7 +290,6 @@ class Metadata(object):
self.seed_ids[station_seed_id] = fname
return True
except Exception as e:
logging.warning(e)
continue
print('Could not find metadata for station_seed_id {} in path {}'.format(station_seed_id, path_to_inventory))
@ -652,8 +654,6 @@ def restitute_data(data, metadata, unit='VEL', force=False, ncores=0):
"""
# data = remove_underscores(data)
if not data:
return
# loop over traces
input_tuples = []
@ -661,14 +661,9 @@ def restitute_data(data, metadata, unit='VEL', force=False, ncores=0):
input_tuples.append((tr, metadata, unit, force))
data.remove(tr)
if ncores == 0:
result = []
for input_tuple in input_tuples:
result.append(restitute_trace(input_tuple))
else:
pool = gen_Pool(ncores)
result = pool.imap_unordered(restitute_trace, input_tuples)
pool.close()
pool = gen_Pool(ncores)
result = pool.imap_unordered(restitute_trace, input_tuples)
pool.close()
for tr, remove_trace in result:
if not remove_trace:

View File

@ -9,7 +9,7 @@
# initial_pick_outlier_threshold: (hopefully) threshold for excluding large outliers of initial (AIC) picks
# export_threshold: automatically exclude all onsets which deviate more than this threshold from corrected taup onsets
# min_picks_export: minimum number of correlated picks for export
# min_picks_autopylot: minimum number of reference auto picks to continue with event
# min_picks_autopylot: minimum number of reference autopicks picks to continue with event
# check_RMS: do RMS check to search for restitution errors (very experimental)
# use_taupy_onsets: use taupy onsets as reference picks instead of external picks
# station_list: use the following stations as reference for stacking
@ -17,11 +17,6 @@
# data_dir: obspyDMT data subdirectory (e.g. 'raw', 'processed')
# pickfile_extension: use quakeML files (PyLoT output) with the following extension, e.g. '_autopylot' for pickfiles
# such as 'PyLoT_20170501_141822_autopylot.xml'
# dt_stacking: time shift for stacking (e.g. [0, 250] for 0 and 250 seconds shift)
# filter_options: filter for first correlation (rough)
# filter_options_final: filter for second correlation (fine)
# filter_type: e.g. 'bandpass'
# sampfreq: sampling frequency of the data
logging: info
pick_phases: ['P', 'S']

View File

@ -25,7 +25,7 @@ class HidePrints:
if self.hide:
self._original_stdout = sys.stdout
devnull = open(os.devnull, "w")
sys.stdout = devnull
#sys.stdout = devnull
def __exit__(self, exc_type, exc_val, exc_tb):
if self.hide:
@ -271,7 +271,7 @@ class TestAutopickStation(unittest.TestCase):
'fm': 'N', 'channel': None}}
with HidePrints():
result, station = autopickstation(wfstream=wfstream, pickparam=self.pickparam_taupy_disabled,
metadata=(None, None))
metadata=(None, None), iplot=2)
compare_dicts(expected=expected['P'], result=result['P'], hint='P-')
compare_dicts(expected=expected['S'], result=result['S'], hint='S-')
self.assertEqual('GRA1', station)