Source code for vdat.gui.fplane

"""Panel with the focal plane"""
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)


from time import sleep
import logging
from PyQt4 import QtGui, QtCore


from pyhetdex.het.fplane import FPlane
import vdat.database as db
import vdat.config as confp
from vdat.gui.relay import get_relay

__FPLANEPANEL__ = None


[docs]class VDATRunControl(object): """Class to store variable which controls looping over IFUs """ ifu_loop = True
[docs]def current_fplane(): """Return the current focal plane (or none if not set) Returns ------- fplane : :class:`pyhetdex.het.fplane.FPlane` the fplane (with the IFUs) of the currently displayed central panel """ global __FPLANEPANEL__ if __FPLANEPANEL__: return __FPLANEPANEL__.fplane else: return None
[docs]def yield_all_ifus(): """Grabs the IFUs from the fplane class variable of FplanePanel and check that that the IFUs have been properly initialized. Returns ------- ifu : :class:`vdat.gui.ifu_widget.IFUWidget` pyhetdex IFU objects """ VDATRunControl.ifu_loop = True log = logging.getLogger('logger') fplane = current_fplane() if not fplane: log.error("No focal plane available. Did you select a directory?") ifus = [] else: ifus = fplane.ifus # Test to see if the IFUs have been initialized (just look at first file) for ifu in ifus: if VDATRunControl.ifu_loop: yield ifu else: raise StopIteration
[docs]def yield_selected_ifus(): """Grabs the IFUs from the fplane class variable of FplanePanel and check that that the IFUs have been properly initialized. Yield selected IFUs Returns ------- ifu : :class:`vdat.gui.ifu_widget.IFUWidget` pyhetdex IFU objects """ log = logging.getLogger('logger') VDATRunControl.ifu_loop = True fplane = current_fplane() if not fplane: log.error("No focal plane available. Did you select a directory?") ifus = [] else: ifus = fplane.ifus # Test to see if the IFUs have been initialized (just look at first file) for ifu in ifus: if not VDATRunControl.ifu_loop: raise StopIteration if ifu.selected: yield ifu else: continue
[docs]def select_all_ifus(): """Selects all IFUs in the FPlanePanel """ log = logging.getLogger('logger') fplane = current_fplane() if not fplane: log.error("No focal plane available. Did you select a directory?") ifus = [] else: ifus = fplane.ifus for ifu in ifus: ifu.selected = True
[docs]def deselect_all_ifus(): """Selects all IFUs in the FPlanePanel """ log = logging.getLogger('logger') fplane = current_fplane() if not fplane: log.error("No focal plane available. Did you select a directory?") ifus = [] else: ifus = fplane.ifus for ifu in ifus: ifu.selected = False
[docs]def change_focal_plane_panel(type_, parent=None): """Create a new focal plane panel, and save it in the global. Delete the old one. Returns ------- __FPLANEPANEL__ : class:`FplanePanel` a panel showing the focal plane """ from vdat.gui.background import get_background global __FPLANEPANEL__ # if one exists, delete it if __FPLANEPANEL__: bg = get_background() VDATRunControl.ifu_loop = False while bg.isImmRunning: sleep(0.1) __FPLANEPANEL__.deleteLater() __FPLANEPANEL__ = FplanePanel(type_, parent=parent) __FPLANEPANEL__.update_ifus(__FPLANEPANEL__.display_type) return __FPLANEPANEL__
[docs]class FplanePanel(QtGui.QWidget): """Class to create and handle the focal plane window in the GUI Set up the basic elements, like the combo box and the widget, of a viewer of HETDEX focal planes Parameters ---------- type_ : str a name of one of the sections of the tabs.yml file (e.g. cal, sci...) """ updateScaleBoxes = QtCore.pyqtSignal(float, float) def __init__(self, type_, parent=None): # put this here to avoid circular imports from vdat.gui.ifu_widget import IFUWidget QtGui.QWidget.__init__(self, parent=None) self.type_ = type_ self._conf = confp.get_config(name='main') self.tabs_conf = confp.get_config(name='tab', section=type_) self.global_scale = False # a grid layout to stick IFUs on self.layout = QtGui.QVBoxLayout() # bar to show image scaling parameters self.scaling_bar = QtGui.QHBoxLayout() self.scaling_bar.setAlignment(QtCore.Qt.AlignLeft) self.focalPlane_layout = QtGui.QGridLayout() self.focalPlane_layout.setSizeConstraint(QtGui.QLayout .SetMinAndMaxSize) self.focalPlane_layout.setObjectName("focalPlane_layout") self.setLayout(self.layout) self.layout.addLayout(self.focalPlane_layout) self.layout.addLayout(self.scaling_bar) # load in the IFUs self.fplane = FPlane(self._conf.get("fplane", "fp_filename"), ifu_class=IFUWidget) # combo box to decide what is displayed, based on whats in the tabs.yml self.comboBox = QtGui.QComboBox() self.comboBox.addItems(list(self.tabs_conf['tabs'].keys())) self.comboBox.activated[str].connect(self.update_ifus) self.focalPlane_layout.addWidget(self.comboBox, 0, 0, 1, 2) # combo box to decide the image (brightness) scaling self.comboBoxScaling = QtGui.QComboBox() self.comboBoxScaling.addItems(["Individual scaling", "Global scaling"]) self.comboBoxScaling.activated[str].connect(self.set_scaling_mode) self.comboBoxScaling.setFixedWidth(150) self.scaling_bar.addWidget(self.comboBoxScaling) # QLineEdits to display global image scaling parameters self.minScaleBox = QtGui.QLineEdit() self.maxScaleBox = QtGui.QLineEdit() self.minScaleBox.setFixedWidth(80) self.maxScaleBox.setFixedWidth(80) # make sure the user inputs a valid number here self.validator = QtGui.QDoubleValidator() self.minScaleBox.setValidator(self.validator) self.maxScaleBox.setValidator(self.validator) # connect the scale boxes to the automatic global scaling self.updateScaleBoxes.connect(self.update_scale_boxes) relay = get_relay() relay.add_signal("scaleboxes", self.updateScaleBoxes) # add information on the image scale self.minLabel = QtGui.QLabel("Min: ") self.maxLabel = QtGui.QLabel("Max: ") self.scaling_bar.addWidget(self.minLabel) self.scaling_bar.addWidget(self.minScaleBox) self.scaling_bar.addWidget(self.maxLabel) self.scaling_bar.addWidget(self.maxScaleBox) # add a button to do manual scaling self.rescaleButton = QtGui.QPushButton("Rescale") self.rescaleButton.released.connect(self.set_scaling) self.scaling_bar.addWidget(self.rescaleButton) # set the displayed tab to the default one self.display_type = (self.tabs_conf['main'])['default_tab'] self.comboBox.setCurrentIndex(self.comboBox .findText(self.display_type)) self.set_scaling_mode("Individual scaling", noFplane=True)
[docs] def update_scale_boxes(self, min_scale, max_scale): """ Update the contents of the image scale boxes Parameters ---------- min_scale : float value to display in the min_scale box max_scale : float value to display in the max_scale box """ self.minScaleBox.setText("{:4.2f}".format(min_scale)) self.maxScaleBox.setText("{:4.2f}".format(max_scale))
[docs] def set_scaling(self): """ Set the image scale parameters, based on what is written in the min_cut and max_cut boxes. """ cdir = self._conf.get("redux_dirs", "selected_dir") min_cut = self.minScaleBox.text() max_cut = self.maxScaleBox.text() with db.connect(): q = (db.ThumbnailScaling.select() .where((db.ThumbnailScaling.path == cdir) & (db.ThumbnailScaling.tab == self.display_type))) if q.exists(): entry = q.get() entry.min_cut = min_cut entry.max_cut = max_cut entry.save() self.update_ifus(self.display_type)
[docs] def set_scaling_mode(self, option_string, noFplane=False): """Set what type of image scaling the focal plane has. Parameters ---------- option_string: str "Global scaling" or "individual scaling" noFplane : optional if true, do nbot attempt to update the IFUs in the panel """ if option_string == "Global scaling": self.global_scale = True self.minScaleBox.setVisible(True) self.maxScaleBox.setVisible(True) self.rescaleButton.setVisible(True) self.minLabel.setVisible(True) self.maxLabel.setVisible(True) else: self.global_scale = False self.minScaleBox.setVisible(False) self.maxScaleBox.setVisible(False) self.rescaleButton.setVisible(False) self.minLabel.setVisible(False) self.maxLabel.setVisible(False) if not noFplane: self.update_ifus(self.display_type)
[docs] def update_ifus(self, display_type): """ Loop through an fplane object plotting the IFUs Parameters ---------- display_type : str an entry in a ``tabs`` subsection of tabs.yml. Determines what is shown as a thumbnail for the IFU """ from vdat.gui.background import get_background from vdat.libvdat.show_fits import show_thumbnails self.display_type = display_type # add widgets for each IFU for ifu in self.fplane.ifus: ifu.type_ = self.type_ # save this here for the IFU viewer self.focalPlane_layout.addWidget(ifu, ifu.yid, ifu.xid, 1, 1) # now create and show the thumbnails get_background().run_now(show_thumbnails, self._conf, self.display_type, (self.tabs_conf['tabs'])[display_type], global_scale=self.global_scale)