[update] added check for nan values in waveforms which crashed obspy filter routines
[minor] some tweaks and optimisations
This commit is contained in:
		
							parent
							
								
									8b95c7a0fe
								
							
						
					
					
						commit
						78f2dbcab2
					
				
							
								
								
									
										9
									
								
								PyLoT.py
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								PyLoT.py
									
									
									
									
									
								
							@ -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,7 +3807,8 @@ class MainWindow(QMainWindow):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def closeEvent(self, event):
 | 
					    def closeEvent(self, event):
 | 
				
			||||||
        if self.okToContinue():
 | 
					        if self.okToContinue():
 | 
				
			||||||
            self.logwidget.close()
 | 
					            if hasattr(self, 'logwidget'):
 | 
				
			||||||
 | 
					                self.logwidget.close()
 | 
				
			||||||
            event.accept()
 | 
					            event.accept()
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            event.ignore()
 | 
					            event.ignore()
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -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)
 | 
				
			||||||
 | 
				
			|||||||
@ -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,
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -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),
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user