Merge branch 'develop'
This commit is contained in:
		
						commit
						795733cc5f
					
				
							
								
								
									
										398
									
								
								QtPyLoT.py
									
									
									
									
									
								
							
							
						
						
									
										398
									
								
								QtPyLoT.py
									
									
									
									
									
								
							| @ -41,6 +41,8 @@ from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \ | ||||
|     QTreeView, QComboBox, QTabWidget, QPushButton, QGridLayout | ||||
| import numpy as np | ||||
| from obspy import UTCDateTime | ||||
| from obspy.core.event import Magnitude | ||||
| from obspy.core.util import AttribDict | ||||
| 
 | ||||
| try: | ||||
|     import pyqtgraph as pg | ||||
| @ -70,6 +72,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 | ||||
| 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, \ | ||||
|     WaveformWidget, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \ | ||||
| @ -143,6 +146,7 @@ class MainWindow(QMainWindow): | ||||
|             self.data = Data(self, lastEvent) | ||||
|         else: | ||||
|             self.data = Data(self) | ||||
|             self.data._new = False | ||||
|         self.autodata = Data(self) | ||||
| 
 | ||||
|         if settings.value("user/FullName", None) is None: | ||||
| @ -172,8 +176,8 @@ class MainWindow(QMainWindow): | ||||
|         self.setupUi() | ||||
| 
 | ||||
|         self.filteroptions = {} | ||||
|         self.picks = {} | ||||
|         self.autopicks = {} | ||||
|         self.pylot_picks = {} | ||||
|         self.pylot_autopicks = {} | ||||
|         self.loc = False | ||||
| 
 | ||||
|     def setupUi(self): | ||||
| @ -311,21 +315,21 @@ class MainWindow(QMainWindow): | ||||
|         #                                    self.createNewEvent, | ||||
|         #                                    QKeySequence.New, newIcon, | ||||
|         #                                    "Create a new event.") | ||||
|         self.openmanualpicksaction = self.createAction(self, "Load &manual picks ...", | ||||
|         self.openmanualpicksaction = self.createAction(self, "Load event ...", | ||||
|                                                        self.load_data, | ||||
|                                                        "Ctrl+M", | ||||
|                                                        manupicksicon, | ||||
|                                                        "Load manual picks for " | ||||
|                                                        "Load event information for " | ||||
|                                                        "the displayed event.") | ||||
|         self.openmanualpicksaction.setEnabled(False) | ||||
|         self.openmanualpicksaction.setData(None) | ||||
| 
 | ||||
|         self.openautopicksaction = self.createAction(self, "Load &automatic picks ... ", | ||||
|                                                      self.load_autopicks, | ||||
|         self.openautopicksaction = self.createAction(self, "Load event information &automatically ... ", | ||||
|                                                      self.load_multiple_data, | ||||
|                                                      "Ctrl+A", | ||||
|                                                      autopicksicon, | ||||
|                                                      "Load automatic picks " | ||||
|                                                      "for the displayed event.") | ||||
|                                                      "Load event data automatically " | ||||
|                                                      "for for all events.") | ||||
|         self.openautopicksaction.setEnabled(False) | ||||
|         self.openautopicksaction.setData(None) | ||||
| 
 | ||||
| @ -637,23 +641,66 @@ class MainWindow(QMainWindow): | ||||
|         fname_dict = dict(phasfn=fn_phases, locfn=fn_loc) | ||||
|         self.load_data(fname_dict, type=type) | ||||
| 
 | ||||
|     def load_data(self, fname=None, type='manual', loc=False): | ||||
|     def load_multiple_data(self, type='manual'): | ||||
|         if not self.okToContinue(): | ||||
|             return | ||||
|         refresh=False | ||||
|         events = self.project.eventlist | ||||
|         fext = '.xml' | ||||
|         for event in events: | ||||
|             path = event.path | ||||
|             eventname = path.split('/')[-1] | ||||
|             filename = os.path.join(path, 'PyLoT_'+eventname+fext) | ||||
|             if os.path.isfile(filename): | ||||
|                 self.load_data(filename, draw=False, event=event, overwrite=True) | ||||
|                 refresh=True | ||||
|         if not refresh: | ||||
|             return | ||||
|         if self.get_current_event().pylot_picks: | ||||
|             self.refreshEvents() | ||||
|         self.setDirty(True) | ||||
| 
 | ||||
|     def load_data(self, fname=None, type='manual', loc=False, draw=True, event=None, overwrite=False): | ||||
|         if not overwrite: | ||||
|             if not self.okToContinue(): | ||||
|                 return | ||||
|         if fname is None: | ||||
|             action = self.sender() | ||||
|             if isinstance(action, QAction): | ||||
|                 fname = self.filename_from_action(action) | ||||
|                 if not fname: | ||||
|                     return | ||||
|         self.set_fname(fname, type) | ||||
|         data = dict(auto=self.autodata, manual=self.data) | ||||
|         data[type] += Data(self, evtdata=fname) | ||||
|         #data = dict(auto=self.autodata, manual=self.data) | ||||
|         if not event: | ||||
|             event = self.get_current_event() | ||||
|         data = Data(self, event) | ||||
|         try: | ||||
|             data_new = Data(self, evtdata=fname) | ||||
|             data += data_new | ||||
|         except ValueError: | ||||
|             qmb = QMessageBox(self, icon=QMessageBox.Question, | ||||
|                               text='Warning: Missmatch in event identifiers {} and {}. Continue?'.format( | ||||
|                                   data_new.get_evt_data().resource_id, | ||||
|                                   data.get_evt_data().resource_id), | ||||
|                               windowTitle='PyLoT - Load data warning') | ||||
|             qmb.setStandardButtons(QMessageBox.Yes | QMessageBox.No) | ||||
|             qmb.setDefaultButton(QMessageBox.No) | ||||
|             ret = qmb.exec_() | ||||
|             if ret == qmb.Yes: | ||||
|                 data_new.setNew() | ||||
|                 data += data_new | ||||
|             else: | ||||
|                 return | ||||
| 
 | ||||
|         self.data = data | ||||
|         print('Loading {} picks from file {}.'.format(type, fname)) | ||||
|         if not loc: | ||||
|             self.updatePicks(type=type) | ||||
|         if self.get_current_event().picks: | ||||
|             self.plotWaveformDataThread() | ||||
|         self.drawPicks(picktype=type) | ||||
|         self.draw() | ||||
|         self.setDirty(True) | ||||
|             self.updatePicks(type=type, event=event) | ||||
|         if draw: | ||||
|             if self.get_current_event().pylot_picks: | ||||
|                 self.refreshEvents() | ||||
|             self.setDirty(True) | ||||
| 
 | ||||
|     def add_recentfile(self, event): | ||||
|         self.recentfiles.insert(0, event) | ||||
| @ -676,8 +723,8 @@ class MainWindow(QMainWindow): | ||||
|     def getWFFnames(self): | ||||
|         try: | ||||
|             evt = self.get_data().get_evt_data() | ||||
|             if evt.picks: | ||||
|                 for pick in evt.picks: | ||||
|             if evt.pylot_picks: | ||||
|                 for pick in evt.pylot_picks: | ||||
|                     try: | ||||
|                         if pick.waveform_id is not None: | ||||
|                             fname = pick.waveform_id.getSEEDstring() | ||||
| @ -728,8 +775,8 @@ class MainWindow(QMainWindow): | ||||
|         ''' | ||||
|         if not eventbox: | ||||
|             eventbox = self.eventBox | ||||
|         index = eventbox.currentIndex() | ||||
|         return eventbox.itemData(index) | ||||
|         path = eventbox.currentText() | ||||
|         return self.project.getEventFromPath(path) | ||||
| 
 | ||||
|     def get_current_event_path(self, eventbox=None): | ||||
|         ''' | ||||
| @ -778,7 +825,7 @@ class MainWindow(QMainWindow): | ||||
|             dirs = { | ||||
|                 'database': path.split('/')[-2], | ||||
|                 'datapath': path.split('/')[-3], | ||||
|                 'rootpath': os.path.join(*path.split('/')[:-3]) | ||||
|                 'rootpath': '/'+os.path.join(*path.split('/')[:-3]) | ||||
|                     } | ||||
|         except Exception as e: | ||||
|             dirs = { | ||||
| @ -788,6 +835,10 @@ class MainWindow(QMainWindow): | ||||
|                     } | ||||
|             print('Warning: Could not automatically init folder structure. ({})'.format(e)) | ||||
|              | ||||
|         settings = QSettings() | ||||
|         settings.setValue("data/dataRoot", dirs['rootpath']) | ||||
|         settings.sync() | ||||
|          | ||||
|         if not self.project.eventlist: | ||||
|             #init parameter object | ||||
|             self.setParameter(show=False) | ||||
| @ -880,10 +931,10 @@ class MainWindow(QMainWindow): | ||||
|             event_path = event.path | ||||
|             event_npicks = 0 | ||||
|             event_nautopicks = 0 | ||||
|             if event.picks: | ||||
|                 event_npicks = len(event.picks) | ||||
|             if event.autopicks: | ||||
|                 event_nautopicks = len(event.autopicks) | ||||
|             if event.pylot_picks: | ||||
|                 event_npicks = len(event.pylot_picks) | ||||
|             if event.pylot_autopicks: | ||||
|                 event_nautopicks = len(event.pylot_autopicks) | ||||
|             event_ref = event.isRefEvent() | ||||
|             event_test = event.isTestEvent() | ||||
| 
 | ||||
| @ -929,7 +980,8 @@ class MainWindow(QMainWindow): | ||||
|                            '{} unequal {}.' | ||||
|                            .format(event.path, self.eventBox.itemText(id))) | ||||
|                 raise ValueError(message) | ||||
|             eventBox.setItemData(id, event) | ||||
|             #not working with obspy events | ||||
|             #eventBox.setItemData(id, event) | ||||
|         eventBox.setCurrentIndex(index) | ||||
|         self.refreshRefTestButtons() | ||||
| 
 | ||||
