File: DisplacementPlotter.py

package info (click to toggle)
esys-particle 2.1-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 7,284 kB
  • sloc: cpp: 77,304; python: 5,647; makefile: 1,176; sh: 10
file content (206 lines) | stat: -rwxr-xr-x 6,654 bytes parent folder | download
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]
    )