From eb07c19c2e6ef63e1ac04e914cd3916408bae45d Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 23 Jul 2018 14:54:53 +0200 Subject: [PATCH] [update] metadata/inventory management [bugfix] errors when there were no manual picks using array_map --- PyLoT.py | 87 ++++++------------------------- pylot/core/util/array_map.py | 55 +++++++------------ pylot/core/util/dataprocessing.py | 32 ++++++++++++ pylot/core/util/widgets.py | 11 ++-- 4 files changed, 73 insertions(+), 112 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index de3f9a35..e33d4abe 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -116,7 +116,7 @@ class MainWindow(QMainWindow): self.apw = None self.paraBox = None self.array_map = None - self._metadata = None + self._metadata = Metadata() self._eventChanged = [False, False] self.apd_local = None self.apd_sge = None @@ -1927,6 +1927,7 @@ class MainWindow(QMainWindow): if self.obspy_dmt: self.metadata = Metadata(os.path.join(self.get_current_event_path(), 'resp')) self.inventoryAction.setEnabled(not self.obspy_dmt) + self.initMapAction.setEnabled(self.obspy_dmt) # MP MP --- @@ -2839,7 +2840,6 @@ class MainWindow(QMainWindow): grid_layout.addWidget(self.new_inv_button, 2, 1) grid_layout.addWidget(self.init_map_button, 3, 1) - self.metadata = Metadata() self.metadata_widget.setLayout(grid_layout) self.array_layout.addWidget(self.metadata_widget) @@ -3101,72 +3101,23 @@ class MainWindow(QMainWindow): if event == current_event: set_background_color(item_list, QtGui.QColor(*(0, 143, 143, 255))) - def read_metadata_thread(self, fninv): - self.rm_thread = Thread(self, Metadata, arg=fninv, progressText='Reading metadata...', - pb_widget=self.mainProgressBarWidget) - self.rm_thread.finished.connect(self.set_metadata) - self.rm_thread.start() - def set_metadata(self): - settings = QSettings() - self.metadata = self.rm_thread.data - if settings.value('saveMetadata'): - self.project.metadata = self.rm_thread.data - self.project.inv_path = settings.value("inventoryFile") - self.init_map_button.setEnabled(True) - self.initMapAction.setEnabled(True) - self.inventory_label.setText('Inventory set!') - self.new_inv_button.setText('Set another inventory file') + self.project.inventories = self.metadata.inventories + if self.metadata.inventories: + self.init_map_button.setEnabled(True) + self.initMapAction.setEnabled(True) + self.inventory_label.setText('Inventory set!') + self.setDirty(True) def get_new_metadata(self): - if hasattr(self, 'add_metadata_widget'): - self.add_metadata_widget.show() - else: - self.add_metadata_widget = AddMetadataWidget(self, metadata=self.metadata) - #self.init_metadata(new=True) - - def add_metadata(self): - pass + self.add_metadata_widget = AddMetadataWidget(self, metadata=self.metadata) + self.add_metadata_widget.close_button.clicked.connect(self.set_metadata) def init_metadata(self, new=False, ask_default=True): - def set_inv(settings): - fninv, _ = QFileDialog.getOpenFileName(self, self.tr( - "Select inventory..."), self.tr("Select file")) - if not fninv: - return False - ans = QMessageBox.question(self, self.tr("Make default..."), - self.tr( - "New inventory filename set.\n" + \ - "Do you want to make it the default value?"), - QMessageBox.Yes | QMessageBox.No, - QMessageBox.No) - if ans == QMessageBox.Yes: - settings.setValue("inventoryFile", fninv) - settings.sync() - self.read_metadata_thread(fninv) - return True - - settings = QSettings() - - if hasattr(self.project, 'metadata') and not new: - self.metadata = self.project.metadata - return True - if self.metadata and not new: - return True - if hasattr(self.project, 'inv_path') and not new: - settings.setValue("inventoryFile", self.project.inv_path) - - fninv = settings.value("inventoryFile", None) - if (fninv and ask_default) and not new: - ans = QMessageBox.question(self, self.tr("Use default metadata..."), - self.tr( - "Do you want to use the default value for metadata?\n({})".format(fninv)), - QMessageBox.Yes | QMessageBox.No, - QMessageBox.Yes) - if ans == QMessageBox.Yes: - self.read_metadata_thread(fninv) - return - set_inv(settings) + if hasattr(self.project, 'inventories'): + self.metadata = Metadata() + for inventory in self.project.inventories: + self.metadata.add_inventory(inventory) def calc_magnitude(self, type='ML'): self.init_metadata() @@ -3289,15 +3240,7 @@ class MainWindow(QMainWindow): self.tabs.setCurrentIndex(0) # implemented to prevent double-loading of waveform data self.init_events(new=True) self.setDirty(False) - if hasattr(self.project, 'metadata'): - if self.project.metadata: - self.init_metadata(ask_default=False) - # self.init_array_map(index=0) - return - if hasattr(self.project, 'inv_path'): - self.init_metadata(ask_default=False) - # self.init_array_map(index=0) - return + self.init_metadata() self.init_array_tab() diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index 91f7fe9d..85fb59a9 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -23,8 +23,7 @@ class Array_map(QtGui.QWidget): ''' QtGui.QWidget.__init__(self) self._parent = parent - self.metadata_type = parent.metadata[0] - self.metadata = parent.metadata[1] + self.metadata = parent.metadata self.picks = None self.picks_dict = None self.autopicks_dict = None @@ -160,33 +159,7 @@ class Array_map(QtGui.QWidget): self.main_box.addWidget(self.status_label, 0) def init_stations(self): - def stat_info_from_parser(parser): - stations_dict = {} - for station in parser.stations: - station_name = station[0].station_call_letters - network_name = station[0].network_code - if not station_name in stations_dict.keys(): - st_id = network_name + '.' + station_name - stations_dict[st_id] = {'latitude': station[0].latitude, - 'longitude': station[0].longitude} - return stations_dict - - def stat_info_from_inventory(inventory): - stations_dict = {} - for network in inventory.networks: - for station in network.stations: - station_name = station.code - network_name = network_name.code - if not station_name in stations_dict.keys(): - st_id = network_name + '.' + station_name - stations_dict[st_id] = {'latitude': station[0].latitude, - 'longitude': station[0].longitude} - return stations_dict - - read_stat = {'xml': stat_info_from_inventory, - 'dless': stat_info_from_parser} - - self.stations_dict = read_stat[self.metadata_type](self.metadata) + self.stations_dict = self.metadata.get_all_coordinates() self.latmin = self.get_min_from_stations('latitude') self.lonmin = self.get_min_from_stations('longitude') self.latmax = self.get_max_from_stations('latitude') @@ -195,13 +168,15 @@ class Array_map(QtGui.QWidget): def init_picks(self): def get_picks(station_dict): picks = {} + # selected phase phase = self.comboBox_phase.currentText() for st_id in station_dict.keys(): try: station_name = st_id.split('.')[-1] + # current_picks_dict: auto or manual pick = self.current_picks_dict()[station_name][phase] if pick['picker'] == 'auto': - if pick['weight'] > 3: + if not pick['spe']: continue picks[st_id] = pick['mpp'] except KeyError: @@ -216,11 +191,12 @@ class Array_map(QtGui.QWidget): for pick in picks.values(): if type(pick) is obspy.core.utcdatetime.UTCDateTime: picks_utc.append(pick) - self._earliest_picktime = min(picks_utc) - for st_id, pick in picks.items(): - if type(pick) is obspy.core.utcdatetime.UTCDateTime: - pick -= self._earliest_picktime - picks_rel[st_id] = pick + if picks_utc: + self._earliest_picktime = min(picks_utc) + for st_id, pick in picks.items(): + if type(pick) is obspy.core.utcdatetime.UTCDateTime: + pick -= self._earliest_picktime + picks_rel[st_id] = pick return picks_rel self.picks = get_picks(self.stations_dict) @@ -330,6 +306,8 @@ class Array_map(QtGui.QWidget): def scatter_picked_stations(self): picks, lats, lons = self.get_picks_lat_lon() + if len(lons) < 1 and len(lats) < 1: + return # workaround because of an issue with latlon transformation of arrays with len <3 if len(lons) <= 2 and len(lats) <= 2: self.sc_picked = self.basemap.scatter(lons[0], lats[0], s=50, facecolor='white', @@ -374,13 +352,16 @@ class Array_map(QtGui.QWidget): self.draw_everything() def draw_everything(self): - if self.picks_dict or self.autopicks_dict: + picktype = self.comboBox_am.currentText() + if (self.picks_dict and picktype == 'manual') \ + or (self.autopicks_dict and picktype == 'auto'): self.init_picks() if len(self.picks) >= 3: self.init_picksgrid() self.draw_contour_filled() self.scatter_all_stations() - if self.picks_dict or self.autopicks_dict: + if (self.picks_dict and picktype == 'manual') \ + or (self.autopicks_dict and picktype == 'auto'): self.scatter_picked_stations() self.cbar = self.add_cbar(label='Time relative to first onset ({}) [s]'.format(self._earliest_picktime)) self.comboBox_phase.setEnabled(True) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 0789187a..9dc95cf4 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -21,6 +21,7 @@ class Metadata(object): # saves filenames holding metadata for a seed_id # seed id as key, path to file as value self.seed_ids = {} + self.stations_dict = {} if inventory: if os.path.isdir(inventory): self.add_inventory(inventory) @@ -172,6 +173,37 @@ class Metadata(object): return return metadata['data'].get_coordinates(seed_id, time) + def get_all_coordinates(self): + def stat_info_from_parser(parser): + for station in parser.stations: + station_name = station[0].station_call_letters + network_name = station[0].network_code + if not station_name in self.stations_dict.keys(): + st_id = network_name + '.' + station_name + self.stations_dict[st_id] = {'latitude': station[0].latitude, + 'longitude': station[0].longitude} + + def stat_info_from_inventory(inventory): + for network in inventory.networks: + for station in network.stations: + station_name = station.code + network_name = network_name.code + if not station_name in self.stations_dict.keys(): + st_id = network_name + '.' + station_name + self.stations_dict[st_id] = {'latitude': station[0].latitude, + 'longitude': station[0].longitude} + + read_stat = {'xml': stat_info_from_inventory, + 'dless': stat_info_from_parser} + + self.read_all() + for item in self.inventory_files.values(): + inventory = item['data'] + invtype = item['invtype'] + read_stat[invtype](inventory) + + return self.stations_dict + def get_paz(self, seed_id, time): """ diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index a5198995..44d7b08b 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -145,6 +145,7 @@ class AddMetadataWidget(QWidget): self.resize(600, 800) self.metadata = metadata if metadata else Metadata() + self.from_metadata() self.center() self.show() @@ -199,6 +200,9 @@ class AddMetadataWidget(QWidget): self.close_button.setShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Escape)) self.main_layout.addWidget(self.close_button) + def from_metadata(self): + for inventory_path in self.metadata.inventories: + self.add_item(inventory_path, from_metadata=True) def refresh_list(self): self.clear_list() @@ -223,10 +227,10 @@ class AddMetadataWidget(QWidget): self.add_item(inventory_path) self.selection_box.setText('') - def add_item(self, inventory_path): + def add_item(self, inventory_path, from_metadata=False): if not inventory_path: return - if inventory_path in self.metadata.inventories: + if inventory_path in self.inventories.keys(): QMessageBox.warning(self, 'Info', 'Path already in list!') return if not os.path.isdir(inventory_path): @@ -237,7 +241,8 @@ class AddMetadataWidget(QWidget): self.inventories[inventory_path] = item self.list_model.appendRow(item) - self.metadata.add_inventory(inventory_path) + if not from_metadata: + self.metadata.add_inventory(inventory_path) def remove_item(self): for index in reversed(self.list_view.selectionModel().selectedIndexes()):