[update] added check for nan values in waveforms which crashed obspy filter routines

[minor] some tweaks and optimisations
This commit is contained in:
Marcel Paffrath 2024-04-30 15:48:54 +02:00
parent 8b95c7a0fe
commit 78f2dbcab2
7 changed files with 46 additions and 48 deletions

View File

@ -2127,7 +2127,7 @@ class MainWindow(QMainWindow):
def finish_pg_plot(self): def finish_pg_plot(self):
self.getPlotWidget().updateWidget() self.getPlotWidget().updateWidget()
plots, gaps = self.wfp_thread.data plots = self.wfp_thread.data
# do not show plot if no data are given # do not show plot if no data are given
self.wf_scroll_area.setVisible(len(plots) > 0) self.wf_scroll_area.setVisible(len(plots) > 0)
self.no_data_label.setVisible(not len(plots) > 0) self.no_data_label.setVisible(not len(plots) > 0)
@ -2301,8 +2301,8 @@ class MainWindow(QMainWindow):
self.plot_method = 'normal' self.plot_method = 'normal'
rval = plotWidget.plotWFData(wfdata=wfst, wfsyn=wfsyn, title=title, mapping=False, component=comp, rval = plotWidget.plotWFData(wfdata=wfst, wfsyn=wfsyn, title=title, mapping=False, component=comp,
nth_sample=int(nth_sample), method=self.plot_method, gain=self.gain) nth_sample=int(nth_sample), method=self.plot_method, gain=self.gain)
plots, gaps = rval if rval else ([], []) plots = rval if rval else []
return plots, gaps return plots
def adjustPlotHeight(self): def adjustPlotHeight(self):
if self.pg: if self.pg:
@ -3807,6 +3807,7 @@ class MainWindow(QMainWindow):
def closeEvent(self, event): def closeEvent(self, event):
if self.okToContinue(): if self.okToContinue():
if hasattr(self, 'logwidget'):
self.logwidget.close() self.logwidget.close()
event.accept() event.accept()
else: else:

View File

@ -9,4 +9,4 @@
conda activate pylot_38 conda activate pylot_38
python ./autoPyLoT.py -i /home/marcel/.pylot/pylot_janis_noisy.in -c $NSLOTS python ./autoPyLoT.py -i /home/marcel/.pylot/pylot_adriaarray.in -c 20 -dmt processed

View File

@ -19,7 +19,7 @@ from pylot.core.util.errors import FormatError, OverwriteError
from pylot.core.util.event import Event from pylot.core.util.event import Event
from pylot.core.util.obspyDMT_interface import qml_from_obspyDMT from pylot.core.util.obspyDMT_interface import qml_from_obspyDMT
from pylot.core.util.utils import fnConstructor, full_range, check4rotated, \ from pylot.core.util.utils import fnConstructor, full_range, check4rotated, \
check4gapsAndMerge, trim_station_components check_for_gaps_and_merge, trim_station_components, check_for_nan
class Data(object): class Data(object):
@ -64,7 +64,7 @@ class Data(object):
elif 'LOC' in evtdata: elif 'LOC' in evtdata:
raise NotImplementedError('PILOT location information ' raise NotImplementedError('PILOT location information '
'read support not yet ' 'read support not yet '
'implemeted.') 'implemented.')
elif 'event.pkl' in evtdata: elif 'event.pkl' in evtdata:
evtdata = qml_from_obspyDMT(evtdata) evtdata = qml_from_obspyDMT(evtdata)
else: else:
@ -457,6 +457,11 @@ class Data(object):
:param fnames: waveform data names to append :param fnames: waveform data names to append
:type fnames: list :type fnames: list
""" """
def check_fname_exists(filenames: list) -> list:
if filenames:
filenames = [fn for fn in filenames if os.path.isfile(fn)]
return filenames
self.wfdata = Stream() self.wfdata = Stream()
self.wforiginal = None self.wforiginal = None
self.wfsyn = Stream() self.wfsyn = Stream()
@ -465,6 +470,8 @@ class Data(object):
self.tstart = tstart self.tstart = tstart
self.tstop = tstop self.tstop = tstop
fnames = check_fname_exists(fnames)
fnames_syn = check_fname_exists(fnames_syn)
# if obspy_dmt: # if obspy_dmt:
# wfdir = 'raw' # wfdir = 'raw'
# self.processed = False # self.processed = False
@ -491,7 +498,9 @@ class Data(object):
# remove possible underscores in station names # remove possible underscores in station names
# self.wfdata = remove_underscores(self.wfdata) # self.wfdata = remove_underscores(self.wfdata)
# check for gaps and merge # check for gaps and merge
self.wfdata = check4gapsAndMerge(self.wfdata) self.wfdata, _ = check_for_gaps_and_merge(self.wfdata)
# check for nans
check_for_nan(self.wfdata)
# check for stations with rotated components # check for stations with rotated components
if checkRotated and metadata is not None: if checkRotated and metadata is not None:
self.wfdata = check4rotated(self.wfdata, metadata, verbosity=0) self.wfdata = check4rotated(self.wfdata, metadata, verbosity=0)

