Skip to content

Commit

Permalink
Merge pull request #683 from girder/handle-path
Browse files Browse the repository at this point in the history
Ensure that all file tile sources can handle Path and str arguments.
  • Loading branch information
manthey authored Nov 15, 2021
2 parents d68aec0 + 07e210b commit 5439255
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Improvements
- Add the image converter to the extra requires ([#677](../../pull/677))
- All file tile sources can take either strings or pathlib.Path values ([#683](../../pull/683))

## Version 1.8.6

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def __init__(self, path, **kwargs): # noqa
"""
super().__init__(path, **kwargs)

largeImagePath = self._getLargeImagePath()
largeImagePath = str(self._getLargeImagePath())

ext = os.path.splitext(largeImagePath)[1]
if not ext:
Expand Down
14 changes: 7 additions & 7 deletions sources/gdal/large_image_source_gdal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,12 @@ def __init__(self, path, projection=None, unitsPerPixel=None, **kwargs):
"""
super().__init__(path, **kwargs)
self._bounds = {}
self._path = self._getLargeImagePath()
self._largeImagePath = str(self._getLargeImagePath())
try:
self.dataset = gdal.Open(self._path, gdalconst.GA_ReadOnly)
self.dataset = gdal.Open(self._largeImagePath, gdalconst.GA_ReadOnly)
except RuntimeError:
if not os.path.isfile(self._path):
raise TileSourceFileNotFoundError(self._path) from None
if not os.path.isfile(self._largeImagePath):
raise TileSourceFileNotFoundError(self._largeImagePath) from None
raise TileSourceError('File cannot be opened via GDAL')
self._getDatasetLock = threading.RLock()
self.tileSize = 256
Expand All @@ -133,8 +133,8 @@ def __init__(self, path, projection=None, unitsPerPixel=None, **kwargs):
self.sourceSizeX = self.sizeX = self.dataset.RasterXSize
self.sourceSizeY = self.sizeY = self.dataset.RasterYSize
except AttributeError:
if not os.path.isfile(self._path):
raise TileSourceFileNotFoundError(self._path) from None
if not os.path.isfile(self._largeImagePath):
raise TileSourceFileNotFoundError(self._largeImagePath) from None
raise TileSourceError('File cannot be opened via GDAL.')
is_netcdf = self._checkNetCDF()
try:
Expand Down Expand Up @@ -1138,7 +1138,7 @@ def getRegion(self, format=(TILE_FORMAT_IMAGE, ), **kwargs):
os.close(fd)
try:
self.logger.info('Using gdal warp %r' % gdalParams)
ds = gdal.Open(self._path, gdalconst.GA_ReadOnly)
ds = gdal.Open(self._largeImagePath, gdalconst.GA_ReadOnly)
gdal.Warp(outputPath, ds, options=gdalParams)
except Exception as exc:
try:
Expand Down
2 changes: 1 addition & 1 deletion sources/mapnik/large_image_source_mapnik/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def _addStyleToMap(self, m, layerSrs, colorizer=None, band=-1, extent=None,
m.append_style(styleName, style)
lyr = mapnik.Layer('layer')
lyr.srs = layerSrs
gdalpath = self._path
gdalpath = self._largeImagePath
gdalband = band
if hasattr(self, '_netcdf') and type(band) is tuple:
gdalband = band[1]
Expand Down
2 changes: 1 addition & 1 deletion sources/nd2/large_image_source_nd2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def __init__(self, path, **kwargs):
"""
super().__init__(path, **kwargs)

self._largeImagePath = self._getLargeImagePath()
self._largeImagePath = str(self._getLargeImagePath())

self._pixelInfo = {}
try:
Expand Down
11 changes: 5 additions & 6 deletions sources/ometiff/large_image_source_ometiff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,10 @@ def __init__(self, path, **kwargs):
# Note this is the super of the parent class, not of this class.
super(TiffFileTileSource, self).__init__(path, **kwargs)

largeImagePath = self._getLargeImagePath()
self._largeImagePath = largeImagePath
self._largeImagePath = str(self._getLargeImagePath())

try:
base = TiledTiffDirectory(largeImagePath, 0, mustBeTiled=None)
base = TiledTiffDirectory(self._largeImagePath, 0, mustBeTiled=None)
except TiffException:
if not os.path.isfile(self._largeImagePath):
raise TileSourceFileNotFoundError(self._largeImagePath) from None
Expand All @@ -106,7 +105,7 @@ def __init__(self, path, **kwargs):
if not info or not info.get('OME'):
raise TileSourceError('Not an OME Tiff')
self._omeinfo = info['OME']
self._checkForOMEZLoop(largeImagePath)
self._checkForOMEZLoop(self._largeImagePath)
self._parseOMEInfo()
omeimages = [
entry['Pixels'] for entry in self._omeinfo['Image'] if
Expand All @@ -119,12 +118,12 @@ def __init__(self, path, **kwargs):
self._omeLevels = [omebylevel.get(key) for key in range(max(omebylevel.keys()) + 1)]
if base._tiffInfo.get('istiled'):
self._tiffDirectories = [
TiledTiffDirectory(largeImagePath, int(entry['TiffData'][0].get('IFD', 0)))
TiledTiffDirectory(self._largeImagePath, int(entry['TiffData'][0].get('IFD', 0)))
if entry else None
for entry in self._omeLevels]
else:
self._tiffDirectories = [
TiledTiffDirectory(largeImagePath, 0, mustBeTiled=None)
TiledTiffDirectory(self._largeImagePath, 0, mustBeTiled=None)
if entry else None
for entry in self._omeLevels]
self._checkForInefficientDirectories(warn=False)
Expand Down
6 changes: 2 additions & 4 deletions sources/openjpeg/large_image_source_openjpeg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,10 @@ def __init__(self, path, **kwargs):
"""
super().__init__(path, **kwargs)

largeImagePath = self._getLargeImagePath()

self._largeImagePath = largeImagePath
self._largeImagePath = str(self._getLargeImagePath())
self._pixelInfo = {}
try:
self._openjpeg = glymur.Jp2k(largeImagePath)
self._openjpeg = glymur.Jp2k(self._largeImagePath)
if not self._openjpeg.shape:
if not os.path.isfile(self._largeImagePath):
raise FileNotFoundError()
Expand Down
2 changes: 1 addition & 1 deletion sources/openslide/large_image_source_openslide/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def __init__(self, path, **kwargs): # noqa
"""
super().__init__(path, **kwargs)

self._largeImagePath = self._getLargeImagePath()
self._largeImagePath = str(self._getLargeImagePath())

try:
self._openslide = openslide.OpenSlide(self._largeImagePath)
Expand Down
16 changes: 7 additions & 9 deletions sources/tiff/large_image_source_tiff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ def __init__(self, path, **kwargs):
"""
super().__init__(path, **kwargs)

largeImagePath = self._getLargeImagePath()
self._largeImagePath = largeImagePath
self._largeImagePath = str(self._getLargeImagePath())

try:
self._initWithTiffTools()
Expand All @@ -100,10 +99,10 @@ def __init__(self, path, **kwargs):

# If there are no tiled images, raise an exception.
if not len(alldir):
if not os.path.isfile(largeImagePath):
raise TileSourceFileNotFoundError(largeImagePath) from None
if not os.path.isfile(self._largeImagePath):
raise TileSourceFileNotFoundError(self._largeImagePath) from None
msg = "File %s didn't meet requirements for tile source: %s" % (
largeImagePath, lastException)
self._largeImagePath, lastException)
config.getConfig('logger').debug(msg)
raise TileSourceError(msg)
# Sort the known directories by image area (width * height). Given
Expand All @@ -120,7 +119,7 @@ def __init__(self, path, **kwargs):
if (td.tileWidth != highest.tileWidth or
td.tileHeight != highest.tileHeight):
if not len(self._associatedImages):
self._addAssociatedImage(largeImagePath, tdir[-2], True, highest)
self._addAssociatedImage(self._largeImagePath, tdir[-2], True, highest)
continue
# If a layer's image is not a multiple of the tile size, it should
# be near a power of two of the highest resolution image.
Expand All @@ -146,7 +145,6 @@ def __init__(self, path, **kwargs):
self._checkForInefficientDirectories()

def _scanDirectories(self):
largeImagePath = self._largeImagePath
lastException = None
# Associated images are smallish TIFF images that have an image
# description and are not tiled. They have their own TIFF directory.
Expand All @@ -164,7 +162,7 @@ def _scanDirectories(self):
for directoryNum in itertools.count(): # pragma: no branch
try:
if dir is None:
dir = TiledTiffDirectory(largeImagePath, directoryNum, validate=False)
dir = TiledTiffDirectory(self._largeImagePath, directoryNum, validate=False)
else:
dir._setDirectory(directoryNum)
dir._loadMetadata()
Expand Down Expand Up @@ -193,7 +191,7 @@ def _scanDirectories(self):
if not alldir and lastException:
raise lastException
for directoryNum in associatedDirs:
self._addAssociatedImage(largeImagePath, directoryNum)
self._addAssociatedImage(self._largeImagePath, directoryNum)
return alldir

def _levelFromIfd(self, ifd, baseifd):
Expand Down
14 changes: 14 additions & 0 deletions test/test_source_base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import re
from pathlib import Path

import pytest

Expand Down Expand Up @@ -88,6 +89,19 @@ def testSourcesCanRead(source, filename):
assert bool(sourceClass.canRead(imagePath)) is bool(canRead)


@pytest.mark.parametrize('filename', registry)
@pytest.mark.parametrize('source', SourceAndFiles)
def testSourcesCanReadPath(source, filename):
sourceInfo = SourceAndFiles[source]
canRead = sourceInfo.get('any') or (
re.search(sourceInfo.get('read', r'^$'), filename) and
not re.search(sourceInfo.get('noread', r'^$'), filename))
imagePath = datastore.fetch(filename)
large_image.tilesource.loadTileSources()
sourceClass = large_image.tilesource.AvailableTileSources[source]
assert bool(sourceClass.canRead(Path(imagePath))) is bool(canRead)


@pytest.mark.parametrize('filename', registry)
@pytest.mark.parametrize('source', SourceAndFiles)
def testSourcesTilesAndMethods(source, filename):
Expand Down

0 comments on commit 5439255

Please sign in to comment.