| @ -940,7 +992,7 @@ class MainWindow(QMainWindow): | ||||
|             caption = "Open an event file" | ||||
|             fname = QFileDialog().getOpenFileName(self, caption=caption, | ||||
|                                                   filter=filt, | ||||
|                                                   dir=self.getRoot()) | ||||
|                                                   dir=self.get_current_event_path()) | ||||
|             fname = fname[0] | ||||
|         else: | ||||
|             fname = str(action.data().toString()) | ||||
| @ -965,7 +1017,7 @@ class MainWindow(QMainWindow): | ||||
|             print('warning: {0}'.format(e)) | ||||
|             directory = self.get_current_event_path() | ||||
|             eventname = self.get_current_event_name() | ||||
|             filename = 'picks_'+eventname | ||||
|             filename = 'PyLoT_'+eventname | ||||
|             outpath = os.path.join(directory, filename) | ||||
|             file_filter = "QuakeML file (*.xml);;VELEST observation file " \ | ||||
|                           "format (*.cnv);;NonLinLoc observation file (*.obs)" | ||||
| @ -986,7 +1038,7 @@ class MainWindow(QMainWindow): | ||||
|         fbasename = self.getEventFileName() | ||||
|         exform = settings.value('data/exportFormat', 'QUAKEML') | ||||
|         try: | ||||
|             self.get_data().applyEVTData(self.getPicks()) | ||||
|             self.get_data().applyEVTData(self.get_current_event(), typ='event')#getPicks()) | ||||
|         except OverwriteError: | ||||
|         #     msgBox = QMessageBox() | ||||
|         #     msgBox.setText("Picks have been modified!") | ||||
| @ -1056,7 +1108,7 @@ class MainWindow(QMainWindow): | ||||
|             return self.get_current_event().getPicks() | ||||
|         if type == 'auto': | ||||
|             return self.get_current_event().getAutopicks() | ||||
|         # rdict = dict(auto=self.autopicks, manual=self.picks) | ||||
|         # rdict = dict(auto=self.pylot_autopicks, manual=self.pylot_picks) | ||||
|         # return rdict[type] | ||||
| 
 | ||||
|     def getPicksOnStation(self, station, type='manual'): | ||||
| @ -1130,7 +1182,7 @@ class MainWindow(QMainWindow): | ||||
|         if event: | ||||
|             self.ref_event_button.setChecked(event.isRefEvent()) | ||||
|             self.test_event_button.setChecked(event.isTestEvent()) | ||||
|             self.enableRefTestButtons(bool(self.get_current_event().picks)) | ||||
|             self.enableRefTestButtons(bool(self.get_current_event().pylot_picks)) | ||||
|             return | ||||
|         self.ref_event_button.setChecked(False) | ||||
|         self.test_event_button.setChecked(False) | ||||
| @ -1189,14 +1241,14 @@ class MainWindow(QMainWindow): | ||||
|             if not event: | ||||
|                 return | ||||
|             # update picks saved in GUI mainwindow (to be changed in future!!) MP MP | ||||
|             if not event.picks: | ||||
|                 self.picks = {} | ||||
|             if not event.pylot_picks: | ||||
|                 self.pylot_picks = {} | ||||
|             else: | ||||
|                 self.picks = event.picks | ||||
|             if not event.autopicks: | ||||
|                 self.autopicks = {} | ||||
|                 self.pylot_picks = event.pylot_picks | ||||
|             if not event.pylot_autopicks: | ||||
|                 self.pylot_autopicks = {} | ||||
|             else: | ||||
|                 self.autopicks = event.autopicks | ||||
|                 self.pylot_autopicks = event.pylot_autopicks | ||||
|         # if current tab is waveformPlot-tab and the data in this tab was not yet refreshed | ||||
|         if self.tabs.currentIndex() == 0: | ||||
|             if self._eventChanged[0]: | ||||
| @ -1342,12 +1394,12 @@ class MainWindow(QMainWindow): | ||||
|         self.openautopicksaction.setEnabled(True) | ||||
|         self.loadpilotevent.setEnabled(True) | ||||
|         event = self.get_current_event() | ||||
|         if event.picks: | ||||
|             self.picks = event.picks | ||||
|         if event.pylot_picks: | ||||
|             self.pylot_picks = event.pylot_picks | ||||
|             self.drawPicks(picktype='manual') | ||||
|             self.enableSaveManualPicksAction() | ||||
|         if event.autopicks: | ||||
|             self.autopicks = event.autopicks | ||||
|         if event.pylot_autopicks: | ||||
|             self.pylot_autopicks = event.pylot_autopicks | ||||
|             self.drawPicks(picktype='auto') | ||||
|             self.compare_action.setEnabled(True) | ||||
|         self.draw() | ||||
| @ -1722,14 +1774,16 @@ class MainWindow(QMainWindow): | ||||
|         #         raise Exception('FATAL: Should never occur!') | ||||
|         # MP MP prompt redundant because new picks have to be accepted in the first place closing PickDlg | ||||
| 
 | ||||
|     def updatePicks(self, type='manual'): | ||||
|     def updatePicks(self, type='manual', event=None): | ||||
|         if not event: | ||||
|             event = self.get_current_event() | ||||
|         picks = picksdict_from_picks(evt=self.get_data(type).get_evt_data()) | ||||
|         if type == 'manual': | ||||
|             self.get_current_event().addPicks(picks) | ||||
|             self.picks.update(picks) | ||||
|             event.addPicks(picks) | ||||
|             self.pylot_picks.update(picks) | ||||
|         elif type == 'auto': | ||||
|             self.get_current_event().addAutopicks(picks)             | ||||
|             self.autopicks.update(picks) | ||||
|             event.addAutopicks(picks)             | ||||
|             self.pylot_autopicks.update(picks) | ||||
|         self.check4Comparison() | ||||
| 
 | ||||
|     def drawPicks(self, station=None, picktype='manual'): | ||||
| @ -1766,7 +1820,7 @@ class MainWindow(QMainWindow): | ||||
| 
 | ||||
|         for phase in stat_picks: | ||||
|             picks = stat_picks[phase] | ||||
|             if type(stat_picks[phase]) is not dict: | ||||
|             if type(stat_picks[phase]) is not dict and type(stat_picks[phase]) is not AttribDict: | ||||
|                 return | ||||
|             colors = phase_col[phase[0].upper()] | ||||
| 
 | ||||
| @ -1880,8 +1934,8 @@ class MainWindow(QMainWindow): | ||||
|         finally: | ||||
|             os.remove(phasepath) | ||||
| 
 | ||||
|         self.get_data().applyEVTData(lt.read_location(locpath), type='event') | ||||
|         self.get_data().applyEVTData(self.calc_magnitude(), type='event') | ||||
|         self.get_data().applyEVTData(lt.read_location(locpath), typ='event') | ||||
|         self.get_data().applyEVTData(self.calc_magnitude(), typ='event') | ||||
| 
 | ||||
