From 3c593d206d76889be5caf140c8da18eb08d808c7 Mon Sep 17 00:00:00 2001 From: Gregor Date: Sun, 15 Jul 2018 11:57:37 +0200 Subject: [PATCH 1/7] add: snuffling Quick Save --- quick_save.py | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 quick_save.py diff --git a/quick_save.py b/quick_save.py new file mode 100644 index 0000000..0cf3ce0 --- /dev/null +++ b/quick_save.py @@ -0,0 +1,126 @@ +#-*- coding: utf-8 -*- + +import getpass +import os + +from pyrocko.snuffling import Choice, Snuffling, Switch +from pyrocko.pile_viewer import Marker + +# TO-DO - save to VELEST format. + +user_def_root_folder = \ +'/user/defined/root/folder' + +class QuickSave(Snuffling): + + """ + + +

Quick Save

+ +

+ Choose the predefined or user defined path from the Root folder + menu, desired options and press Run. Path to marker file is + printed to the terminal.
+ User defined path is selected by default and can be modified in the source + file. It is given as a string under user_def_root_folder variable + (line 11). +

+

+ Options:
+

+

+

+ Author: G. Rajh. +

+ + + + """ + + def setup(self): + self.set_name('Quick Save') + + username = getpass.getuser() + + self.add_parameter(Choice('Root folder', 'root_folder', + user_def_root_folder, [user_def_root_folder, + '/home/' + username + '/Desktop', + '/home/' + username + '/Documents' + ])) + + self.add_parameter(Switch( + 'Save only selected markers', 'save_sel_markers', False)) + self.add_parameter(Switch( + 'Save only markers associated\nto the active event', + 'save_asc_markers', False)) + self.add_parameter(Switch('Add active event name to path', + 'name_to_path', False)) + self.add_parameter(Switch('Use active event name as filename', + 'name_as_filename', False)) + # self.add_parameter(Switch('Save in Velest format', + # 'velest_format', False)) + + self.setup_gui(reloaded=True) + self.set_live_update(False) + + def parse_markers(self): + self.cleanup() + + if self.save_asc_markers and not self.save_sel_markers: + active_event, asc_phase_markers = \ + self.get_active_event_and_phase_markers() + asc_phase_markers.insert(0, active_event) + self.selected_markers = asc_phase_markers + self.ae_name = active_event.get_event().name + elif not self.save_asc_markers and self.save_sel_markers: + self.selected_markers = self.get_selected_markers + else: + self.selected_markers = self.get_markers() + + def save_markers(self): + if self.save_asc_markers and not self.save_sel_markers: + if self.name_to_path and self.name_as_filename: + save_path = self.root_folder + "/" + self.ae_name + try: + os.makedirs(save_path) + except OSError: + if not os.path.isdir(save_path): + raise + self.save_path = save_path + "/" + self.ae_name + elif self.name_to_path: + save_path = self.root_folder + "/" + self.ae_name + try: + os.makedirs(save_path) + except OSError: + if not os.path.isdir(save_path): + raise + self.save_path = save_path + "/picks" + elif self.name_as_filename: + self.save_path = self.root_folder + "/" + self.ae_name + else: + self.save_path = self.root_folder + "picks" + else: + self.save_path = self.root_folder + "picks" + + Marker.save_markers(self.selected_markers, self.save_path) + + def save_velest(self): + pass + + def call(self): + self.parse_markers() + self.save_markers() + print("Markers saved to: {}.".format(self.save_path)) + +def __snufflings__(): + """Returns a list of snufflings to be exported by this module.""" + + return[QuickSave()] \ No newline at end of file From f6a3f43e64e5698c1c793c21e214ee4c324e5036 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 16 Jul 2018 09:34:07 +0200 Subject: [PATCH 2/7] corr: proposed changes --- quick_save.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/quick_save.py b/quick_save.py index 0cf3ce0..e0afb6d 100644 --- a/quick_save.py +++ b/quick_save.py @@ -1,6 +1,5 @@ #-*- coding: utf-8 -*- -import getpass import os from pyrocko.snuffling import Choice, Snuffling, Switch @@ -8,8 +7,9 @@ # TO-DO - save to VELEST format. -user_def_root_folder = \ -'/user/defined/root/folder' +# Defaults to user's home folder. +USER_DEF_ROOT_FOLDER = \ +os.path.expanduser('~') class QuickSave(Snuffling): @@ -23,8 +23,8 @@ class QuickSave(Snuffling): menu, desired options and press Run. Path to marker file is printed to the terminal.
User defined path is selected by default and can be modified in the source - file. It is given as a string under user_def_root_folder variable - (line 11). + file. It is given as a string under USER_DEF_ROOT_FOLDER variable + (line 11). Its default value points to user's home folder.

Options:
@@ -48,12 +48,12 @@ class QuickSave(Snuffling): def setup(self): self.set_name('Quick Save') - username = getpass.getuser() + home_folder = os.path.expanduser('~') self.add_parameter(Choice('Root folder', 'root_folder', - user_def_root_folder, [user_def_root_folder, - '/home/' + username + '/Desktop', - '/home/' + username + '/Documents' + USER_DEF_ROOT_FOLDER, [USER_DEF_ROOT_FOLDER, + home_folder + '/Desktop', + home_folder + '/Documents' ])) self.add_parameter(Switch( @@ -123,4 +123,4 @@ def call(self): def __snufflings__(): """Returns a list of snufflings to be exported by this module.""" - return[QuickSave()] \ No newline at end of file + return[QuickSave()] From 84d9706d0f5ddafd542b987283692c9fc21f198b Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 16 Jul 2018 12:10:21 +0200 Subject: [PATCH 3/7] corr: newline at EOF --- quick_save.py | 1 + 1 file changed, 1 insertion(+) diff --git a/quick_save.py b/quick_save.py index e0afb6d..7a1c434 100644 --- a/quick_save.py +++ b/quick_save.py @@ -124,3 +124,4 @@ def __snufflings__(): """Returns a list of snufflings to be exported by this module.""" return[QuickSave()] + From ab34783f9e4fe4aacf7dca4ca25d15aef95922ae Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 16 Jul 2018 16:52:38 +0200 Subject: [PATCH 4/7] corr: various --- quick_save.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quick_save.py b/quick_save.py index 7a1c434..d203a77 100644 --- a/quick_save.py +++ b/quick_save.py @@ -106,9 +106,9 @@ def save_markers(self): elif self.name_as_filename: self.save_path = self.root_folder + "/" + self.ae_name else: - self.save_path = self.root_folder + "picks" + self.save_path = self.root_folder + "/picks" else: - self.save_path = self.root_folder + "picks" + self.save_path = self.root_folder + "/picks" Marker.save_markers(self.selected_markers, self.save_path) From 061c873ea85da1a85d0765b22a5bfd8aea836298 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 16 Jul 2018 23:12:04 +0200 Subject: [PATCH 5/7] add: Velest support. --- quick_save.py | 142 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 20 deletions(-) diff --git a/quick_save.py b/quick_save.py index d203a77..3fc08ef 100644 --- a/quick_save.py +++ b/quick_save.py @@ -1,16 +1,24 @@ #-*- coding: utf-8 -*- +import datetime import os from pyrocko.snuffling import Choice, Snuffling, Switch from pyrocko.pile_viewer import Marker -# TO-DO - save to VELEST format. - -# Defaults to user's home folder. +# Defaults to user's home folder. os.path.expanduser('~') USER_DEF_ROOT_FOLDER = \ os.path.expanduser('~') + +def folder_check(save_path): + try: + os.makedirs(save_path) + except OSError: + if not os.path.isdir(save_path): + raise + + class QuickSave(Snuffling): """ @@ -34,6 +42,7 @@ class QuickSave(Snuffling):

