def translate_line(steno3d_resource, view, _lookup_dict=None):
    """Translate Steno3D line into LineSet Element and Arrays"""
    vertices = files.Array(steno3d_resource.mesh.vertices)
    segments = files.Array(steno3d_resource.mesh.segments)
    data = [
        translate_binder(dat, view, _lookup_dict=_lookup_dict)
        for dat in steno3d_resource.data
    ]
    element = spatial.ElementLineSet(
        name=steno3d_resource.title or '',
        description=steno3d_resource.description or '',
        vertices=vertices,
        segments=segments,
        data=data,
    )
    if steno3d_resource.mesh.opts.view_type == 'tube':
        opts = spatial.OptionsTubes(radius={'value': 10})
    else:
        opts = spatial.OptionsLines()
    opts.visible = True
    opts.color.value = 'random'
    opts.opacity.value = 1.
    if steno3d_resource.opts.color is not None:
        opts.color.value = steno3d_resource.opts.color
    if steno3d_resource.opts.opacity is not None:
        opts.opacity.value = steno3d_resource.opts.opacity
    element.defaults = opts
    view.contents += [vertices, segments, element]
    view.elements += [element]
    if _lookup_dict is not None and hasattr(steno3d_resource, '_upload_data'):
        _lookup_dict.update({steno3d_resource._upload_data['uid']: element})
    return element
def translate_data_array(steno3d_data, location, view, _lookup_dict=None):
    """Translate Steno3D array data into Data, Mapping, and Arrays"""
    arr = files.Array(steno3d_data.array)
    data = spatial.DataBasic(
        name=steno3d_data.title or '',
        description=steno3d_data.description or '',
        array=arr,
        location=location,
    )
    if steno3d_data.colormap is not None:
        gradient = files.Array(steno3d_data.colormap)
        mapping = spatial.MappingContinuous(
            gradient=gradient,
            data_controls=[
                np.nanmin(steno3d_data.array),
                np.nanmax(steno3d_data.array),
            ],
            gradient_controls=[0., 1.],
            visibility=[True, True, True],
        )
        data.mappings = [mapping]
        view.contents += [mapping, gradient]
    view.contents += [arr, data]
    if _lookup_dict is not None and hasattr(steno3d_data, '_upload_data'):
        _lookup_dict.update({steno3d_data._upload_data['uid']: data})
    return data
def translate_data_category(steno3d_data, location, view, _lookup_dict=None):
    """Translate Steno3D category data into Data, Mappings, and Array"""
    arr = files.Array(steno3d_data.array)
    data = spatial.DataCategory(
        name=steno3d_data.title or '',
        description=steno3d_data.description or '',
        array=arr,
        location=location,
    )
    if steno3d_data.categories is not None:
        mapping = spatial.MappingCategory(
            values=steno3d_data.categories,
            indices=list(range(len(steno3d_data.categories))),
            visibility=[True] * len(steno3d_data.categories),
        )
        data.categories = mapping
        view.contents.append(mapping)
    if steno3d_data.colormap is not None:
        mapping = spatial.MappingCategory(
            values=steno3d_data.colormap,
            indices=list(range(len(steno3d_data.colormap))),
            visibility=[True] * len(steno3d_data.colormap),
        )
        if not data.categories:
            data.categories = mapping
        else:
            data.mappings = [mapping]
        view.contents.append(mapping)
    view.contents += [arr, data]
    if _lookup_dict is not None and hasattr(steno3d_data, '_upload_data'):
        _lookup_dict.update({steno3d_data._upload_data['uid']: data})
    return data