|     def init_array_tab(self): | ||||
|         ''' | ||||
| @ -1966,6 +2020,12 @@ class MainWindow(QMainWindow): | ||||
|         if not self.array_map: | ||||
|             return | ||||
|         # refresh with new picks here!!! | ||||
|         event = self.get_current_event() | ||||
|         if hasattr(event, 'origins'): | ||||
|             if event.origins: | ||||
|                 lat = event.origins[0].latitude | ||||
|                 lon = event.origins[0].longitude | ||||
|                 self.array_map.eventLoc = (lat, lon) | ||||
|         self.array_map.refresh_drawings(self.get_current_event().getPicks()) | ||||
|         self._eventChanged[1] = False | ||||
| 
 | ||||
| @ -1992,19 +2052,19 @@ class MainWindow(QMainWindow): | ||||
|             # changes attributes of the corresponding event | ||||
|             table = self.project._table | ||||
|             event = self.project.getEventFromPath(table[row][0].text()) | ||||
|             if column == 3 or column == 4: | ||||
|             if column == 8 or column == 9: | ||||
|                 #toggle checked states (exclusive) | ||||
|                 item_ref = table[row][3] | ||||
|                 item_test = table[row][4] | ||||
|                 if column == 3 and item_ref.checkState(): | ||||
|                 item_ref = table[row][8] | ||||
|                 item_test = table[row][9] | ||||
|                 if column == 8 and item_ref.checkState(): | ||||
|                     item_test.setCheckState(QtCore.Qt.Unchecked) | ||||
|                     event.setRefEvent(True) | ||||
|                 elif column == 3 and not item_ref.checkState(): | ||||
|                 elif column == 8 and not item_ref.checkState(): | ||||
|                     event.setRefEvent(False)                     | ||||
|                 elif column == 4 and item_test.checkState(): | ||||
|                 elif column == 9 and item_test.checkState(): | ||||
|                     item_ref.setCheckState(QtCore.Qt.Unchecked) | ||||
|                     event.setTestEvent(True) | ||||
|                 elif column == 4 and not item_test.checkState(): | ||||
|                 elif column == 9 and not item_test.checkState(): | ||||
|                     event.setTestEvent(False) | ||||
|                 self.fill_eventbox() | ||||
|             elif column == 5: | ||||
| @ -2020,22 +2080,35 @@ class MainWindow(QMainWindow): | ||||
|              | ||||
|         # init new qtable | ||||
|         self.event_table = QtGui.QTableWidget() | ||||
|         self.event_table.setColumnCount(6) | ||||
|         self.event_table.setColumnCount(11) | ||||
|         self.event_table.setRowCount(len(eventlist)) | ||||
|         self.event_table.setHorizontalHeaderLabels(['Event', '[N] MP', | ||||
|                                             '[N] AP', 'Tuning Set', | ||||
|                                             'Test Set', 'Notes']) | ||||
|         self.event_table.setHorizontalHeaderLabels(['Event', | ||||
|                                                     'Time', | ||||
|                                                     'Lat', | ||||
|                                                     'Lon', | ||||
|                                                     'Depth', | ||||
|                                                     'Mag', | ||||
|                                                     '[N] MP', | ||||
|                                                     '[N] AP', | ||||
|                                                     'Tuning Set', | ||||
|                                                     'Test Set', | ||||
|                                                     'Notes']) | ||||
| 
 | ||||
|         # iterate through eventlist and generate items for table rows | ||||
|         self.project._table = [] | ||||
|         for index, event in enumerate(eventlist): | ||||
|             event_npicks = 0 | ||||
|             event_nautopicks = 0 | ||||
|             if event.picks: | ||||
|                 event_npicks = len(event.picks) | ||||
|             if event.autopicks: | ||||
|                 event_nautopicks = len(event.autopicks) | ||||
|             if event.pylot_picks: | ||||
|                 event_npicks = len(event.pylot_picks) | ||||
|             if event.pylot_autopicks: | ||||
|                 event_nautopicks = len(event.pylot_autopicks) | ||||
|             item_path = QtGui.QTableWidgetItem() | ||||
|             item_time = QtGui.QTableWidgetItem() | ||||
|             item_lat = QtGui.QTableWidgetItem() | ||||
|             item_lon = QtGui.QTableWidgetItem() | ||||
|             item_depth = QtGui.QTableWidgetItem() | ||||
|             item_mag = QtGui.QTableWidgetItem()                         | ||||
|             item_nmp = QtGui.QTableWidgetItem(str(event_npicks)) | ||||
|             item_nmp.setIcon(self.manupicksicon_small) | ||||
|             item_nap = QtGui.QTableWidgetItem(str(event_nautopicks)) | ||||
| @ -2047,11 +2120,23 @@ class MainWindow(QMainWindow): | ||||
|             item_ref.setBackground(self._colors['ref']) | ||||
|             item_test.setBackground(self._colors['test']) | ||||
|             item_path.setText(event.path) | ||||
|             item_notes.setText(event.notes)             | ||||
|             if hasattr(event, 'origins'): | ||||
|                 if event.origins: | ||||
|                     origin = event.origins[0] | ||||
|                     item_time.setText(str(origin.time).split('.')[0]) | ||||
|                     item_lon.setText(str(origin.longitude)) | ||||
|                     item_lat.setText(str(origin.latitude)) | ||||
|                     item_depth.setText(str(origin.depth)) | ||||
|             if hasattr(event, 'magnitudes'): | ||||
|                 if event.magnitudes: | ||||
|                     magnitude = event.magnitudes[0] | ||||
|                     item_mag.setText(str(magnitude.mag)) | ||||
|             item_notes.setText(event.notes) | ||||
|              | ||||
|             set_enabled(item_path, True, False) | ||||
|             set_enabled(item_nmp, True, False) | ||||
|             set_enabled(item_nap, True, False) | ||||
|             if event.picks: | ||||
|             if event.pylot_picks: | ||||
|                 set_enabled(item_ref, True, True) | ||||
|                 set_enabled(item_test, True, True) | ||||
|             else: | ||||
| @ -2067,7 +2152,8 @@ class MainWindow(QMainWindow): | ||||
|             else: | ||||
|                 item_test.setCheckState(QtCore.Qt.Unchecked) | ||||
|                  | ||||
|             column=[item_path, item_nmp, item_nap, item_ref, item_test, item_notes] | ||||
|             column=[item_path, item_time, item_lat, item_lon, item_depth, item_mag, | ||||
|                     item_nmp, item_nap, item_ref, item_test, item_notes] | ||||
|             self.project._table.append(column) | ||||
| 
 | ||||
|         for r_index, row in enumerate(self.project._table): | ||||
| @ -2315,7 +2401,7 @@ class MainWindow(QMainWindow): | ||||
|         self.setDirty(True) | ||||
|          | ||||
|     def setDirty(self, value): | ||||
|         self.saveProjectAction.setEnabled(value) | ||||
|         self.saveProjectAction.setEnabled(bool(self.get_current_event().picks)) | ||||
|         self.saveProjectAsAction.setEnabled(True) | ||||
|         self.project.setDirty(value) | ||||
|         self.dirty = value | ||||
| @ -2382,6 +2468,63 @@ class Project(object): | ||||
|                 self.setDirty() | ||||
|             else: | ||||
|                 print('Skipping event with path {}. Already part of project.'.format(event.path)) | ||||
|         self.search_eventfile_info() | ||||
| 
 | ||||
|     def read_eventfile_info(self, filename, separator=','): | ||||
|         ''' | ||||
|         Try to read event information from file (:param:filename) comparing specific event datetimes. | ||||
|         File structure (each row): event, date, time, magnitude, latitude, longitude, depth | ||||
|         separated by :param:separator each. | ||||
|         ''' | ||||
|         infile = open(filename, 'r') | ||||
|         for line in infile.readlines(): | ||||
|             event, date, time, mag, lat, lon, depth  = line.split(separator)[:7] | ||||
|             #skip first line | ||||
|             try: | ||||
|                 month, day, year = date.split('/') | ||||
|             except: | ||||
|                 continue | ||||
|             year = int(year) | ||||
|             #hardcoded, if year only consists of 2 digits (e.g. 16 instead of 2016) | ||||
|             if year<100: | ||||
|                 year += 2000 | ||||
|             datetime = '{}-{}-{}T{}'.format(year, month, day, time)                 | ||||
|             try: | ||||
|                 datetime = UTCDateTime(datetime) | ||||
|             except Exception as e: | ||||
|                 print(e, datetime, filename) | ||||
|                 continue | ||||
|             for event in self.eventlist: | ||||
|                 if not event.origins: | ||||
|                     continue | ||||
|                 origin = event.origins[0] #should have only one origin | ||||
|                 if origin.time == datetime: | ||||
|                     origin.latitude = float(lat) | ||||
|                     origin.longitude = float(lon) | ||||
|                     origin.depth = float(depth) | ||||
|                     event.magnitudes.append(Magnitude(resource_id=event.resource_id, | ||||
|                                                       mag=float(mag), | ||||
|                                                       mag_type='M')) | ||||
|                      | ||||
|     def search_eventfile_info(self): | ||||
|         ''' | ||||
|         Search all datapaths in rootpath for filenames with given file extension fext | ||||
|         and try to read event info from it | ||||
|         ''' | ||||
|         datapaths = [] | ||||
|         fext='.csv' | ||||
|         for event in self.eventlist: | ||||
|             if not event.datapath in datapaths: | ||||
|                 datapaths.append(event.datapath) | ||||
|         for datapath in datapaths: | ||||
|             datapath = os.path.join(self.rootpath, datapath) | ||||
|             for filename in os.listdir(datapath): | ||||
|                 filename = os.path.join(datapath, filename) | ||||
|                 if os.path.isfile(filename) and filename.endswith(fext): | ||||
|                     try: | ||||
|                         self.read_eventfile_info(filename) | ||||
|                     except Exception as e: | ||||
|                         print('Failed on reading eventfile info from file {}: {}'.format(filename, e)) | ||||
| 
 | ||||
|     def getPaths(self): | ||||
|         ''' | ||||
| @ -2442,123 +2585,6 @@ class Project(object): | ||||
|         return project | ||||
|      | ||||
| 
 | ||||
| class Event(object): | ||||
|     ''' | ||||
|     Pickable class containing information on a single event. | ||||
|     ''' | ||||
|     def __init__(self, path): | ||||
|         self.path = path | ||||
|         self.database = path.split('/')[-2] | ||||
|         self.datapath = path.split('/')[-3] | ||||
|         self.rootpath = os.path.join(*path.split('/')[:-3]) | ||||
|         self.autopicks = {} | ||||
|         self.picks = {} | ||||
|         self.notes = '' | ||||
|         self._testEvent = False | ||||
|         self._refEvent = False | ||||
|         try: | ||||
|             self.get_notes() | ||||
|         except: | ||||
|             pass | ||||
| 
 | ||||
