Source code for in2Trans.ascUtils

"""
    ASCII file reader and handler

"""

import numpy as np
import logging


# create local logger
log = logging.getLogger(__name__)


[docs]def readASCheader(fname): """ return a class with information from an ascii file header Parameters ----------- fname: str or pathlib object path to ascii file Returns -------- headerInfo: class information that is stored in header (ncols, nrows, xllcenter, yllcenter, noDataValue) """ headerInfo = {} infile = open(fname, "r") i = 0 ln = 0 for aline in infile: item = aline.split() if ln == 0: if item[0].lower() == 'ncols': headerInfo['ncols'] = int(item[1]) else: message = 'DEM header is not in correct format - check line 1: should be ncols' log.error(message) raise ValueError(message) elif ln == 1: if item[0].lower() == 'nrows': headerInfo['nrows'] = int(item[1]) else: message = ('DEM header is not in correct format - check line 2: should be nrows') log.error(message) raise ValueError(message) elif ln == 2: if item[0].lower() == "xllcorner": headerInfo['xllcorner'] = float(item[1]) elif item[0].lower() == "xllcenter": headerInfo['xllcenter'] = float(item[1]) else: message = ('DEM header is not in correct format - check line 3: should be xllcenter or xllcorner') log.error(message) raise ValueError(message) elif ln == 3: if item[0].lower() == "yllcorner": headerInfo['yllcorner'] = float(item[1]) elif item[0].lower() == "yllcenter": headerInfo['yllcenter'] = float(item[1]) else: message = ('DEM header is not in correct format - check line 4: should be yllcenter or yllcorner') log.error(message) raise ValueError(message) elif ln == 4: if item[0].lower() == 'cellsize': headerInfo['cellsize'] = float(item[1]) else: message = ('DEM header is not in correct format - check line 5: should be cellsize') log.error(message) raise ValueError(message) elif ln == 5: if 'nodata' in item[0].lower(): headerInfo['noDataValue'] = float(item[1]) else: message = ('DEM header is not in correct format - check line 6: should be noDataValue') log.error(message) raise ValueError(message) ln += 1 if 'xllcenter' not in headerInfo: headerInfo['xllcenter'] = headerInfo['xllcorner'] + headerInfo['cellsize'] / 2 headerInfo['yllcenter'] = headerInfo['yllcorner'] + headerInfo['cellsize'] / 2 # remove xllcorner, yllcorner headerInfo.pop('xllcorner') headerInfo.pop('yllcorner') infile.close() return headerInfo
[docs]def isEqualASCheader(headerA, headerB): """ Test if two headers (A,B) are the same (except for noData Values) Parameters ----------- headerA: class headerB: class Returns -------- boolean: True if header A and B are equal (disregrad the noData field) """ a = headerA b = headerB return (a['ncols'] == b['ncols']) and (a['nrows'] == b['nrows']) and (a['xllcenter'] == b['xllcenter']) and\ (a['yllcenter'] == b['yllcenter']) and (a['cellsize'] == b['cellsize'])
[docs]def readASCdata2numpyArray(fName): """ Read ascii matrix as numpy array Parameters ----------- fname: str or pathlib object path to ascii file Returns -------- -rasterdata : 2D numpy array 2D numpy array of ascii matrix """ infile = open(fName, "r") rasterdata = np.loadtxt(fName, skiprows=6) infile.close() return (rasterdata)
[docs]def readRaster(fname, noDataToNan=True): """ Read raster file (.asc) Parameters ----------- fname: str or pathlib object path to ascii file noDataToNan: bool if True convert noDataValues to nan and set noDataValue to nan Returns -------- data: dict -headerInfo: class information that is stored in header (ncols, nrows, xllcenter, yllcenter, noDataValue) -rasterdata : 2D numpy array 2D numpy array of ascii matrix """ log.debug('Reading dem : %s', fname) header = readASCheader(fname) rasterdata = readASCdata2numpyArray(fname) data = {} data['header'] = header if noDataToNan: rasterdata[rasterdata == header['noDataValue']] = np.NaN data['header']['noDataValue'] = np.nan data['rasterData'] = np.flipud(rasterdata) return data
[docs]def writeResultToAsc(header, resultArray, outFileName, flip=False): """ Write 2D array to an ascii file with header and save to location of outFileName Parameters ---------- header : class class with methods that give cellsize, nrows, ncols, xllcenter yllcenter, noDataValue resultArray : 2D numpy array 2D numpy array of values that shall be written to file outFileName : str path incl. name of file to be written """ # Open outfile with open(outFileName, 'w') as outFile: # write the header and array values to file outFile.write("ncols %d\n" % header['ncols']) outFile.write("nrows %d\n" % header['nrows']) outFile.write("xllcenter %.2f\n" % header['xllcenter']) outFile.write("yllcenter %.2f\n" % header['yllcenter']) outFile.write("cellsize %.2f\n" % header['cellsize']) outFile.write("noDataValue %.2f\n" % header['noDataValue']) M = resultArray.shape[0] for m in range(M): if flip: line = np.array([resultArray[M-m-1,:]]) else: line = np.array([resultArray[m,:]]) np.savetxt(outFile, line, fmt='%.16g') outFile.close()