View File

@ -660,7 +660,7 @@ class AutopickStation(object):
ax1.set_ylim([-1.5, 1.5]) ax1.set_ylim([-1.5, 1.5])
ax1.set_ylabel('Normalized Counts') ax1.set_ylabel('Normalized Counts')
if self.horizontal_traces_exist() and self.s_data.Sflag == 1: if self.horizontal_traces_exist():# and self.s_data.Sflag == 1:
# plot E trace # plot E trace
ax2 = fig.add_subplot(3, 1, 2, sharex=ax1) ax2 = fig.add_subplot(3, 1, 2, sharex=ax1)
th1data = np.linspace(0, self.etrace.stats.endtime - self.etrace.stats.starttime, th1data = np.linspace(0, self.etrace.stats.endtime - self.etrace.stats.starttime,

View File

@ -1332,22 +1332,6 @@ def get_quality_class(uncertainty, weight_classes):
return quality return quality
def set_NaNs_to(data, nan_value):
"""
Replace all NaNs in data with nan_value
:param data: array holding data
:type data: `~numpy.ndarray`
:param nan_value: value which all NaNs are set to
:type nan_value: float, int
:return: data array with all NaNs replaced with nan_value
:rtype: `~numpy.ndarray`
"""
nn = np.isnan(data)
if np.any(nn):
data[nn] = nan_value
return data
def taper_cf(cf): def taper_cf(cf):
""" """
Taper cf data to get rid off of side maximas Taper cf data to get rid off of side maximas

View File

@ -818,19 +818,6 @@ def trim_station_components(data, trim_start=True, trim_end=True):
return data return data
def merge_stream(stream):
gaps = stream.get_gaps()
if gaps:
# list of merged stations (seed_ids)
merged = ['{}.{}.{}.{}'.format(*gap[:4]) for gap in gaps]
stream.merge(method=1)
print('Merged the following stations because of gaps:')
for merged_station in merged:
print(merged_station)
return stream, gaps
def check4gapsAndRemove(data): def check4gapsAndRemove(data):
""" """
check for gaps in Stream and remove them check for gaps in Stream and remove them
@ -851,12 +838,12 @@ def check4gapsAndRemove(data):
return data return data
def check4gapsAndMerge(data): def check_for_gaps_and_merge(data):
""" """
check for gaps in Stream and merge if gaps are found check for gaps in Stream and merge if gaps are found
:param data: stream of seismic data :param data: stream of seismic data
:type data: `~obspy.core.stream.Stream` :type data: `~obspy.core.stream.Stream`
:return: data stream :return: data stream, gaps returned from obspy get_gaps
:rtype: `~obspy.core.stream.Stream` :rtype: `~obspy.core.stream.Stream`
""" """
gaps = data.get_gaps() gaps = data.get_gaps()
@ -867,7 +854,7 @@ def check4gapsAndMerge(data):
for merged_station in merged: for merged_station in merged:
print(merged_station) print(merged_station)
return data return data, gaps
def check4doubled(data): def check4doubled(data):
@ -897,6 +884,21 @@ def check4doubled(data):
return data return data
def check_for_nan(data, nan_value=0.):
"""
Replace all NaNs in data with nan_value (in place)
:param data: stream of seismic data
:type data: `~obspy.core.stream.Stream`
:param nan_value: value which all NaNs are set to
:type nan_value: float, int
:return: None
"""
if not data:
return
for trace in data:
np.nan_to_num(trace.data, copy=False, nan=nan_value)
def get_stations(data): def get_stations(data):
""" """
Get list of all station names in data stream Get list of all station names in data stream

View File

@ -51,7 +51,7 @@ from pylot.core.pick.autopick import fmpicker
from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS
from pylot.core.util.utils import prepTimeAxis, full_range, demeanTrace, isSorted, findComboBoxIndex, clims, \ from pylot.core.util.utils import prepTimeAxis, full_range, demeanTrace, isSorted, findComboBoxIndex, clims, \
pick_linestyle_plt, pick_color_plt, \ pick_linestyle_plt, pick_color_plt, \
check4rotated, check4doubled, merge_stream, identifyPhase, \ check4rotated, check4doubled, check_for_gaps_and_merge, check_for_nan, identifyPhase, \
loopIdentifyPhase, trim_station_components, transformFilteroptions2String, \ loopIdentifyPhase, trim_station_components, transformFilteroptions2String, \
identifyPhaseID, get_bool, get_None, pick_color, getAutoFilteroptions, SetChannelComponents, \ identifyPhaseID, get_bool, get_None, pick_color, getAutoFilteroptions, SetChannelComponents, \
station_id_remove_channel station_id_remove_channel
@ -897,7 +897,7 @@ class WaveformWidgetPG(QtWidgets.QWidget):
else: else:
st_select = wfdata st_select = wfdata
st_select, gaps = merge_stream(st_select) # st_select, gaps = check_for_gaps_and_merge(st_select) #MP MP commented because probably done twice
# list containing tuples of network, station, channel (for sorting) # list containing tuples of network, station, channel (for sorting)
nslc = [] nslc = []
@ -968,7 +968,7 @@ class WaveformWidgetPG(QtWidgets.QWidget):
self.ylabel = '' self.ylabel = ''
self.setXLims([0, self.wfend - self.wfstart]) self.setXLims([0, self.wfend - self.wfstart])
self.setYLims([0.5, nmax + 0.5]) self.setYLims([0.5, nmax + 0.5])
return plots, gaps return plots
def minMax(self, trace, time_ax): def minMax(self, trace, time_ax):
''' '''
@ -990,7 +990,7 @@ class WaveformWidgetPG(QtWidgets.QWidget):
min_ = data.min(axis=1) min_ = data.min(axis=1)
max_ = data.max(axis=1) max_ = data.max(axis=1)
if remaining_samples: if remaining_samples:
extreme_values = np.empty((npixel + 1, 2), dtype=np.float) extreme_values = np.empty((npixel + 1, 2), dtype=float)
extreme_values[:-1, 0] = min_ extreme_values[:-1, 0] = min_
extreme_values[:-1, 1] = max_ extreme_values[:-1, 1] = max_
extreme_values[-1, 0] = \ extreme_values[-1, 0] = \
@ -998,7 +998,7 @@ class WaveformWidgetPG(QtWidgets.QWidget):
extreme_values[-1, 1] = \ extreme_values[-1, 1] = \
trace.data[-remaining_samples:].max() trace.data[-remaining_samples:].max()
else: else:
extreme_values = np.empty((npixel, 2), dtype=np.float) extreme_values = np.empty((npixel, 2), dtype=float)
extreme_values[:, 0] = min_ extreme_values[:, 0] = min_
extreme_values[:, 1] = max_ extreme_values[:, 1] = max_
data = extreme_values.flatten() data = extreme_values.flatten()
@ -3581,8 +3581,9 @@ class TuneAutopicker(QWidget):
# wfdat = remove_underscores(wfdat) # wfdat = remove_underscores(wfdat)
# rotate misaligned stations to ZNE # rotate misaligned stations to ZNE
# check for gaps and doubled channels # check for gaps and doubled channels
wfdat, gaps = merge_stream(wfdat) wfdat, _ = check_for_gaps_and_merge(wfdat)
# check4gaps(wfdat) # check for nans
check_for_nan(wfdat)
check4doubled(wfdat) check4doubled(wfdat)
wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0) wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0)
# trim station components to same start value # trim station components to same start value
@ -3737,6 +3738,7 @@ class TuneAutopicker(QWidget):
st = self.data.getWFData() st = self.data.getWFData()
tr = st.select(station=self.get_current_station())[0] tr = st.select(station=self.get_current_station())[0]
starttime = tr.stats.starttime starttime = tr.stats.starttime
# create two lists with figure names and subindices (for subplots) to get the correct axes
p_axes = [ p_axes = [
('mainFig', 0), ('mainFig', 0),
('aicFig', 0), ('aicFig', 0),