|     def get_notes_path(self): | ||||
|         notesfile = os.path.join(self.path, 'notes.txt') | ||||
|         return notesfile | ||||
|      | ||||
|     def get_notes(self): | ||||
|         notesfile = self.get_notes_path() | ||||
|         if os.path.isfile(notesfile): | ||||
|             with open(notesfile) as infile: | ||||
|                 text = '[eventInfo: '+str(infile.readlines()[0].split('\n')[0])+']' | ||||
|                 self.addNotes(text) | ||||
| 
 | ||||
|     def addNotes(self, notes): | ||||
|         self.notes = str(notes) | ||||
| 
 | ||||
|     def clearNotes(self): | ||||
|         self.notes = None | ||||
| 
 | ||||
|     def isRefEvent(self): | ||||
|         return self._refEvent | ||||
| 
 | ||||
|     def isTestEvent(self): | ||||
|         return self._testEvent | ||||
| 
 | ||||
|     def setRefEvent(self, bool): | ||||
|         self._refEvent = bool | ||||
|         if bool: self._testEvent = False | ||||
| 
 | ||||
|     def setTestEvent(self, bool): | ||||
|         self._testEvent = bool | ||||
|         if bool: self._refEvent = False | ||||
| 
 | ||||
|     def addPicks(self, picks): | ||||
|         for station in picks: | ||||
|             self.picks[station] = picks[station] | ||||
|          | ||||
|     def addAutopicks(self, autopicks): | ||||
|         for station in autopicks: | ||||
|             self.autopicks[station] = autopicks[station] | ||||
|          | ||||
|     def setPick(self, station, pick): | ||||
|         if pick: | ||||
|             self.picks[station] = pick | ||||
| 
 | ||||
|     def setPicks(self, picks): | ||||
|         self.picks = picks | ||||
|          | ||||
|     def getPick(self, station): | ||||
|         if station in self.picks.keys(): | ||||
|             return self.picks[station] | ||||
| 
 | ||||
|     def getPicks(self): | ||||
|         return self.picks | ||||
| 
 | ||||
|     def setAutopick(self, station, autopick): | ||||
|         if autopick: | ||||
|             self.autopicks[station] = autopick | ||||
| 
 | ||||
|     def setAutopicks(self, autopicks): | ||||
|         self.autopicks = autopicks | ||||
|          | ||||
|     def getAutopick(self, station): | ||||
|         if station in self.autopicks.keys(): | ||||
|             return self.autopicks[station] | ||||
| 
 | ||||
|     def getAutopicks(self): | ||||
|         return self.autopicks | ||||
| 
 | ||||
|     def save(self, filename): | ||||
|         ''' | ||||
|         Save PyLoT Event to a file.  | ||||
|         Can be loaded by using event.load(filename). | ||||
|         ''' | ||||
|         try: | ||||
|             import cPickle | ||||
|         except ImportError: | ||||
|             import _pickle as cPickle | ||||
| 
 | ||||
|         try: | ||||
|             outfile = open(filename, 'wb') | ||||
|             cPickle.dump(self, outfile, -1) | ||||
|         except Exception as e: | ||||
|             print('Could not pickle PyLoT event. Reason: {}'.format(e)) | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def load(filename): | ||||
|         ''' | ||||
|         Load project from filename. | ||||
|         ''' | ||||
|         try: | ||||
|             import cPickle | ||||
|         except ImportError: | ||||
|             import _pickle as cPickle | ||||
|         infile = open(filename, 'rb') | ||||
|         event = cPickle.load(infile) | ||||
|         print('Loaded %s' % filename) | ||||
|         return event | ||||
| 
 | ||||
|      | ||||
| class getExistingDirectories(QFileDialog): | ||||
|     ''' | ||||
|     File dialog with possibility to select multiple folders. | ||||
|  | ||||
							
								
								
									
										81
									
								
								autoPyLoT.py
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								autoPyLoT.py
									
									
									
									
									
								
							| @ -98,8 +98,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even | ||||
| 
 | ||||
|         exf = ['root', 'dpath', 'dbase'] | ||||
|          | ||||
|         if parameter.hasParam('eventID') and fnames == 'None': | ||||
|             dsfields['eventID'] = parameter.get('eventID') | ||||
|         if parameter['eventID'] is not '*' and fnames == 'None': | ||||
|             dsfields['eventID'] = parameter['eventID'] | ||||
|             exf.append('eventID') | ||||
| 
 | ||||
|         datastructure.modifyFields(**dsfields) | ||||
| @ -133,13 +133,13 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even | ||||
|         if not input_dict: | ||||
|             # started in production mode | ||||
|             datapath = datastructure.expandDataPath() | ||||
|             if fnames == 'None' and not parameter['eventID']: | ||||
|             if fnames == 'None' and parameter['eventID'] is '*': | ||||
|                 # multiple event processing | ||||
|                 # read each event in database | ||||
|                 events = [events for events in glob.glob(os.path.join(datapath, '*')) if os.path.isdir(events)] | ||||
|             elif fnames == 'None' and parameter['eventID']: | ||||
|             elif fnames == 'None' and parameter['eventID'] is not '*': | ||||
|                 # single event processing | ||||
|                 events = glob.glob(os.path.join(datapath, parameter.get('eventID'))) | ||||
|                 events = glob.glob(os.path.join(datapath, parameter['eventID'])) | ||||
|             else: | ||||
|                 # autoPyLoT was initialized from GUI | ||||
|                 events = [] | ||||
| @ -243,7 +243,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even | ||||
|                         # get latest NLLoc-location file if several are available | ||||
|                         nllocfile = max(glob.glob(locsearch), key=os.path.getctime) | ||||
|                         evt = read_events(nllocfile)[0] | ||||
|                         # calculating seismic moment Mo and moment magnitude Mw | ||||
|                         # calculate seismic moment Mo and moment magnitude Mw | ||||
|                         moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'), | ||||
|                                                      parameter.get('Qp'), | ||||
|                                                      parameter.get('rho'), True, \ | ||||
| @ -252,15 +252,29 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even | ||||
|                         for station, props in moment_mag.moment_props.items(): | ||||
|                             picks[station]['P'].update(props) | ||||
|                         evt = moment_mag.updated_event() | ||||
|                         net_mw = moment_mag.net_magnitude() | ||||
|                         print("Network moment magnitude: %4.1f" % net_mw.mag) | ||||
|                         # calculate local (Richter) magntiude | ||||
|                         WAscaling = parameter.get('WAscaling') | ||||
|                         magscaling = parameter.get('magscaling') | ||||
|                         local_mag = LocalMagnitude(corr_dat, evt, | ||||
|                                                    parameter.get('sstop'), parameter.get('WAscaling'), \ | ||||
|                                                    True, iplot) | ||||
|                                                    parameter.get('sstop'),  | ||||
|                                                    WAscaling, True, iplot) | ||||
|                         for station, amplitude in local_mag.amplitudes.items(): | ||||
|                             picks[station]['S']['Ao'] = amplitude.generic_amplitude | ||||
|                         evt = local_mag.updated_event() | ||||
|                         print("Local station magnitudes scaled with:") | ||||
|                         print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],  | ||||
|                                                                        WAscaling[1], | ||||
|                                                                        WAscaling[2])) | ||||
|                         evt = local_mag.updated_event(magscaling) | ||||
|                         net_ml = local_mag.net_magnitude(magscaling) | ||||
|                         print("Network local magnitude: %4.1f" % net_ml.mag) | ||||
|                         print("Network local magnitude scaled with:") | ||||
|                         print("%f * Ml + %f" % (magscaling[0], magscaling[1])) | ||||
|                     else: | ||||
|                         print("autoPyLoT: No NLLoc-location file available!") | ||||
|                         print("No source parameter estimation possible!") | ||||
|                         locflag = 9 | ||||
|                 else: | ||||
|                     # get theoretical P-onset times from NLLoc-location file | ||||
|                     locsearch = '%s/loc/%s.????????.??????.grid?.loc.hyp' % (nllocroot, nllocout) | ||||
| @ -301,7 +315,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even | ||||
|                                 nlloccounter = maxnumit | ||||
|                         evt = read_events(nllocfile)[0] | ||||
|                         if locflag < 2: | ||||
|                             # calculating seismic moment Mo and moment magnitude Mw | ||||
|                             # calculate seismic moment Mo and moment magnitude Mw | ||||
|                             moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'), | ||||
|                                                          parameter.get('Qp'), | ||||
|                                                          parameter.get('rho'), True, \ | ||||
| @ -310,14 +324,25 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even | ||||
|                             for station, props in moment_mag.moment_props.items(): | ||||
|                                 picks[station]['P'].update(props) | ||||
|                             evt = moment_mag.updated_event() | ||||
|                             local_mag = LocalMagnitude(corr_dat, evt, | ||||
|                                                        parameter.get('sstop'), parameter.get('WAscaling'), \ | ||||
|                                                        True, iplot) | ||||
|                             for station, amplitude in local_mag.amplitudes.items(): | ||||
|                                 picks[station]['S']['Ao'] = amplitude.generic_amplitude | ||||
|                             evt = local_mag.updated_event() | ||||
|                             net_mw = moment_mag.net_magnitude() | ||||
|                             print("Network moment magnitude: %4.1f" % net_mw.mag) | ||||
|                             # calculate local (Richter) magntiude | ||||
|                             WAscaling = parameter.get('WAscaling') | ||||
|                             magscaling = parameter.get('magscaling') | ||||
|                             local_mag = LocalMagnitude(corr_dat, evt, | ||||
|                                                        parameter.get('sstop'),  | ||||
|                                                        WAscaling, True, iplot) | ||||
|                             for station, amplitude in local_mag.amplitudes.items(): | ||||
|                                 picks[station]['S']['Ao'] = amplitude.generic_amplitude | ||||
|                             print("Local station magnitudes scaled with:") | ||||
|                             print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],  | ||||
|                                                                            WAscaling[1], | ||||
|                                                                            WAscaling[2])) | ||||
|                             evt = local_mag.updated_event(magscaling) | ||||
|                             net_ml = local_mag.net_magnitude(magscaling) | ||||
|                             print("Network local magnitude: %4.1f" % net_ml.mag) | ||||
|                             print("Network local magnitude scaled with:") | ||||
|                             print("%f * Ml + %f" % (magscaling[0], magscaling[1])) | ||||
|                     else: | ||||
|                         print("autoPyLoT: No NLLoc-location file available! Stop iteration!") | ||||
|                         locflag = 9 | ||||
| @ -328,26 +353,26 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even | ||||
|             data.applyEVTData(picks) | ||||
|             if evt is not None: | ||||
|                 data.applyEVTData(evt, 'event') | ||||
|             fnqml = '%s/autoPyLoT' % event | ||||
|             data.exportEvent(fnqml) | ||||
|             # HYPO71 | ||||
|             hypo71file = '%s/autoPyLoT_HYPO71_phases' % event | ||||
|             hypo71.export(picks, hypo71file, parameter) | ||||
|             # HYPOSAT | ||||
|             hyposatfile = '%s/autoPyLoT_HYPOSAT_phases' % event | ||||
|             hyposat.export(picks, hyposatfile, parameter) | ||||
|             fnqml = '%s/PyLoT_%s' % (event, evID) | ||||
|             data.exportEvent(fnqml, fnext='.xml', fcheck='manual') | ||||
|             if locflag == 1: | ||||
|                 # HYPO71 | ||||
|                 hypo71file = '%s/PyLoT_%s_HYPO71_phases' % (event, evID) | ||||
|                 hypo71.export(picks, hypo71file, parameter) | ||||
|                 # HYPOSAT | ||||
|                 hyposatfile = '%s/PyLoT_%s_HYPOSAT_phases' % (event, evID) | ||||
|                 hyposat.export(picks, hyposatfile, parameter) | ||||
|             	# VELEST | ||||
|             	velestfile = '%s/autoPyLoT_VELEST_phases.cnv' % event | ||||
|             	velestfile = '%s/PyLoT_%s_VELEST_phases.cnv' % (event, evID) | ||||
|             	velest.export(picks, velestfile, parameter, evt) | ||||
|             	# hypoDD | ||||
|             	hypoddfile = '%s/autoPyLoT_hypoDD_phases.pha' % event | ||||
|             	hypoddfile = '%s/PyLoT_%s_hypoDD_phases.pha' % (event, evID) | ||||
|             	hypodd.export(picks, hypoddfile, parameter, evt) | ||||
|             	# FOCMEC | ||||
|             	focmecfile = '%s/autoPyLoT_FOCMEC.in' % event | ||||
|             	focmecfile = '%s/PyLoT_%s_FOCMEC.in' % (event, evID) | ||||
|             	focmec.export(picks, focmecfile, parameter, evt) | ||||
|             	# HASH | ||||
|             	hashfile = '%s/autoPyLoT_HASH' % event | ||||
|             	hashfile = '%s/PyLoT_%s_HASH' % (event, evID) | ||||
|             	hash.export(picks, hashfile, parameter, evt) | ||||
| 
 | ||||
|             endsplash = '''------------------------------------------\n' | ||||
|  | ||||
| @ -1 +0,0 @@ | ||||
| f91e1-dirty | ||||
| @ -2,6 +2,7 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| """ | ||||
| Created autumn/winter 2015. | ||||
| Revised/extended summer 2017. | ||||
| 
 | ||||
| :author: Ludger Küperkoch / MAGS2 EP3 working group | ||||
| """ | ||||
| @ -115,23 +116,30 @@ class Magnitude(object): | ||||
|     def calc(self): | ||||
|         pass | ||||
| 
 | ||||
