Revision 4eaf0dce8350a336dd310a788f96f236db7f0d7f authored by Eh Tan on 08 September 2008, 19:18:16 UTC, committed by Eh Tan on 08 September 2008, 19:18:16 UTC
1 parent b20f4d7
Citcoms_Hdf2Vtk.py
#!/usr/bin/env python
# Script to generate TVTK files from CitcomS hdf files
# author: Martin Weier
# Copyright (C) 2006 California Institue of Technology
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#import scipy
import sys
from datetime import datetime
from getopt import getopt, GetoptError
from pprint import *
from math import *
import tables #For HDF support
import numpy
import pyvtk
import sys
# defaults
path = "./example0.h5"
vtk_path = "./vtk_output"
vtkfile = "%s.%d.vtk"
initial = 0
timesteps= None
create_topo = False
create_bottom = False
create_surface = False
create_ascii = False
nx = None
ny = None
nz = None
nx_redu=None
ny_redu=None
nz_redu=None
el_nx_redu = None
el_ny_redu = None
el_nz_redu = None
radius_inner = None
radius_outer = None
nproc_surf = None
#Filehandler to the HDF file
f = None
#####################
polygons3d = [] # arrays containing connectivity information
polygons2d = []
counter=0 #Counts iterations of citcom2vtk
def print_help():
print "Program to convert CitcomS HDF to Vtk files.\n"
print "-p, --path [path to hdf] \n\t Specify input file."
print "-o, --output [output filename] \n\t Specify the path to the folder for output files."
print ("-i, --initial [initial timestep] \n\t Specify initial timestep to export. If not \n \
\t specified script starts exporting from timestep 0.")
print "-t, --timestep [max timestep] \n\t Specify to which timestep you want to export. If not\n \
\t specified export all all timestep starting from intial timestep."
print "-x, --nx_reduce [nx] \n\t Set new nx to reduce output grid."
print "-y, --ny_reduce [ny] \n\t Set new ny to reduce output grid."
print "-z, --nz_reduce [nz] \n\t Set new nz to reduce output grid."
print "-b, --bottom \n\t Set to export Bottom information to Vtk file."
print "-s, --surface \n\t Set to export Surface information to Vtk file."
print "-c, --createtopo \n\t Set to create topography information in bottom and surface Vtk file."
print "-a, --ascii \n\t Create Vtk ASCII encoded files instead if binary."
print "-h, --help, -? \n\t Print this help."
#Iterator for CitcomDataRepresentation(yxz) to VTK(xyz)
def vtk_iter(nx,ny,nz):
for i in xrange(nx):
for j in xrange(ny):
for k in xrange(nz):
yield k + i * nz + j * nz * nx
#Reduces the CitcomS grid
def reduce_iter(n,nredu):
i=0
n_f=float(n)
nredu_f=float(nredu)
fl=(n_f-1)/nredu_f
redu = 0
for i in xrange(nredu+1):
yield int(round(redu))
redu = redu + fl
#Transform Vectors in Spherical to Cartesian Coordinates 2d
#def velocity2cart2d(vel_colat, vel_lon,x , y):
# x1 = vel_colat*cos(x)*cos(y)-vel_lon*sin(y)
# y1 = vel_colat*cos(x)*sin(y)+vel_lon*cos(y)
# z1 = -vel_colat*sin(x)
# return x1,y1,z1
#Converts Spherical to Carthesian Coordinates 2d
#def RTF2XYZ2d(vel_colat, vel_lon):
# x1 = sin(vel_colat)*cos(vel_lon)
# y1 = sin(vel_colat)*sin(vel_lon)
# z1 = cos(vel_colat)
# return x1,y1,z1
#Transform Vectors in Spherical to Cartesian Coordinates
def velocity2cart(vel_colat,vel_long,r, x, y, z):
x1 = r*sin(x)*cos(y)+vel_colat*cos(x)*cos(y)-vel_long*sin(y)
y1 = r*sin(x)*sin(y)+vel_colat*cos(x)*sin(y)+vel_long*cos(y)
z1 = r*cos(x)-vel_colat*sin(x)
return x1, y1, z1
#Converts Spherical to Cartesian Coordinates
def RTF2XYZ(thet, phi, r):
x = r * sin(thet) * cos(phi)
y = r * sin(thet) * sin(phi)
z = r * cos(thet)
return x, y, z
#Reads Citcom Files and creates a VTK File
def citcom2vtk(t):
print "Timestep:",t
benchmarkstr = ""
#Assign create_bottom and create_surface to bottom and surface
#to make them valid in methods namespace
bottom = create_bottom
surface = create_surface
ordered_points = [] #reset Sequences for points
ordered_temperature = []
ordered_velocity = []
ordered_visc = []
#Surface and Bottom Points
#Initialize empty sequences
surf_vec = []
botm_vec = []
surf_topo = []
surf_hflux = []
botm_topo = []
botm_hflux = []
surf_points = []
botm_points = []
for capnr in xrange(nproc_surf):
###Benchmark Point 1 Start##
#start = datetime.now()
############################
print "Processing cap",capnr+1,"of",nproc_surf
cap = f.root._f_getChild("cap%02d" % capnr)
#Information from hdf
#This information needs to be read only once
hdf_coords = cap.coord[:]
hdf_velocity = cap.velocity[t]
hdf_temperature = cap.temperature[t]
hdf_viscosity = cap.viscosity[t]
###Benchmark Point 1 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf," % (delta.seconds + float(delta.microseconds)/1e6)
###Benchmark Point 2 Start##
#start = datetime.now()
############################
#Create Iterator to change data representation
nx_redu_iter = reduce_iter(nx,nx_redu)
ny_redu_iter = reduce_iter(ny,ny_redu)
nz_redu_iter = reduce_iter(nz,nz_redu)
#vtk_i = vtk_iter(el_nx_redu,el_ny_redu,el_nz_redu)
# read citcom data - zxy (z fastest)
for j in xrange(el_ny_redu):
j_redu = ny_redu_iter.next()
nx_redu_iter = reduce_iter(nx,nx_redu)
for i in xrange(el_nx_redu):
i_redu = nx_redu_iter.next()
nz_redu_iter = reduce_iter(nz,nz_redu)
for k in xrange(el_nz_redu):
k_redu = nz_redu_iter.next()
colat, lon, r = map(float,hdf_coords[i_redu,j_redu,k_redu])
x_coord, y_coord, z_coord = RTF2XYZ(colat,lon,r)
ordered_points.append((x_coord,y_coord,z_coord))
ordered_temperature.append(float(hdf_temperature[i_redu,j_redu,k_redu]))
ordered_visc.append(float(hdf_viscosity[i_redu,j_redu,k_redu]))
vel_colat, vel_lon , vel_r = map(float,hdf_velocity[i_redu,j_redu,k_redu])
x_velo, y_velo, z_velo = velocity2cart(vel_colat,vel_lon,vel_r, colat,lon , r)
ordered_velocity.append((x_velo,y_velo,z_velo))
##Delete Objects for GC
del hdf_coords
del hdf_velocity
del hdf_temperature
del hdf_viscosity
###Benchmark Point 2 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf," % (delta.seconds + float(delta.microseconds)/1e6)
###Benchmark Point 3 Start##
#start = datetime.now()
############################
#Bottom Information from hdf
if bottom == True:
try:
hdf_bottom_coord = cap.botm.coord[:]
hdf_bottom_heatflux = cap.botm.heatflux[t]
hdf_bottom_topography = cap.botm.topography[t]
hdf_bottom_velocity = cap.botm.velocity[t]
except:
print "\tCould not find bottom information in file.\n \
Set create bottom to false"
bottom = False
#Surface Information from hdf
if surface==True:
try:
hdf_surface_coord = cap.surf.coord[:]
hdf_surface_heatflux = cap.surf.heatflux[t]
hdf_surface_topography = cap.surf.topography[t]
hdf_surface_velocity = cap.surf.velocity[t]
except:
print "\tCould not find surface information in file.\n \
Set create surface to false"
surface = False
###Benchmark Point 3 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf," % (delta.seconds + float(delta.microseconds)/1e6)
###Benchmark Point 4 Start##
#start = datetime.now()
############################
#Compute surface/bottom topography mean
if create_topo:
surf_mean=0.0
botm_mean=0.0
if surface:
for i in xrange(nx):
surf_mean += numpy.mean(hdf_surface_topography[i])
surf_mean = surf_mean/ny
if bottom:
for i in xrange(nx):
botm_mean += numpy.mean(hdf_bottom_topography[i])
botm_mean = botm_mean/nx
###Benchmark Point 4 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf," % (delta.seconds + float(delta.microseconds)/1e6)
###Benchmark Point 5 Start##
#start = datetime.now()
############################
#Read Surface and Bottom Data
if bottom==True or surface == True:
for i in xrange(nx):
for j in xrange(ny):
if bottom==True:
#Bottom Coordinates
if create_topo==True:
colat, lon = hdf_bottom_coord[i,j]
x,y,z = RTF2XYZ(colat,lon,radius_inner+float( (hdf_bottom_topography[i,j]-botm_mean)*(10**21)/(6371000**2/10**(-6))/(3300*10)/1000 ))
botm_points.append((x,y,z))
else:
colat, lon = hdf_bottom_coord[i,j]
x,y,z = RTF2XYZ(colat, lon,radius_inner)
botm_points.append((x,y,z))
#Bottom Heatflux
botm_hflux.append(float(hdf_bottom_heatflux[i,j]))
#Bottom Velocity
vel_colat, vel_lon = map(float,hdf_bottom_velocity[i,j])
x,y,z = velocity2cart(vel_colat,vel_lon, radius_inner, colat, lon, radius_inner)
botm_vec.append((x,y,z))
if surface==True:
#Surface Information
if create_topo==True:
colat,lon = hdf_surface_coord[i,j]
#637100 = Earth radius, 33000 = ?
x,y,z = RTF2XYZ(colat,lon,radius_outer+float( (hdf_surface_topography[i,j]-surf_mean)*(10**21)/(6371000**2/10**(-6))/(3300*10)/1000 ))
surf_points.append((x,y,z))
else:
colat, lon = hdf_surface_coord[i,j]
x,y,z = RTF2XYZ(colat, lon,radius_outer)
surf_points.append((x,y,z))
#Surface Heatflux
surf_hflux.append(float(hdf_surface_heatflux[i,j]))
#Surface Velocity
vel_colat, vel_lon = map(float,hdf_surface_velocity[i,j])
x,y,z = velocity2cart(vel_colat,vel_lon, radius_outer, colat, lon, radius_outer)
surf_vec.append((x,y,z))
#del variables for GC
if bottom==True:
del hdf_bottom_coord
del hdf_bottom_heatflux
del hdf_bottom_velocity
if surface==True:
del hdf_surface_coord
del hdf_surface_heatflux
del hdf_surface_velocity
###Benchmark Point 5 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf," % (delta.seconds + float(delta.microseconds)/1e6)
###Benchmark Point 6 Start##
#start = datetime.now()
############################
##################################################################
#Create Connectivity info
if counter==0:
#For 3d Data
i=1 #Counts X Direction
j=1 #Counts Y Direction
k=1 #Counts Z Direction
for n in xrange((el_nx_redu*el_ny_redu*el_nz_redu)-(el_nz_redu*el_nx_redu)):
if (i%el_nz_redu)==0: #X-Values!!!
j+=1 #Count Y-Values
if (j%el_nx_redu)==0:
k+=1 #Count Z-Values
if i%el_nz_redu!=0 and j%el_nx_redu!=0: #Check if Box can be created
#Get Vertnumbers
n0 = n+(capnr*(el_nx_redu*el_ny_redu*el_nz_redu))
n1 = n0+el_nz_redu
n2 = n1+el_nz_redu*el_nx_redu
n3 = n0+el_nz_redu*el_nx_redu
n4 = n0+1
n5 = n4+el_nz_redu
n6 = n5+el_nz_redu*el_nx_redu
n7 = n4+el_nz_redu*el_nx_redu
#Created Polygon Box
polygons3d.append([n0,n1,n2,n3,n4,n5,n6,n7]) #Hexahedron VTK Representation
i+=1
if bottom==True or surface==True:
#Connectivity for 2d-Data
i=1
for n in xrange((nx)*(ny) - ny):
if i%ny!=0 :
n0 = n+(capnr*((nx)*(ny)))
n1 = n0+1
n2 = n0+ny
n3 = n2+1
polygons2d.append([n0,n1,n2,n3])
i+=1
###Benchmark Point 6 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf\n" % (delta.seconds + float(delta.microseconds)/1e6)
#print benchmarkstr
#################################################################
#Write Data to VTK
#benchmarkstr = "\n\nIO:\n"
###Benchmark Point 7 Start##
#start = datetime.now()
############################
print 'Writing data to vtk...'
#Surface Points
if surface==True:
struct_coords = pyvtk.UnstructuredGrid(surf_points, pixel=polygons2d)
#topo_scal = pyvtk.Scalars(surf_topo,'Surface Topography', lookup_table='default')
hflux_scal = pyvtk.Scalars(surf_hflux,'Surface Heatflux',lookup_table='default')
vel_vec = pyvtk.Vectors(surf_vec,'Surface Velocity Vectors')
##
tempdata = pyvtk.PointData(hflux_scal,vel_vec)
data = pyvtk.VtkData(struct_coords, tempdata,'CitcomS Output %s Timestep %s' % ('surface info',t))
if create_ascii:
data.tofile(vtk_path + (vtkfile % ('surface',t)),)
else:
data.tofile(vtk_path + (vtkfile % ('surface',t)),'binary')
print "Written Surface information to file"
###Benchmark Point 7 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf," % (delta.seconds + float(delta.microseconds)/1e6)
###Benchmark Point 8 Start##
#start = datetime.now()
############################
if bottom==True:
#Bottom Points
struct_coords = pyvtk.UnstructuredGrid(botm_points, pixel=polygons2d)
#topo_scal = pyvtk.Scalars(botm_topo,'Bottom Topography','default')
hflux_scal = pyvtk.Scalars(botm_hflux,'Bottom Heatflux','default')
vel_vec = pyvtk.Vectors(botm_vec,'Bottom Velocity Vectors')
##
tempdata = pyvtk.PointData(hflux_scal,vel_vec)
data = pyvtk.VtkData(struct_coords, tempdata, 'CitcomS Output %s Timestep %s' % ('Bottom info',t))
if create_ascii:
data.tofile(vtk_path + (vtkfile % ('bottom',t)))
else:
data.tofile(vtk_path + (vtkfile % ('bottom',t)),'binary')
print "Written Bottom information to file"
###Benchmark Point 8 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf," % (delta.seconds + float(delta.microseconds)/1e6)
###Benchmark Point 9 Start##
#start = datetime.now()
#General Data
struct_coords = pyvtk.UnstructuredGrid(ordered_points,hexahedron=polygons3d)
vel_vec = pyvtk.Vectors(ordered_velocity, 'Velocity Vectors')
temp_scal = pyvtk.Scalars(ordered_temperature,'Temperature Scalars','default')
visc_scal = pyvtk.Scalars(ordered_visc,'Viscosity Scalars','default')
##
tempdata = pyvtk.PointData(temp_scal,visc_scal,vel_vec)
data = pyvtk.VtkData(struct_coords, tempdata, 'CitcomS Output %s Timestep:%d NX:%d NY:%d NZ:%d Radius_Inner:%f' % (path,t,el_nx_redu,el_ny_redu,el_nz_redu,radius_inner))
############################
if create_ascii:
data.tofile(vtk_path + (vtkfile % ('general',t)))
else:
data.tofile(vtk_path + (vtkfile % ('general',t)),'binary')
print "Written general data to file"
###Benchmark Point 9 Stop##
#delta = datetime.now() - start
#benchmarkstr += "%.5lf\n" % (delta.seconds + float(delta.microseconds)/1e6)
#print benchmarkstr
#print "\n"
# parse command line parameters
def initialize():
global path
global vtk_path
global initial
global timesteps
global create_topo
global create_bottom
global create_surface
global create_ascii
global nx
global ny
global nz
global nx_redu
global ny_redu
global nz_redu
global el_nx_redu
global el_ny_redu
global el_nz_redu
global radius_inner
global radius_outer
global nproc_surf
global f
try:
opts, args = getopt(sys.argv[1:], "p:o:i:t:x:y:z:bscah?", ['path=','output=','timestep=','x=','y=','z=','bottom','surface','createtopo','ascii', 'help','?'])
except GetoptError, msg:
print "Error: %s" % msg
sys.exit(1)
if len(opts)<=1:
print_help()
sys.exit(0)
for opt,arg in opts:
if opt in ('-p','--path'):
path = arg
if opt in ('-o','--output'):
vtk_path = arg
if opt in ('-i','--initial'):
try:
initial = int(arg)
except ValueError:
print "Initial is not a number."
sys.exit(1)
if opt in ('-t','--timestep'):
try:
timesteps = int(arg)
except ValueError:
print "Timestep is not a number."
sys.exit(1)
if opt in ('-x','--nx_reduce'):
try:
nx_redu = int(arg)
except ValueError:
print "NX is not a number."
if opt in ('-y','--ny_reduce'):
try:
ny_redu = int(arg)
except ValueError:
print "NY is not a number."
if opt in ('-z','--nz_reduce'):
try:
nz_redu = int(arg)
except ValueError:
print "NZ is not a number."
if opt in ('-b','--bottom'):
create_bottom = True
if opt in ('-s','--surface'):
create_surface = True
if opt in ('-c','--createtopo'):
create_topo = True
if opt in ('-a','--ascii'):
create_ascii = True
if opt in ('-h','--help'):
print_help()
sys.exit(0)
if opt == '-?':
print_help()
sys.exit(0)
f = tables.openFile(path,'r')
nx = int(f.root.input._v_attrs.nodex)
ny = int(f.root.input._v_attrs.nodey)
nz = int(f.root.input._v_attrs.nodez)
#If not defined as argument read from hdf
hdf_timesteps = int(f.root.time.nrows)
if timesteps==None or timesteps>hdf_timesteps:
timesteps = hdf_timesteps
if nx_redu==None:
nx_redu = nx-1
if ny_redu==None:
ny_redu = ny-1
if nz_redu==None:
nz_redu = nz-1
if nx_redu>=nx:
nx_redu=nx-1
if ny_redu>=ny:
ny_redu=ny-1
if nz_redu>=nz:
nz_redu=nz-1
el_nx_redu = nx_redu+1
el_ny_redu = ny_redu+1
el_nz_redu = nz_redu+1
radius_inner = float(f.root.input._v_attrs.radius_inner)
radius_outer = float(f.root.input._v_attrs.radius_outer)
nproc_surf = int(f.root.input._v_attrs.nproc_surf)
###############################################################################
def citcoms_hdf2vtk():
global counter
#Call initialize to get and set input params
initialize()
d1 = datetime.now()
print "Converting Hdf to Vtk"
print "Initial:",initial, "Timesteps:",timesteps
print "NX:",el_nx_redu, "NY:",el_ny_redu, "NZ:", el_nz_redu
print "Create Bottom: ",create_bottom, " Create Surface: ", create_surface
print "Create Topography: ", create_topo
for t in xrange(initial,timesteps):
start = datetime.now()
citcom2vtk(t)
counter+=1
delta = datetime.now() - start
print "\t%.3lf sec" % (delta.seconds + float(delta.microseconds)/1e6)
d2 = datetime.now()
f.close()
print "Total: %d seconds" % (d2 - d1).seconds
###############################################################################
if __name__ == '__main__':
citcoms_hdf2vtk()

Computing file changes ...