Commit c6529af4 authored by Hoek, Steven's avatar Hoek, Steven
Browse files

Test scripts developed and bugs fixed; arguments of methods __init__ had to be given default values

parent a037d9b4
eclipse.preferences.version=1
encoding//formats/bilraster.py=utf-8
encoding//formats/bsqraster.py=utf-8
encoding//toolbox/scalelib.py=latin1
from . import formats
from . import toolbox
......@@ -7,7 +7,7 @@ from .gridenvelope2d import GridEnvelope2D;
__author__ = "Steven B. Hoek"
class AsciiGrid(Raster, GridEnvelope2D):
"A raster represented by an ASCII file, with extension 'asc'"
"""A raster represented by an ASCII file, with extension 'asc'"""
# Data attributes - assign some dummy values for the mean time
_const = None
......@@ -24,11 +24,15 @@ class AsciiGrid(Raster, GridEnvelope2D):
__mode = 'r';
__digitspercell = 7;
def __init__(self, filepath, *datatype):
def __init__(self, filepath='', *datatype):
# Check input
if filepath == '':
print('File path cannot be an empty string (method __init__).')
# Module wide constants
self._const = Const()
self._const.FILEXT = "asc";
self._const.MAXDIGITSPERCELL = 6 # 11
self._const.MAXDIGITSPERCELL = 6 # TODO this is hardcoded - change this
self.name = "dummy." + self._const.FILEXT;
# Initialise further
......@@ -176,7 +180,7 @@ class AsciiGrid(Raster, GridEnvelope2D):
self.datafile.write(s);
else:
totalwidth = self._const.MAXDIGITSPERCELL - 1
fmtstr = "{:" + str(totalwidth) + ".2f}"
fmtstr = "{:" + str(totalwidth) + ".3f}" # TODO format is hardcoded - change this!
for k in range(0, self.ncols):
s = fmtstr.format(sequence_with_data[k]).rjust(self._const.MAXDIGITSPERCELL + 1);
self.datafile.write(s);
......
......@@ -180,7 +180,7 @@ class BandRaster(Raster, GridEnvelope2D):
hf.write(const.NCOLS.upper() + " " + str(self.ncols) + "\n")
hf.write("NBANDS " + str(self.nbands) + "\n")
hf.write("NBITS " + str(self.nbits) + "\n")
bandrowbytes = self.nbits * self.ncols / 8
bandrowbytes = int(self.nbits * self.ncols / 8)
hf.write("BANDROWBYTES " + str(bandrowbytes) + "\n")
hf.write("TOTALROWBYTES " + str(self.nbands * bandrowbytes) + "\n")
if self.dataformat.lower() == 'i':
......
......@@ -23,7 +23,14 @@ class BilRaster(BandRaster):
_const = None
name = "";
def __init__(self, filepath, *dataformat):
def __init__(self, filepath='', *dataformat):
# Process input
if filepath == '':
print('File path cannot be an empty string (method __init__).')
if len(dataformat) == 0:
print("Data type 'float' assumed (method __init__).")
dataformat = 'f'
# Initialise super class instance
BandRaster.__init__(self, filepath, dataformat[0])
if self._const == None:
......@@ -36,7 +43,7 @@ class BilRaster(BandRaster):
self.name = "dummy." + self._const.DATAFILEXT
self.currow = -1
def open(self, mode, ncols=1, nrows=1, nbands=3, xll=0, yll=0, cellsize=100, nodatavalue=256):
def open(self, mode, ncols=1, nrows=1, nbands=1, xll=0, yll=0, cellsize=100, nodatavalue=256):
self.nbits = struct.calcsize(self.dataformat)*8
result = super(BilRaster, self).open(mode, ncols, nrows, nbands, xll, yll, cellsize, nodatavalue);
if (mode[0] == 'w'):
......@@ -135,6 +142,8 @@ class BilRaster(BandRaster):
if not isinstance(sequence_with_data[0][0], (int, float)) and len(sequence_with_data[0]) != self.nbands:
raise ValueError("Input sequence elements haven't got the expected number of values")
else:
if isinstance(sequence_with_data, np.ndarray) and len(sequence_with_data.shape) == 1:
sequence_with_data = np.reshape(sequence_with_data, (sequence_with_data.shape[0], 1))
if (not isinstance(sequence_with_data[0][0], (int, float, np.int32, np.float32, np.float64))) or len(sequence_with_data[0]) != self.nbands:
raise ValueError("Input sequence elements haven't got the expected number of values")
if self.nbands > 1 and not self._is_sequence(sequence_with_data[0]):
......
......@@ -23,7 +23,14 @@ class BsqRaster(BandRaster):
_const = None
name = "";
def __init__(self, filepath, *dataformat):
def __init__(self, filepath='', *dataformat):
# Check input
if filepath == '':
print('File path cannot be an empty string (method __init__).')
if len(dataformat) == 0:
print("Data type 'float' assumed (method __init__).")
dataformat = 'f'
# Initialise super class instance
BandRaster.__init__(self, filepath, dataformat[0])
if self._const == None:
......@@ -36,7 +43,7 @@ class BsqRaster(BandRaster):
self.name = "dummy." + self._const.DATAFILEXT
self.currow = -1;
def open(self, mode, ncols=1, nrows=1, nbands=3, xll=0, yll=0, cellsize=100, nodatavalue=256):
def open(self, mode, ncols=1, nrows=1, nbands=1, xll=0, yll=0, cellsize=100, nodatavalue=256):
result = super(BsqRaster, self).open(mode, ncols, nrows, nbands, xll, yll, cellsize, nodatavalue)
if (mode[0] == 'w'):
return result
......@@ -48,7 +55,7 @@ class BsqRaster(BandRaster):
try:
bytesperpix = struct.calcsize(self.dataformat)
except:
raise ValueError, "Supplied data format " + str(self.dataformat) + " is invalid"
raise ValueError("Supplied data format " + str(self.dataformat) + " is invalid")
# end try
# Check file size matches with size attributes
......@@ -60,9 +67,9 @@ class BsqRaster(BandRaster):
checknum = (((filesize / float(self.nbands)) / float(self.nrows)) / float(bytesperpix)) / self.ncols
if checknum != 1:
if fabs(checknum - 1) < 0.00003:
raise ValueError, "File size and size calculated from attributes only match approximately"
raise ValueError("File size and size calculated from attributes only match approximately")
else:
raise ValueError, "File size and supplied attributes do not match at all!"
raise ValueError("File size and supplied attributes do not match at all!")
# Open the file for reading in binary mode
try:
......
import os.path;
import stat
from array import array
from .const import Const, constants as const
from .raster import Raster
from .gridenvelope2d import GridEnvelope2D;
......@@ -6,7 +8,7 @@ from .gridenvelope2d import GridEnvelope2D;
__author__ = "Steven B. Hoek"
class FloatingPointRaster(Raster, GridEnvelope2D):
"A raster represented by 2 files, with extensions 'flt' and 'hdr'"
"""A raster represented by 2 files, with extensions 'flt' and 'hdr'"""
# Attributes - assign some dummy values for the mean time
_const = None
......@@ -23,7 +25,11 @@ class FloatingPointRaster(Raster, GridEnvelope2D):
currow = 0;
__envelope = None;
def __init__(self, filepath, *datatype):
def __init__(self, filepath='', *datatype):
# Check input
if filepath == '':
print('File path cannot be an empty string (method __init__).')
# Initialise
Raster.__init__(self, filepath)
self._const = Const()
......@@ -32,6 +38,7 @@ class FloatingPointRaster(Raster, GridEnvelope2D):
self._const.LSBFIRST = "LSBFIRST";
self._const.BYTESPERCELL = 4;
self._const.DATAFILEXT = "flt"
self._const.DATAFILEXTALT = "int"
self._const.WORLDEXT = "wld"
self.byteorder = self._const.LSBFIRST
......@@ -52,7 +59,7 @@ class FloatingPointRaster(Raster, GridEnvelope2D):
# If file does not exist and mode[0] = 'w', create it!
if (mode[0] == 'w') and (not os.path.exists(self.folder + os.path.sep + self.name)):
self.datafile = open(self.folder + os.path.sep + self.name, 'w');
self.datafile = open(self.folder + os.path.sep + self.name, 'wb');
self.__envelope = GridEnvelope2D.__init__(self, ncols, nrows, xll, yll, cellsize, cellsize);
return True;
else:
......@@ -79,10 +86,16 @@ class FloatingPointRaster(Raster, GridEnvelope2D):
def readheader(self):
# Read header file and assign all attributes
pos = str.rfind(str(self.name), "." + self._const.DATAFILEXT);
pos1 = str.rfind(str(self.name), "." + self._const.DATAFILEXT)
pos2 = str.rfind(str(self.name), "." + self._const.DATAFILEXTALT)
pos = max(pos1, pos2)
if pos != -1: hdrFilename = self.name[0:pos] + "." + const.HEADEREXT
else: raise ValueError("Invalid file name: " + self.name);
if os.path.exists(self.folder + os.path.sep + hdrFilename):
fileinfo = os.stat(os.path.join(self.folder, self.name))
filesize = fileinfo[stat.ST_SIZE]
if filesize == 0:
raise RuntimeError("Empty header file found!")
hf = open(self.folder + os.path.sep + hdrFilename, 'r');
hl = hf.readline();
self.ncols = int(hl.replace('ncols', '').strip());
......@@ -111,7 +124,8 @@ class FloatingPointRaster(Raster, GridEnvelope2D):
try:
self.currow += 1;
if (self.currow > self.nrows): raise StopIteration;
return self.datafile.read(self.ncols * self._const.BYTESPERCELL);
result = self.datafile.read(self.ncols * self._const.BYTESPERCELL);
return array(self.datatype, result);
except:
raise StopIteration;
......@@ -129,7 +143,9 @@ class FloatingPointRaster(Raster, GridEnvelope2D):
def writeheader(self):
# Write header file with all attributes
pos = str.rfind(str(self.name), "." + self._const.DATAFILEXT);
pos1 = str.rfind(str(self.name), "." + self._const.DATAFILEXT)
pos2 = str.rfind(str(self.name), "." + self._const.DATAFILEXTALT)
pos = max(pos1, pos2)
if pos != -1: hdrFilename = self.name[0:pos] + "." + const.HEADEREXT
else: raise ValueError("Invalid file name: " + self.name);
try:
......
import tests
tests.test_all()
\ No newline at end of file
import unittest
from . import test_asciigrid
from . import test_floatingpointraster
from . import test_bilraster
from . import test_bsqraster
def make_test_suite(dsn=None):
"""Assemble test suite and return it
"""
allsuites = unittest.TestSuite([test_asciigrid.suite(),
test_floatingpointraster.suite(),
test_bilraster.suite(),
test_bsqraster.suite()
])
return allsuites
def test_all():
"""Assemble test suite and run the test using the TextTestRunner
"""
allsuites = make_test_suite()
unittest.TextTestRunner(verbosity=2).run(allsuites)
import unittest
from .test_asciigrid import suite as test_asciigrid_suite
def make_test_suite(dsn=None):
"""Assemble test suite and return it
"""
allsuites = unittest.TestSuite([test_asciigrid_suite()
])
return allsuites
def test_all():
"""Assemble test suite and run the test using the TextTestRunner
"""
allsuites = make_test_suite()
unittest.TextTestRunner(verbosity=2).run(allsuites)
test_all()
\ No newline at end of file
......@@ -3,4 +3,4 @@ nrows 30
xllcorner 3.25
yllcorner 50.625
cellsize 0.1
NODATA_value -1
NODATA_value -1.0
No preview for this file type
......@@ -40,7 +40,11 @@ def main():
ncols = page.tags['ImageWidth'].value
# Also derive the data from the TIFF file; divide by 10 to get some decimals!
# And add some extra noise to make sure not all numbers in a line are the same
data = imread(fn) / 10
for i in range(nrows):
for k in range(ncols):
data[i,k] = data[i,k] + k*0.005
# Derive the geographic origin and pixel size from the world file (manipulated)
fn = os.path.join('..', '..', 'geodata', 'float.wld')
......
from formats.asciigrid import AsciiGrid
import numpy as np
import os.path
from .test_baseraster import TestBaseRaster
import unittest
f = None
try:
# Test writing and reading of a grid with integer numbers
fn = os.path.join('data', 'intasc.npy')
data = np.load(fn)
hfn = os.path.join('data', 'intasc.hdr')
f = open(hfn, 'r')
header = f.readlines()
__author__ = "Steven B. Hoek"
finally:
if f != None: f.close()
class TestAsciiGrid(TestBaseRaster):
# Load data from a pickle file and metadata from a header file
# Write the data to an AsciiGrid. Close and open teh file again for reading and check
test_class = AsciiGrid
int_extension = 'asc'
flt_extension = 'asc'
def suite():
""" This defines all the tests of a module"""
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAsciiGrid))
return suite
f = None
try:
# Test reading and writing of a grid with float numbers
fn = os.path.join('data', 'fltasc.npy')
data = np.load(fn)
finally:
if f != None: f.close()
\ No newline at end of file
import os.path
import unittest
import numpy as np
__author__ = "Steven B. Hoek"
class TestBaseRaster(unittest.TestCase):
test_class = None
int_extension = 'xxx'
flt_extension = 'xxx'
def test_int_grid(self):
f = None
br = None
curdir = os.path.dirname(__file__)
try:
# Test writing and reading of a grid with integer numbers; first the data
fn = os.path.join(curdir, 'data', 'intasc.npy')
data = np.load(fn)
# Then the header
hfn = os.path.join(curdir, 'data', 'intasc.hdr')
f = open(hfn, 'r')
hls = f.readlines()
ncols = int(hls[0].replace('ncols', ''));
nrows = int(hls[1].replace('nrows', ''));
xll = float(hls[2].replace('xllcorner', ''));
yll = float(hls[3].replace('yllcorner', ''));
cellsize = float(hls[4].replace('cellsize', ''));
nodatavalue = int(hls[5].replace('NODATA_value', ''));
# Write the file
br = self.test_class(os.path.join(curdir, 'output', 'int.' + self.int_extension), 'i')
br.open('w', ncols=ncols, nrows=nrows, xll=xll, yll=yll, cellsize=cellsize, nodatavalue=nodatavalue)
for i in range(nrows):
line = data[i, :]
br.writenext(line)
finally:
if f != None: f.close()
if br != None: br.close()
br = None
try:
# Open file for reading again
br = self.test_class(os.path.join(curdir, 'output', 'int.' + self.int_extension), 'i')
br.open('r')
self.assertEqual(nrows, br.nrows)
self.assertEqual(ncols, br.ncols)
self.assertEqual(xll, br.xll)
self.assertEqual(yll, br.yll)
self.assertEqual(cellsize, br.cellsize)
self.assertEqual(nodatavalue, br.nodatavalue)
for i in range(nrows):
line = br.next()
for k in range(ncols):
self.assertEqual(data[i,k], line[k])
finally:
if br != None: br.close()
def test_flt_grid(self):
f = None
br = None
curdir = os.path.dirname(__file__)
try:
# Test reading and writing of a grid with float numbers; first the data
fn = os.path.join(curdir, 'data', 'fltasc.npy')
data = np.load(fn)
# Then the header
hfn = os.path.join(curdir, 'data', 'fltasc.hdr')
f = open(hfn, 'r')
hls = f.readlines()
ncols = int(hls[0].replace('ncols', ''));
nrows = int(hls[1].replace('nrows', ''));
xll = float(hls[2].replace('xllcorner', ''));
yll = float(hls[3].replace('yllcorner', ''));
cellsize = float(hls[4].replace('cellsize', ''));
nodatavalue = float(hls[5].replace('NODATA_value', ''));
# Write the file
br = self.test_class(os.path.join(curdir, 'output', 'flt.' + self.flt_extension), 'f')
br.open('w', ncols=ncols, nrows=nrows, xll=xll, yll=yll, cellsize=cellsize, nodatavalue=nodatavalue)
for i in range(nrows):
line = data[i, :]
br.writenext(line)
finally:
if f != None: f.close()
if br != None: br.close()
try:
# Open file for reading again
fname = os.path.join(curdir, 'output', 'flt.' + self.flt_extension)
br = self.test_class(fname, 'f')
br.open('r')
self.assertEqual(nrows, br.nrows)
self.assertEqual(ncols, br.ncols)
self.assertAlmostEqual(xll, br.xll, places=3)
self.assertAlmostEqual(yll, br.yll, places=3)
self.assertAlmostEqual(cellsize, br.cellsize, places=3)
self.assertAlmostEqual(nodatavalue, br.nodatavalue, places=3)
for i in range(nrows):
line = br.next()
for k in range(ncols):
self.assertAlmostEqual(data[i,k], line[k], places=3)
finally:
if br != None: br.close()
\ No newline at end of file
from formats.bilraster import BilRaster
from .test_baseraster import TestBaseRaster
import unittest
# Test reading and writing of a grid with integer numbers
__author__ = "Steven B. Hoek"
# Test reading and writing of a grid with float numbers
\ No newline at end of file
# TODO this test has limited relevance because the test is carried out with only one band (= default)
class TestBilRaster(TestBaseRaster):
# Load data from a pickle file and metadata from a header file
# Write the data to an AsciiGrid. Close and open teh file again for reading and check
test_class = BilRaster
int_extension = 'bil'
flt_extension = 'bil'
def suite():
""" This defines all the tests of a module"""
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestBilRaster))
return suite
\ No newline at end of file
from formats.bsqraster import BsqRaster
from .test_baseraster import TestBaseRaster
import unittest
__author__ = "Steven B. Hoek"
# TODO this test has limited relevance because the test is carried out with only one band (= default)
class TestBsqRaster(TestBaseRaster):
# Load data from a pickle file and metadata from a header file
# Write the data to an AsciiGrid. Close and open teh file again for reading and check
test_class = BsqRaster
int_extension = 'bsq'
flt_extension = 'bsq'
def suite():
""" This defines all the tests of a module"""
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestBsqRaster))
return suite
\ No newline at end of file
from formats.floatingpointraster import FloatingPointRaster
from .test_baseraster import TestBaseRaster
import unittest
# Test reading and writing of a grid with integer numbers
__author__ = "Steven B. Hoek"
# Test reading and writing of a grid with float numbers
\ No newline at end of file
class TestFloatingPointRaster(TestBaseRaster):
# Load data from a pickle file and metadata from a header file
# Write the data to an AsciiGrid. Close and open teh file again for reading and check
test_class = FloatingPointRaster
int_extension = 'int'
flt_extension = 'flt'
def suite():
""" This defines all the tests of a module"""
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestFloatingPointRaster))
return suite
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment