示例#1
0
文件: Base.py 项目: ElricleNecro/LISA
class Base(object):
    def __init__(self, data, linetype=Point(), shaders=None):
        self.data = data

        self._model = m.Identity()

        self._plot_prop = linetype

        self._shaders = Shaders()
        if shaders is not None:
            for v in shaders:
                self._shaders += v

    def createShaders(self, parent):
        if len(self._shaders) == 0:
            self._shaders += t.shader_path("basic.vsh")
            self._shaders += t.shader_path("basic.fsh")
        self._shaders.link()

    def show(self, parent):
        if self._modified_data:
            # self._plot_prop.init()
            pass
        GL.glEnable(GL.GL_DEPTH_TEST)

        GL.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT)

        matrice = parent._view * self._model

        self._shaders.bind()
        self._shaders.setUniformValue("modelview", matrice)
        self._shaders.setUniformValue("projection", parent._projection)

        self._shaders.enableAttributeArray("position")

        self._shaders.setAttributeArray("position", self._data)

        self._plot_prop(self._data)

        self._shaders.disableAttributeArray("position")

        self._shaders.release()

    @property
    def data(self):
        self._modified_data = True
        return self._data
    @data.setter
    def data(self, val):
        self._modified_data = True
        if len(val.shape) != 1:
            self._data = val.flatten()
        else:
            self._data = val

    @property
    def model(self):
        return self._model
    @model.setter
    def model(self, model):
        self._model = model

    @property
    def shaders(self):
        return self._shaders

    def __lshift__(self, inst):
        self._plot_prop = inst