|     def updated_event(self): | ||||
|         self.event.magnitudes.append(self.net_magnitude()) | ||||
|     def updated_event(self, magscaling=None): | ||||
|         self.event.magnitudes.append(self.net_magnitude(magscaling)) | ||||
|         return self.event | ||||
| 
 | ||||
|     def net_magnitude(self): | ||||
|     def net_magnitude(self, magscaling=None): | ||||
|         if self: | ||||
|             # TODO if an average Magnitude instead of the median is calculated | ||||
|             # StationMagnitudeContributions should be added to the returned | ||||
|             # Magnitude object | ||||
|             # mag_error => weights (magnitude error estimate from peak_to_peak, calcsourcespec?) | ||||
|             # weights => StationMagnitdeContribution | ||||
|             mag = ope.Magnitude( | ||||
|                 mag=np.median([M.mag for M in self.magnitudes.values()]), | ||||
|                 magnitude_type=self.type, | ||||
|                 origin_id=self.origin_id, | ||||
|                 station_count=len(self.magnitudes), | ||||
|                 azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap) | ||||
|             if magscaling is not None and str(magscaling) is not '[0.0, 0.0]': | ||||
|                 # scaling necessary | ||||
|                 print("Scaling network magnitude ...") | ||||
|                 mag = ope.Magnitude( | ||||
|                     mag=np.median([M.mag for M in self.magnitudes.values()]) *\ | ||||
|                                    magscaling[0] + magscaling[1], | ||||
|                     magnitude_type=self.type, | ||||
|                     origin_id=self.origin_id, | ||||
|                     station_count=len(self.magnitudes), | ||||
|                     azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap) | ||||
|             else: | ||||
|                 # no saling necessary | ||||
|                 mag = ope.Magnitude( | ||||
|                     mag=np.median([M.mag for M in self.magnitudes.values()]), | ||||
|                     magnitude_type=self.type, | ||||
|                     origin_id=self.origin_id, | ||||
|                     station_count=len(self.magnitudes), | ||||
|                     azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap) | ||||
|             return mag | ||||
|         return None | ||||
| 
 | ||||
| @ -153,7 +161,7 @@ class LocalMagnitude(Magnitude): | ||||
| 
 | ||||
|     _amplitudes = dict() | ||||
| 
 | ||||
|     def __init__(self, stream, event, calc_win, wascaling=None, verbosity=False, iplot=0): | ||||
|     def __init__(self, stream, event, calc_win, wascaling, verbosity=False, iplot=0): | ||||
|         super(LocalMagnitude, self).__init__(stream, event, verbosity, iplot) | ||||
| 
 | ||||
