diff --git a/QtPyLoT.py b/QtPyLoT.py index a2476e9c..08a67127 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -43,6 +43,7 @@ from obspy import UTCDateTime from pylot.core.read.data import Data from pylot.core.read.inputs import FilterOptions, AutoPickParameter from pylot.core.pick.autopick import autopickevent +from pylot.core.read.io import picks_from_evt from pylot.core.loc.nll import locate as locateNll from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP from pylot.core.util.errors import FormatError, DatastructureError, \ @@ -734,34 +735,7 @@ class MainWindow(QMainWindow): return rval def updatePicks(self, type='manual'): - evt = self.getData().getEvtData() - picks = {} - for pick in evt.picks: - phase = {} - station = pick.waveform_id.station_code - try: - onsets = picks[station] - except KeyError as e: - print(e) - onsets = {} - mpp = pick.time - lpp = mpp + pick.time_errors.upper_uncertainty - epp = mpp - pick.time_errors.lower_uncertainty - spe = pick.time_errors.uncertainty - phase['mpp'] = mpp - phase['epp'] = epp - phase['lpp'] = lpp - phase['spe'] = spe - try: - picker = str(pick.method_id) - if picker.startswith('smi:local/'): - picker = picker.split('smi:local/')[1] - phase['picker'] = picker - except IndexError: - pass - - onsets[pick.phase_hint] = phase.copy() - picks[station] = onsets.copy() + picks = picks_from_evt(evt=self.getData().getEvtData()) if type == 'manual': self.picks.update(picks) elif type == 'auto': diff --git a/pylot/core/pick/compare.py b/pylot/core/pick/compare.py index 0f51b97b..c0be3fed 100644 --- a/pylot/core/pick/compare.py +++ b/pylot/core/pick/compare.py @@ -1,8 +1,31 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from obspy import read_events + +from pylot.core.read.io import picks_from_evt from pylot.core.util.pdf import ProbabilityDensityFunction from pylot.core.util.version import get_git_version as _getVersionString __version__ = _getVersionString() __author__ = 'sebastianw' + + +def readData(fn): + """ + Reads pick data from QuakeML files named FN and returns a dictionary + containing a ProbabilityDensityFunction object for each pick. + :param fn: name of the QuakeML file which contains the picks + :type fn: str + :return: a dictionary containing the picks represented as pdfs + """ + pdf_picks = picks_from_evt(read_events(fn)[0]) + + for station, phases in pdf_picks.items(): + for phase, values in phases.items(): + phases[phase] = ProbabilityDensityFunction.fromPick(values['epp'], + values['mpp'], + values['lpp'], + type='exp') + + return pdf_picks diff --git a/pylot/core/read/io.py b/pylot/core/read/io.py index cd9b2149..b499d911 100644 --- a/pylot/core/read/io.py +++ b/pylot/core/read/io.py @@ -134,3 +134,40 @@ def readPILOTEvent(phasfn=None, locfn=None, authority_id=None, **kwargs): except AttributeError as e: raise AttributeError('{0} - Matlab LOC files {1} and {2} contains \ insufficient data!'.format(e, phasfn, locfn)) + +def picks_from_evt(evt): + ''' + 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` + :return: pick dictionary + ''' + picks = {} + for pick in evt.picks: + phase = {} + station = pick.waveform_id.station_code + try: + onsets = picks[station] + except KeyError as e: + print(e) + onsets = {} + mpp = pick.time + lpp = mpp + pick.time_errors.upper_uncertainty + epp = mpp - pick.time_errors.lower_uncertainty + spe = pick.time_errors.uncertainty + phase['mpp'] = mpp + phase['epp'] = epp + phase['lpp'] = lpp + phase['spe'] = spe + try: + picker = str(pick.method_id) + if picker.startswith('smi:local/'): + picker = picker.split('smi:local/')[1] + phase['picker'] = picker + except IndexError: + pass + + onsets[pick.phase_hint] = phase.copy() + picks[station] = onsets.copy() + return picks \ No newline at end of file diff --git a/pylot/core/util/pdf.py b/pylot/core/util/pdf.py index 556f36ca..89481ce6 100644 --- a/pylot/core/util/pdf.py +++ b/pylot/core/util/pdf.py @@ -180,7 +180,8 @@ class ProbabilityDensityFunction(object): self._x = np.array(x) @classmethod - def fromPick(self, incr, lbound, barycentre, rbound, decfact=0.01, type='gauss'): + def fromPick(self, lbound, barycentre, rbound, incr=0.005, decfact=0.01, + type='gauss'): ''' Initialize a new ProbabilityDensityFunction object. Takes incr, lbound, barycentre and rbound to derive x0 and the number @@ -199,7 +200,10 @@ class ProbabilityDensityFunction(object): try: midpoint = (rbound + lbound) / 2 except TypeError: - midpoint = (rbound + float(lbound)) / 2 + try: + midpoint = (rbound + float(lbound)) / 2 + except TypeError: + midpoint = float(rbound + float(lbound)) / 2 # find x0 on a grid point and sufficient npts n = int(np.ceil((barycentre - midpoint) / incr))