Source code for imagesplit.file.file_wrapper
# coding=utf-8
"""
Wrapping code for managing virtual images that may consist of multiple
subimages
Author: Tom Doel
Copyright UCL 2017
"""
import os
import numpy as np
from imagesplit.utils.utilities import file_linear_byte_offset, rescale_image
[docs]class FileStreamer(object):
"""Handle streaming of image data with arbitrarily large files"""
def __init__(self, file_wrapper, image_size, bytes_per_voxel, numpy_format,
dimension_ordering):
self._bytes_per_voxel = bytes_per_voxel
self._image_size = image_size
self._file_wrapper = file_wrapper
self._numpy_format = numpy_format
self._dimension_ordering = dimension_ordering
[docs] def read_line(self, start_coords, num_voxels):
"""Read a line of image data from a binary file at the specified
image location """
offset = file_linear_byte_offset(self._image_size,
self._bytes_per_voxel,
start_coords)
self._file_wrapper.get_handle().seek(offset)
data_type = np.dtype(self._numpy_format)
bytes_array = self._file_wrapper.get_handle().read(
num_voxels * self._bytes_per_voxel)
return np.frombuffer(bytes_array, dtype=data_type)
[docs] def write_line(self, start_coords, image_line, rescale_limits):
"""Write a line of image data to a binary file at the specified image
location """
offset = file_linear_byte_offset(self._image_size,
self._bytes_per_voxel,
start_coords)
self._file_wrapper.get_handle().seek(offset)
data_type = np.dtype(self._numpy_format)
if rescale_limits:
image_line = rescale_image(data_type, image_line,
rescale_limits)
self._file_wrapper.get_handle().write(
image_line.astype(data_type).tobytes())
[docs] def close(self):
"""Close any files that have been opened."""
self._file_wrapper.close()
[docs]class FileWrapper(object):
"""Read or write to arbitrarily large files."""
def __init__(self, name, file_handle_factory, mode):
self._file_handle_factory = file_handle_factory
self._filename = name
self._mode = mode
self._file_handle = None
def __del__(self):
self.close()
def __enter__(self):
self.open()
return self._file_handle
def __exit__(self, exit_type, value, traceback):
self.close()
[docs] def get_handle(self):
"""Returns the file handle, opening if necessary"""
if not self._file_handle:
self.open()
return self._file_handle
[docs] def open(self):
"""Opens the file"""
self._file_handle = self._file_handle_factory.create_file_handle(
self._filename, self._mode)
[docs] def close(self):
"""Close the file"""
if self._file_handle and not self._file_handle.closed:
self._file_handle.close()
self._file_handle = None
[docs]class FileHandleFactory(object):
"""Creates file handles, allowing for abstraction to virtual files"""
def __init__(self):
pass
[docs] @staticmethod
def create_file_handle(filename, mode):
"""Create and open a real file with this path and file access mode"""
folder = os.path.dirname(filename)
if not os.path.exists(folder):
os.makedirs(folder)
return open(filename, mode)