def translate_point(steno3d_resource, view, _lookup_dict=None):
    """Translate Steno3D point into PointSet Element and Array"""
    vertices = files.Array(steno3d_resource.mesh.vertices)
    data = [
        translate_binder(dat, view, _lookup_dict=_lookup_dict)
        for dat in steno3d_resource.data
    ] + [
        translations[tex.__class__](tex, view, _lookup_dict=_lookup_dict)
        for tex in steno3d_resource.textures
    ]
    element = spatial.ElementPointSet(
        name=steno3d_resource.title or '',
        description=steno3d_resource.description or '',
        vertices=vertices,
        data=data,
    )
    if steno3d_resource.opts.color is not None:
        element.defaults.color.value = steno3d_resource.opts.color
    if steno3d_resource.opts.opacity is not None:
        element.defaults.opacity.value = steno3d_resource.opts.opacity
    view.contents += [vertices, element]
    view.elements += [element]
    if _lookup_dict is not None and hasattr(steno3d_resource, '_upload_data'):
        _lookup_dict.update({steno3d_resource._upload_data['uid']: element})
    return element
def translate_data_discrete(steno3d_data, location, view, _lookup_dict=None):
    """Translate Steno3D discrete data into Data, Mapping, and Array"""
    arr = files.Array(steno3d_data.array)
    if steno3d_data.range_visibility is not None:
        visibility = [bool(rv) for rv in steno3d_data.range_visibility]
    else:
        visibility = [True] * (len(steno3d_data.end_values) + 1)
    if steno3d_data.end_inclusive is not None:
        end_inclusive = [bool(ei) for ei in steno3d_data.end_inclusive]
    else:
        end_inclusive = [True] * len(steno3d_data.end_values)
    mapping = spatial.MappingDiscrete(
        end_points=steno3d_data.end_values,
        visibility=visibility,
        end_inclusive=end_inclusive,
        values=steno3d_data.colormap
        or [''] * (len(steno3d_data.end_values) + 1),
    )
    data = spatial.DataBasic(name=steno3d_data.title or '',
                             description=steno3d_data.description or '',
                             array=arr,
                             location=location,
                             mappings=[mapping])
    view.contents += [arr, mapping, data]
    if _lookup_dict is not None and hasattr(steno3d_data, '_upload_data'):
        _lookup_dict.update({steno3d_data._upload_data['uid']: data})
    return data
def translate_surface(steno3d_resource, view, _lookup_dict=None):
    """Translate Steno3D surface into Surface Element and Arrays"""
    data = [
        translate_binder(dat, view, _lookup_dict=_lookup_dict)
        for dat in steno3d_resource.data
    ] + [
        translations[tex.__class__](tex, view, _lookup_dict=_lookup_dict)
        for tex in steno3d_resource.textures
    ]
    if isinstance(steno3d_resource.mesh, steno3d.Mesh2D):
        vertices = files.Array(steno3d_resource.mesh.vertices)
        triangles = files.Array(steno3d_resource.mesh.triangles)
        element = spatial.ElementSurface(
            name=steno3d_resource.title or '',
            description=steno3d_resource.description or '',
            vertices=vertices,
            triangles=triangles,
            data=data,
        )
        view.contents += [vertices, triangles]
    else:
        element = spatial.ElementSurfaceGrid(
            name=steno3d_resource.title or '',
            description=steno3d_resource.description or '',
            tensor_u=list(steno3d_resource.mesh.h1),
            tensor_v=list(steno3d_resource.mesh.h2),
            axis_u=steno3d_resource.mesh.U,
            axis_v=steno3d_resource.mesh.V,
            origin=steno3d_resource.mesh.O,
            data=data,
        )
        if (steno3d_resource.mesh.Z is not None
                and len(steno3d_resource.mesh.Z)):
            offset_w = files.Array(steno3d_resource.mesh.Z)
            element.offset_w = offset_w
            view.contents.append(offset_w)
    if steno3d_resource.opts.color is not None:
        element.defaults.color.value = steno3d_resource.opts.color
    if steno3d_resource.opts.opacity is not None:
        element.defaults.opacity.value = steno3d_resource.opts.opacity
    if steno3d_resource.mesh.opts.wireframe is not None:
        element.defaults.wireframe.active = steno3d_resource.mesh.opts.wireframe
    view.contents.append(element)
    view.elements += [element]
    if _lookup_dict is not None and hasattr(steno3d_resource, '_upload_data'):
        _lookup_dict.update({steno3d_resource._upload_data['uid']: element})
    return element
def test_array_init(input_arr):
    arr = files.Array(input_arr)
    assert arr.validate()
    assert isinstance(arr.array, np.ndarray)
    assert np.array_equal(arr.array, np.array([1, 2, 3]))
    assert arr.dtype.startswith('Int')
    assert arr.shape == [3]
    assert arr.content_type == 'application/octet-stream'
    assert arr.content_length == np.dtype(arr.array.dtype).itemsize * 3
    assert arr.is_1d()
def test_array_serialize():
    arr = files.Array([[1]])
    arr.validate()
    serial_arr = arr.serialize()
    assert serial_arr == {
        '__class__': 'Array',
        'content_length': np.dtype(arr.array.dtype).itemsize,
        'content_type': 'application/octet-stream',
        'dtype': 'Int32Array',
        'shape': [1, 1],
    }
Exemple #9
0
def test_upload(mock_regex, mock_upload_image, mock_upload_array, mock_put,
                mock_patch, mock_post, verbose, workers, parallel, session):
    mock_resp = mock.MagicMock()
    mock_resp.json.return_value = {
        'links': {
            'self': 'https://example.com/api/self',
            'location': 'https://example.com/api/location',
            'thumbnail': 'https://example.com/api/self/thumbnail'
        },
    }
    mock_resp.ok = True
    mock_post.return_value = mock_resp
    mock_patch.return_value = mock_resp
    mock_put.return_value = mock_resp
    mock_file_resp = mock.MagicMock()
    mock_file_resp.json.return_value = {}
    mock_file_resp.ok = True
    mock_upload_array.return_value = mock_file_resp
    mock_upload_image.return_value = mock_file_resp
    mock_regex.return_value = re.compile(r'^https://example\.com/api/')

    mapping_uploaded = spatial.MappingDiscrete(
        values=[(255, 0, 0), (0, 255, 0), (0, 0, 255)],
        end_points=[10., 20.],
        end_inclusive=[True, True],
        visibility=[True, True, True],
    )
    mapping_uploaded._links = {
        'self': 'https://example.com/api/mapping_uploaded'
    }
    array_data = files.Array([0., 10, 20])
    img = io.BytesIO()
    s = [[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0]]
    w = png.Writer(4, 4, greyscale=True, bitdepth=16)
    w.write(img, s)

    view = manifests.View(
        name='Test View',
        elements=[
            spatial.ElementPointSet(
                vertices=files.Array([[0., 0, 0], [1, 1, 1], [2, 2, 2]]),
                data=[
                    spatial.DataBasic(
                        name='Dataset 1',
                        location='n',
                        array=array_data,
                        uid='local_id',
                    ),
                    spatial.DataBasic(
                        name='Dataset 2',
                        description='Same array as dataset 1',
                        location='n',
                        array=array_data,
                        mappings=[
                            spatial.MappingContinuous(
                                gradient='https://example.com/api/my_colormap',
                                data_controls=[0., 10., 20., 30.],
                            ),
                            mapping_uploaded,
                        ]),
                    spatial.TextureProjection(
                        origin=[0., 0, 0],
                        axis_u=[1., 0, 0],
                        axis_v=[0., 1, 0],
                        image=img,
                    ),
                ],
                defaults={
                    'color': {
                        'value': '#FF0000'
                    },
                    'opacity': {
                        'value': 1
                    },
                    'size': {
                        'value': 10
                    },
                    'shape': 'square'
                },
            ),
            'https://example.com/api/my_element',
        ])
    try:
        dirname, _ = os.path.split(os.path.abspath(__file__))
        png_file = os.path.sep.join(dirname.split(os.path.sep) + ['temp.png'])
        s = ['110010010011', '101011010100', '110010110101', '100010010011']
        s = [[int(v) for v in val] for val in s]
        f = open(png_file, 'wb')
        w = png.Writer(len(s[0]), len(s), greyscale=True, bitdepth=16)
        w.write(f, s)
        f.close()

        session.upload(
            view,
            verbose=verbose,
            thumbnail=png_file,
            parallel=parallel,
            workers=workers,
        )
    finally:
        os.remove(png_file)

    assert mock_post.call_count == 9
    assert mock_patch.call_count == 1
    assert mock_put.call_count == 1
    assert mock_upload_array.call_count == 2
    assert mock_upload_image.call_count == 2

    mock_post.assert_has_calls(
        [
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/files/array',
                json={
                    'shape': [3, 3],
                    'dtype': 'Float64Array',
                    'content_type': 'application/octet-stream',
                    'content_length': 31,
                    'content_encoding': 'gzip'
                },
            ),
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/files/array',
                json={
                    'shape': [3],
                    'dtype': 'Float64Array',
                    'content_type': 'application/octet-stream',
                    'content_length':
                    24,  # this file is 29 bytes when compressed
                },
            ),
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/files/image',
                json={
                    'content_type': 'image/png',
                    'content_length': img.seek(0, 2),
                },
            ),
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/mappings/continuous',
                json={
                    'gradient': 'https://example.com/api/my_colormap',
                    'data_controls': [0., 10., 20., 30.],
                    'gradient_controls': [0., 0., 1., 1.],
                    'visibility': [False, True, True, True, False],
                    'interpolate': False,
                },
            ),
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/data/basic',
                json={
                    'name': 'Dataset 1',
                    'location': 'nodes',
                    'array': 'https://example.com/api/self',
                    'mappings': [],
                },
            ),
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/data/basic',
                json={
                    'name':
                    'Dataset 2',
                    'description':
                    'Same array as dataset 1',
                    'location':
                    'nodes',
                    'array':
                    'https://example.com/api/self',
                    'mappings': [
                        'https://example.com/api/self',
                        'https://example.com/api/mapping_uploaded',
                    ],
                },
            ),
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/textures/projection',
                json={
                    'origin': [0., 0, 0],
                    'axis_u': [1., 0, 0],
                    'axis_v': [0., 1, 0],
                    'image': 'https://example.com/api/self',
                },
            ),
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/elements/pointset',
                json={
                    'vertices':
                    'https://example.com/api/self',
                    'data': [
                        'https://example.com/api/self',
                        'https://example.com/api/self',
                        'https://example.com/api/self',
                    ],
                    'defaults': {
                        'visible': True,
                        'color': {
                            'value': '#FF0000'
                        },
                        'opacity': {
                            'value': 1
                        },
                        'size': {
                            'value': 10
                        },
                        'shape': 'square'
                    },
                },
            ),
            mock.call(
                'https://example.com/api/v1/project/myorg/myproj/views',
                json={
                    'name':
                    'Test View',
                    'elements': [
                        'https://example.com/api/self',
                        'https://example.com/api/my_element',
                    ],
                    'contents': [
                        'https://example.com/api/self',
                        'https://example.com/api/self',
                        'https://example.com/api/my_colormap',
                        'https://example.com/api/self',
                        'https://example.com/api/mapping_uploaded',
                        'https://example.com/api/self',
                        'https://example.com/api/self',
                        'https://example.com/api/self',
                        'https://example.com/api/self',
                        'https://example.com/api/self',
                        'https://example.com/api/my_element',
                    ],
                },
            ),
        ],
        any_order=True)
    mock_patch.assert_called_with(
        'https://example.com/api/mapping_uploaded',
        json={
            'values': ['#FF0000', '#00FF00', '#0000FF'],
            'end_points': [10., 20.],
            'end_inclusive': [True, True],
            'visibility': [True, True, True],
        },
    )
    mock_put.assert_called_with(
        'https://example.com/api/self/thumbnail',
        json={
            'content_type': 'image/png',
            'content_length': 88,
        },
    )