示例#2
0
class Widget(object):

    def __init__(self):

        # the mesh used to draw the widget on the screen
        self._mesh = np.array(
            [0., 0., 0.0,
             0., 1, 0.0,
             1, 1, 0.0,
             1, 0, 0.0],
            dtype=np.float32,
        )
        self._indices = np.array([0, 1, 2, 3], dtype=np.uint32)
        self._npoints = len(self._indices)

        # the upper left corner of the widget
        self._corner = Vector(0, 0, dtype=np.float32)

        # the size of the widget
        self._size = Vector(1., 1., dtype=np.float32)
        self._minWidth, self._minHeight = 0., 0.

        # for borders
        self._borders = [10, 10]

        # for events
        self._mousePress = False
        self._mousePressBorders = False
        self._mouse = Vector(0., 0., dtype=np.float32)
        self._mouseOffset = Vector(0., 0., dtype=np.float32)

        # init shaders
        self._shaders = Shaders()

        # the matrix model
        self._model = m.Identity()

        # a list of children object
        self._children = []

        # set default padding and margin for the widget
        self.padding = 5
        self.margin = 3

        # set the size_hint
        self.size_hint = None

        # set the parent
        self._parent = None

    def addWidget(self, widget):
        """
        Add a widget in the list of children and set correctly sizes
        accordingly to the parent.
        """

        # set the parent of the widget
        widget.parent = self

        # append the widget to children
        self._children.append(widget)

    @property
    def parent(self):
        return self._parent

    @parent.setter
    def parent(self, parent):
        self._parent = parent

    @property
    def minWidth(self):
        return self._minWidth

    @minWidth.setter
    def minWidth(self, minWidth):
        self._minWidth = minWidth
        if self.parent is not None:
            self.parent.minWidth = float(self._minWidth + self.margin_x.sum())
        self.width = self.width

    @property
    def minHeight(self):
        return self._minHeight

    @minHeight.setter
    def minHeight(self, minHeight):
        self._minHeight = minHeight
        if self.parent is not None:
            self.parent.minHeight = float(
                self._minHeight + self.margin_y.sum()
            )
        self.height = self.height

    @property
    def x_border(self):
        return self._x_border

    @x_border.setter
    def x_border(self, x_border):
        self._x_border = x_border
        self._border[0] = self._x_border

    @property
    def y_border(self):
        return self._y_border

    @y_border.setter
    def y_border(self, y_border):
        self._y_border = y_border
        self._border[1] = self._y_border

    @property
    def width(self):
        return self._size[0]

    @width.setter
    def width(self, width):
        self._size[0] = width
        if self._size[0] <= self.minWidth:
            self._size[0] = self.minWidth
        if self.parent is not None:
            self.parent.width = self._size[0]

    @property
    def height(self):
        return self._size[1]

    @height.setter
    def height(self, height):
        self._size[1] = height
        if self._size[1] < self.minHeight:
            self._size[1] = self.minHeight
        if self.parent is not None:
            self.parent.height = self._size[1]

    @property
    def x(self):
        return self._corner[0]

    @x.setter
    def x(self, x):
        self._corner[0] = x

    @property
    def y(self):
        return self._corner[1]

    @y.setter
    def y(self, y):
        self._corner[1] = y

    @property
    def size_hint(self):
        return self._size_hint

    @size_hint.setter
    def size_hint(self, size_hint):
        self._size_hint = [size_hint] * 2

    @property
    def size_hint_x(self):
        return self._size_hint[0]

    @size_hint_x.setter
    def size_hint_x(self, size_hint_x):
        self._size_hint[0] = size_hint_x

    @property
    def size_hint_y(self):
        return self._size_hint[1]

    @size_hint_y.setter
    def size_hint_y(self, size_hint_y):
        self._size_hint[1] = size_hint_y

    @property
    def padding(self):
        return self._padding

    @padding.setter
    def padding(self, padding):
        self._padding = Vector(*[padding] * 4, dtype=np.float32)

    @property
    def padding_x(self):
        return self._padding[:2]

    @padding_x.setter
    def padding_x(self, padding_x):
        self._padding[:2] = padding_x

    @property
    def padding_y(self):
        return self._padding[2:]

    @padding_y.setter
    def padding_y(self, padding_y):
        self._padding[2:] = padding_y

    @property
    def padding_left(self):
        return self._padding[0]

    @padding_left.setter
    def padding_left(self, padding_left):
        self._padding[0] = padding_left

    @property
    def padding_right(self):
        return self._padding[1]

    @padding_right.setter
    def padding_right(self, padding_right):
        self._padding[1] = padding_right

    @property
    def padding_top(self):
        return self._padding[2]

    @padding_top.setter
    def padding_top(self, padding_top):
        self._padding[2] = padding_top

    @property
    def padding_bottom(self):
        return self._padding[3]

    @padding_bottom.setter
    def padding_bottom(self, padding_bottom):
        self._padding[3] = padding_bottom

    @property
    def margin(self):
        return self._margin

    @margin.setter
    def margin(self, margin):
        self._margin = Vector(*[margin] * 4, dtype=np.float32)

    @property
    def margin_x(self):
        return self._margin[:2]

    @margin_x.setter
    def margin_x(self, margin_x):
        self._margin[:2] = margin_x

    @property
    def margin_y(self):
        return self._margin[2:]

    @margin_y.setter
    def margin_y(self, margin_y):
        self._margin[2:] = margin_y

    @property
    def margin_left(self):
        return self._margin[0]

    @margin_left.setter
    def margin_left(self, margin_left):
        self._margin[0] = margin_left

    @property
    def margin_right(self):
        return self._margin[1]

    @margin_right.setter
    def margin_right(self, margin_right):
        self._margin[1] = margin_right

    @property
    def margin_top(self):
        return self._margin[2]

    @margin_top.setter
    def margin_top(self, margin_top):
        self._margin[2] = margin_top

    @property
    def margin_bottom(self):
        return self._margin[3]

    @margin_bottom.setter
    def margin_bottom(self, margin_bottom):
        self._margin[3] = margin_bottom

    def createShaders(self):

        self._shaders += t.shader_path("widget/widget.vsh")
        self._shaders += t.shader_path("widget/widget.fsh")

        # create buffers
        self._vertices = VBO(VERTEX_BUFFER)
        self._index = VBO(INDEX_BUFFER)
        self._vertices.create()
        self._index.create()

        # allocate buffers
        self._vertices.bind()
        self._vertices.allocate(
            self._mesh,
            len(self._mesh) * 4
        )
        self._vertices.release()
        self._index.bind()
        self._index.allocate(
            self._indices,
            len(self._indices) * 4
        )
        self._index.release()

        for widget in self._children:
            widget.createShaders()

    def draw(self, parent):

        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL)
        GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
        GL.glEnable(GL.GL_BLEND)

        self._shaders.bind()

        self._shaders.setUniformValue(
            "modelview",
            parent._widget_projection * self._model
        )

        self._shaders.setUniformValue(
            "corner",
            self._corner,
        )
        self._shaders.setUniformValue(
            "size",
            self._size,
        )

        self._vertices.bind()
        self._shaders.enableAttributeArray("window")
        self._shaders.setAttributeBuffer(
            "window",
            self._mesh,
        )
        self._vertices.release()

        self._index.bind()
        GL.glDrawElements(
            GL.GL_QUADS,
            self._npoints,
            GL.GL_UNSIGNED_INT,
            None
        )
        self._index.release()

        self._shaders.disableAttributeArray("window")
        self._shaders.release()

        for widget in self._children:
            widget.draw(parent)

    def mouseEvent(self, event):

        for widget in self._children:
            if widget.mouseEvent(event):
                return True

    def keyEvent(self, event):
        for widget in self._children:
            if widget.keyEvent(event):
                return True

    def wheelEvent(self, event):
        for widget in self._children:
            if widget.wheelEvent(event):
                return True

    def inside(self, x, y):
        """
        Method returning true if the widget accepts the events because the
        mouse is over it, else returns false.
        """
        return (
            self._corner[0] <= x <= self._corner[0] + self._size[0]
            and
            self._corner[1] <= y <= self._corner[1] + self._size[1]
        )

    def _inside_border(self, x, y):
        return (
            self._corner[0] + self._size[0] - self._borders[0] <=
            x <= self._corner[0] + self._size[0]
            and
            self._corner[1] + self._size[1] - self._borders[1] <=
            y <= self._corner[1] + self._size[1]
        )
