diff --git a/QtPyLoT.py b/QtPyLoT.py index c57f754e..a1ea2a47 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -74,7 +74,7 @@ from pylot.core.util.connection import checkurl from pylot.core.util.dataprocessing import read_metadata, restitute_data from pylot.core.util.utils import fnConstructor, getLogin, \ full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \ - pick_linestyle_plt, identifyPhase, loopIdentifyPhase, remove_underscores + pick_linestyle_plt, identifyPhase, loopIdentifyPhase, remove_underscores, check4doubled from pylot.core.util.event import Event from pylot.core.io.location import create_creation_info, create_event from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ @@ -1377,7 +1377,9 @@ class MainWindow(QMainWindow): wfdat = self.data.getWFData() # all available streams # remove possible underscores in station names wfdat = remove_underscores(wfdat) + # check for gaps and doubled channels check4gaps(wfdat) + check4doubled(wfdat) # trim station components to same start value trim_station_components(wfdat, trim_start=True, trim_end=False) self._stime = full_range(self.get_data().getWFData())[0] diff --git a/autoPyLoT.py b/autoPyLoT.py index cadf9eb8..62a47525 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -26,7 +26,7 @@ from pylot.core.util.dataprocessing import restitute_data, read_metadata from pylot.core.util.defaults import SEPARATOR from pylot.core.util.event import Event from pylot.core.util.structure import DATASTRUCTURE -from pylot.core.util.utils import real_None, remove_underscores, trim_station_components, check4gaps +from pylot.core.util.utils import real_None, remove_underscores, trim_station_components, check4gaps, check4doubled from pylot.core.util.version import get_git_version as _getVersionString __version__ = _getVersionString() @@ -242,6 +242,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even wfdat = remove_underscores(wfdat) # trim components for each station to avoid problems with different trace starttimes for one station wfdat = check4gaps(wfdat) + wfdat = check4doubled(wfdat) wfdat = trim_station_components(wfdat, trim_start=True, trim_end=False) metadata = read_metadata(parameter.get('invdir')) corr_dat = None diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index c5c9804c..85733f3e 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -19,7 +19,7 @@ from pylot.core.pick.picker import AICPicker, PragPicker from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker, \ getSNR, fmpicker, checkPonsets, wadaticheck from pylot.core.util.utils import getPatternLine, gen_Pool, identifyPhase, loopIdentifyPhase, \ - full_range + real_Bool from obspy.taup import TauPyModel @@ -140,7 +140,7 @@ def autopickstation(wfstream, pickparam, verbose=False, algoS = pickparam.get('algoS') sstart = pickparam.get('sstart') sstop = pickparam.get('sstop') - use_taup = pickparam.get('use_taup') + use_taup = real_Bool(pickparam.get('use_taup')) taup_model = pickparam.get('taup_model') bph1 = pickparam.get('bph1') bph2 = pickparam.get('bph2') @@ -229,7 +229,7 @@ def autopickstation(wfstream, pickparam, verbose=False, # for global seismology: use tau-p method for estimating travel times (needs source and station coords.) # if not given: sets Lc to infinity to use full stream - if use_taup == True or use_taup == 'True': + if use_taup == True: Lc = np.inf print('autopickstation: use_taup flag active.') if not metadata[1]: @@ -262,14 +262,23 @@ def autopickstation(wfstream, pickparam, verbose=False, # modifiy pstart and pstop relative to estimated first P arrival (relative to station time axis) pstart += (source_origin.time + estFirstP) - zdat[0].stats.starttime pstop += (source_origin.time + estFirstP) - zdat[0].stats.starttime - Lc = pstop - pstart print('autopick: CF calculation times respectively:' ' pstart: {} s, pstop: {} s'.format(pstart, pstop)) elif not origin: print('No source origins given!') - else: + + # make sure pstart and pstop are inside zdat[0] + pstart = max(pstart, 0) + pstop = min(pstop, len(zdat[0])*zdat[0].stats.delta) + + if not use_taup == True or origin: Lc = pstop - pstart + Lwf = zdat[0].stats.endtime - zdat[0].stats.starttime + if not Lwf > 0: + print('autopickstation: empty trace! Return!') + return + Ldiff = Lwf - Lc if Ldiff < 0: msg = 'autopickstation: Cutting times are too large for actual ' \ @@ -517,16 +526,31 @@ def autopickstation(wfstream, pickparam, verbose=False, else: ndat = edat - if edat is not None and ndat is not None and len(edat) > 0 and len( - ndat) > 0 and Pweight < 4: + pickSonset = (edat is not None and ndat is not None and len(edat) > 0 and len( + ndat) > 0 and Pweight < 4) + + if pickSonset: + # determine time window for calculating CF after P onset + cuttimesh = [ + round(max([mpickP + sstart, 0])), # MP MP relative time axis + round(min([ + mpickP + sstop, + edat[0].stats.endtime-edat[0].stats.starttime, + ndat[0].stats.endtime-ndat[0].stats.starttime + ])) + ] + + if not cuttimesh[1] >= cuttimesh[0]: + print('Cut window for horizontal phases too small! Will not pick S onsets.') + pickSonset = False + + if pickSonset: msg = 'Go on picking S onset ...\n' \ '##################################################\n' \ 'Working on S onset of station {0}\nFiltering horizontal ' \ 'traces ...'.format(edat[0].stats.station) if verbose: print(msg) - # determine time window for calculating CF after P onset - cuttimesh = [round(max([mpickP + sstart, 0])), - round(min([mpickP + sstop, Lwf]))] + if algoS == 'ARH': # re-create stream object including both horizontal components diff --git a/pylot/core/pick/compare.py b/pylot/core/pick/compare.py index 7346dc8c..f8ec8ecc 100644 --- a/pylot/core/pick/compare.py +++ b/pylot/core/pick/compare.py @@ -8,6 +8,7 @@ import os import matplotlib.pyplot as plt import numpy as np from obspy import read_events +from obspy.core import AttribDict from pylot.core.io.phases import picksdict_from_picks from pylot.core.util.pdf import ProbabilityDensityFunction from pylot.core.util.utils import find_in_list @@ -31,7 +32,7 @@ class Comparison(object): for name, fn in kwargs.items(): if isinstance(fn, PDFDictionary): self._pdfs[name] = fn - elif isinstance(fn, dict): + elif isinstance(fn, dict) or isinstance(fn, AttribDict): self._pdfs[name] = PDFDictionary(fn) else: self._pdfs[name] = PDFDictionary.from_quakeml(fn) diff --git a/pylot/core/util/pdf.py b/pylot/core/util/pdf.py index 0ca37c65..de05727d 100644 --- a/pylot/core/util/pdf.py +++ b/pylot/core/util/pdf.py @@ -248,7 +248,7 @@ class ProbabilityDensityFunction(object): self._x = np.array(x) @classmethod - def from_pick(self, lbound, barycentre, rbound, incr=0.001, decfact=0.01, + def from_pick(self, lbound, barycentre, rbound, incr=0.1, decfact=0.01, type='exp'): ''' Initialize a new ProbabilityDensityFunction object. diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index ffeb29c3..c51f6599 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -221,6 +221,15 @@ def real_None(value): return value +def real_Bool(value): + if value == 'True': + return True + elif value == 'False': + return False + else: + return value + + def four_digits(year): """ takes a two digit year integer and returns the correct four digit equivalent @@ -621,6 +630,31 @@ def check4gaps(data): return data +def check4doubled(data): + ''' + check for doubled stations for same channel in Stream and take only the first one + :param data: stream of seismic data + :return: data stream + ''' + stations = get_stations(data) + + for station in stations: + wf_station = data.select(station=station) + # create list of all possible channels + channels = [] + for trace in wf_station: + channel = trace.stats.channel + if not channel in channels: + channels.append(channel) + else: + print('check4doubled: removed the following trace for station {}, as there is' + ' already a trace with the same channel given:\n{}'.format( + station, trace + )) + data.remove(trace) + return data + + def get_stations(data): stations = [] for tr in data: diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index b03002a9..77347459 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -127,7 +127,7 @@ class ComparisonDialog(QDialog): phasesComboBox=None, histCheckBox=None) self._phases = 'PS' - self._plotprops = dict(station=self.stations[0], phase=self.phases[0]) + self._plotprops = dict(station=list(self.stations)[0], phase=list(self.phases)[0]) super(ComparisonDialog, self).__init__(parent) self.setupUI() self.plotcomparison()