|         self._calc_win = calc_win | ||||
| @ -207,6 +215,8 @@ class LocalMagnitude(Magnitude): | ||||
|         th = np.arange(0, len(sqH) * dt, dt) | ||||
|         # get maximum peak within pick window | ||||
|         iwin = getsignalwin(th, t0 - stime, self.calc_win) | ||||
|         ii = min([iwin[len(iwin)-1], len(th)]) | ||||
|         iwin = iwin[0:ii] | ||||
|         wapp = np.max(sqH[iwin]) | ||||
|         if self.verbose: | ||||
|             print("Determined Wood-Anderson peak-to-peak amplitude for station {0}: {1} " | ||||
| @ -257,12 +267,13 @@ class LocalMagnitude(Magnitude): | ||||
|             self.amplitudes = (station, amplitude) | ||||
|             # using standard Gutenberg-Richter relation | ||||
|             # or scale WA amplitude with given scaling relation | ||||
|             if self.wascaling == None: | ||||
|             if str(self.wascaling) == '[0.0, 0.0, 0.0]': | ||||
|                 print("Calculating original Richter magnitude ...") | ||||
|                 magnitude = ope.StationMagnitude(mag=np.log10(a0) \ | ||||
|                             + richter_magnitude_scaling(delta)) | ||||
|             else: | ||||
|                 print("Calculating scaled local magnitude ...") | ||||
|                 a0 = a0 * 1e03 # mm to nm (see Havskov & Ottemöller, 2010) | ||||
|                 magnitude = ope.StationMagnitude(mag=np.log10(a0) \ | ||||
|                             + self.wascaling[0] * np.log10(delta) + self.wascaling[1]  | ||||
|                             * delta + self.wascaling[2]) | ||||
|  | ||||
| @ -6,11 +6,12 @@ import os | ||||
| from obspy import read_events | ||||
| from obspy.core import read, Stream, UTCDateTime | ||||
| from obspy.io.sac import SacIOError | ||||
| from obspy.core.event import Event | ||||
| from obspy.core.event import Event as ObsPyEvent | ||||
| from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \ | ||||
|     picksdict_from_pilot, merge_picks | ||||
| from pylot.core.util.errors import FormatError, OverwriteError | ||||
| from pylot.core.util.utils import fnConstructor, full_range | ||||
| from pylot.core.util.event import Event | ||||
| 
 | ||||
| class Data(object): | ||||
|     """ | ||||
| @ -33,7 +34,7 @@ class Data(object): | ||||
|             self.comp = 'Z' | ||||
|             self.wfdata = Stream() | ||||
|         self._new = False | ||||
|         if isinstance(evtdata, Event): | ||||
|         if isinstance(evtdata, ObsPyEvent) or isinstance(evtdata, Event): | ||||
|             pass | ||||
|         elif isinstance(evtdata, dict): | ||||
|             evt = readPILOTEvent(**evtdata) | ||||
| @ -49,7 +50,7 @@ class Data(object): | ||||
|                 if 'Unknown format for file' in e.message: | ||||
|                     if 'PHASES' in evtdata: | ||||
|                         picks = picksdict_from_pilot(evtdata) | ||||
|                         evtdata = Event() | ||||
|                         evtdata = ObsPyEvent() | ||||
|                         evtdata.picks = picks_from_picksdict(picks) | ||||
|                     elif 'LOC' in evtdata: | ||||
|                         raise NotImplementedError('PILOT location information ' | ||||
| @ -61,7 +62,7 @@ class Data(object): | ||||
|                     raise e | ||||
|         else:  # create an empty Event object | ||||
|             self.setNew() | ||||
|             evtdata = Event() | ||||
|             evtdata = ObsPyEvent() | ||||
|             evtdata.picks = [] | ||||
|         self.evtdata = evtdata | ||||
|         self.wforiginal = None | ||||
| @ -73,6 +74,8 @@ class Data(object): | ||||
| 
 | ||||
|     def __add__(self, other): | ||||
|         assert isinstance(other, Data), "operands must be of same type 'Data'" | ||||
|         rs_id = self.get_evt_data().get('resource_id') | ||||
|         rs_id_other = other.get_evt_data().get('resource_id')         | ||||
|         if other.isNew() and not self.isNew(): | ||||
|             picks_to_add = other.get_evt_data().picks | ||||
|             old_picks = self.get_evt_data().picks | ||||
| @ -84,7 +87,7 @@ class Data(object): | ||||
|             self.evtdata = new.get_evt_data() | ||||
|         elif self.isNew() and other.isNew(): | ||||
|             pass | ||||
|         elif self.get_evt_data().get('id') == other.get_evt_data().get('id'): | ||||
|         elif rs_id == rs_id_other: | ||||
|             other.setNew() | ||||
|             return self + other | ||||
|         else: | ||||
| @ -95,7 +98,7 @@ class Data(object): | ||||
|     def getPicksStr(self): | ||||
|         picks_str = '' | ||||
|         for pick in self.get_evt_data().picks: | ||||
|             picks_str += str(pick) + '\n' | ||||
|             picks_str += str(PyLoT) + '\n' | ||||
|         return picks_str | ||||
| 
 | ||||
|     def getParent(self): | ||||
| @ -144,12 +147,13 @@ class Data(object): | ||||
|         # handle forbidden filenames especially on windows systems | ||||
|         return fnConstructor(str(ID)) | ||||
| 
 | ||||
|     def exportEvent(self, fnout, fnext='.xml'): | ||||
|     def exportEvent(self, fnout, fnext='.xml', fcheck='auto'): | ||||
| 
 | ||||
|         """ | ||||
| 
 | ||||
|         :param fnout: | ||||
|         :param fnext: | ||||
|         :param fcheck: | ||||
|         :raise KeyError: | ||||
|         """ | ||||
|         from pylot.core.util.defaults import OUTPUTFORMATS | ||||
| @ -160,13 +164,35 @@ class Data(object): | ||||
|             errmsg = '{0}; selected file extension {1} not ' \ | ||||
|                      'supported'.format(e, fnext) | ||||
|             raise FormatError(errmsg) | ||||
|     | ||||
|         # check for already existing xml-file | ||||
|         if fnext == '.xml': | ||||
|             if os.path.isfile(fnout + fnext): | ||||
|                 print("xml-file already exists! Check content ...") | ||||
|                 cat_old = read_events(fnout + fnext) | ||||
|                 checkflag = 0 | ||||
|                 for j in range(len(cat_old.events[0].picks)): | ||||
|                    if cat_old.events[0].picks[j].method_id.id.split('/')[1] == fcheck: | ||||
|                       print("Found %s pick(s), append to new catalog." % fcheck) | ||||
|                       checkflag = 1 | ||||
|                       break | ||||
|                 if checkflag == 1: | ||||
|                     self.get_evt_data().write(fnout + fnext, format=evtformat) | ||||
|                     cat_new = read_events(fnout + fnext) | ||||
|                     cat_new.append(cat_old.events[0]) | ||||
|                     cat_new.write(fnout + fnext, format=evtformat) | ||||
|                 else: | ||||
|                     self.get_evt_data().write(fnout + fnext, format=evtformat) | ||||
|             else: | ||||
|                 self.get_evt_data().write(fnout + fnext, format=evtformat) | ||||
| 
 | ||||
|         # try exporting event via ObsPy | ||||
|         try: | ||||
|             self.get_evt_data().write(fnout + fnext, format=evtformat) | ||||
|         except KeyError as e: | ||||
|             raise KeyError('''{0} export format | ||||
|                               not implemented: {1}'''.format(evtformat, e)) | ||||
|         else: | ||||
|             try: | ||||
|                 self.get_evt_data().write(fnout + fnext, format=evtformat) | ||||
|             except KeyError as e: | ||||
|                 raise KeyError('''{0} export format | ||||
|                                   not implemented: {1}'''.format(evtformat, e)) | ||||
| 
 | ||||
|     def getComp(self): | ||||
|         """ | ||||
| @ -279,12 +305,12 @@ class Data(object): | ||||
|     def setEvtData(self, event): | ||||
|         self.evtdata = event | ||||
| 
 | ||||
|     def applyEVTData(self, data, type='pick', authority_id='rub'): | ||||
|     def applyEVTData(self, data, typ='pick', authority_id='rub'): | ||||
| 
 | ||||
|         """ | ||||
| 
 | ||||
|         :param data: | ||||
|         :param type: | ||||
|         :param typ: | ||||
|         :param authority_id: | ||||
|         :raise OverwriteError: | ||||
|         """ | ||||
| @ -326,19 +352,27 @@ class Data(object): | ||||
|             information on the event to the actual data | ||||
|             :param event: | ||||
|             """ | ||||
|             if not self.isNew(): | ||||
|             if self.isNew(): | ||||
|                 self.setEvtData(event) | ||||
|             else: | ||||
|                 # prevent overwriting original pick information | ||||
|                 picks =  copy.deepcopy(self.get_evt_data().picks) | ||||
|                 event_old = self.get_evt_data() | ||||
|                 print(event_old.resource_id, event.resource_id) | ||||
|                 if not event_old.resource_id == event.resource_id: | ||||
|                     print("WARNING: Missmatch in event resource id's: {} and {}".format( | ||||
|                         event_old.resource_id, | ||||
|                         event.resource_id)) | ||||
|                 picks = copy.deepcopy(event_old.picks) | ||||
|                 event = merge_picks(event, picks) | ||||
|                 # apply event information from location | ||||
|                 self.get_evt_data().update(event) | ||||
|                 event_old.update(event) | ||||
| 
 | ||||
|         applydata = {'pick': applyPicks, | ||||
|                      'event': applyEvent} | ||||
| 
 | ||||
|         applydata[type](data) | ||||
|         applydata[typ](data) | ||||
|         self._new = False | ||||
|          | ||||
| 
 | ||||
| 
 | ||||
| class GenericDataStructure(object): | ||||
|  | ||||
| @ -14,7 +14,7 @@ defaults = {'rootpath': {'type': str, | ||||
|                          'value': ''}, | ||||
|              | ||||
|             'eventID': {'type': str, | ||||
|                         'tooltip': 'event ID for single event processing', | ||||
|                         'tooltip': 'event ID for single event processing (* for all events found in database)', | ||||
|                         'value': ''}, | ||||
|              | ||||
|             'extent': {'type': str, | ||||
| @ -278,12 +278,14 @@ defaults = {'rootpath': {'type': str, | ||||
|                              'value': 1.0}, | ||||
|              | ||||
|             'WAscaling': {'type': (float, float, float), | ||||
|                          'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm]', | ||||
|                          'value': (1.0, 1.0, 1.0)}, | ||||
|                          'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] \ | ||||
|                                      If zeros are set, original Richter magnitude is calculated!', | ||||
|                          'value': (0., 0., 0.)}, | ||||
| 
 | ||||
|             'magscaling': {'type': (float, float), | ||||
|                          'tooltip': 'Scaling relation for derived local magnitude [a*Ml+b]', | ||||
|                          'value': (1.0, 1.0)} | ||||
|                          'tooltip': 'Scaling relation for derived local magnitude [a*Ml+b]. \ | ||||
|                                      If zeros are set, no scaling of network magnitude is applied!', | ||||
|                          'value': (0., 0.)} | ||||
| } | ||||
| 
 | ||||
| settings_main={ | ||||
|  | ||||
| @ -221,24 +221,23 @@ class PylotParameter(object): | ||||
|         # for key, value in self.iteritems(): | ||||
|         #     lines.append('{key}\t{value}\n'.format(key=key, value=value)) | ||||
|         # fid_out.writelines(lines) | ||||
| 
 | ||||
|         header = ('%This is a parameter input file for PyLoT/autoPyLoT.\n'+ | ||||
|                   '%All main and special settings regarding data handling\n'+ | ||||
|                   '%and picking are to be set here!\n'+ | ||||
|                   '%Parameters are optimized for local data sets!\n') | ||||
|         seperator = '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n' | ||||
|                   '%Parameters are optimized for %{} data sets!\n'.format(self.get_main_para_names()['pick'][0])) | ||||
|         separator = '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n' | ||||
| 
 | ||||
|         fid_out.write(header) | ||||
|         self.write_section(fid_out, self.get_main_para_names()['dirs'], | ||||
|                            'main settings', seperator) | ||||
|                            'main settings', separator) | ||||
|         self.write_section(fid_out, self.get_main_para_names()['nlloc'], | ||||
|                            'NLLoc settings', seperator) | ||||
|                            'NLLoc settings', separator) | ||||
|         self.write_section(fid_out, self.get_main_para_names()['smoment'], | ||||
|                            'parameters for seismic moment estimation', seperator) | ||||
|                            'parameters for seismic moment estimation', separator) | ||||
|         self.write_section(fid_out, self.get_main_para_names()['localmag'], | ||||
|                            'settings local magnitude', seperator) | ||||
|                            'settings local magnitude', separator) | ||||
|         self.write_section(fid_out, self.get_main_para_names()['pick'], | ||||
|                            'common settings picker', seperator) | ||||
|                            'common settings picker', separator) | ||||
|         fid_out.write(('#special settings for calculating CF#\n'+ | ||||
|                        '%!!Edit the following only if you know what you are doing!!%\n')) | ||||
|         self.write_section(fid_out, self.get_special_para_names()['z'], | ||||
| @ -250,9 +249,9 @@ class PylotParameter(object): | ||||
|         self.write_section(fid_out, self.get_special_para_names()['quality'], | ||||
|                            'quality assessment', None) | ||||
| 
 | ||||
|     def write_section(self, fid, names, title, seperator): | ||||
|         if seperator: | ||||
|             fid.write(seperator) | ||||
|     def write_section(self, fid, names, title, separator): | ||||
|         if separator: | ||||
|             fid.write(separator) | ||||
|         fid.write('#{}#\n'.format(title)) | ||||
|         l_val = 50 | ||||
|         l_name = 15 | ||||
|  | ||||
| @ -7,6 +7,7 @@ import os | ||||
| import scipy.io as sio | ||||
| import warnings | ||||
| from obspy.core import UTCDateTime | ||||
| from obspy.core.util import AttribDict | ||||
| 
 | ||||
| from pylot.core.io.inputs import PylotParameter | ||||
| from pylot.core.io.location import create_arrival, create_event, \ | ||||
| @ -195,6 +196,7 @@ def picksdict_from_picks(evt): | ||||
|         phase = {} | ||||
|         station = pick.waveform_id.station_code | ||||
|         channel = pick.waveform_id.channel_code | ||||
|         network = pick.waveform_id.network_code | ||||
|         try: | ||||
|             onsets = picks[station] | ||||
|         except KeyError as e: | ||||
| @ -215,6 +217,7 @@ def picksdict_from_picks(evt): | ||||
|         phase['lpp'] = lpp | ||||
|         phase['spe'] = spe | ||||
|         phase['channel'] = channel | ||||
|         phase['network'] = network | ||||
|         try: | ||||
|             picker = str(pick.method_id) | ||||
|             if picker.startswith('smi:local/'): | ||||
| @ -231,7 +234,7 @@ def picks_from_picksdict(picks, creation_info=None): | ||||
|     picks_list = list() | ||||
|     for station, onsets in picks.items(): | ||||
|         for label, phase in onsets.items(): | ||||
|             if not isinstance(phase, dict): | ||||
|             if not isinstance(phase, dict) and not isinstance(phase, AttribDict): | ||||
|                 continue | ||||
|             onset = phase['mpp'] | ||||
|             try: | ||||
| @ -382,12 +385,12 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None | ||||
|     evt.picks = picks_from_picksdict(picks_dict) | ||||
|     # write phase information to file | ||||
|     if not out_dir: | ||||
|         fnout_prefix = os.path.join(root_dir, db_dir, event_id, '{0}.'.format(event_id)) | ||||
|         fnout_prefix = os.path.join(root_dir, db_dir, event_id, 'PyLoT_{0}.'.format(event_id)) | ||||
|     else: | ||||
|         out_dir = os.path.join(out_dir, db_dir) | ||||
|         if not os.path.isdir(out_dir): | ||||
|             os.makedirs(out_dir) | ||||
|         fnout_prefix = os.path.join(out_dir, '{0}.'.format(event_id)) | ||||
|         fnout_prefix = os.path.join(out_dir, 'PyLoT_{0}.'.format(event_id)) | ||||
|     evt.write(fnout_prefix + 'xml', format='QUAKEML') | ||||
|     #evt.write(fnout_prefix + 'cnv', format='VELEST') | ||||
| 
 | ||||
| @ -835,9 +838,10 @@ def merge_picks(event, picks): | ||||
|         err = pick.time_errors | ||||
|         phase = pick.phase_hint | ||||
|         station = pick.waveform_id.station_code | ||||
|         network = pick.waveform_id.network_code | ||||
|         method = pick.method_id | ||||
|         for p in event.picks: | ||||
|             if p.waveform_id.station_code == station and p.phase_hint == phase: | ||||
|                 p.time, p.time_errors, p.method_id = time, err, method | ||||
|         del time, err, phase, station, method | ||||
|                 p.time, p.time_errors, p.waveform_id.network_code, p.method_id = time, err, network, method | ||||
|         del time, err, phase, station, network, method | ||||
|     return event | ||||
|  | ||||
| @ -212,6 +212,14 @@ class AICPicker(AutoPicker): | ||||
|                 self.Data[0].data = self.Data[0].data * 1000000 | ||||
|             # get signal window | ||||
|             isignal = getsignalwin(self.Tcf, self.Pick, self.TSNR[2]) | ||||
|             ii = min([isignal[len(isignal)-1], len(self.Tcf)]) | ||||
|             isignal = isignal[0:ii] | ||||
|             try: | ||||
|                aic[isignal] | ||||
|             except IndexError as e: | ||||
|                msg = "Time series out of bounds! {}".format(e) | ||||
|                print(msg) | ||||
|                return | ||||
|             # calculate SNR from CF | ||||
|             self.SNR = max(abs(aic[isignal] - np.mean(aic[isignal]))) / \ | ||||
|                        max(abs(aic[inoise] - np.mean(aic[inoise]))) | ||||
|  | ||||
							
								
								
									
										144
									
								
								pylot/core/util/event.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								pylot/core/util/event.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,144 @@ | ||||
| #!/usr/bin/env python | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| import os | ||||
| 
 | ||||
| from obspy import UTCDateTime | ||||
| from obspy.core.event import Event as ObsPyEvent | ||||
| from obspy.core.event import Origin, Magnitude, ResourceIdentifier | ||||
| 
 | ||||
| from pylot.core.io.phases import picks_from_picksdict | ||||
| 
 | ||||
| 
 | ||||
| class Event(ObsPyEvent): | ||||
|     ''' | ||||
|     Pickable class derived from ~obspy.core.event.Event containing information on a single event. | ||||
|     ''' | ||||
|     def __init__(self, path): | ||||
|         self.pylot_id = path.split('/')[-1] | ||||
|         # initialize super class | ||||
|         super(Event, self).__init__(resource_id=ResourceIdentifier('smi:local/'+self.pylot_id)) | ||||
|         self.path = path | ||||
|         self.database = path.split('/')[-2] | ||||
|         self.datapath = path.split('/')[-3] | ||||
|         self.rootpath = '/' + os.path.join(*path.split('/')[:-3]) | ||||
|         self.pylot_autopicks = {} | ||||
|         self.pylot_picks = {} | ||||
|         self.notes = '' | ||||
|         self._testEvent = False | ||||
|         self._refEvent = False | ||||
|         self.get_notes() | ||||
| 
 | ||||
|     def get_notes_path(self): | ||||
|         notesfile = os.path.join(self.path, 'notes.txt') | ||||
|         return notesfile | ||||
|      | ||||
|     def get_notes(self): | ||||
|         notesfile = self.get_notes_path() | ||||
|         if os.path.isfile(notesfile): | ||||
|             with open(notesfile) as infile: | ||||
|                 path = str(infile.readlines()[0].split('\n')[0]) | ||||
|                 text = '[eventInfo: '+path+']' | ||||
|                 self.addNotes(text) | ||||
|                 try: | ||||
|                     datetime = UTCDateTime(path.split('/')[-1]) | ||||
|                     origin = Origin(resource_id=self.resource_id, time=datetime, latitude=0, longitude=0, depth=0) | ||||
|                     self.origins.append(origin) | ||||
|                 except: | ||||
|                     pass | ||||
| 
 | ||||
|     def addNotes(self, notes): | ||||
|         self.notes = str(notes) | ||||
| 
 | ||||
|     def clearNotes(self): | ||||
|         self.notes = None | ||||
| 
 | ||||
|     def isRefEvent(self): | ||||
|         return self._refEvent | ||||
| 
 | ||||
|     def isTestEvent(self): | ||||
|         return self._testEvent | ||||
| 
 | ||||
|     def setRefEvent(self, bool): | ||||
|         self._refEvent = bool | ||||
|         if bool: self._testEvent = False | ||||
| 
 | ||||
|     def setTestEvent(self, bool): | ||||
|         self._testEvent = bool | ||||
|         if bool: self._refEvent = False | ||||
| 
 | ||||
|     def addPicks(self, picks): | ||||
|         ''' | ||||
|         add pylot picks and overwrite existing | ||||
|         ''' | ||||
|         for station in picks: | ||||
|             self.pylot_picks[station] = picks[station] | ||||
|         #add ObsPy picks | ||||
|         self.picks = picks_from_picksdict(self.pylot_picks) | ||||
|          | ||||
|     def addAutopicks(self, autopicks): | ||||
|         for station in autopicks: | ||||
|             self.pylot_autopicks[station] = autopicks[station] | ||||
|          | ||||
|     def setPick(self, station, pick): | ||||
|         if pick: | ||||
|             self.pylot_picks[station] = pick | ||||
|         self.picks = picks_from_picksdict(self.pylot_picks) | ||||
|          | ||||
|     def setPicks(self, picks): | ||||
|         ''' | ||||
|         set pylot picks and delete and overwrite all existing | ||||
|         ''' | ||||
|         self.pylot_picks = picks | ||||
|         self.picks = picks_from_picksdict(self.pylot_picks) | ||||
|                  | ||||
|     def getPick(self, station): | ||||
|         if station in self.pylot_picks.keys(): | ||||
|             return self.pylot_picks[station] | ||||
| 
 | ||||
|     def getPicks(self): | ||||
|         return self.pylot_picks | ||||
| 
 | ||||
|     def setAutopick(self, station, autopick): | ||||
|         if autopick: | ||||
|             self.pylot_autopicks[station] = autopick | ||||
| 
 | ||||
|     def setAutopicks(self, autopicks): | ||||
|         self.pylot_autopicks = autopicks | ||||
|          | ||||
|     def getAutopick(self, station): | ||||
|         if station in self.pylot_autopicks.keys(): | ||||
|             return self.pylot_autopicks[station] | ||||
| 
 | ||||
|     def getAutopicks(self): | ||||
|         return self.pylot_autopicks | ||||
| 
 | ||||
|     def save(self, filename): | ||||
|         ''' | ||||
|         Save PyLoT Event to a file.  | ||||
|         Can be loaded by using event.load(filename). | ||||
|         ''' | ||||
|         try: | ||||
|             import cPickle | ||||
|         except ImportError: | ||||
|             import _pickle as cPickle | ||||
| 
 | ||||
|         try: | ||||
|             outfile = open(filename, 'wb') | ||||
|             cPickle.dump(self, outfile, -1) | ||||
|         except Exception as e: | ||||
|             print('Could not pickle PyLoT event. Reason: {}'.format(e)) | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def load(filename): | ||||
|         ''' | ||||
|         Load project from filename. | ||||
|         ''' | ||||
|         try: | ||||
|             import cPickle | ||||
|         except ImportError: | ||||
|             import _pickle as cPickle | ||||
|         infile = open(filename, 'rb') | ||||
|         event = cPickle.load(infile) | ||||
|         print('Loaded %s' % filename) | ||||
|         return event | ||||
| @ -22,6 +22,7 @@ class map_projection(QtGui.QWidget): | ||||
|         self.parser = parent.metadata[1] | ||||
|         self.picks = None | ||||
|         self.picks_dict = None | ||||
|         self.eventLoc = None | ||||
|         self.figure = figure | ||||
|         self.init_graphics() | ||||
|         self.init_stations() | ||||
| @ -244,6 +245,10 @@ class map_projection(QtGui.QWidget): | ||||
|         self.sc = self.basemap.scatter(self.lon, self.lat, s=50, facecolor='none', latlon=True, | ||||
|                                   zorder=10, picker=True, edgecolor='m', label='Not Picked') | ||||
|         self.cid = self.canvas.mpl_connect('pick_event', self.onpick) | ||||
|         if self.eventLoc: | ||||
|             lat, lon = self.eventLoc | ||||
|             self.sc_event = self.basemap.scatter(lon, lat, s=100, facecolor='red', | ||||
|                                                  latlon=True, zorder=11, label='Event (might be outside map region)') | ||||
| 
 | ||||
|     def scatter_picked_stations(self): | ||||
|         lon = self.lon_no_nan | ||||
| @ -274,8 +279,7 @@ class map_projection(QtGui.QWidget): | ||||
| 
 | ||||
|     def refresh_drawings(self, picks=None): | ||||
|         self.picks_dict = picks | ||||
|         self.remove_drawings() | ||||
|         self.draw_everything() | ||||
|         self._refresh_drawings() | ||||
| 
 | ||||
|     def _refresh_drawings(self): | ||||
|         self.remove_drawings() | ||||
| @ -303,6 +307,9 @@ class map_projection(QtGui.QWidget): | ||||
|         if hasattr(self, 'sc_picked'): | ||||
|             self.sc_picked.remove() | ||||
|             del(self.sc_picked) | ||||
|         if hasattr(self, 'sc_event'): | ||||
|             self.sc_event.remove() | ||||
|             del(self.sc_event) | ||||
|         if hasattr(self, 'cbar'): | ||||
|             self.cbar.remove() | ||||
|             del(self.cbar) | ||||
|  | ||||
| @ -12,7 +12,7 @@ import subprocess | ||||
| from obspy import UTCDateTime, read | ||||
| from pylot.core.io.inputs import PylotParameter | ||||
| 
 | ||||
| 
 | ||||
|      | ||||
| def _pickle_method(m): | ||||
|     if m.im_self is None: | ||||
|         return getattr, (m.im_class, m.im_func.func_name) | ||||
|  | ||||
| @ -1646,7 +1646,7 @@ class TuneAutopicker(QWidget): | ||||
|         model = self.stationBox.model() | ||||
|         for network, station in stations: | ||||
|             item = QtGui.QStandardItem(network+'.'+station) | ||||
|             if station in self.get_current_event().picks: | ||||
|             if station in self.get_current_event().pylot_picks: | ||||
|                 item.setBackground(self.parent._colors['ref']) | ||||
|             model.appendRow(item) | ||||
| 
 | ||||
| @ -1687,8 +1687,8 @@ class TuneAutopicker(QWidget): | ||||
|         self.listWidget.scrollToBottom() | ||||
|          | ||||
|     def get_current_event(self): | ||||
|         index = self.eventBox.currentIndex() | ||||
|         return self.eventBox.itemData(index) | ||||
|         path = self.eventBox.currentText() | ||||
|         return self.parent.project.getEventFromPath(path) | ||||
|          | ||||
|     def get_current_event_name(self): | ||||
|         return self.eventBox.currentText().split('/')[-1] | ||||
| @ -1698,13 +1698,13 @@ class TuneAutopicker(QWidget): | ||||
| 
 | ||||
|     def get_current_event_picks(self, station): | ||||
|         event = self.get_current_event() | ||||
|         if station in event.picks.keys(): | ||||
|             return event.picks[station] | ||||
|         if station in event.pylot_picks.keys(): | ||||
|             return event.pylot_picks[station] | ||||
|          | ||||
|     def get_current_event_autopicks(self, station): | ||||
|         event = self.get_current_event() | ||||
|         if event.autopicks: | ||||
|             return event.autopicks[station] | ||||
|         if event.pylot_autopicks: | ||||
|             return event.pylot_autopicks[station] | ||||
|          | ||||
|     def get_current_station(self): | ||||
|         return str(self.stationBox.currentText()).split('.')[-1] | ||||
| @ -1855,6 +1855,9 @@ class TuneAutopicker(QWidget): | ||||
|         self.init_tab_names() | ||||
| 
 | ||||
|     def fill_eventbox(self): | ||||
|         project = self.parent.project | ||||
|         if not project: | ||||
|             return | ||||
|         # update own list | ||||
|         self.parent.fill_eventbox(eventBox=self.eventBox, select_events='ref') | ||||
|         index_start = self.parent.eventBox.currentIndex() | ||||
| @ -1862,11 +1865,15 @@ class TuneAutopicker(QWidget): | ||||
|         if index == -1: | ||||
|             index += 1 | ||||
|         nevents = self.eventBox.model().rowCount() | ||||
|         if self.eventBox.itemData(index).isTestEvent(): | ||||
|         path = self.eventBox.itemText(index) | ||||
|         if project.getEventFromPath(path).isTestEvent(): | ||||
|             for index in range(nevents): | ||||
|                 if not self.eventBox.itemData(index).isTestEvent(): | ||||
|                     break | ||||
|                 elif index == nevents - 1: | ||||
|                 path = self.eventBox.itemText(index) | ||||
|                 if project.getEventFromPath(index): | ||||
|                     if not project.getEventFromPath(index).isTestEvent(): | ||||
|                         break | ||||
|                 #in case all events are marked as test events and last event is reached | ||||
|                 if index == nevents - 1: | ||||
|                     index = -1 | ||||
|         self.eventBox.setCurrentIndex(index) | ||||
|         if not index == index_start: | ||||
| @ -1911,8 +1918,8 @@ class TuneAutopicker(QWidget): | ||||
|             self._warn('Could not execute picker:\n{}'.format( | ||||
|                 self.ap_thread._executedError)) | ||||
|             return | ||||
|         self.picks = self.ap_thread.data | ||||
|         if not self.picks: | ||||
|         self.pylot_picks = self.ap_thread.data | ||||
|         if not self.pylot_picks: | ||||
|             self._warn('No picks found. See terminal output.') | ||||
|             return | ||||
|         #renew tabs | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user