diff --git a/sources/multi/setup.py b/sources/multi/setup.py index 642ab4e35..9ce58718e 100644 --- a/sources/multi/setup.py +++ b/sources/multi/setup.py @@ -45,6 +45,7 @@ def prerelease_local_scheme(version): install_requires=[ 'jsonschema', 'large-image>=1.0.0', + 'pyyaml', 'scipy', ], extras_require={ diff --git a/test/datastore.py b/test/datastore.py index 0eb10049e..64ee7c797 100644 --- a/test/datastore.py +++ b/test/datastore.py @@ -72,6 +72,9 @@ # Geospatial file without a projection # Source: generated from geojs oahu sample and a script 'oahu-dense.tiff': 'sha512:414b7807f14991d6f8229134ad6ccbc2cc2d4b05423ccebfd3ede7d7323dfcf04ef1a7b2c2b4c45c31f8a36bccd390782af3e7d3e99f01f1b95650c5da1f122b', # noqa + # Multi source file using different sources + # Source: manually generated. + 'multi_source.yml': 'sha512:81d7768b06eca6903082daa5b91706beaac8557ba4cede7f826524303df69a33478d6bb205c56af7ee2b45cd7d75897cc4b5704f743ddbf71bb3537ed3b9e8a8', # noqa } diff --git a/test/test_files/multi3.yml b/test/test_files/multi3.yml new file mode 100644 index 000000000..d56f27321 --- /dev/null +++ b/test/test_files/multi3.yml @@ -0,0 +1,9 @@ +--- +name: Multi orientation +description: A test multi file +scale: + mm_x: 0.0005 + mm_y: 0.0005 +sources: + - path: . + pathPattern: 'test_orient(?P[1-8])\.tif' diff --git a/test/test_files/multi_composite.yml b/test/test_files/multi_composite.yml new file mode 100644 index 000000000..ab9740466 --- /dev/null +++ b/test/test_files/multi_composite.yml @@ -0,0 +1,50 @@ +--- +name: Multi orientation +description: A test multi file +scale: + mm_x: 0.0005 + mm_y: 0.0005 +width: 360 +height: 360 +sources: + - name: First image + path: ./test_orient1.tif + z: 0 + position: + x: 0 + y: 0 + - path: ./test_orient2.tif + z: 0 + position: + x: 180 + y: 0 + - path: ./test_orient3.tif + z: 0 + position: + x: 0 + y: 180 + - path: ./test_orient4.tif + z: 0 + position: + x: 180 + y: 180 + - path: ./test_orient5.tif + z: 1 + position: + x: 0 + y: 0 + - path: ./test_orient6.tif + z: 1 + position: + x: 180 + y: 0 + - path: ./test_orient7.tif + z: 1 + position: + x: 0 + y: 180 + - path: ./test_orient8.tif + z: 1 + position: + x: 180 + y: 180 diff --git a/test/test_files/multi_simple_scaling.yml b/test/test_files/multi_simple_scaling.yml new file mode 100644 index 000000000..22f22310e --- /dev/null +++ b/test/test_files/multi_simple_scaling.yml @@ -0,0 +1,39 @@ +--- +name: Multi orientation +description: A test multi file +scale: + mm_x: 0.0005 + mm_y: 0.0005 +width: 2048 +height: 1540 +tileWidth: 256 +tileHeight: 256 +backgroundColor: + - 0 + - 0 + - 255 +sources: + - path: ./test_orient1.tif + z: 0 + - path: ./test_orient2.tif + z: 1 + position: + scale: 4 + - path: ./test_orient3.tif + z: 2 + position: + scale: 0.25 + - path: ./test_orient4.tif + z: 3 + position: + x: 137 + y: 32 + scale: 4 + - path: ./test_orient5.tif + z: 4 + - path: ./test_orient6.tif + z: 5 + - path: ./test_orient7.tif + z: 6 + - path: ./test_orient8.tif + z: 7 diff --git a/test/test_source_base.py b/test/test_source_base.py index 98bc80c81..831601a32 100644 --- a/test/test_source_base.py +++ b/test/test_source_base.py @@ -30,6 +30,9 @@ 'noread': r'(huron\.image2_jpeg2k|sample_jp2k_33003|TCGA-DU-6399|\.(ome.tiff)$)', # we should only test this with a projection 'skipTiles': r''}, + 'multi': { + 'read': r'\.(yml|yaml)$', + }, 'nd2': {'read': r'\.(nd2)$'}, 'ometiff': {'read': r'\.(ome\.tif.*)$'}, 'openjpeg': {'read': r'\.(jp2)$'}, diff --git a/test/test_source_multi.py b/test/test_source_multi.py new file mode 100644 index 000000000..52a8dab17 --- /dev/null +++ b/test/test_source_multi.py @@ -0,0 +1,88 @@ +import os + +import large_image_source_multi +import pytest + +from . import utilities +from .datastore import datastore + + +@pytest.mark.parametrize('filename', [ + 'multi1.yml', + 'multi2.yml', + 'multi3.yml', +]) +def testTilesFromMulti(filename): + testDir = os.path.dirname(os.path.realpath(__file__)) + imagePath = os.path.join(testDir, 'test_files', filename) + source = large_image_source_multi.open(imagePath) + tileMetadata = source.getMetadata() + assert tileMetadata['tileWidth'] == 64 + assert tileMetadata['tileHeight'] == 64 + assert tileMetadata['sizeX'] == 180 + assert tileMetadata['sizeY'] == 180 + assert tileMetadata['levels'] == 3 + assert len(tileMetadata['frames']) == 8 + + utilities.checkTilesZXY(source, tileMetadata) + + +def testTilesFromMultiComposite(): + testDir = os.path.dirname(os.path.realpath(__file__)) + imagePath = os.path.join(testDir, 'test_files', 'multi_composite.yml') + source = large_image_source_multi.open(imagePath) + tileMetadata = source.getMetadata() + assert tileMetadata['tileWidth'] == 64 + assert tileMetadata['tileHeight'] == 64 + assert tileMetadata['sizeX'] == 360 + assert tileMetadata['sizeY'] == 360 + assert tileMetadata['levels'] == 4 + assert len(tileMetadata['frames']) == 2 + + utilities.checkTilesZXY(source, tileMetadata) + + +def testTilesFromMultiSimpleScaling(): + testDir = os.path.dirname(os.path.realpath(__file__)) + imagePath = os.path.join(testDir, 'test_files', 'multi_simple_scaling.yml') + source = large_image_source_multi.open(imagePath) + tileMetadata = source.getMetadata() + assert tileMetadata['tileWidth'] == 256 + assert tileMetadata['tileHeight'] == 256 + assert tileMetadata['sizeX'] == 2048 + assert tileMetadata['sizeY'] == 1540 + assert tileMetadata['levels'] == 4 + assert len(tileMetadata['frames']) == 8 + + for frame in range(len(tileMetadata['frames'])): + utilities.checkTilesZXY(source, tileMetadata, tileParams={'frame': frame}) + + +def testTilesFromMultiMultiSource(): + imagePath = datastore.fetch('multi_source.yml') + source = large_image_source_multi.open(imagePath) + tileMetadata = source.getMetadata() + assert tileMetadata['tileWidth'] == 256 + assert tileMetadata['tileHeight'] == 256 + assert tileMetadata['sizeX'] == 55988 + assert tileMetadata['sizeY'] == 16256 + assert tileMetadata['levels'] == 9 + assert len(tileMetadata['frames']) == 300 + + utilities.checkTilesZXY(source, tileMetadata) + utilities.checkTilesZXY(source, tileMetadata, tileParams={'frame': 50}) + + +def testInternalMetadata(): + imagePath = datastore.fetch('multi_source.yml') + source = large_image_source_multi.open(imagePath) + metadata = source.getInternalMetadata() + assert 'frames' in metadata + + +def testAssociatedImages(): + imagePath = datastore.fetch('multi_source.yml') + source = large_image_source_multi.open(imagePath) + assert 'label' in source.getAssociatedImagesList() + image, mimeType = source.getAssociatedImage('label') + assert image[:len(utilities.JPEGHeader)] == utilities.JPEGHeader