def test_array_assignment(input_arr):
    arr = files.Array()
    with pytest.raises(ValueError):
        arr.array = input_arr
def test_object_without_array():
    arr = files.Array()
    arr.content_length = 64
    arr.dtype = 'Int8Array'
    arr.shape = [64]
    assert arr.validate()
def test_is_1d(input, is_1d):
    assert files.Array(input).is_1d() == is_1d
def test_bad_input():
    with pytest.raises(properties.ValidationError):
        files.Array(dtype='bad')
    arr = files.Array(dtype='Int32Array', shape=[1])
    with pytest.raises(properties.ValidationError):
        arr.content_length = 100
def test_empty_init():
    arr = files.Array()
    with pytest.raises(properties.ValidationError):
        arr.validate()
import properties
from lfview.resources import files, spatial


def test_types():
    assert spatial.DataBasic.BASE_TYPE == 'data'
    assert spatial.DataBasic.SUB_TYPE == 'basic'
    assert spatial.DataCategory.BASE_TYPE == 'data'
    assert spatial.DataCategory.SUB_TYPE == 'category'


@pytest.mark.parametrize('array', [
    'https://example.com/api/files/array/abc123',
    [10., 20, 15.],
    files.Array(shape=[3], dtype='Float32Array', content_length=12),
])
@pytest.mark.parametrize('location', ['nodes', 'cells', 'N', 'CC'])
@pytest.mark.parametrize(
    'mappings', [[
        'https://example.com/api/mappings/continuous/abc123',
        'https://example.com/api/mappings/discrete/def456'
    ],
                 [{
                     'gradient': 'https://example.com/api/files/array/ghi789',
                     'data_controls': [1., 2., 3., 4.]
                 }, {
                     'values': ['a', 'b'],
                     'end_points': [1.],
                     'end_inclusive': [True],
                     'visibility': [True, True]
def test_unsupported_array():
    with pytest.raises(ValueError):
        files.Array('bad array')
    int64array = np.array([100000000000])
    with pytest.raises(ValueError):
        files.Array(int64array)

def test_types():
    assert spatial.MappingContinuous.BASE_TYPE == 'mappings'
    assert spatial.MappingDiscrete.BASE_TYPE == 'mappings'
    assert spatial.MappingCategory.BASE_TYPE == 'mappings'
    assert spatial.MappingContinuous.SUB_TYPE == 'continuous'
    assert spatial.MappingDiscrete.SUB_TYPE == 'discrete'
    assert spatial.MappingCategory.SUB_TYPE == 'category'


@pytest.mark.parametrize(
    'gradient', [
        'https://example.com/api/files/array/abc123',
        [[0, 0, 0], [255, 255, 255]],
        files.Array(shape=[5, 3], dtype='Int16Array', content_length=30)
    ]
)
@pytest.mark.parametrize('data_controls', [[-1., 2., 3.], [1., 1., 1.]])
@pytest.mark.parametrize('gradient_controls', [[0., 0.5, 1], [0., 0., 0.]])
@pytest.mark.parametrize(
    'visibility', [[True, True, True, True], [0, 0, 1, 0]]
)
@pytest.mark.parametrize('interpolate', [0, 1])
def test_good_continuous(
        gradient, data_controls, gradient_controls, visibility, interpolate
):
    mc = spatial.MappingContinuous(
        gradient=gradient,
        data_controls=data_controls,
        gradient_controls=gradient_controls,
Exemple #18
0
    session.upload_feedback(feedback, slide=slide_url, verbose=verbose)
    if isinstance(feedback, scene.Feedback):
        mock_upload.assert_called_once_with(
            resource=feedback,
            verbose=verbose,
            chunk_size=None,
            json_dict=expected_json_dict,
            post_url=expected_post_url,
            executor=mock_executor,
        )
    else:
        mock_upload.assert_called_once()


@pytest.mark.parametrize(('feedback', 'slide_url'), [
    (files.Array([1., 2.]),
     'https://example.com/api/v1/view/org1/proj1/view1/slides/slide1'),
    (None, None),
    (None,
     'https://example.com/api/v1/view/org1/proj1/view1/slides/slide1/feedback'
     ),
])
@pytest.mark.parametrize('verbose', [True, False])
def test_bad_upload_feedback(feedback, slide_url, verbose, session):
    if not feedback:
        feedback = scene.Feedback(comment='bad')
    with pytest.raises(ValueError):
        session.upload_feedback(feedback, slide=slide_url, verbose=verbose)


@pytest.fixture