1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
|
#############################################################
## ##
## Copyright (c) 2003-2011 by The University of Queensland ##
## Earth Systems Science Computational Centre (ESSCC) ##
## http://www.uq.edu.au/esscc ##
## ##
## Primary Business: Brisbane, Queensland, Australia ##
## Licensed under the Open Software License version 3.0 ##
## http://www.opensource.org/licenses/osl-3.0.php ##
## ##
#############################################################
#!/bin/env python
import sys
import string
from math import sqrt
from optparse import OptionParser
from esys.lsm.util import InstallInfo
if (InstallInfo.haveVtk()):
from esys.lsm.vis.vtk import *
class Data:
"""
Objects store position and displacement vectors.
"""
def __init__(self, point, displacement):
"""
Initialise data.
@type point: 3 element sequence of floats
@param point: position of displacement.
@type displacement: 3 element sequence of floats
@param displacement: displacement at point.
"""
self.point = point
self.displacement = displacement
def getPoint(self):
"""
Returns position.
@return: data position
@rtype: 3 element sequence of floats
"""
return self.point
def getDisplacement(self):
"""
Returns displacement.
@return: data displacement
@rtype: 3 element sequence of floats
"""
return self.displacement
def getDisplacementMagnitude(self):
"""
Returns displacement magnitude.
@rtype: float
@return: magnitude of seld.getDisplacement() vector
"""
return \
sqrt(
sum(
map(lambda x:x*x, self.displacement)
)
)
def surfaceRenderDisplacements(fileName, zField, subsample, scaleMultiplier, imageSize):
"""
Renders a surface of displacements data.
@param fileName: name of the data file.
@type zField: string C{in ["dx", "dy", "dm", "vx", "vy", "vm"]}.
@param zField: Which component of the data is used for
the surface heights.
@type subsample: int C{>= 1}
@param subsample: A subset of data is rendered for C{subsample > 1}.
@type scaleMultiplier: float
@param scaleMultiplier: Scale factor for surface heights.
"""
dataList = []
f = file(fileName, "r")
xrange=[1000000,-10000000]
yrange=[1000000,-10000000]
drange=[1000000,-10000000]
i = 0
for line in f.readlines():
if ((i % subsample) == 0):
elemList = string.split(string.strip(line), " ")
elemList = map(float, elemList)
if ((len(zField) > 6) and (zField[0]=="v")):
dataList.append(
Data(elemList[0:3], elemList[6:9])
)
else:
dataList.append(
Data(elemList[0:3], elemList[3:6])
)
i += 1
xList = [d.getPoint()[0] for d in dataList]
yList = [d.getPoint()[1] for d in dataList]
dList = \
[d.getDisplacementMagnitude() for d in dataList] \
+\
[d.getDisplacement()[0] for d in dataList] \
+\
[d.getDisplacement()[1] for d in dataList]
xrange = [min(xList), max(xList)]
yrange = [min(yList), max(yList)]
drange = [min(dList), max(dList)]
scaleFactor = 1.0
if (drange[1] > 0.0):
scaleFactor = \
scaleMultiplier \
* \
(max([xrange[1]-xrange[0], yrange[1]-yrange[0]])/2.0)/drange[1]
if (zField[1] == "x"):
extr = lambda x : [x.getPoint()[0], x.getPoint()[1], scaleFactor*x.getDisplacement()[0]]
elif (zField[1] == "y"):
extr = lambda x : [x.getPoint()[0], x.getPoint()[1], scaleFactor*x.getDisplacement()[1]]
else:
extr = lambda x : [x.getPoint()[0], x.getPoint()[1], scaleFactor*x.getDisplacementMagnitude()]
scene = Scene()
scene.setBackground(Colors.LightBlue)
scene.add(SurfaceData(dataList, PointExtractor(extr)))
scene.render(offScreen=False, size=imageSize)
def getOptionParser():
"""
Returns an object for parsing command line arguemnts.
@rtype: C{optparse.OptionParser}
@return: a parser initialised with some relevent command line options.
"""
usage = "usage: %prog [options] <dataFile>\n\n"
usage += "Displays a fitted surface of displacement/velocity data"
usage += " from the\nfile"
usage += " <dataFile>. This file is expected to contain lines\nof"
usage += " the form \"px py pz dx dy dz vx vy vz\"."
usage += " The pz and vz components\nare ignored."
parser = OptionParser(usage=usage)
parser.add_option(
"-z", "--z-component",
dest="zComponent",
metavar="Z",
default="dmag",
help=\
"Defines the component of the displacement or velocity which " +\
"is used as the surface height," +\
"Z={'dx', 'dy', 'dmagnitude', 'vx', 'vy', 'vmagnitude'}" +\
" (default Z=\"dmagnitude\")."
)
parser.add_option(
"-s", "--subsample",
dest="subsample",
metavar="S",
type = "int",
default=1,
help=\
"Only every S-th data point is read from file, rest are skipped " +\
" (default S=1)."
)
parser.add_option(
"-x", "--scale-multiplier",
dest="scaleMultiplier",
metavar="S",
type = "float",
default=1.0,
help=\
"Scale heights by this amount." +\
" (default S=1.0)."
)
parser.add_option(
"-i", "--image-size",
dest="imageSize",
metavar="P",
type = "int",
default=1024,
help=\
"Size of the image will be PxP pixels." +\
" (default P=1024)."
)
return parser
__doc__ = \
"""
Defines functions for rendering displacement data as a 3D surface.
This module can be as a C{__main__} and has the following usage::
%s
""" % (" " + string.replace(getOptionParser().format_help(), "\n", "\n "))
if (__name__ == "__main__"):
parser = getOptionParser()
(options, args) = parser.parse_args(sys.argv[1:])
fileName = args[0]
surfaceRenderDisplacements(
fileName,
options.zComponent,
options.subsample,
options.scaleMultiplier,
[options.imageSize, options.imageSize]
)
|