From 6aacd2dd55958f58647e0b21a5ddc84f1265c23c Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Mon, 13 Nov 2017 11:44:57 +0100 Subject: [PATCH] [add] docstrings in pylot/core/io --- pylot/core/io/data.py | 137 ++++++++++++++++------------ pylot/core/io/default_parameters.py | 4 + pylot/core/io/inputs.py | 98 ++++++++++++++++++++ pylot/core/io/location.py | 8 +- pylot/core/io/phases.py | 79 ++++++++++++---- 5 files changed, 250 insertions(+), 76 deletions(-) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 5d15b1f9..cb6ef984 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -99,6 +99,11 @@ class Data(object): return self def getPicksStr(self): + """ + Return picks in event data + :return: picks seperated by newlines + :rtype: str + """ picks_str = '' for pick in self.get_evt_data().picks: picks_str += str(pick) + '\n' @@ -106,18 +111,11 @@ class Data(object): def getParent(self): """ - - - :return: + Get PySide.QtGui.QWidget parent object """ return self._parent def isNew(self): - """ - - - :return: - """ return self._new def setNew(self): @@ -125,9 +123,9 @@ class Data(object): def getCutTimes(self): """ - - - :return: + Returns earliest start and latest end of all waveform data + :return: minimum start time and maximum end time as a tuple + :rtype: (UTCDateTime, UTCDateTime) """ if self.cuttimes is None: self.updateCutTimes() @@ -135,22 +133,34 @@ class Data(object): def updateCutTimes(self): """ - - + Update cuttimes to contain earliest start and latest end time + of all waveform data + :rtype: None """ self.cuttimes = full_range(self.getWFData()) def getEventFileName(self): - """ - - - :return: - """ ID = self.getID() # handle forbidden filenames especially on windows systems return fnConstructor(str(ID)) def checkEvent(self, event, fcheck, forceOverwrite=False): + """ + Check information in supplied event and own event and replace own + information with supplied information if own information not exiisting + or forced by forceOverwrite + :param event: Event that supplies information for comparison + :type event: pylot.core.util.event.Event + :param fcheck: check and delete existing information + can be a str or a list of strings of ['manual', 'auto', 'origin', 'magnitude'] + :type fcheck: str, [str] + :param forceOverwrite: Set to true to force overwrite own information. If false, + supplied information from event is only used if there is no own information in that + category (given in fcheck: manual, auto, origin, magnitude) + :type forceOverwrite: bool + :return: + :rtype: None + """ if 'origin' in fcheck: self.replaceOrigin(event, forceOverwrite) if 'magnitude' in fcheck: @@ -161,18 +171,47 @@ class Data(object): self.replacePicks(event, 'manual') def replaceOrigin(self, event, forceOverwrite=False): + """ + Replace own origin with the one supplied in event if own origin is not + existing or forced by forceOverwrite = True + :param event: Event that supplies information for comparison + :type event: pylot.core.util.event.Event + :param forceOverwrite: always replace own information with supplied one if true + :type forceOverwrite: bool + :return: + :rtype: None + """ if self.get_evt_data().origins or forceOverwrite: if event.origins: print("Found origin, replace it by new origin.") event.origins = self.get_evt_data().origins def replaceMagnitude(self, event, forceOverwrite=False): + """ + Replace own magnitude with the one supplied in event if own magnitude is not + existing or forced by forceOverwrite = True + :param event: Event that supplies information for comparison + :type event: pylot.core.util.event.Event + :param forceOverwrite: always replace own information with supplied one if true + :type forceOverwrite: bool + :return: + :rtype: None + """ if self.get_evt_data().magnitudes or forceOverwrite: if event.magnitudes: print("Found magnitude, replace it by new magnitude") event.magnitudes = self.get_evt_data().magnitudes def replacePicks(self, event, picktype): + """ + Replace own picks with the one in event + :param event: Event that supplies information for comparison + :type event: pylot.core.util.event.Event + :param picktype: 'auto' or 'manual' picks + :type picktype: str + :return: + :rtype: None + """ checkflag = 0 picks = event.picks # remove existing picks @@ -189,10 +228,10 @@ class Data(object): picks.append(pick) def exportEvent(self, fnout, fnext='.xml', fcheck='auto', upperErrors=None): - """ + Export event to file :param fnout: basename of file - :param fnext: file extension + :param fnext: file extension, xml, cnv, obs :param fcheck: check and delete existing information can be a str or a list of strings of ['manual', 'auto', 'origin', 'magnitude'] """ @@ -304,17 +343,13 @@ class Data(object): def getComp(self): """ - - - :return: + Get component (ZNE) """ return self.comp def getID(self): """ - - - :return: + Get unique resource id """ try: return self.evtdata.get('resource_id').id @@ -323,16 +358,17 @@ class Data(object): def filterWFData(self, kwargs): """ - - :param kwargs: + Filter waveform data + :param kwargs: arguments to pass through to filter function """ self.getWFData().filter(**kwargs) self.dirty = True def setWFData(self, fnames): """ - - :param fnames: + Clear current waveform data and set given waveform data + :param fnames: waveform data names to append + :type fnames: list """ self.wfdata = Stream() self.wforiginal = None @@ -346,8 +382,9 @@ class Data(object): def appendWFData(self, fnames): """ - - :param fnames: + Read waveform data from fnames and append it to current wf data + :param fnames: waveform data to append + :type fnames: list """ assert isinstance(fnames, list), "input parameter 'fnames' is " \ "supposed to be of type 'list' " \ @@ -372,54 +409,42 @@ class Data(object): print(warnmsg) def getWFData(self): - """ - - - :return: - """ return self.wfdata def getOriginalWFData(self): - """ - - - :return: - """ return self.wforiginal def resetWFData(self): """ - - + Set waveform data to original waveform data """ self.wfdata = self.getOriginalWFData().copy() self.dirty = False def resetPicks(self): """ - - + Clear all picks from event """ self.get_evt_data().picks = [] def get_evt_data(self): - """ - - - :return: - """ return self.evtdata def setEvtData(self, event): self.evtdata = event def applyEVTData(self, data, typ='pick', authority_id='rub'): - """ - - :param data: - :param typ: - :param authority_id: + Either takes an `obspy.core.event.Event` object and applies all new + information on the event to the actual data if typ is 'event or + creates ObsPy pick objects and append it to the picks list from the + PyLoT dictionary contain all picks if type is pick + :param data: data to apply, either picks or complete event + :type data: + :param typ: which event data to apply, 'pick' or 'event' + :type typ: str + :param authority_id: (currently unused) + :type: str :raise OverwriteError: """ diff --git a/pylot/core/io/default_parameters.py b/pylot/core/io/default_parameters.py index 3ef2f7a8..903b71c0 100644 --- a/pylot/core/io/default_parameters.py +++ b/pylot/core/io/default_parameters.py @@ -1,6 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +""" +Default parameters used for picking +""" + defaults = {'rootpath': {'type': str, 'tooltip': 'project path', 'value': '', diff --git a/pylot/core/io/inputs.py b/pylot/core/io/inputs.py index 2e7d254e..ecc225b9 100644 --- a/pylot/core/io/inputs.py +++ b/pylot/core/io/inputs.py @@ -70,6 +70,7 @@ class PylotParameter(object): # Set default values of parameter names def __init_default_paras(self): + """set default values of parameter names""" parameters = default_parameters.defaults self.__defaults = parameters @@ -104,15 +105,34 @@ class PylotParameter(object): return len(self.__parameter.keys()) def iteritems(self): + """ + Iterate over parameters + :return: key, value tupel + :rtype: + """ for key, value in self.__parameter.items(): yield key, value def hasParam(self, parameter): + """ + Check if parameter is in keys + :param parameter: parameter to look for in keys + :type parameter: + :return: + :rtype: bool + """ if parameter in self.__parameter.keys(): return True return False def get(self, *args): + """ + Get first available parameter in args + :param args: + :type args: + :return: + :rtype: + """ try: for param in args: try: @@ -128,15 +148,35 @@ class PylotParameter(object): raise ParameterError(e) def get_defaults(self): + """ + get default parameters + :return: + :rtype: dict + """ return self.__defaults def get_main_para_names(self): + """ + Get main parameter names + :return: list of keys available in parameters + :rtype: + """ return self._settings_main def get_special_para_names(self): + """ + Get pick parameter names + :return: list of keys available in parameters + :rtype: + """ return self._settings_special_pick def get_all_para_names(self): + """ + Get all parameter names + :return: + :rtype: list + """ all_names = [] all_names += self.get_main_para_names()['dirs'] all_names += self.get_main_para_names()['nlloc'] @@ -151,6 +191,16 @@ class PylotParameter(object): return all_names def checkValue(self, param, value): + """ + Check type of value against expected type of param. + Print warning message if type check fails + :param param: + :type param: + :param value: + :type value: + :return: + :rtype: + """ is_type = type(value) expect_type = self.get_defaults()[param]['type'] if not is_type == expect_type and not is_type == tuple: @@ -159,9 +209,25 @@ class PylotParameter(object): print(Warning(message)) def setParamKV(self, param, value): + """ + set parameter param to value + :param param: + :type param: + :param value: + :type value: + :return: + :rtype: None + """ self.__setitem__(param, value) def setParam(self, **kwargs): + """ + Set multiple parameters + :param kwargs: + :type kwargs: + :return: + :rtype: None + """ for key in kwargs: self.__setitem__(key, kwargs[key]) @@ -170,11 +236,23 @@ class PylotParameter(object): print('ParameterError:\n non-existent parameter %s' % errmsg) def reset_defaults(self): + """ + Reset current parameters to default parameters + :return: + :rtype: None + """ defaults = self.get_defaults() for param in defaults: self.setParamKV(param, defaults[param]['value']) def from_file(self, fnin=None): + """ + read parameters from file and set values to read values + :param fnin: filename + :type fnin: + :return: + :rtype: None + """ if not fnin: if self.__filename is not None: fnin = self.__filename @@ -221,6 +299,13 @@ class PylotParameter(object): self.__parameter = self._parFileCont def export2File(self, fnout): + """ + Export parameters to file + :param fnout: Filename of export file + :type fnout: str + :return: + :rtype: + """ fid_out = open(fnout, 'w') lines = [] # for key, value in self.iteritems(): @@ -257,6 +342,19 @@ class PylotParameter(object): 'quality assessment', None) def write_section(self, fid, names, title, separator): + """ + write a section of parameters to file + :param fid: File object to write to + :type fid: + :param names: which parameter names to write to file + :type names: + :param title: title of section + :type title: str + :param separator: section separator, written at start of section + :type separator: str + :return: + :rtype: + """ if separator: fid.write(separator) fid.write('#{}#\n'.format(title)) diff --git a/pylot/core/io/location.py b/pylot/core/io/location.py index d7ee26d8..6fa2bbac 100644 --- a/pylot/core/io/location.py +++ b/pylot/core/io/location.py @@ -54,7 +54,7 @@ def create_arrival(pickresID, cinfo, phase, azimuth=None, dist=None): def create_creation_info(agency_id=None, creation_time=None, author=None): ''' - + get creation info of obspy event :param agency_id: :param creation_time: :param author: @@ -197,9 +197,9 @@ def create_pick(origintime, picknum, picktime, eventnum, cinfo, phase, station, def create_resourceID(timetohash, restype, authority_id=None, hrstr=None): ''' - - :param timetohash: - :type timetohash + create unique resource id + :param timetohash: event origin time to hash + :type timetohash: class: `~obspy.core.utcdatetime.UTCDateTime` object :param restype: type of the resource, e.g. 'orig', 'earthquake' ... :type restype: str :param authority_id: name of the institution carrying out the processing diff --git a/pylot/core/io/phases.py b/pylot/core/io/phases.py index 6e4a920d..b5650fe6 100644 --- a/pylot/core/io/phases.py +++ b/pylot/core/io/phases.py @@ -118,6 +118,13 @@ def readPILOTEvent(phasfn=None, locfn=None, authority_id='RUB', **kwargs): def picksdict_from_pilot(fn): + """ + Create pick dictionary from matlab file + :param fn: matlab file + :type fn: + :return: pick dictionary + :rtype: dict + """ from pylot.core.util.defaults import TIMEERROR_DEFAULTS picks = dict() phases_pilot = sio.loadmat(fn) @@ -147,6 +154,13 @@ def picksdict_from_pilot(fn): def stations_from_pilot(stat_array): + """ + Create stations list from pilot station array + :param stat_array: + :type stat_array: + :return: + :rtype: list + """ stations = list() cur_stat = None for stat in stat_array: @@ -164,6 +178,13 @@ def stations_from_pilot(stat_array): def convert_pilot_times(time_array): + """ + Convert pilot times to UTCDateTimes + :param time_array: pilot times + :type time_array: + :return: + :rtype: + """ times = [int(time) for time in time_array] microseconds = int((time_array[-1] - times[-1]) * 1e6) times.append(microseconds) @@ -171,6 +192,13 @@ def convert_pilot_times(time_array): def picksdict_from_obs(fn): + """ + create pick dictionary from obs file + :param fn: filename + :type fn: + :return: + :rtype: + """ picks = dict() station_name = str() for line in open(fn, 'r'): @@ -240,6 +268,16 @@ def picksdict_from_picks(evt): def picks_from_picksdict(picks, creation_info=None): + """ + Create a list of picks out of a pick dictionary + :param picks: pick dictionary + :type picks: dict + :param creation_info: obspy creation information to apply to picks + :type creation_info: + :param creation_info: obspy creation information to apply to picks + :return: list of picks + :rtype: list + """ picks_list = list() for station, onsets in picks.items(): for label, phase in onsets.items(): @@ -410,25 +448,24 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None): HYPO71, NLLoc, VELEST, HYPOSAT, and hypoDD - :param: arrivals - :type: dictionary containing all phase information including - station ID, phase, first motion, weight (uncertainty), - .... + :param arrivals:dictionary containing all phase information including + station ID, phase, first motion, weight (uncertainty), ... + :type arrivals: dict - :param: fformat - :type: string, chosen file format (location routine), - choose between NLLoc, HYPO71, HYPOSAT, VELEST, - HYPOINVERSE, and hypoDD + :param fformat: chosen file format (location routine), + choose between NLLoc, HYPO71, HYPOSAT, VELEST, + HYPOINVERSE, and hypoDD + :type fformat: str - :param: filename, full path and name of phase file - :type: string + :param filename: full path and name of phase file + :type filename: string - :param: parameter, all input information - :type: object + :param parameter: all input information + :type parameter: object - :param: eventinfo, optional, needed for VELEST-cnv file + :param eventinfo: optional, needed for VELEST-cnv file and FOCMEC- and HASH-input files - :type: `obspy.core.event.Event` object + :type eventinfo: `obspy.core.event.Event` object """ if fformat == 'NLLoc': @@ -874,10 +911,20 @@ def merge_picks(event, picks): def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1): """ - Script to get onset uncertainties from Quakeml.xml files created by PyLoT. + Script to get onset uncertainties from Quakeml.xml files created by PyLoT. Uncertainties are tranformed into quality classes and visualized via histogram if desired. Ludger Küperkoch, BESTEC GmbH, 07/2017 - """ + :param xmlnames: list of xml obspy event files containing picks + :type xmlnames: list + :param ErrorsP: time errors of P waves for the four discrete quality classes + :type ErrorsP: + :param ErrorsS: time errors of S waves for the four discrete quality classes + :type ErrorsS: + :param plotflag: + :type plotflag: + :return: + :rtype: + """ from pylot.core.pick.utils import getQualityFromUncertainty from pylot.core.util.utils import loopIdentifyPhase, identifyPhase