class HomePage(QWidget): stack_images = pyqtSignal(str) import_image = pyqtSignal(str) calibrate = pyqtSignal(str) math = pyqtSignal(str) finish = pyqtSignal(str) new_project = pyqtSignal() open_project = pyqtSignal(str) def __init__(self, settings, database): QWidget.__init__(self) last_files_list = LastFilesList(settings) self.settings = settings self.database = database self.ui = Ui_HomePage() self.ui.setupUi(self) self.toolbar = QToolBar() welcome_text = "{} {}".format(QApplication.instance().applicationName(), QApplication.instance().applicationVersion()) self.ui.welcome_label.setText(self.ui.welcome_label.text().format(welcome_text)) file_action = QtCommons.addToolbarPopup(self.toolbar, 'File', icon_file=':/file_20') project_action = QtCommons.addToolbarPopup(self.toolbar, 'Project', icon_file=':/project_20') #file_action.menu().addAction(QIcon(':/stack_20'), 'Stack Images', lambda: open_file_sticky('Open Reference FITS Image',FITS_IMG_EXTS, lambda f: self.stack_images.emit(f[0]), settings, IMPORT_IMG )) import_image_action = lambda: ImportImage.pick(lambda f: self.import_image.emit(f[0]), settings) file_action.menu().addAction(ImportImage.icon(), ImportImage.ACTION_TEXT, import_image_action) self.ui.import_image.clicked.connect(import_image_action) file_action.menu().addAction(QIcon(':/plot_20'), 'Calibrate Spectrum', lambda: open_file_sticky('Open raw FITS Spectrum',FITS_EXTS, lambda f: self.calibrate.emit(f[0]), settings, RAW_PROFILE, [IMPORT_IMG] )) file_action.menu().addAction(QIcon(':/math_20'), 'Spectra Math', lambda: self.math.emit(None) ) file_action.menu().addAction(QIcon(':/done_20'), 'Finish Spectrum', lambda: open_file_sticky('Open FITS Spectrum',FITS_EXTS, lambda f: self.finish.emit(f[0]), settings, CALIBRATED_PROFILE, [RAW_PROFILE,IMPORT_IMG] )) project_action.menu().addAction(QIcon(':/project_new_20'), 'New', lambda: self.new_project.emit()) pick_project = lambda: open_directory_sticky('Open Project', self.__project_picked, settings, PROJECTS) self.ui.pick_project.clicked.connect(pick_project) project_action.menu().addAction(QIcon(':/new_open_20'), 'Open...', pick_project) self.recent_raw_model = QStandardItemModel() self.recent_calibrated_model = QStandardItemModel() self.recent_projects_model = QStandardItemModel() self.ui.recent_raw_list.setModel(self.recent_raw_model) self.ui.recent_calibrated_list.setModel(self.recent_calibrated_model) self.ui.recent_projects.setModel(self.recent_projects_model) for widget in [self.ui.recent_raw_list, self.ui.recent_calibrated_list, self.ui.recent_projects]: widget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) LastFilesList.instance().files_changed.connect(self.__populate_lists) selected_path = lambda model, view: model.item(view.selectionModel().selectedRows()[0].row()).data() button_enable = lambda view, button: view.selectionModel().selectionChanged.connect(lambda sel, desel: button.setEnabled(len(sel.indexes() )) ) button_enable(self.ui.recent_raw_list, self.ui.calibrate) button_enable(self.ui.recent_calibrated_list, self.ui.math) button_enable(self.ui.recent_calibrated_list, self.ui.finish) button_enable(self.ui.recent_projects, self.ui.open_recent_project) self.ui.calibrate.clicked.connect(lambda: self.calibrate.emit(selected_path(self.recent_raw_model, self.ui.recent_raw_list))) self.ui.math.clicked.connect(lambda: self.math.emit(selected_path(self.recent_calibrated_model, self.ui.recent_calibrated_list))) self.ui.finish.clicked.connect(lambda: self.finish.emit(selected_path(self.recent_calibrated_model, self.ui.recent_calibrated_list))) self.ui.open_recent_project.clicked.connect(lambda: self.open_project.emit(selected_path(self.recent_projects_model, self.ui.recent_projects))) self.ui.new_project.clicked.connect(self.new_project.emit) self.reference_catalogues = ReferenceCatalogues(database) self.ui.download_catalogs.clicked.connect(self.download_catalogs) self.__populate_lists() def __project_picked(self, file): try: project = Project(file[0]) self.open_project.emit(project.path) except FileNotFoundError: QMessageBox.warning(self, 'Project not found', 'Missing or invalid project specified') def __populate_lists(self): get_names = { RAW_PROFILE: ('File', lambda n, p: n), CALIBRATED_PROFILE: ('File', lambda n, p: n ), PROJECTS: ('Name', lambda n, p: Project(p).get_name() ) } for key, model in [(RAW_PROFILE, self.recent_raw_model), (CALIBRATED_PROFILE, self.recent_calibrated_model), (PROJECTS, self.recent_projects_model)]: model.clear() for name, dir, path in LastFilesList.instance().last_files(key): try: model.setHorizontalHeaderLabels([get_names[key][0], "Directory"]) item = QStandardItem(get_names[key][1](name, path)) item.setData(path) model.appendRow([item, QStandardItem(dir)]) except: pass def download_catalogs(self): dialog = QDialog() dialog.setWindowTitle('Download Catalogs') dialog.setLayout(QVBoxLayout()) dialog.layout().addWidget(QLabel('Select catalogues to be downloaded')) checkboxes = dict([(c, QCheckBox(c)) for c in self.reference_catalogues.catalogues]) for name, checkbox in checkboxes.items(): checkbox.setChecked(True) dialog.layout().addWidget(checkbox) buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonbox.accepted.connect(dialog.accept) buttonbox.rejected.connect(dialog.reject) dialog.layout().addWidget(buttonbox) if dialog.exec() == QDialog.Rejected: return for cat, checkbox in checkboxes.items(): if not checkbox.isChecked(): continue spectra = self.reference_catalogues.spectra(cat) progress = QProgressDialog('Downloading spectra from catalog {}'.format(cat), 'Cancel', 0, len(spectra)) progress.setWindowTitle('Downloading catalogs') progress.setWindowModality(Qt.WindowModal) progress.show() for index, spectrum in enumerate(spectra): progress.setValue(index) if progress.wasCanceled(): return; QApplication.instance().processEvents() self.reference_catalogues.fits(spectrum)
class ReferenceSpectraDialog(QDialog): fits_picked = pyqtSignal(str) def __init__(self, database, main_spectrum=None): super(ReferenceSpectraDialog, self).__init__() self.main_spectrum = main_spectrum self.ui = Ui_ReferenceSpectraDialog() self.ui.setupUi(self) self.reference_catalogues = ReferenceCatalogues(database) self.full_model = QStandardItemModel() self.catalogues_model = QStandardItemModel() self.ui.catalogue.setModel(self.catalogues_model) self.ui.catalogue.currentTextChanged.connect( lambda txt: self.populate()) for catname, cat in self.reference_catalogues.catalogues.items(): row = QStandardItem(catname) row.setData(cat) self.catalogues_model.appendRow(row) self.model = QSortFilterProxyModel() self.model.setSourceModel(self.full_model) self.model.setFilterCaseSensitivity(Qt.CaseInsensitive) self.model.setFilterKeyColumn(0) self.ui.entries.setModel(self.model) self.ui.type_filter.currentTextChanged.connect( lambda txt: self.model.setFilterWildcard("{}*".format(txt))) self.ui.buttonBox.button(QDialogButtonBox.Open).setEnabled(False) self.ui.entries.selectionModel().selectionChanged.connect( lambda selected, deselected: self.ui.buttonBox.button( QDialogButtonBox.Open).setEnabled(len(selected.indexes()) > 0)) self.accepted.connect(self.load_fits) self.populate() def set_main_spectrum(self, spectrum): self.main_spectrum = spectrum def populate(self): self.full_model.clear() catalogue = self.catalogues_model.item( self.ui.catalogue.currentIndex()).data() self.full_model.setHorizontalHeaderLabels(['Spectral Type']) entries = self.reference_catalogues.spectra(catalogue['name']) self.ui.type_filter.clear() self.ui.type_filter.addItem('') self.ui.type_filter.addItems( sorted(set([i['sptype'] for i in entries]))) for entry in entries: item = QStandardItem(entry['sptype']) item.setData(entry) self.full_model.appendRow(item) def load_fits(self): original_index = self.model.mapToSource( self.ui.entries.selectionModel().selectedIndexes()[0]) entry = self.full_model.item(original_index.row()).data() self.fits_picked.emit(self.reference_catalogues.fits(entry)) def setup_menu(self, toolbar, axes, settings): self.current_line = None reference_action = QtCommons.addToolbarPopup(toolbar, "Reference") reference_action.menu().addAction("Reference library", lambda: self.show()) reference_action.menu().addAction( "Load from FITS file", lambda: open_file_sticky( 'Open Reference Profile', FITS_EXTS, lambda f: self. __open_reference(f[0], axes), settings, REFERENCE)) self.close_action = reference_action.menu().addAction( "Close", lambda: self.__close_reference(axes)) self.close_action.setEnabled(False) self.fits_picked.connect(lambda f: self.__open_reference(f, axes)) self.blackbody_menu = blackbody.BlackBodyAction( lambda bb: self.blackbody(bb, axes), reference_action.menu()) return reference_action.menu() def blackbody(self, blackbody, axes): self.__open(blackbody.spectrum(), axes) def __open_reference(self, file, axes): fits_spectrum = FitsSpectrum(fits.open(file)) self.__open(fits_spectrum.spectrum, axes) def __open(self, spectrum, axes): self.__close_reference(axes) if spectrum.dispersion() < 0.4 and spectrum.dispersion() > 0: spectrum.resample(spectrum.dispersion() / 0.4) if (self.main_spectrum): print("Cutting spectrum: {0}, {1}".format( self.main_spectrum.wavelengths[0], self.main_spectrum.wavelengths[-1])) spectrum.cut_lambda(self.main_spectrum.wavelengths[0], self.main_spectrum.wavelengths[-1]) spectrum.normalize_to_max() self.current_line = Line2D(spectrum.wavelengths, spectrum.fluxes, color='gray') axes.add_line(self.current_line) axes.figure.canvas.draw() self.close_action.setEnabled(True) def __close_reference(self, axes): self.close_action.setEnabled(False) if self.current_line: try: # TODO: verify self.current_line.remove() self.current_line = None axes.figure.canvas.draw() except: pass
class HomePage(QWidget): stack_images = pyqtSignal(str) import_image = pyqtSignal(str) calibrate = pyqtSignal(str) math = pyqtSignal(str) finish = pyqtSignal(str) new_project = pyqtSignal() open_project = pyqtSignal(str) def __init__(self, settings, database): QWidget.__init__(self) last_files_list = LastFilesList(settings) self.settings = settings self.database = database self.ui = Ui_HomePage() self.ui.setupUi(self) self.toolbar = QToolBar() welcome_text = "{} {}".format( QApplication.instance().applicationName(), QApplication.instance().applicationVersion()) self.ui.welcome_label.setText( self.ui.welcome_label.text().format(welcome_text)) file_action = QtCommons.addToolbarPopup(self.toolbar, 'File', icon_file=':/file_20') project_action = QtCommons.addToolbarPopup(self.toolbar, 'Project', icon_file=':/project_20') #file_action.menu().addAction(QIcon(':/stack_20'), 'Stack Images', lambda: open_file_sticky('Open Reference FITS Image',FITS_IMG_EXTS, lambda f: self.stack_images.emit(f[0]), settings, IMPORT_IMG )) import_image_action = lambda: ImportImage.pick( lambda f: self.import_image.emit(f[0]), settings) file_action.menu().addAction(ImportImage.icon(), ImportImage.ACTION_TEXT, import_image_action) self.ui.import_image.clicked.connect(import_image_action) file_action.menu().addAction( QIcon(':/plot_20'), 'Calibrate Spectrum', lambda: open_file_sticky( 'Open raw FITS Spectrum', FITS_EXTS, lambda f: self.calibrate. emit(f[0]), settings, RAW_PROFILE, [IMPORT_IMG])) file_action.menu().addAction(QIcon(':/math_20'), 'Spectra Math', lambda: self.math.emit(None)) file_action.menu().addAction( QIcon(':/done_20'), 'Finish Spectrum', lambda: open_file_sticky( 'Open FITS Spectrum', FITS_EXTS, lambda f: self.finish.emit(f[ 0]), settings, CALIBRATED_PROFILE, [RAW_PROFILE, IMPORT_IMG])) project_action.menu().addAction(QIcon(':/project_new_20'), 'New', lambda: self.new_project.emit()) pick_project = lambda: open_directory_sticky( 'Open Project', self.__project_picked, settings, PROJECTS) self.ui.pick_project.clicked.connect(pick_project) project_action.menu().addAction(QIcon(':/new_open_20'), 'Open...', pick_project) self.recent_raw_model = QStandardItemModel() self.recent_calibrated_model = QStandardItemModel() self.recent_projects_model = QStandardItemModel() self.ui.recent_raw_list.setModel(self.recent_raw_model) self.ui.recent_calibrated_list.setModel(self.recent_calibrated_model) self.ui.recent_projects.setModel(self.recent_projects_model) for widget in [ self.ui.recent_raw_list, self.ui.recent_calibrated_list, self.ui.recent_projects ]: widget.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) LastFilesList.instance().files_changed.connect(self.__populate_lists) selected_path = lambda model, view: model.item(view.selectionModel( ).selectedRows()[0].row()).data() button_enable = lambda view, button: view.selectionModel( ).selectionChanged.connect(lambda sel, desel: button.setEnabled( len(sel.indexes()))) button_enable(self.ui.recent_raw_list, self.ui.calibrate) button_enable(self.ui.recent_calibrated_list, self.ui.math) button_enable(self.ui.recent_calibrated_list, self.ui.finish) button_enable(self.ui.recent_projects, self.ui.open_recent_project) self.ui.calibrate.clicked.connect(lambda: self.calibrate.emit( selected_path(self.recent_raw_model, self.ui.recent_raw_list))) self.ui.math.clicked.connect(lambda: self.math.emit( selected_path(self.recent_calibrated_model, self.ui. recent_calibrated_list))) self.ui.finish.clicked.connect(lambda: self.finish.emit( selected_path(self.recent_calibrated_model, self.ui. recent_calibrated_list))) self.ui.open_recent_project.clicked.connect( lambda: self.open_project.emit( selected_path(self.recent_projects_model, self.ui. recent_projects))) self.ui.new_project.clicked.connect(self.new_project.emit) self.reference_catalogues = ReferenceCatalogues(database) self.ui.download_catalogs.clicked.connect(self.download_catalogs) self.__populate_lists() def __project_picked(self, file): try: project = Project(file[0]) self.open_project.emit(project.path) except FileNotFoundError: QMessageBox.warning(self, 'Project not found', 'Missing or invalid project specified') def __populate_lists(self): get_names = { RAW_PROFILE: ('File', lambda n, p: n), CALIBRATED_PROFILE: ('File', lambda n, p: n), PROJECTS: ('Name', lambda n, p: Project(p).get_name()) } for key, model in [(RAW_PROFILE, self.recent_raw_model), (CALIBRATED_PROFILE, self.recent_calibrated_model), (PROJECTS, self.recent_projects_model)]: model.clear() for name, dir, path in LastFilesList.instance().last_files(key): try: model.setHorizontalHeaderLabels( [get_names[key][0], "Directory"]) item = QStandardItem(get_names[key][1](name, path)) item.setData(path) model.appendRow([item, QStandardItem(dir)]) except: pass def download_catalogs(self): dialog = QDialog() dialog.setWindowTitle('Download Catalogs') dialog.setLayout(QVBoxLayout()) dialog.layout().addWidget(QLabel('Select catalogues to be downloaded')) checkboxes = dict([(c, QCheckBox(c)) for c in self.reference_catalogues.catalogues]) for name, checkbox in checkboxes.items(): checkbox.setChecked(True) dialog.layout().addWidget(checkbox) buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonbox.accepted.connect(dialog.accept) buttonbox.rejected.connect(dialog.reject) dialog.layout().addWidget(buttonbox) if dialog.exec() == QDialog.Rejected: return for cat, checkbox in checkboxes.items(): if not checkbox.isChecked(): continue spectra = self.reference_catalogues.spectra(cat) progress = QProgressDialog( 'Downloading spectra from catalog {}'.format(cat), 'Cancel', 0, len(spectra)) progress.setWindowTitle('Downloading catalogs') progress.setWindowModality(Qt.WindowModal) progress.show() for index, spectrum in enumerate(spectra): progress.setValue(index) if progress.wasCanceled(): return QApplication.instance().processEvents() self.reference_catalogues.fits(spectrum)
class ReferenceSpectraDialog(QDialog): fits_picked = pyqtSignal(str) def __init__(self, database, main_spectrum = None): super(ReferenceSpectraDialog, self).__init__() self.main_spectrum = main_spectrum self.ui = Ui_ReferenceSpectraDialog() self.ui.setupUi(self) self.reference_catalogues = ReferenceCatalogues(database) self.full_model = QStandardItemModel() self.catalogues_model = QStandardItemModel() self.ui.catalogue.setModel(self.catalogues_model) self.ui.catalogue.currentTextChanged.connect(lambda txt: self.populate()) for catname, cat in self.reference_catalogues.catalogues.items(): row = QStandardItem(catname) row.setData(cat) self.catalogues_model.appendRow(row) self.model = QSortFilterProxyModel() self.model.setSourceModel(self.full_model) self.model.setFilterCaseSensitivity(Qt.CaseInsensitive) self.model.setFilterKeyColumn(0) self.ui.entries.setModel(self.model) self.ui.type_filter.currentTextChanged.connect(lambda txt: self.model.setFilterWildcard("{}*".format(txt) ) ) self.ui.buttonBox.button(QDialogButtonBox.Open).setEnabled(False) self.ui.entries.selectionModel().selectionChanged.connect(lambda selected, deselected: self.ui.buttonBox.button(QDialogButtonBox.Open).setEnabled(len(selected.indexes()) > 0) ) self.accepted.connect(self.load_fits) self.populate() def set_main_spectrum(self, spectrum): self.main_spectrum = spectrum def populate(self): self.full_model.clear() catalogue = self.catalogues_model.item(self.ui.catalogue.currentIndex()).data() self.full_model.setHorizontalHeaderLabels(['Spectral Type']) entries = self.reference_catalogues.spectra(catalogue['name']) self.ui.type_filter.clear() self.ui.type_filter.addItem('') self.ui.type_filter.addItems( sorted(set([i['sptype'] for i in entries])) ) for entry in entries: item = QStandardItem(entry['sptype']) item.setData(entry) self.full_model.appendRow(item) def load_fits(self): original_index = self.model.mapToSource(self.ui.entries.selectionModel().selectedIndexes()[0]) entry = self.full_model.item(original_index.row()).data() self.fits_picked.emit(self.reference_catalogues.fits(entry)) def setup_menu(self, toolbar, axes, settings): self.current_line = None reference_action = QtCommons.addToolbarPopup(toolbar, "Reference") reference_action.menu().addAction("Reference library", lambda: self.show()) reference_action.menu().addAction("Load from FITS file", lambda: open_file_sticky('Open Reference Profile', FITS_EXTS, lambda f: self.__open_reference(f[0], axes), settings, REFERENCE )) self.close_action = reference_action.menu().addAction("Close", lambda: self.__close_reference(axes)) self.close_action.setEnabled(False) self.fits_picked.connect(lambda f: self.__open_reference(f, axes)) self.blackbody_menu = blackbody.BlackBodyAction(lambda bb: self.blackbody(bb, axes), reference_action.menu()) return reference_action.menu() def blackbody(self, blackbody, axes): self.__open(blackbody.spectrum(), axes) def __open_reference(self, file, axes): fits_spectrum = FitsSpectrum(fits.open(file)) self.__open(fits_spectrum.spectrum, axes) def __open(self, spectrum, axes): self.__close_reference(axes) if spectrum.dispersion() < 0.4 and spectrum.dispersion() > 0: spectrum.resample(spectrum.dispersion() /0.4) if(self.main_spectrum): print("Cutting spectrum: {0}, {1}".format(self.main_spectrum.wavelengths[0], self.main_spectrum.wavelengths[-1])) spectrum.cut_lambda(self.main_spectrum.wavelengths[0], self.main_spectrum.wavelengths[-1]) spectrum.normalize_to_max() self.current_line = Line2D(spectrum.wavelengths, spectrum.fluxes, color='gray') axes.add_line(self.current_line) axes.figure.canvas.draw() self.close_action.setEnabled(True) def __close_reference(self, axes): self.close_action.setEnabled(False) if self.current_line: try: # TODO: verify self.current_line.remove() self.current_line = None axes.figure.canvas.draw() except: pass