@@ -65,8 +74,8 @@ def setup(self): 'name_to_path', False)) self.add_parameter(Switch('Use active event name as filename', 'name_as_filename', False)) - # self.add_parameter(Switch('Save in Velest format', - # 'velest_format', False)) + self.add_parameter(Switch('Save to Velest format', + 'velest_format', False)) self.setup_gui(reloaded=True) self.set_live_update(False) @@ -75,50 +84,143 @@ def parse_markers(self): self.cleanup() if self.save_asc_markers and not self.save_sel_markers: - active_event, asc_phase_markers = \ + active_event_marker, asc_phase_markers = \ self.get_active_event_and_phase_markers() - asc_phase_markers.insert(0, active_event) + self.phase_markers = asc_phase_markers[:] + asc_phase_markers.insert(0, active_event_marker) self.selected_markers = asc_phase_markers - self.ae_name = active_event.get_event().name + self.active_event = active_event_marker.get_event() + self.ae_name = self.active_event.name + elif not self.save_asc_markers and self.save_sel_markers: self.selected_markers = self.get_selected_markers + else: self.selected_markers = self.get_markers() def save_markers(self): if self.save_asc_markers and not self.save_sel_markers: + if self.name_to_path and self.name_as_filename: save_path = self.root_folder + "/" + self.ae_name - try: - os.makedirs(save_path) - except OSError: - if not os.path.isdir(save_path): - raise + folder_check(save_path) self.save_path = save_path + "/" + self.ae_name + elif self.name_to_path: save_path = self.root_folder + "/" + self.ae_name - try: - os.makedirs(save_path) - except OSError: - if not os.path.isdir(save_path): - raise + folder_check(save_path) self.save_path = save_path + "/picks" + elif self.name_as_filename: self.save_path = self.root_folder + "/" + self.ae_name + else: self.save_path = self.root_folder + "/picks" + else: self.save_path = self.root_folder + "/picks" Marker.save_markers(self.selected_markers, self.save_path) def save_velest(self): - pass + if self.save_asc_markers and not self.save_sel_markers: + start_time = datetime.datetime(1970, 1, 1) + event_time = self.active_event.time + event_date = start_time.utcfromtimestamp(event_time) + + event_year = int(str(event_date.year)[2:]) + event_month = event_date.month + event_day = event_date.day + event_hour = event_date.hour + event_min = event_date.minute + event_sec = event_date.second + ( + round(event_date.microsecond / 10**6, 2)) + event_lat = round(self.active_event.lat, 4) + event_lon = round(self.active_event.lon, 4) + event_depth = round(self.active_event.depth / 10**3, 2) + event_mag = round(self.active_event.magnitude, 2) + + if event_lat >= 0: + event_NS = "N" + else: + event_NS = "S" + + if event_lon >= 0: + event_EW = "E" + else: + event_EW = "W" + else: + pass + + event_line = "{:02d}{:02d}{:02d} {:02d}{:02d} {:05.2f} {:7.4f}{} \ +{:8.4f}{}{:8.2f}{:7.2f} 99 0.0 0.00 1.0 1.0 \n".format( + event_year, event_month, event_day, event_hour, event_min, + event_sec, event_lat, event_NS, event_lon, event_EW, event_depth, + event_mag + ) + + self.save_path_velest = self.save_path + "_velest" + + if self.name_to_path or self.name_as_filename: + velest_file = open(self.save_path_velest, 'w') + else: + velest_file = open(self.save_path_velest, 'a+') + + velest_file.write(event_line) + + phase_i = 0 + phase_num = len(self.phase_markers) + + for phase_marker in self.phase_markers: + phase_i += 1 + phase_station = list(phase_marker.nslc_ids)[0][1] + phase_name = phase_marker._phasename + phase_tmin = phase_marker.tmin + phase_tmax = phase_marker.tmax + phase_unc = phase_marker._uncertainty + + if phase_tmin == phase_tmax: + phase_time = phase_tmin + else: + phase_mid_int = (phase_tmax - phase_tmin) * 0.5 + phase_time = phase_tmin + phase_mid_int + + phase_rtime = round(phase_time - event_time, 2) + + if phase_unc <= 0.1: + phase_unc_class = 0 + elif 0.1 < phase_unc <= 0.2: + phase_unc_class = 1 + elif 0.2 < phase_unc <= 0.5: + phase_unc_class = 2 + else: + phase_unc_class = 3 + + if phase_i % 6.0 == 0 or phase_i == phase_num: + phase_block = "{:4s}{}{}{:06.2f}\n".format(phase_station, + phase_name, phase_unc_class, phase_rtime) + else: + phase_block = "{:4s}{}{}{:06.2f}".format(phase_station, + phase_name, phase_unc_class, phase_rtime) + + + velest_file.write(phase_block) + + velest_file.write('\n') + velest_file.close() def call(self): self.parse_markers() self.save_markers() - print("Markers saved to: {}.".format(self.save_path)) + print('Markers saved to: {}.'.format(self.save_path)) + + if self.velest_format: + self.save_asc_markers = True + self.parse_markers() + self.save_velest() + print('Velest format saved to: {}.'.format(self.save_path_velest)) + else: + pass def __snufflings__(): """Returns a list of snufflings to be exported by this module.""" From ebca0845a580c5c69da89caa4f61dee356e4d40d Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 16 Jul 2018 23:35:12 +0200 Subject: [PATCH 6/7] corr: various --- quick_save.py | 55 ++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/quick_save.py b/quick_save.py index 3fc08ef..ebf4e14 100644 --- a/quick_save.py +++ b/quick_save.py @@ -93,7 +93,7 @@ def parse_markers(self): self.ae_name = self.active_event.name elif not self.save_asc_markers and self.save_sel_markers: - self.selected_markers = self.get_selected_markers + self.selected_markers = self.get_selected_markers() else: self.selected_markers = self.get_markers() @@ -123,35 +123,31 @@ def save_markers(self): Marker.save_markers(self.selected_markers, self.save_path) def save_velest(self): - if self.save_asc_markers and not self.save_sel_markers: - start_time = datetime.datetime(1970, 1, 1) - event_time = self.active_event.time - event_date = start_time.utcfromtimestamp(event_time) - - event_year = int(str(event_date.year)[2:]) - event_month = event_date.month - event_day = event_date.day - event_hour = event_date.hour - event_min = event_date.minute - event_sec = event_date.second + ( - round(event_date.microsecond / 10**6, 2)) - event_lat = round(self.active_event.lat, 4) - event_lon = round(self.active_event.lon, 4) - event_depth = round(self.active_event.depth / 10**3, 2) - event_mag = round(self.active_event.magnitude, 2) - - if event_lat >= 0: - event_NS = "N" - else: - event_NS = "S" + start_time = datetime.datetime(1970, 1, 1) + event_time = self.active_event.time + event_date = start_time.utcfromtimestamp(event_time) + event_year = int(str(event_date.year)[2:]) + event_month = event_date.month + event_day = event_date.day + event_hour = event_date.hour + event_min = event_date.minute + event_sec = event_date.second + ( + round(event_date.microsecond / 10**6, 2)) + event_lat = round(self.active_event.lat, 4) + event_lon = round(self.active_event.lon, 4) + event_depth = round(self.active_event.depth / 10**3, 2) + event_mag = round(self.active_event.magnitude, 2) + + if event_lat >= 0: + event_NS = "N" + else: + event_NS = "S" - if event_lon >= 0: - event_EW = "E" - else: - event_EW = "W" + if event_lon >= 0: + event_EW = "E" else: - pass - + event_EW = "W" + event_line = "{:02d}{:02d}{:02d} {:02d}{:02d} {:05.2f} {:7.4f}{} \ {:8.4f}{}{:8.2f}{:7.2f} 99 0.0 0.00 1.0 1.0 \n".format( event_year, event_month, event_day, event_hour, event_min, @@ -216,6 +212,7 @@ def call(self): if self.velest_format: self.save_asc_markers = True + self.save_sel_markers = False self.parse_markers() self.save_velest() print('Velest format saved to: {}.'.format(self.save_path_velest)) @@ -225,5 +222,5 @@ def call(self): def __snufflings__(): """Returns a list of snufflings to be exported by this module.""" - return[QuickSave()] + return[ QuickSave() ] From d871b67db3167104b2f442ee843497fda4f71691 Mon Sep 17 00:00:00 2001 From: Gregor Date: Tue, 17 Jul 2018 01:48:39 +0200 Subject: [PATCH 7/7] corr: optimization, corrections, rigorous testing --- quick_save.py | 120 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 41 deletions(-) diff --git a/quick_save.py b/quick_save.py index ebf4e14..8f1c17f 100644 --- a/quick_save.py +++ b/quick_save.py @@ -11,14 +11,6 @@ os.path.expanduser('~') -def folder_check(save_path): - try: - os.makedirs(save_path) - except OSError: - if not os.path.isdir(save_path): - raise - - class QuickSave(Snuffling): """ @@ -80,10 +72,41 @@ def setup(self): self.setup_gui(reloaded=True) self.set_live_update(False) - def parse_markers(self): - self.cleanup() + def folder_check(self, save_path): + try: + os.makedirs(save_path) + except OSError: + if not os.path.isdir(save_path): + raise + + def check_params(self): + if self.save_asc_markers and self.save_sel_markers: + self.error(' Select either "Save only selected markers" or \ +"Save only markers associated to the active event" option.') + self.checked = False + + elif not self.save_asc_markers and self.name_to_path: + self.save_asc_markers = True + self.save_sel_markers = False + self.checked = True + + elif not self.save_asc_markers and self.name_as_filename: + self.save_asc_markers = True + self.save_sel_markers = False + self.checked = True + + elif not self.save_asc_markers and self.velest_format: + self.save_asc_markers = True + self.save_sel_markers = False + self.checked = True + + else: + self.checked = True - if self.save_asc_markers and not self.save_sel_markers: + self.reset_gui(reloaded=True) + + def parse_markers(self): + if self.save_asc_markers: active_event_marker, asc_phase_markers = \ self.get_active_event_and_phase_markers() self.phase_markers = asc_phase_markers[:] @@ -92,35 +115,30 @@ def parse_markers(self): self.active_event = active_event_marker.get_event() self.ae_name = self.active_event.name - elif not self.save_asc_markers and self.save_sel_markers: + elif self.save_sel_markers: self.selected_markers = self.get_selected_markers() else: self.selected_markers = self.get_markers() def save_markers(self): - if self.save_asc_markers and not self.save_sel_markers: - - if self.name_to_path and self.name_as_filename: - save_path = self.root_folder + "/" + self.ae_name - folder_check(save_path) - self.save_path = save_path + "/" + self.ae_name + if self.name_to_path and self.name_as_filename: + save_path = self.root_folder + "/" + self.ae_name + self.folder_check(save_path) + self.save_path = save_path + "/" + self.ae_name - elif self.name_to_path: - save_path = self.root_folder + "/" + self.ae_name - folder_check(save_path) - self.save_path = save_path + "/picks" + elif self.name_to_path: + save_path = self.root_folder + "/" + self.ae_name + self.folder_check(save_path) + self.save_path = save_path + "/picks" - elif self.name_as_filename: - self.save_path = self.root_folder + "/" + self.ae_name - - else: - self.save_path = self.root_folder + "/picks" + elif self.name_as_filename: + self.save_path = self.root_folder + "/" + self.ae_name else: self.save_path = self.root_folder + "/picks" - Marker.save_markers(self.selected_markers, self.save_path) + Marker.save_markers(self.selected_markers, self.save_path + '.txt') def save_velest(self): start_time = datetime.datetime(1970, 1, 1) @@ -155,7 +173,7 @@ def save_velest(self): event_mag ) - self.save_path_velest = self.save_path + "_velest" + self.save_path_velest = self.save_path + "_velest.txt" if self.name_to_path or self.name_as_filename: velest_file = open(self.save_path_velest, 'w') @@ -199,28 +217,48 @@ def save_velest(self): phase_block = "{:4s}{}{}{:06.2f}".format(phase_station, phase_name, phase_unc_class, phase_rtime) - velest_file.write(phase_block) velest_file.write('\n') velest_file.close() def call(self): - self.parse_markers() - self.save_markers() - print('Markers saved to: {}.'.format(self.save_path)) - - if self.velest_format: - self.save_asc_markers = True - self.save_sel_markers = False + self.check_params() + + if self.checked: self.parse_markers() - self.save_velest() - print('Velest format saved to: {}.'.format(self.save_path_velest)) + self.save_markers() + print('Markers saved to: {}.'.format(self.save_path + '.txt')) + self.show_message('Success', ' Markers saved to: {}.'.format( + self.save_path + '.txt' + )) + + if self.velest_format: + self.save_velest() + print('Velest format saved to: {}.'.format( + self.save_path_velest + )) + self.show_message( + 'Success', ' Velest format saved to: {}.'.format( + self.save_path_velest + )) + else: + pass + else: - pass + self.save_sel_markers = False + self.save_asc_markers = False + self.name_to_path = False + self.name_as_filename = False + self.velest_format = False + self.reset_gui(reloaded=True) + self.warn( + ' Please select appropriate parameters. All markers are \ +saved in case none is selected.\n\n\t\tSelection cleared.' + ) def __snufflings__(): """Returns a list of snufflings to be exported by this module.""" - return[ QuickSave() ] + return[QuickSave()]