1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
from __future__ import absolute_import, division, print_function
import pytest
import numpy as np
import pandas as pd
from mock import MagicMock
from .. import qglue
from ..core import Data
from ..core.exceptions import IncompatibleAttribute
from ..core.registry import Registry
from .helpers import requires_astropy, requires_qt
@requires_qt
@requires_astropy
class TestQGlue(object):
def setup_method(self, method):
from glue.app.qt import GlueApplication
from astropy.table import Table
from astropy.io.fits import HDUList, ImageHDU
Registry().clear()
x = [1, 2, 3]
y = [2, 3, 4]
u = [10, 20, 30, 40]
v = [20, 40, 60, 80]
self.xy = {'x': x, 'y': y}
self.dict_data = {'u': u, 'v': v}
self.recarray_data = np.rec.array([(0, 1), (2, 3)],
dtype=[(str('a'), int), (str('b'), int)])
self.astropy_table = Table({'x': x, 'y': y})
self.bad_data = {'x': x, 'u': u}
self.hdulist = HDUList([ImageHDU(x, name='PRIMARY')])
self.x = np.array(x)
self.y = np.array(y)
self.u = np.array(u)
self.v = np.array(v)
self._start = GlueApplication.start
GlueApplication.start = MagicMock()
def teardown_method(self, method):
from glue.app.qt import GlueApplication
GlueApplication.start = self._start
def check_setup(self, dc, expected):
# assert that the assembled data collection returned
# form qglue matches expected structure
# test for expected data, components
for data in dc:
components = set(c.label for c in data.components)
e = expected.pop(data.label)
for component in e:
assert component in components
assert len(expected) == 0
def test_qglue_starts_application(self):
pandas_data = pd.DataFrame(self.xy)
app = qglue(data1=pandas_data)
app.start.assert_called_once_with()
def test_single_pandas(self):
dc = qglue(data1=self.xy).data_collection
self.check_setup(dc, {'data1': ['x', 'y']})
def test_single_pandas_nonstring_column(self):
dc = qglue(data1=pd.DataFrame({1: [1, 2, 3]})).data_collection
self.check_setup(dc, {'data1': ['1']})
def test_single_numpy(self):
dc = qglue(data1=np.array([1, 2, 3])).data_collection
self.check_setup(dc, {'data1': ['data1']})
def test_single_list(self):
dc = qglue(data1=[1, 2, 3]).data_collection
self.check_setup(dc, {'data1': ['data1']})
def test_single_dict(self):
dc = qglue(data2=self.dict_data).data_collection
self.check_setup(dc, {'data2': ['u', 'v']})
def test_recarray(self):
dc = qglue(data3=self.recarray_data).data_collection
self.check_setup(dc, {'data3': ['a', 'b']})
def test_astropy_table(self):
dc = qglue(data4=self.astropy_table).data_collection
self.check_setup(dc, {'data4': ['x', 'y']})
def test_multi_data(self):
dc = qglue(data1=self.dict_data, data2=self.xy).data_collection
self.check_setup(dc, {'data1': ['u', 'v'],
'data2': ['x', 'y']})
def test_hdulist(self):
dc = qglue(data1=self.hdulist).data_collection
self.check_setup(dc, {'data1[PRIMARY]': ['PRIMARY']})
def test_glue_data(self):
d = Data(x=[1, 2, 3])
dc = qglue(x=d).data_collection
assert d.label == 'x'
def test_simple_link(self):
using = lambda x: x * 2
links = [['data1.x', 'data2.u', using]]
dc = qglue(data1=self.xy, data2=self.dict_data,
links=links).data_collection
links = [[['x'], 'u', using]]
self.check_setup(dc, {'data1': ['x', 'y'],
'data2': ['u', 'v']})
d = dc[0] if dc[0].label == 'data1' else dc[1]
np.testing.assert_array_equal(d['x'], self.x)
np.testing.assert_array_equal(d['u'], self.x * 2)
d = dc[0] if dc[0].label == 'data2' else dc[1]
with pytest.raises(IncompatibleAttribute) as exc:
d['x']
def test_multi_link(self):
forwards = lambda *args: (args[0] * 2, args[1] * 3)
backwards = lambda *args: (args[0] / 2, args[1] / 3)
links = [[['Data1.x', 'Data1.y'],
['Data2.u', 'Data2.v'], forwards, backwards]]
dc = qglue(Data1=self.xy, Data2=self.dict_data,
links=links).data_collection
self.check_setup(dc, {'Data1': ['x', 'y'],
'Data2': ['u', 'v']})
for d in dc:
if d.label == 'Data1':
np.testing.assert_array_equal(d['x'], self.x)
np.testing.assert_array_equal(d['y'], self.y)
np.testing.assert_array_equal(d['u'], self.x * 2)
np.testing.assert_array_equal(d['v'], self.y * 3)
else:
np.testing.assert_array_equal(d['x'], self.u / 2)
np.testing.assert_array_equal(d['y'], self.v / 3)
np.testing.assert_array_equal(d['u'], self.u)
np.testing.assert_array_equal(d['v'], self.v)
def test_implicit_identity_link(self):
links = [('Data1.x', 'Data2.v'),
('Data1.y', 'Data2.u')]
dc = qglue(Data1=self.xy, Data2=self.dict_data,
links=links).data_collection
# currently, identity links rename the second link to first,
# so u/v disappear
for d in dc:
if d.label == 'Data1':
np.testing.assert_array_equal(d['x'], self.x)
np.testing.assert_array_equal(d['y'], self.y)
else:
np.testing.assert_array_equal(d['y'], self.u)
np.testing.assert_array_equal(d['x'], self.v)
def test_bad_link(self):
forwards = lambda *args: args
links = [(['Data1.a'], ['Data2.b'], forwards)]
with pytest.raises(ValueError) as exc:
dc = qglue(Data1=self.xy, Data2=self.dict_data,
links=links).data_collection
assert exc.value.args[0] == "Invalid link (no component named Data1.a)"
def test_bad_data_shape(self):
with pytest.raises(ValueError) as exc:
dc = qglue(d=self.bad_data).data_collection
assert exc.value.args[0].startswith("Invalid format for data 'd'")
def test_bad_data_format(self):
with pytest.raises(TypeError) as exc:
dc = qglue(d=5).data_collection
assert exc.value.args[0].startswith("Invalid data description")
def test_malformed_data_dict(self):
with pytest.raises(ValueError) as exc:
dc = qglue(d={'x': 'bad'}).data_collection
assert exc.value.args[0].startswith("Invalid format for data 'd'")
|