Source code for pynoddy.output

'''Noddy output file analysis
Created on 24/03/2014

@author: Florian Wellmann
'''

import numpy as np
import matplotlib.pyplot as plt

[docs]class NoddyOutput(): """Class definition for Noddy output analysis""" def __init__(self, output_name): """Noddy output analysis **Arguments**: - *output_name* = string : (base) name of Noddy output files """ self.basename = output_name self.load_model_info() self.load_geology()
[docs] def load_model_info(self): """Load information about model discretisation from .g00 file""" filelines = open(self.basename + ".g00").readlines() for line in filelines: if 'NUMBER OF LAYERS' in line: self.nz = int(line.split("=")[1]) elif 'LAYER 1 DIMENSIONS' in line: (self.nx, self.ny) = [int(l) for l in line.split("=")[1].split(" ")[1:]] elif 'UPPER SW CORNER' in line: l = [float(l) for l in line.split("=")[1].split(" ")[1:]] (self.xmin, self.ymin, self.zmax) = l elif 'LOWER NE CORNER' in line: l = [float(l) for l in line.split("=")[1].split(" ")[1:]] (self.xmax, self.ymax, self.zmin) = l elif 'NUM ROCK' in line: self.n_rocktypes = int(line.split('=')[1]) self.n_total = self.nx * self.ny * self.nz (self.extent_x, self.extent_y, self.extent_z) = (self.xmax - self.xmin, self.ymax - self.ymin, self.zmax - self.zmin) (self.delx, self.dely, self.delz) = (self.extent_x / float(self.nx), self.extent_y / float(self.ny), self.extent_z / float(self.nz))
[docs] def load_geology(self): """Load block geology ids from .g12 output file""" f = open(self.basename + ".g12") self.block = np.loadtxt(f, dtype="int") # reshape to proper 3-D shape self.block = self.block.reshape((self.nz,self.ny,self.nx)) self.block = np.swapaxes(self.block, 0, 2) # self.block = np.swapaxes(self.block, 0, 1) # print np.shape(self.block)
[docs] def determine_unit_volumes(self): """Determine volumes of geological units in the discretized block model """ # # Note: for the time being, the following implementation is extremely simple # and could be optimised, for example to test specifically for units defined # in stratigraphies, intrusions, etc.! # self.block_volume = self.delx * self.dely * self.delz self.unit_ids = np.unique(self.block) self.unit_volumes = np.empty(np.shape(self.unit_ids)) for i,unit_id in enumerate(self.unit_ids): self.unit_volumes[i] = np.sum(self.block == unit_id) * self.block_volume
[docs] def plot_section(self, direction='y', position='center', **kwds): """Create a section block through the model **Arguments**: - *direction* = 'x', 'y', 'z' : coordinate direction of section plot (default: 'y') - *position* = int or 'center' : cell position of section as integer value or identifier (default: 'center') **Optional Keywords**: - *ax* = matplotlib.axis : append plot to axis (default: create new plot) - *figsize* = (x,y) : matplotlib figsize - *colorbar* = bool : plot colorbar (default: True) - *title* = string : plot title - *savefig* = bool : save figure to file (default: show directly on screen) - *cmap* = matplotlib.cmap : colormap - *fig_filename* = string : figure filename """ cmap = kwds.get('cmap', 'jet') if kwds.has_key('ax'): # append plot to existing axis ax = kwds['ax'] return_axis = True else: return_axis = False figsize = kwds.get("figsize", (10,6)) fig = plt.figure(figsize=figsize) ax = fig.add_subplot(111) savefig = kwds.get("savefig", False) colorbar = kwds.get("colorbar", True) # extract slice if direction == 'x': if position == 'center': cell_pos = self.nx / 2 else: cell_pos = position section_slice = self.block[cell_pos,:,:].transpose() xlabel = "y" ylabel = "z" if direction == 'y': if position == 'center': cell_pos = self.ny / 2 else: cell_pos = position section_slice = self.block[:,cell_pos,:].transpose() xlabel = "x" ylabel = "z" if direction == 'z': if position == 'center': cell_pos = self.nz / 2 else: cell_pos = position section_slice = self.block[:,:,cell_pos].transpose() xlabel = "x" ylabel = "y" title = kwds.get("title", "Section in %s-direction, pos=%d" % (direction, cell_pos)) im = ax.imshow(section_slice, interpolation='nearest', aspect=1., cmap=cmap) if colorbar: cbar = plt.colorbar(im) _ = cbar ax.set_title(title) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) if return_axis: return ax elif savefig: fig_filename = kwds.get("fig_filename", "%s_section_%s_pos_%d" % (self.basename, direction, cell_pos)) plt.savefig(fig_filename) else: plt.show()
[docs] def export_to_vtk(self, **kwds): """Export model to VTK Export the geology blocks to VTK for visualisation of the entire 3-D model in an external VTK viewer, e.g. Paraview. ..Note:: Requires pyevtk, available for free on: https://github.com/firedrakeproject/firedrake/tree/master/python/evtk **Optional keywords**: - *vtk_filename* = string : filename of VTK file (default: output_name) """ vtk_filename = kwds.get("vtk_filename", self.basename) from evtk.hl import gridToVTK # Coordinates x = np.arange(0, self.extent_x + 0.1*self.delx, self.delx, dtype='float64') y = np.arange(0, self.extent_y + 0.1*self.dely, self.dely, dtype='float64') z = np.arange(0, self.extent_z + 0.1*self.delz, self.delz, dtype='float64') gridToVTK(vtk_filename, x, y, z, cellData = {"geology" : self.block})
if __name__ == '__main__': # some testing and debugging functions... import os os.chdir(r'/Users/Florian/git/pynoddy/sandbox') NO = NoddyOutput("faults_out")