示例#3
0
文件: Mock.py 项目: ElricleNecro/LISA
class Mock(ReadMock):

    def __init__(self, *args, **kwargs):

        # set the reader
        super(Mock, self).__init__(*args, **kwargs)

        self._projections = ["Celestial sphere", "Redshift space", "Cartesian"]
        self.widgetChanged = Signal()
        self.widgetChanged.connect(self.updateWidget)

        # load data from mock catalogue
        self._load_data()

        # make cartesian projection by default
        self._projection_cartesian()

        # colormap
        colormap = getattr(CM, "LinearInterpolation")
        self._colormap = colormap(self._data[self._quantity].values)
        self._callback_colormap()
        self._colormap.changed.connect(self._callback_colormap)

        self._voxelSize = 0.01
        self._voxelSize_max = 0.05

        self._shaders = Shaders()
        self._shaders += t.shader_path("reader/mock/couleurs.vsh")
        self._shaders += t.shader_path("reader/mock/couleurs.fsh")

    def _callback_colormap(self):
        self._color = self._colormap(self._data[self._quantity].values)

    def _load_data(self):

        # store the data of the mock catalogue
        self._data = self.__call__(
            select="positions_x, positions_y, positions_z, alpha, delta, " +
            "redshift"
        )

        # rescale data
        for i in "xyz":
            field = "positions_{0}".format(i)
            self._data[field] = (
                self._data[field] - self._data[field].min()
            ) / (self._data[field].max() - self._data[field].min())

        field = "redshift"
        self._quantity = field
        self._data[field] = (
            self._data[field] - self._data[field].min()
        ) / (self._data[field].max() - self._data[field].min())

    def createShaders(self, parent):

        GL.glEnable(GL.GL_PROGRAM_POINT_SIZE)
        GL.glEnable(GL.GL_POINT_SPRITE)
        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glEnable(GL.GL_BLEND)
        GL.glDepthMask(GL.GL_FALSE)

    def show(self, parent):

        GL.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT)

        matrice = parent._view * parent._model

        self._shaders.bind()
        self._shaders.setUniformValue("modelview", matrice)
        self._shaders.setUniformValue("projection", parent._projection)
        self._shaders.setUniformValue("screenSize", parent._screensize)
        self._shaders.setUniformValue("voxelSize", Vector(self._voxelSize))

        self._shaders.enableAttributeArray("position")
        self._shaders.setAttributeArray(
            "position",
            self._pos,
        )

        self._shaders.enableAttributeArray("color")
        self._shaders.setAttributeArray(
            "color",
            self._color,
        )

        GL.glDrawArrays(GL.GL_POINTS, 0, self._pos.shape[0] // 3)

        self._shaders.disableAttributeArray("position")
        self._shaders.disableAttributeArray("color")

        self._shaders.release()

    def createWidget(self, title="Mock catalogue controls", parent=None):
        pass

        # create a dialig window
        # self._dialog = Qt.QDialog(parent=parent)
        # self._dialog.setWindowOpacity(0.4)
        # self._dialog.setWindowTitle(title)

        # # set a layout
        # self._dialog.setLayout(Qt.QVBoxLayout())

        # self.updateWidget()

        # return self._dialog

    def updateWidget(self):
        pass

        # get the layout and clear children
        # try:
            # layout = self._dialog.layout()
            # while layout.takeAt(0):
                # child = layout.takeAt(0)
                # del child
        # except:
            # pass

        # # create a slider
        # slider = Qt.QSlider(QtCore.Qt.Horizontal)
        # slider.valueChanged[int].connect(self._set_voxelsize)

        # # add a label for slider and the slider
        # self._dialog.layout().addWidget(
            # Qt.QLabel("Point size")
        # )
        # self._dialog.layout().addWidget(slider)

        # # create a list of projections
        # combo = Qt.QComboBox()
        # for projection in self._projections:
            # combo.addItem(projection)
        # self._dialog.layout().addWidget(
            # Qt.QLabel("Kind of projections")
        # )
        # combo.activated[str].connect(self._projection_changed)
        # self._dialog.layout().addWidget(combo)

        # # get the quantity to color
        # self._dialog.layout().addWidget(Qt.QLabel("Colormap quantity"))
        # lineInput = Qt.QLineEdit()

        # def _getText():
            # text = lineInput.text()
            # self._load_quantity(text)
        # lineInput.returnPressed.connect(_getText)
        # self._dialog.layout().addWidget(lineInput)

        # # create a list of colormaps
        # combomap = Qt.QComboBox()
        # for colormap in CM.ColorMap.__subclasses__():
            # combomap.addItem(colormap.__name__)
        # self._dialog.layout().addWidget(
            # Qt.QLabel("Kind of colormap")
        # )
        # combomap.activated[str].connect(self._colormap_changed)
        # self._dialog.layout().addWidget(combomap)

        # # add the widget of the colormap
        # self._dialog.layout().addWidget(
            # Qt.QLabel("Colormap controls")
        # )
        # self._colormap.createWidget(self._dialog.layout())

    def _load_quantity(self, quantity):
        if quantity not in self._data:
            try:
                self._data[quantity] = self.__call__(select=quantity)
                self._quantity = quantity
                self._colormap.data = self._data[self._quantity].values
                self._callback_colormap()
            except:
                pass

    def _colormap_changed(self, text):

        # get the new colormap
        colormap = getattr(CM, text)
        self._colormap = colormap(self._data[self._quantity].values)
        self._callback_colormap()
        self._colormap.changed.connect(self._callback_colormap)
        self.widgetChanged()

    def _projection_changed(self, text):

        # get the method to call according to the projection
        projection = text.lower().replace(" ", "_")
        method = getattr(self, "_projection_" + projection)
        method()

    def _projection_celestial_sphere(self):
        X = np.cos(self._data["alpha"]) * np.cos(self._data["delta"])
        Y = np.sin(self._data["alpha"]) * np.cos(self._data["delta"])
        Z = np.sin(self._data["delta"])
        self._pos = np.vstack([X, Y, Z]).T.astype(np.float32).flatten()

    def _projection_cartesian(self):
        self._pos = np.vstack([
            self._data["positions_x"].values,
            self._data["positions_y"].values,
            self._data["positions_z"].values,
        ]).T.astype(np.float32).flatten()

    def _projection_redshift_space(self):
        redshift = self._data["redshift"]
        X = np.cos(self._data["alpha"]) * np.cos(self._data["delta"])
        Y = np.sin(self._data["alpha"]) * np.cos(self._data["delta"])
        Z = np.sin(self._data["delta"])
        self._pos = np.vstack(
            [
                redshift * X,
                redshift * Y,
                redshift * Z
            ]
        ).T.astype(np.float32).flatten()

    def _set_voxelsize(self, value):
        self._voxelSize = value / 100. * self._voxelSize_max