def main(): app = QtGui.QApplication([]) # PySide stuff (start) mw = QtGui.QMainWindow() mw.show() lib = SoundSpeedLibrary(progress=QtProgress(parent=mw), callbacks=QtCallbacks(parent=mw)) tests = [ (43.026480, -70.318824, dt.utcnow()), # offshore Portsmouth # (-19.1, 74.16, dt.utcnow()), # Indian Ocean # (18.2648113, 16.1761115, dt.utcnow()), # in land -> middle of Africa ] # download the woa09 if not present if not lib.has_woa09(): success = lib.download_woa09() if not success: raise RuntimeError("unable to download") logger.info("has woa09: %s" % lib.has_woa09()) # logger.info("load woa09: %s" % lib.atlases.woa09.load_grids()) # test for a few locations for test in tests: start_time = time.time() # just the ssp (there are also ssp_min and ssp_max) logger.info("woa09 profiles:\n%s" % lib.atlases.woa09.query( lat=test[0], lon=test[1], datestamp=test[2])) logger.info("execution time: %.3f s" % (time.time() - start_time))
def setUp(self): def add_cast(lat, lon): self.lib.ssp.cur.meta.latitude = lat self.lib.ssp.cur.meta.longitude = lon self.lib.ssp.cur.meta.utc_time = datetime.now() self.lib.ssp.cur.init_data(self.levels) self.lib.ssp.cur.data.depth[:self.levels] = self.depth self.lib.ssp.cur.data.speed[:self.levels] = 1415 self.lib.restart_proc() self.lib.store_data() self.max_pk = 5 self.levels = self.max_pk * self.max_pk self.depth = np.array(range(self.levels)) projects_folder = os.path.abspath(os.curdir) project_name = 'unittest' db_name = '%s.db' % project_name self.db_path = os.path.join(projects_folder, db_name) self.tearDown() self.lib = SoundSpeedLibrary() self.lib.projects_folder = projects_folder self.lib.current_project = project_name self.lib.ssp = ProfileList() self.lib.ssp.append() if len(self.lib.db_list_profiles()) < self.max_pk: for i in range(self.max_pk): add_cast(20 + i, -75)
def main(): # create a project with test-callbacks lib = SoundSpeedLibrary(callbacks=TestCallbacks()) # set the current project name lib.setup.current_project = 'test' # retrieve data input/output folders data_input = testing.input_data_folder() logger.info('input folder: %s' % data_input) data_output = testing.output_data_folder() logger.info('output folder: %s' % data_output) # test readers/writers logger.info('test: *** START ***') filters = [ "aml", ] tests = testing.input_dict_test_files(inclusive_filters=filters) # print(tests) # import each identified file for idx, testfile in enumerate(tests.keys()): logger.debug("filename: %s" % testfile) if idx > 4: # FILE FILTER break logger.info("test: * New profile: #%03d *" % idx) # import lib.import_data(data_path=testfile, data_format=tests[testfile].name) # print(lib.cur) lib.plot_ssp(more=True, show=False) # store the current profile success = lib.store_data() logger.info("stored: %s" % success) from matplotlib import pyplot as plt plt.show() # retrieve all the id profiles from db lst = lib.db_list_profiles() logger.info("Profiles: %s" % len(lst)) for p in lst: logger.info(p) # retrieve a specific profile and delete it ssp_pk = lst[0][0] ssp = lib.db_retrieve_profile(pk=ssp_pk) logger.info("Retrieved profile:\n%s" % ssp) ret = lib.delete_db_profile(pk=ssp_pk) logger.info("Deleted profile: %s" % ret) logger.info('test: *** END ***')
def test_creation_of_Atlases(self): lib = SoundSpeedLibrary(data_folder=self.cur_dir) atl = atlases.Atlases(prj=lib) self.assertTrue("atlases" in atl.rtofs_folder) self.assertTrue("woa" in atl.woa09_folder) self.assertTrue("woa" in atl.woa13_folder) lib.close()
def test_download_db_from_Rtofs(self): prj = SoundSpeedLibrary(data_folder=self.cur_dir) rtofs = Rtofs(data_folder=prj.data_folder, prj=prj) rtofs.download_db(server_mode=True) # to avoid test failures if not rtofs.is_present(): logger.warning("unable to download RTOFS data") # self.assertTrue(rtofs.is_present()) prj.close()
class TestSoundSpeedDb(unittest.TestCase): def setUp(self): def add_cast(lat, lon): self.lib.ssp.cur.meta.latitude = lat self.lib.ssp.cur.meta.longitude = lon self.lib.ssp.cur.meta.utc_time = datetime.now() self.lib.ssp.cur.init_data(self.levels) self.lib.ssp.cur.data.depth[:self.levels] = self.depth self.lib.ssp.cur.data.speed[:self.levels] = 1415 self.lib.restart_proc() self.lib.store_data() self.max_pk = 5 self.levels = self.max_pk * self.max_pk self.depth = np.array(range(self.levels)) projects_folder = os.path.abspath(os.curdir) project_name = 'unittest' db_name = '%s.db' % project_name self.db_path = os.path.join(projects_folder, db_name) self.tearDown() self.lib = SoundSpeedLibrary() self.lib.projects_folder = projects_folder self.lib.current_project = project_name self.lib.ssp = ProfileList() self.lib.ssp.append() if len(self.lib.db_list_profiles()) < self.max_pk: for i in range(self.max_pk): add_cast(20 + i, -75) def tearDown(self): if os.path.exists(self.db_path): os.remove(self.db_path) @unittest.skipUnless(sys.platform.startswith("win"), "only works with GDAL < 2.0 on Windows") def test_save_load_cast(self): def test_pk(pk): self.lib.ssp = self.lib.db_retrieve_profile(pk) self.lib.store_data() self.lib.ssp = self.lib.db_retrieve_profile(pk) sum_ = len(self.lib.ssp.cur.proc.speed) + len( self.lib.ssp.cur.proc.depth) sum_ += len(self.lib.ssp.cur.data.speed) + len( self.lib.ssp.cur.data.depth) self.assertEqual(sum_, self.levels * 4) self.assertTrue((self.lib.ssp.cur.data.depth == self.depth).all()) self.assertTrue((self.lib.ssp.cur.proc.depth == self.depth).all()) for i in range(self.levels): # pk = random.randint(1, self.max_pk) pk = i % self.max_pk + 1 test_pk(pk)
def main(): app = QtGui.QApplication([]) # PySide stuff (start) mw = QtGui.QMainWindow() mw.show() lib = SoundSpeedLibrary(progress=QtProgress(parent=mw), callbacks=QtCallbacks(parent=mw)) tests = [ (43.026480, -70.318824, dt.utcnow()), # offshore Portsmouth (-19.1, 74.16, dt.utcnow()), # Indian Ocean (18.2648113, 16.1761115, dt.utcnow()), # in land -> middle of Africa ] # download the woa13 if not present if not lib.has_woa13(): success = lib.download_woa13() if not success: raise RuntimeError("unable to download") logger.info("has woa09: %s" % lib.has_woa13()) # logger.info("load woa13: %s" % lib.atlases.woa13.load_grids()) # test user interaction: 3 profiles (avg, min, max) lib.retrieve_woa13() logger.info("lib retrieve rtofs: %s" % lib.ssp) app.exec_() # PySide stuff (end)
def main(): # initialize the library lib = SoundSpeedLibrary() # print(lib) # # exploring folders # lib.open_data_folder() # lib.open_release_folder() # lib.open_projects_folder() # lib.open_atlases_folder() ssp_list = lib.db_list_profiles() print('profiles in db: %d' % len(ssp_list)) print('setup version: %s' % lib.setup.setup_version) lib.close()
def gui(): """Run the Sound Speed Settings gui""" app = QtGui.QApplication(sys.argv) lib = SoundSpeedLibrary() main = mainwin.MainWin(lib=lib) main.show() sys.exit(app.exec_())
def main(): app = QtGui.QApplication([]) lib = SoundSpeedLibrary() lib.progress.start("TEST") sleep(0.5) lib.progress.update(30) sleep(0.5) lib.progress.update(60) sleep(0.5) lib.progress.end() app.exec_()
def main(): # create a project with test-callbacks lib = SoundSpeedLibrary(callbacks=TestCallbacks()) # set the current project name lib.setup.current_project = 'test' # retrieve data input/output folders data_input = testing.input_data_folder() logger.info('input folder: %s' % data_input) data_output = testing.output_data_folder() logger.info('output folder: %s' % data_output) # test readers/writers logger.info('test: *** START ***') filters = [ "castaway", ] formats = [ "asvp", ] data_outputs = [ data_output, ] tests = testing.input_dict_test_files(inclusive_filters=filters) # print(tests) # import each identified file for idx, testfile in enumerate(tests.keys()): # # just 1 file # if idx != 1: # continue logger.info("test: * New profile: #%03d *" % idx) # import lib.import_data(data_path=testfile, data_format=tests[testfile].name) # replace temp and salinity lib.replace_cur_temp_sal() # export lib.export_data(data_paths=data_outputs, data_formats=formats) logger.info('test: *** END ***')
def test_available_projects(self): from hyo.soundspeed.soundspeed import SoundSpeedLibrary lib = SoundSpeedLibrary() ssp_list = lib.db_list_profiles() self.assertGreaterEqual(len(ssp_list), 0) prj_list = lib.list_projects() self.assertGreaterEqual(len(prj_list), 1) lib.close()
def main(): app = QtGui.QApplication([]) # noinspection PyArgumentList app.setApplicationName('test') app.setOrganizationName("HydrOffice") app.setOrganizationDomain("hydroffice.org") mw = QtGui.QMainWindow() mw.show() lib = SoundSpeedLibrary() body = "<pre style='margin:3px;'><b>Test!</b> #001: OK</pre>" \ "<pre style='margin:3px;'><b>Test!</b> #002: KO</pre>" dlg = TextEditorDialog(title="Text", basename="test", body=body, main_win=mw, lib=lib, parent=None) dlg.exec_()
def main(): # initialize the library lib = SoundSpeedLibrary() prj_list = lib.list_projects() print("projects: %s" % len(prj_list)) for prj in prj_list: print('- %s' % prj) lib.current_project = "test2" ssp_list = lib.db_list_profiles() print('profiles in db: %d' % len(ssp_list)) lib.close()
def _run(self, filters): # create a project with test-callbacks lib = SoundSpeedLibrary(callbacks=TestCallbacks()) # set the current project name lib.setup.current_project = 'test_read_store_and_write' tests = testing.input_dict_test_files(inclusive_filters=filters) data_outputs = dict() for format in self.formats: data_outputs[format] = self.data_output for idx, testfile in enumerate(tests.keys()): logger.info("test: * New profile: #%03d *" % idx) lib.import_data(data_path=testfile, data_format=tests[testfile].name) lib.store_data() lib.export_data(data_paths=data_outputs, data_formats=self.formats)
def main(): app = QtGui.QApplication([]) # PySide stuff (start) mw = QtGui.QMainWindow() mw.show() lib = SoundSpeedLibrary(callbacks=QtCallbacks(mw)) tests = [ (43.026480, -70.318824, dt.utcnow()), # offshore Portsmouth (-19.1, 74.16, dt.utcnow()), # Indian Ocean (18.2648113, 16.1761115, dt.utcnow()), # in land -> middle of Africa ] # download the current-time rtofs if not lib.has_rtofs(): lib.download_rtofs() logger.info("has rtofs: %s" % lib.has_rtofs()) # test today urls temp_url, sal_url = lib.atlases.rtofs._build_check_urls(dt.utcnow()) logger.info("urls:\n%s [%s]\n%s [%s]" % (temp_url, lib.atlases.rtofs._check_url(temp_url), sal_url, lib.atlases.rtofs._check_url(sal_url))) # test yesterday urls temp_url, sal_url = lib.atlases.rtofs._build_check_urls(dt.utcnow() - timedelta(days=1)) logger.info("urls:\n%s [%s]\n%s [%s]" % (temp_url, lib.atlases.rtofs._check_url(temp_url), sal_url, lib.atlases.rtofs._check_url(sal_url))) # test for a few locations for test in tests: logger.info("rtofs profile:\n%s" % lib.atlases.rtofs.query(lat=test[0], lon=test[1], datestamp=test[2])) # test user interaction lib.retrieve_rtofs() logger.info("lib retrieve rtofs: %s" % lib.ssp) app.exec_() # PySide stuff (end)
def main(): # create a project with test-callbacks lib = SoundSpeedLibrary(callbacks=TestCallbacks()) # set the current project name lib.setup.current_project = 'test' # retrieve data input/output folders data_input = testing.input_data_folder() logger.info('input folder: %s' % data_input) data_output = testing.output_data_folder() logger.info('output folder: %s' % data_output) # test readers/writers logger.info('test: *** START ***') filters = ["valeport", ] formats = ["caris", "csv", "elac", "hypack", "ixblue", "asvp", "qps", "sonardyne", "unb", ] data_outputs = dict() for format in formats: data_outputs[format] = data_output tests = testing.input_dict_test_files(inclusive_filters=filters) # print(tests) # import each identified file for idx, testfile in enumerate(tests.keys()): logger.info("test: * New profile: #%03d *" % idx) # import lib.import_data(data_path=testfile, data_format=tests[testfile].name) # export # lib.export_data(data_path=data_output, data_formats=lib.name_writers) lib.export_data(data_paths=data_outputs, data_formats=formats) logger.info('test: *** END ***')
def main(): # create a project lib = SoundSpeedLibrary() # set the current project name lib.setup.current_project = 'test' lib.setup.save_to_db() # retrieve all the id profiles from db lst = lib.db_list_profiles() logger.info("Profiles: %s" % len(lst)) # plots/maps/exports # - map lib.map_db_profiles() lib.save_map_db_profiles() # - aggregate plot ssp_times = lib.db_timestamp_list() dates = [ssp_times[0][0].date(), ssp_times[-1][0].date()] lib.aggregate_plot(dates=dates) lib.save_aggregate_plot(dates=dates) # - daily plots lib.plot_daily_db_profiles() lib.save_daily_db_profiles() # - exports lib.export_db_profiles_metadata(ogr_format=GdalAux.ogr_formats[b'KML']) lib.export_db_profiles_metadata(ogr_format=GdalAux.ogr_formats[b'CSV']) lib.export_db_profiles_metadata( ogr_format=GdalAux.ogr_formats[b'ESRI Shapefile']) logger.info('test: *** END ***')
class MainWin(QtGui.QMainWindow): here = os.path.abspath(os.path.dirname(__file__)) # to be overloaded media = os.path.join(here, "media") # noinspection PyUnresolvedReferences def __init__(self): super(MainWin, self).__init__() logger.info("* > APP: initializing ...") # set the application name and the version self.name = ssm_name self.version = ssm_version self.setWindowTitle('%s v.%s' % (self.name, self.version)) # noinspection PyArgumentList _app = QtCore.QCoreApplication.instance() _app.setApplicationName('%s' % self.name) _app.setOrganizationName("HydrOffice") _app.setOrganizationDomain("hydroffice.org") # set the minimum and the initial size self.setMinimumSize(640, 480) self.resize(920, 600) # set icons icon_info = QtCore.QFileInfo(os.path.join(self.media, 'favicon.png')) self.setWindowIcon(QtGui.QIcon(icon_info.absoluteFilePath())) if (sys.platform == 'win32') or (os.name is "nt"): # is_windows() try: # This is needed to display the app icon on the taskbar on Windows 7 import ctypes app_id = '%s v.%s' % (self.name, self.version) ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(app_id) except AttributeError as e: logger.debug("Unable to change app icon: %s" % e) # set palette/stylesheet style_info = QtCore.QFileInfo(os.path.join(self.here, 'styles', 'main.stylesheet')) style_content = open(style_info.filePath()).read() self.setStyleSheet(style_content) # check if setup db exists; if yes, ask to copy has_setup = SoundSpeedLibrary.setup_exists() logger.info("setup exists: %s" % has_setup) if not has_setup: other_setups = SoundSpeedLibrary.list_other_setups() if len(other_setups) != 0: logger.debug("other existing setups: %d" % len(other_setups)) sel, ok = QtGui.QInputDialog.getItem(self, 'Do you want to copy an existing setup?', 'Select one (or click on Cancel to create a new one):', other_setups, 0, False) if ok: SoundSpeedLibrary.copy_setup(input_setup=sel) # create the project self.lib = SoundSpeedLibrary(callbacks=QtCallbacks(parent=self), progress=QtProgress(parent=self)) logger.debug("dependencies:\n%s" % info_libs()) self.check_woa09() self.check_woa13() # self.check_rtofs() # no need to wait for the download at the beginning self.check_sis() self.check_sippican() self.check_mvp() # init default settings settings = QtCore.QSettings() export_folder = settings.value("export_folder") if (export_folder is None) or (not os.path.exists(export_folder)): settings.setValue("export_folder", self.lib.data_folder) import_folder = settings.value("import_folder") if (import_folder is None) or (not os.path.exists(import_folder)): settings.setValue("import_folder", self.lib.data_folder) # menu self.menu = self.menuBar() self.file_menu = self.menu.addMenu("File") self.edit_menu = self.menu.addMenu("Process") self.database_menu = self.menu.addMenu("Database") self.monitor_menu = self.menu.addMenu("Monitor") self.server_menu = self.menu.addMenu("Server") self.setup_menu = self.menu.addMenu("Setup") self.help_menu = self.menu.addMenu("Help") # make tabs self.tabs = QtGui.QTabWidget() self.setCentralWidget(self.tabs) self.tabs.setIconSize(QtCore.QSize(42, 42)) self.tabs.blockSignals(True) # during the initialization self.tabs.currentChanged.connect(self.onChange) # changed! # editor self.tab_editor = Editor(lib=self.lib, main_win=self) self.idx_editor = self.tabs.insertTab(0, self.tab_editor, QtGui.QIcon(os.path.join(self.here, 'media', 'editor.png')), "") self.tabs.setTabToolTip(self.idx_editor, "Editor") # database self.tab_database = Database(lib=self.lib, main_win=self) self.idx_database = self.tabs.insertTab(1, self.tab_database, QtGui.QIcon(os.path.join(self.here, 'media', 'database.png')), "") self.tabs.setTabToolTip(self.idx_database, "Database") # seacat # self.tab_seacat = Seacat(lib=self.lib, main_win=self) # self.idx_seacat = self.tabs.insertTab(2, self.tab_seacat, # QtGui.QIcon(os.path.join(self.here, 'media', 'seacat.png')), "") # self.tabs.setTabToolTip(self.idx_seacat, "SeaCAT") # if not self.lib.setup.noaa_tools: # self.tab_seacat.setDisabled(True) # survey data monitor self.has_sdm_support = True try: # try.. except to make SSM working also without SDM from hyo.surveydatamonitor.app.widgets.monitor import SurveyDataMonitor self.tab_monitor = SurveyDataMonitor(lib=self.lib, main_win=self) self.idx_monitor = self.tabs.insertTab(3, self.tab_monitor, QtGui.QIcon(os.path.join(self.here, 'media', 'surveydatamonitor.png')), "") self.tabs.setTabToolTip(self.idx_monitor, "Survey Data Monitor") logger.info("Support for Survey Monitor: ON") except Exception as e: traceback.print_exc() self.has_sdm_support = False logger.info("Support for Survey Monitor: OFF(%s)" % e) # server self.tab_server = Server(lib=self.lib, main_win=self) self.idx_server = self.tabs.insertTab(4, self.tab_server, QtGui.QIcon(os.path.join(self.here, 'media', 'server.png')), "") self.tabs.setTabToolTip(self.idx_server, "Synthetic Profile Server") # refraction self.tab_refraction = Refraction(lib=self.lib, main_win=self) # idx = self.tabs.insertTab(5, self.tab_refraction, # QtGui.QIcon(os.path.join(self.here, 'media', 'refraction.png')), "") # self.tabs.setTabToolTip(idx, "Refraction Monitor") # setup self.tab_setup = Settings(lib=self.lib, main_win=self) self.idx_setup = self.tabs.insertTab(6, self.tab_setup, QtGui.QIcon(os.path.join(self.here, 'media', 'settings.png')), "") self.tabs.setTabToolTip(self.idx_setup, "Setup") # info self.tab_info = Info(main_win=self, default_url=web_url()) self.idx_info = self.tabs.insertTab(6, self.tab_info, QtGui.QIcon(os.path.join(self.here, 'media', 'info.png')), "") self.tabs.setTabToolTip(self.idx_info, "Info") self.statusBar().setStyleSheet("QStatusBar{color:rgba(0,0,0,128);font-size: 8pt;}") self.status_bar_normal_style = self.statusBar().styleSheet() self.statusBar().showMessage("%s" % ssm_version, 2000) self.releaseInfo = QtGui.QLabel() self.statusBar().addPermanentWidget(self.releaseInfo) self.releaseInfo.setStyleSheet("QLabel{color:rgba(0,0,0,128);font-size: 8pt;}") timer = QtCore.QTimer(self) timer.timeout.connect(self.update_gui) timer.start(1500) self.timer_execs = 0 self.data_cleared() self.tabs.blockSignals(False) logger.info("* > APP: initialized!") def onChange(self, i): # logger.debug("Current Tab Index: %s" % type(self.tabs.widget(i))) if type(self.tabs.widget(i)) == Settings: self.tab_setup.setup_changed() def switch_to_editor_tab(self): if self.tabs.currentIndex() != self.idx_editor: self.tabs.setCurrentIndex(self.idx_editor) def switch_to_database_tab(self): if self.tabs.currentIndex() != self.idx_database: self.tabs.setCurrentIndex(self.idx_database) def switch_to_monitor_tab(self): if self.tabs.currentIndex() != self.idx_monitor: self.tabs.setCurrentIndex(self.idx_monitor) def switch_to_server_tab(self): if self.tabs.currentIndex() != self.idx_server: self.tabs.setCurrentIndex(self.idx_server) def switch_to_setup_tab(self): if self.tabs.currentIndex() != self.idx_setup: self.tabs.setCurrentIndex(self.idx_setup) def switch_to_info_tab(self): if self.tabs.currentIndex() != self.idx_info: self.tabs.setCurrentIndex(self.idx_info) def check_woa09(self): """ helper function that looks after WOA09 database""" if not self.lib.use_woa09(): logger.debug('WOA09: disabled by settings') return if self.lib.has_woa09(): logger.debug('WOA09: enabled') return msg = 'The WOA09 atlas is required by some advanced application functions.\n\n' \ 'The data set (~120MB) can be retrieved from:\n' \ ' ftp.ccom.unh.edu/fromccom/hydroffice/woa09.red.zip\n' \ 'then unzipped it into:\n' \ ' %s\n\n' \ 'Do you want that I perform this operation for you?\n' \ 'Internet connection is required!\n' % self.lib.woa09_folder # noinspection PyCallByClass ret = QtGui.QMessageBox.information(self, "Sound Speed Manager - WOA09 Atlas", msg, QtGui.QMessageBox.Ok | QtGui.QMessageBox.No) if ret == QtGui.QMessageBox.No: msg = 'You can also manually install it. The steps are:\n' \ ' - download the archive from (anonymous ftp):\n' \ ' ftp.ccom.unh.edu/fromccom/hydroffice/woa09.red.zip\n' \ ' - unzip the archive into:\n' \ ' %s\n' \ ' - restart Sound Speed Manager\n' % self.lib.woa09_folder # noinspection PyCallByClass QtGui.QMessageBox.information(self, "Sound Speed Manager - WOA09 Atlas", msg, QtGui.QMessageBox.Ok) logger.debug('WOA09: disabled') return success = self.lib.download_woa09() if not success: msg = 'Unable to retrieve the WOA09 atlas.\n\n ' \ 'You may manually install it. The steps are:\n' \ ' - download the archive from (anonymous ftp):\n' \ ' ftp.ccom.unh.edu/fromccom/hyo/woa09.red.zip\n' \ ' - unzip the archive into:\n' \ ' %s\n' \ ' - restart Sound Speed Manager\n' % self.lib.woa09_folder # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - WOA09 Atlas", msg, QtGui.QMessageBox.Ok) logger.debug('WOA09: disabled') return logger.debug('WOA09: enabled') def check_woa13(self): """ helper function that looks after WOA13 database""" if not self.lib.use_woa13(): logger.debug('WOA13: disabled by settings') return if self.lib.has_woa13(): logger.debug('WOA13: enabled') return msg = 'The WOA13 atlas is required by some advanced application functions.\n\n' \ 'The data set (~4GB) can be retrieved from:\n' \ ' ftp.ccom.unh.edu/fromccom/hydroffice/woa13_temp.red.zip\n' \ ' ftp.ccom.unh.edu/fromccom/hydroffice/woa13_sal.red.zip\n' \ 'then unzipped it into:\n' \ ' %s\n\n' \ 'Do you want that I perform this operation for you?\n' \ 'Internet connection is required!\n' % self.lib.woa13_folder # noinspection PyCallByClass ret = QtGui.QMessageBox.information(self, "Sound Speed Manager - WOA13 Atlas", msg, QtGui.QMessageBox.Ok | QtGui.QMessageBox.No) if ret == QtGui.QMessageBox.No: msg = 'You can also manually install it. The steps are:\n' \ ' - download the archive from (anonymous ftp):\n' \ ' ftp.ccom.unh.edu/fromccom/hydroffice/woa13_temp.red.zip\n' \ ' ftp.ccom.unh.edu/fromccom/hydroffice/woa13_sal.red.zip\n' \ ' - unzip the archive into:\n' \ ' %s\n' \ ' - restart Sound Speed Manager\n' % self.lib.woa13_folder # noinspection PyCallByClass QtGui.QMessageBox.information(self, "Sound Speed Manager - WOA13 Atlas", msg, QtGui.QMessageBox.Ok) logger.debug('WOA13: disabled') return success = self.lib.download_woa13() if not success: msg = 'Unable to retrieve the WOA13 atlas.\n\n ' \ 'You may manually install it. The steps are:\n' \ ' - download the archive from (anonymous ftp):\n' \ ' ftp.ccom.unh.edu/fromccom/hyo/woa13_temp.red.zip\n' \ ' ftp.ccom.unh.edu/fromccom/hyo/woa13_sal.red.zip\n' \ ' - unzip the archive into:\n' \ ' %s\n' \ ' - restart Sound Speed Manager\n' % self.lib.woa13_folder # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - WOA13 Atlas", msg, QtGui.QMessageBox.Ok) logger.debug('WOA13: disabled') return logger.debug('WOA13: enabled') def check_rtofs(self): """ helper function that looks after RTOFS connection""" if not self.lib.use_rtofs(): logger.debug('RTOFS: disabled by settings') return if self.lib.has_rtofs(): logger.debug('RTOFS: enabled') return success = self.lib.download_rtofs() if not success: msg = 'Unable to retrieve the RTOFS atlas.\n\n ' \ 'The application needs an internet connection to access\n' \ 'this server (with port 9090 open):\n' \ ' - http://nomads.ncep.noaa.gov:9090\n\n' \ 'You can disable the RTOFS support in Settings/Basic/Use RTOFS.\n' # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - RTOFS Atlas", msg, QtGui.QMessageBox.Ok) logger.debug('RTOFS: disabled') return logger.debug('RTOFS: enabled') def check_sis(self): if self.lib.use_sis(): if not self.lib.listen_sis(): msg = 'Unable to listen SIS.' # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - SIS", msg, QtGui.QMessageBox.Ok) else: if not self.lib.stop_listen_sis(): msg = 'Unable to stop listening SIS.' # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - SIS", msg, QtGui.QMessageBox.Ok) def check_sippican(self): if self.lib.use_sippican(): if not self.lib.listen_sippican(): msg = 'Unable to listening Sippican.' # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - Sippican", msg, QtGui.QMessageBox.Ok) else: if not self.lib.stop_listen_sippican(): msg = 'Unable to stop listening Sippican.' # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - Sippican", msg, QtGui.QMessageBox.Ok) def check_mvp(self): if self.lib.use_mvp(): if not self.lib.listen_mvp(): msg = 'Unable to listening MVP.' # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - MVP", msg, QtGui.QMessageBox.Ok) else: if not self.lib.stop_listen_mvp(): msg = 'Unable to stop listening MVP.' # noinspection PyCallByClass QtGui.QMessageBox.warning(self, "Sound Speed Manager - MVP", msg, QtGui.QMessageBox.Ok) def data_cleared(self): self.tab_editor.data_cleared() self.tab_database.data_cleared() self.tab_server.data_cleared() self.tab_refraction.data_cleared() self.tab_setup.data_cleared() def data_imported(self): self.tab_editor.data_imported() self.tab_database.data_imported() self.tab_server.data_imported() self.tab_refraction.data_imported() self.tab_setup.data_imported() def data_stored(self): self.tab_editor.data_stored() self.tab_database.data_stored() self.tab_server.data_stored() self.tab_refraction.data_stored() self.tab_setup.data_stored() def data_removed(self): self.tab_editor.data_removed() self.tab_database.data_removed() self.tab_server.data_removed() self.tab_refraction.data_removed() self.tab_setup.data_removed() def server_started(self): # clear widgets as for data clear self.data_cleared() self.tab_editor.server_started() self.tab_database.server_started() self.tab_server.server_started() self.tab_refraction.server_started() self.tab_setup.server_started() self.statusBar().setStyleSheet("QStatusBar{color:rgba(0,0,0,128);" "font-size: 8pt;background-color:rgba(51,204,255,128);}") def server_stopped(self): self.tab_editor.server_stopped() self.tab_database.server_stopped() self.tab_server.server_stopped() self.tab_refraction.server_stopped() self.tab_setup.server_stopped() self.statusBar().setStyleSheet(self.status_bar_normal_style) def _check_latest_release(self): new_release = False new_bugfix = False latest_version = None try: response = urlopen('http://www.hydroffice.org/latest/soundspeedmanager.txt', timeout=2) latest_version = response.read().split()[0].decode() cur_maj, cur_min, cur_fix = ssm_version.split('.') lat_maj, lat_min, lat_fix = latest_version.split('.') if int(lat_maj) > int(cur_maj): new_release = True elif (int(lat_maj) == int(cur_maj)) and (int(lat_min) > int(cur_min)): new_release = True elif (int(lat_maj) == int(cur_maj)) and (int(lat_min) == int(cur_min)) and (int(lat_fix) > int(cur_fix)): new_bugfix = True except (URLError, ssl.SSLError, socket.timeout, ConnectionResetError, ValueError) as e: logger.info("unable to check latest release (reason: %s)" % e) if new_release: logger.info("new release available: %s" % latest_version) self.releaseInfo.setText("New release available: %s" % latest_version) self.releaseInfo.setStyleSheet("QLabel{background-color:rgba(255,0,0,128);" "color:rgba(0,0,0,128);" "font-size: 8pt;}") elif new_bugfix: logger.info("new bugfix available: %s" % latest_version) self.releaseInfo.setText("New bugfix available: %s" % latest_version) self.releaseInfo.setStyleSheet("QLabel{background-color:rgba(255,255,0,128);" "color:rgba(0,0,0,128);" "font-size: 8pt;}") def update_gui(self): if self.timer_execs % 200 == 0: # logger.debug("timer executions: %d" % self.timer_execs) self._check_latest_release() self.timer_execs += 1 # if self.lib.setup.noaa_tools: # self.tab_seacat.setEnabled(True) # else: # self.tab_seacat.setDisabled(True) # update the windows title self.setWindowTitle('%s v.%s [project: %s]' % (self.name, self.version, self.lib.current_project)) msg = str() tokens = list() if self.lib.server.is_alive(): tokens.append("SRV") if self.lib.has_ref(): tokens.append("REF") if self.lib.use_rtofs(): tokens.append("RTF") if self.lib.use_woa09(): tokens.append("W09") if self.lib.use_woa13(): tokens.append("W13") if self.lib.use_sippican(): tokens.append("SIP") if self.lib.use_mvp(): tokens.append("MVP") if self.lib.use_sis(): tokens.append("SIS") msg += "|".join(tokens) if not self.lib.use_sis(): # in case that SIS was disabled self.statusBar().showMessage(msg, 1000) return msg += " - " # add some spacing if self.lib.listeners.sis.nav is not None: # time stamp msg += "time:" if self.lib.listeners.sis.nav.dg_time is not None: msg += "%s, " % (self.lib.listeners.sis.nav.dg_time.strftime("%H:%M:%S")) else: msg += "NA, " # position msg += "pos:" if (self.lib.listeners.sis.nav.latitude is not None) and (self.lib.listeners.sis.nav.longitude is not None): latitude = self.lib.listeners.sis.nav.latitude if latitude >= 0: letter = "N" else: letter = "S" lat_min = float(60 * math.fabs(latitude - int(latitude))) lat_str = "%02d\N{DEGREE SIGN}%7.3f'%s" % (int(math.fabs(latitude)), lat_min, letter) longitude = self.lib.listeners.sis.nav.longitude if longitude < 0: letter = "W" else: letter = "E" lon_min = float(60 * math.fabs(longitude - int(longitude))) lon_str = "%03d\N{DEGREE SIGN}%7.3f'%s" % (int(math.fabs(longitude)), lon_min, letter) msg += "(%s, %s), " % (lat_str, lon_str) else: msg += "(NA, NA), " if self.lib.listeners.sis.xyz88 is not None: msg += 'tss:' if self.lib.listeners.sis.xyz88.sound_speed is not None: msg += '%.1f m/s, ' % self.lib.listeners.sis.xyz88.sound_speed else: msg += 'NA m/s, ' msg += 'avg.depth:' mean_depth = self.lib.listeners.sis.xyz88.mean_depth if mean_depth: msg += '%.1f m' % mean_depth else: msg += 'NA m' else: msg += 'XYZ88 NA [pinging?]' self.statusBar().showMessage(msg, 2000) if self.lib.has_ssp(): if self.lib.server.is_alive(): # server mode if not self.tab_server.dataplots.is_drawn: self.tab_server.dataplots.reset() self.tab_server.dataplots.on_first_draw() self.tab_server.dataplots.update_data() self.tab_server.dataplots.redraw() else: # user mode if self.lib.has_mvp_to_process() or self.lib.has_sippican_to_process(): # logger.debug("data to import from listeners") # logger.debug("plot drawn: %s" % self.tab_editor.dataplots.is_drawn) if not self.tab_editor.dataplots.is_drawn: self.data_imported() if self.lib.cur.listener_completed and not self.lib.cur.listener_displayed: self.tab_editor.dataplots.on_first_draw() self.lib.cur.listener_displayed = True self.tab_editor.dataplots.update_data() self.tab_editor.dataplots.redraw() if not self.lib.server.is_alive(): # user mode - listeners if self.lib.has_mvp_to_process() or self.lib.has_sippican_to_process(): self.statusBar().setStyleSheet("QStatusBar{color:rgba(0,0,0,128);" "font-size: 8pt;background-color:rgba(255,163,102,128);}") else: self.statusBar().setStyleSheet(self.status_bar_normal_style) def change_info_url(self, url): self.tab_info.change_default(url) # Quitting # def _do_you_really_want(self, title="Quit", text="quit"): """helper function that show to the user a message windows asking to confirm an action""" msg_box = QtGui.QMessageBox(self) msg_box.setWindowTitle(title) msg_box.setIconPixmap(QtGui.QPixmap(os.path.join(self.media, 'favicon.png')).scaled(QtCore.QSize(36, 36))) msg_box.setText('Do you really want to %s?' % text) msg_box.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) msg_box.setDefaultButton(QtGui.QMessageBox.No) return msg_box.exec_() def closeEvent(self, event): """ actions to be done before close the app """ reply = self._do_you_really_want("Quit", "quit %s" % self.name) # reply = QtGui.QMessageBox.Yes if reply == QtGui.QMessageBox.Yes: event.accept() self.lib.close() if self.has_sdm_support: self.tab_monitor.stop_plotting() super(MainWin, self).closeEvent(event) else: event.ignore() # -------------------------- development-only -------------------------- def do(self): """ development-mode only helper function """ pass
def __init__(self): super(MainWin, self).__init__() logger.info("* > APP: initializing ...") # set the application name and the version self.name = ssm_name self.version = ssm_version self.setWindowTitle('%s v.%s' % (self.name, self.version)) # noinspection PyArgumentList _app = QtCore.QCoreApplication.instance() _app.setApplicationName('%s' % self.name) _app.setOrganizationName("HydrOffice") _app.setOrganizationDomain("hydroffice.org") # set the minimum and the initial size self.setMinimumSize(640, 480) self.resize(920, 600) # set icons icon_info = QtCore.QFileInfo(os.path.join(self.media, 'favicon.png')) self.setWindowIcon(QtGui.QIcon(icon_info.absoluteFilePath())) if (sys.platform == 'win32') or (os.name is "nt"): # is_windows() try: # This is needed to display the app icon on the taskbar on Windows 7 import ctypes app_id = '%s v.%s' % (self.name, self.version) ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(app_id) except AttributeError as e: logger.debug("Unable to change app icon: %s" % e) # set palette/stylesheet style_info = QtCore.QFileInfo(os.path.join(self.here, 'styles', 'main.stylesheet')) style_content = open(style_info.filePath()).read() self.setStyleSheet(style_content) # check if setup db exists; if yes, ask to copy has_setup = SoundSpeedLibrary.setup_exists() logger.info("setup exists: %s" % has_setup) if not has_setup: other_setups = SoundSpeedLibrary.list_other_setups() if len(other_setups) != 0: logger.debug("other existing setups: %d" % len(other_setups)) sel, ok = QtGui.QInputDialog.getItem(self, 'Do you want to copy an existing setup?', 'Select one (or click on Cancel to create a new one):', other_setups, 0, False) if ok: SoundSpeedLibrary.copy_setup(input_setup=sel) # create the project self.lib = SoundSpeedLibrary(callbacks=QtCallbacks(parent=self), progress=QtProgress(parent=self)) logger.debug("dependencies:\n%s" % info_libs()) self.check_woa09() self.check_woa13() # self.check_rtofs() # no need to wait for the download at the beginning self.check_sis() self.check_sippican() self.check_mvp() # init default settings settings = QtCore.QSettings() export_folder = settings.value("export_folder") if (export_folder is None) or (not os.path.exists(export_folder)): settings.setValue("export_folder", self.lib.data_folder) import_folder = settings.value("import_folder") if (import_folder is None) or (not os.path.exists(import_folder)): settings.setValue("import_folder", self.lib.data_folder) # menu self.menu = self.menuBar() self.file_menu = self.menu.addMenu("File") self.edit_menu = self.menu.addMenu("Process") self.database_menu = self.menu.addMenu("Database") self.monitor_menu = self.menu.addMenu("Monitor") self.server_menu = self.menu.addMenu("Server") self.setup_menu = self.menu.addMenu("Setup") self.help_menu = self.menu.addMenu("Help") # make tabs self.tabs = QtGui.QTabWidget() self.setCentralWidget(self.tabs) self.tabs.setIconSize(QtCore.QSize(42, 42)) self.tabs.blockSignals(True) # during the initialization self.tabs.currentChanged.connect(self.onChange) # changed! # editor self.tab_editor = Editor(lib=self.lib, main_win=self) self.idx_editor = self.tabs.insertTab(0, self.tab_editor, QtGui.QIcon(os.path.join(self.here, 'media', 'editor.png')), "") self.tabs.setTabToolTip(self.idx_editor, "Editor") # database self.tab_database = Database(lib=self.lib, main_win=self) self.idx_database = self.tabs.insertTab(1, self.tab_database, QtGui.QIcon(os.path.join(self.here, 'media', 'database.png')), "") self.tabs.setTabToolTip(self.idx_database, "Database") # seacat # self.tab_seacat = Seacat(lib=self.lib, main_win=self) # self.idx_seacat = self.tabs.insertTab(2, self.tab_seacat, # QtGui.QIcon(os.path.join(self.here, 'media', 'seacat.png')), "") # self.tabs.setTabToolTip(self.idx_seacat, "SeaCAT") # if not self.lib.setup.noaa_tools: # self.tab_seacat.setDisabled(True) # survey data monitor self.has_sdm_support = True try: # try.. except to make SSM working also without SDM from hyo.surveydatamonitor.app.widgets.monitor import SurveyDataMonitor self.tab_monitor = SurveyDataMonitor(lib=self.lib, main_win=self) self.idx_monitor = self.tabs.insertTab(3, self.tab_monitor, QtGui.QIcon(os.path.join(self.here, 'media', 'surveydatamonitor.png')), "") self.tabs.setTabToolTip(self.idx_monitor, "Survey Data Monitor") logger.info("Support for Survey Monitor: ON") except Exception as e: traceback.print_exc() self.has_sdm_support = False logger.info("Support for Survey Monitor: OFF(%s)" % e) # server self.tab_server = Server(lib=self.lib, main_win=self) self.idx_server = self.tabs.insertTab(4, self.tab_server, QtGui.QIcon(os.path.join(self.here, 'media', 'server.png')), "") self.tabs.setTabToolTip(self.idx_server, "Synthetic Profile Server") # refraction self.tab_refraction = Refraction(lib=self.lib, main_win=self) # idx = self.tabs.insertTab(5, self.tab_refraction, # QtGui.QIcon(os.path.join(self.here, 'media', 'refraction.png')), "") # self.tabs.setTabToolTip(idx, "Refraction Monitor") # setup self.tab_setup = Settings(lib=self.lib, main_win=self) self.idx_setup = self.tabs.insertTab(6, self.tab_setup, QtGui.QIcon(os.path.join(self.here, 'media', 'settings.png')), "") self.tabs.setTabToolTip(self.idx_setup, "Setup") # info self.tab_info = Info(main_win=self, default_url=web_url()) self.idx_info = self.tabs.insertTab(6, self.tab_info, QtGui.QIcon(os.path.join(self.here, 'media', 'info.png')), "") self.tabs.setTabToolTip(self.idx_info, "Info") self.statusBar().setStyleSheet("QStatusBar{color:rgba(0,0,0,128);font-size: 8pt;}") self.status_bar_normal_style = self.statusBar().styleSheet() self.statusBar().showMessage("%s" % ssm_version, 2000) self.releaseInfo = QtGui.QLabel() self.statusBar().addPermanentWidget(self.releaseInfo) self.releaseInfo.setStyleSheet("QLabel{color:rgba(0,0,0,128);font-size: 8pt;}") timer = QtCore.QTimer(self) timer.timeout.connect(self.update_gui) timer.start(1500) self.timer_execs = 0 self.data_cleared() self.tabs.blockSignals(False) logger.info("* > APP: initialized!")
def test_new_projects(self): from hyo.soundspeed.soundspeed import SoundSpeedLibrary lib = SoundSpeedLibrary() ssp_list = lib.db_list_profiles() self.assertGreaterEqual(len(ssp_list), 0) lib.current_project = "zzz" ssp_list = lib.db_list_profiles() self.assertGreaterEqual(len(ssp_list), 0) prj_list = lib.list_projects() self.assertGreaterEqual(len(prj_list), 2) lib.current_project = "aaa" lib.remove_project("zzz") prj_list = lib.list_projects() self.assertGreaterEqual(len(prj_list), 1) lib.close()
def test_creation_of_Rtofs(self): prj = SoundSpeedLibrary(data_folder=self.cur_dir) rtofs = Rtofs(data_folder=prj.rtofs_folder, prj=prj) self.assertTrue('rtofs' in rtofs.data_folder) self.assertFalse(rtofs.is_present()) prj.close()
from hyo.soundspeed.logging import test_logging import time import logging logger = logging.getLogger() from hyo.soundspeed.server.server import Server from hyo.soundspeed.soundspeed import SoundSpeedLibrary lib = SoundSpeedLibrary() lib.listen_sis() time.sleep(3) # for SIS emulator server = Server(prj=lib) success = server.check_settings() if not success: exit("Issue while checking the settings") logger.debug("Settings successfully checked") server.start() time.sleep(20) server.force_send = True time.sleep(10) server.stop()