def omf2vtk(input_omf_file, output_vtk_file, output_format='ascii' ): """ Convert a given input_omf_file into a VTK file in ascii or binary format Magnetisation (direction and magnitude) values are stored as cell values """ data = MagnetisationData(input_omf_file) data.generate_field() data.generate_coordinates() grid = (np.linspace(data.xmin * 1e9, data.xmax * 1e9, data.nx + 1), np.linspace(data.ymin * 1e9, data.ymax * 1e9, data.ny + 1), np.linspace(data.zmin * 1e9, data.zmax * 1e9, data.nz + 1)) structure = pyvtk.RectilinearGrid(* grid) vtk_data = pyvtk.VtkData(structure, "") # Save the magnetisation vtk_data.cell_data.append(pyvtk.Vectors(np.column_stack((data.field_x, data.field_y, data.field_z)), "m")) # Save Ms as scalar field vtk_data.cell_data.append(pyvtk.Scalars(data.field_norm, "Ms")) # Save to VTK file with specified output filename vtk_data.tofile(output_vtk_file, output_format)
def numpy2vtkgrid_file(outfilename, xmin, xmax, ymin, ymax, numpy_matrix, zlevel=0.0, vtk_format='ascii', vtkfilecomment="Created with numpy2vtkgrid", vtkdatacomment="Scalar field"): assert len(numpy_matrix.shape) == 2,\ "data needs to be 2d, but shape is '%s'" % numpy_matrix.shape nx, ny = numpy_matrix.shape xpos = numpy.linspace(xmin, xmax, nx) ypos = numpy.linspace(ymin, ymax, ny) print "point set = %d*%d=%d" % (nx, ny, nx * ny) vtk = pyvtk.VtkData( pyvtk.RectilinearGrid(\ xpos.tolist(),ypos.tolist(),[zlevel] ), vtkfilecomment, pyvtk.PointData( pyvtk.Scalars( numpy_matrix.flatten().tolist(), vtkdatacomment ) ), format=vtk_format ) vtk.tofile(outfilename, format=vtk_format)
def test_vtk_writer_speed(): """ Comparison of C backend with the old pyvtk interface For this we use a 200 x 200 x 1 mesh and convert the OMF file into a VTK file using both the C library and the PyVTK library. We run the same conversion for each method during 20 times and print a mean. """ # C backend --------------------------------------------------------------- _file = glob.glob('./vtk_writer_omfs/isolated_sk_Cnv_n_200-Oxs*.omf')[0] data = op.MagnetisationData(_file) data.generate_field() data.generate_coordinates() output_vtk_file = 'vtk_writer_omfs/isolated_sk_Cnv_n_200.vtk' C_timings = [] for i in range(20): start = timeit.default_timer() ot.clib.WriteVTK_RectilinearGrid_C(data.grid[0], data.grid[1], data.grid[2], data.field.reshape(-1), data.field_norm, data.nx, data.ny, data.nz, output_vtk_file) end = timeit.default_timer() C_timings.append(end - start) print('C writer (best of 20): ', np.mean(np.array(C_timings))) # PyVTK ------------------------------------------------------------------- output_vtk_file = 'vtk_writer_omfs/isolated_sk_Cnv_n_200_pyvtk.vtk' pyvtk_timings = [] for i in range(20): start = timeit.default_timer() structure = pyvtk.RectilinearGrid(*data.grid) vtk_data = pyvtk.VtkData(structure, "") # Save the magnetisation vtk_data.cell_data.append(pyvtk.Vectors(data.field, "m")) # Save Ms as scalar field vtk_data.cell_data.append(pyvtk.Scalars(data.field_norm, "Ms")) # Save to VTK file with specified output filename vtk_data.tofile(output_vtk_file, 'binary') end = timeit.default_timer() pyvtk_timings.append(end - start) print('PyVTK writer (best of 20): ', np.mean(np.array(pyvtk_timings)))
def visitPrint(self, k): """ Uses PyVTK to write out data in a VisIt Visualization Tool capable format. """ import pyvtk uVel = pyvtk.Scalars(self.fluid.u().flatten(), name='u') vVel = pyvtk.Scalars(self.fluid.v().flatten(), name='v') totp = pyvtk.Scalars(self.fluid.p().flatten(), name='p') celldat = pyvtk.PointData(uVel, vVel, totp) grid = pyvtk.RectilinearGrid(self.domain.x, self.domain.y, self.domain.z) vtk = pyvtk.VtkData(grid, celldat) vtk.tofile('data%i' % k)
def savevtk(v, fn='', lons=[], lats=[], levels=[]): """save tracer field into vtk format, """ import pyvtk def norm(c): return (c - c[0]) / (c[-1] - c[0]) z = levels / abs(levels).max() * (lons.max() - lons.min()) * 0.7 point_data = pyvtk.PointData(pyvtk.Scalars(v.T.flatten())) vtk_object = pyvtk.VtkData(pyvtk.RectilinearGrid(x=lons, y=lats, z=z), point_data) vtk_object.tofile(fn) return
def _writevtk(self, filename): grid = [ pmini + np.linspace(0, li, ni + 1) for pmini, li, ni in zip(self.mesh.pmin, self.mesh.l, self.mesh.n) ] structure = pyvtk.RectilinearGrid(*grid) vtkdata = pyvtk.VtkData(structure) vectors = [self.__call__(i) for i in self.mesh.coordinates] vtkdata.cell_data.append(pyvtk.Vectors(vectors, self.name)) for i, component in enumerate(dfu.axesdict.keys()): name = "{}_{}".format(self.name, component) vtkdata.cell_data.append( pyvtk.Scalars(list(zip(*vectors))[i], name)) vtkdata.tofile(filename)
def __init__(self, mesh, header="", directory=".", filename="unnamed"): self.mesh = mesh self.directory = directory self.filename = filename if isinstance(mesh, HexagonalMesh): structure = pyvtk.PolyData(points=mesh.vertices, polygons=mesh.hexagons) elif isinstance(mesh, CuboidMesh): # for keyword argument dimensions: if the mesh is made up of # nx * ny * nz cells, it has (nx + 1) * (ny + 1) * (nz + 1) # vertices. structure = pyvtk.RectilinearGrid(*mesh.grid) else: raise NotImplementedError( "Mesh should be CuboidMesh or HexagonalMesh, is {}.".format( mesh.__class__.__name__)) self.structure = structure self.header = header self.init_VtkData(structure, header)
def ovf2vtk_main(): start_time = time.time() banner_doc = 70 * "-" + \ "\novf2vtk --- converting ovf files to vtk files" + "\n" + \ "Hans Fangohr, Richard Boardman, University of Southampton\n"""\ + 70 * "-" # extracts command line arguments # If any of the arguments given appear in the command line, a list of... # ...these args and corresponding values (if any) is returned -> ('args'). # Any arguments that dont dont match the given ones are retuned in a... # ...separate list -> ('params') # Note (fangohr 30/12/2006 20:52): the use of getopt is historic, args, params = getopt.getopt(sys.argv[1:], 'Vvhbta:', [ "verbose", "help", "add=", "binary", "text", "ascii", "surface-effects", "version", "datascale=", "posscale=" ]) # default value surfaceEffects = False datascale = 0.0 # 0.0 has special meaning -- see help text posscale = 0.0 # 0.0 has special meaning -- see help text # provide data from getopt.getopt (args) in form of dictionary options = {} for item in args: if item[1] == '': options[item[0]] = None else: options[item[0]] = item[1] keys = options.keys() # set system responses to arguments given if "--surface-effects" in keys: surfaceEffects = True if "--posscale" in keys: posscale = float(options["--posscale"]) if "--datascale" in keys: datascale = float(options["--datascale"]) if "-v" in keys or "--verbose" in keys: print("running in verbose mode") debug = True else: debug = False if "-h" in keys or "--help" in keys: print(__doc__) sys.exit(0) if "-V" in keys or "--version" in keys: print("This is version {:s}.".format(version)) sys.exit(0) if len(params) == 0: print(__doc__) print("ERROR: An input file (and an output file need to be " "specified).") sys.exit(1) else: infile = params[0] if len(params) == 1: print(__doc__) print("ERROR: An input file AND an output file need to be specified.") print("specify output file") sys.exit(1) else: outfile = params[1] # okay: it seems the essential parameters are given. # Let's check for others: print(banner_doc) if debug: print("infile = {}".format(infile)) print("outfile = {}".format(outfile)) print("args = {}".format(args)) print("options = {}".format(options)) print("datascale = {}".format(datascale)) print("posscale = {}".format(posscale)) # read data from infile vf = omf.read_structured_omf_file(infile, debug) # compute magnitude for all cells Ms = ana.magnitude(vf) # Compute number of cells with non-zero Ms (rpb01r) Ms_num_of_nonzeros = Numeric.sum(Numeric.not_equal(Ms, 0.0)) print("({:5.2f}% of {:d} cells filled)".format( 100.0 * Ms_num_of_nonzeros / len(Ms), len(Ms))) # scale magnetisation data as required: if datascale == 0.0: scale = max(Ms) print("Will scale data down by {:f}".format(scale)) else: scale = datascale # normalise vectorfield by scale vf = Numeric.divide(vf, scale) # read metadata in data file ovf_run = omf.analyze(infile) datatitle = ovf_run["Title:"] + "/{:g}".format(scale) # # need x, y and z vectors for vtk format # # taking actual spacings for dx, dy and dz results generally in # poor visualisation results (in particular for thin films, one # would like to have some magnification in z-direction). Also:vtk # is not happy with positions on the 10e-9 scale, so one better # scales this to something closer to unity. # extract dimensions from file dimensions = (int(ovf_run["xnodes:"]), int(ovf_run["ynodes:"]), int(ovf_run["znodes:"])) # scale data by given factor if posscale != 0.0: # find range between max and min values of components xrange = abs(float(ovf_run["xmax:"]) - float(ovf_run["xmin:"])) yrange = abs(float(ovf_run["ymax:"]) - float(ovf_run["ymin:"])) zrange = abs(float(ovf_run["zmax:"]) - float(ovf_run["zmin:"])) # define no. of x,y,z nodes xnodes = float(ovf_run["xnodes:"]) ynodes = float(ovf_run["ynodes:"]) znodes = float(ovf_run["znodes:"]) # define stepsizes xstepsize = float(ovf_run["xstepsize:"]) ystepsize = float(ovf_run["ystepsize:"]) zstepsize = float(ovf_run["zstepsize:"]) # define bases xbase = float(ovf_run["xbase:"]) ybase = float(ovf_run["ybase:"]) zbase = float(ovf_run["zbase:"]) # find dx, dy, dz in SI units: dx = xrange / xnodes dy = yrange / ynodes dz = zrange / znodes # find scale factor that OOMMF uses for xstepsize and xnodes, # etc. (Don't know how to get this directly.) xscale = dx * xstepsize yscale = dy * ystepsize zscale = dz * zstepsize # extract x, y and z positions from ovf file. xbasevector = [None] * dimensions[0] # create empty vector for i in range(dimensions[0]): # data is stored for 'centre' of each cuboid, therefore (i+0.5) xbasevector[i] = xbase + (i + 0.5) * xstepsize * xscale ybasevector = [None] * dimensions[1] for i in range(dimensions[1]): ybasevector[i] = ybase + (i + 0.5) * ystepsize * yscale zbasevector = [None] * dimensions[2] for i in range(dimensions[2]): zbasevector[i] = zbase + (i + 0.5) * zstepsize * zscale # finally, convert list to numeric (need to have this consistent) xbasevector = Numeric.array(xbasevector) / float(posscale) ybasevector = Numeric.array(ybasevector) / float(posscale) zbasevector = Numeric.array(zbasevector) / float(posscale) else: # posscale == 0.0 # this generally looks better: xbasevector = Numeric.arange(dimensions[0]) ybasevector = Numeric.arange(dimensions[1]) zbasevector = Numeric.arange(dimensions[2]) # # write ascii or binary vtk-file (default is binary) # vtk_data = 'binary' if '--ascii' in keys or '-t' in keys or '--text' in keys: vtk_data = 'ascii' if debug: print("switching to ascii vtk-data") if '--binary' in keys or '-b' in keys: vtk_data = 'binary' if debug: print("switching to binary vtk-data") # # and now open vtk-file # vtkfilecomment = "Output from ovf2vtk (version {:s}), {:s}, infile={:s}. "\ .format(version, time.asctime(), infile) vtkfilecomment += "Calling command line was '{:s}' executed in '{:s}'"\ .format(" ".join(sys.argv), os.getcwd()) # define inputs RecGrid = pyvtk.RectilinearGrid(xbasevector.tolist(), ybasevector.tolist(), zbasevector.tolist()) PData = pyvtk.PointData(pyvtk.Vectors(vf.tolist(), datatitle)) # define vtk file. vtk = pyvtk.VtkData(RecGrid, vtkfilecomment, PData, format=vtk_data) # now compute all the additional data such as angles, etc # check whether we should do all keys = map(lambda x: x[1], args) if "all" in keys: args = [] for add_arg in add_features: args.append(("--add", add_arg)) # when ovf2vtk was re-written using Numeric, I had to group # certain operations to make them fast. Now some switches are # unneccessary. (fangohr 25/08/2003 01:35) # To avoid executing the # same code again, we remember what we have computed already: done_angles = 0 done_comp = 0 for arg in args: if arg[0] == "-a" or arg[0] == "--add": print("working on {}".format(arg)) data = [] lookup_table = 'default' # compute observables that need more than one field value # i.e. div, rot if arg[1][0:6] == "divrot": # rotation = vorticity, curl (div, rot, rotx, roty, rotz, rotmag) = \ ana.divergence_and_curl(vf, surfaceEffects, ovf_run) # change order of observables for upcoming loop observables = (rotx, roty, rotz, rotmag, rot, div) comments = [ "curl, x-comp", "curl, y-comp", "curl, z-comp", "curl, magnitude", "curl", "divergence" ] # append data to vtk file for obs, comment in zip(observables, comments): # for rotx, roty, rotz, rotmag, div if comment != "curl": vtk.point_data.append( pyvtk.Scalars(obs.tolist(), comment, lookup_table)) # for rot else: vtk.point_data.append( pyvtk.Vectors(obs.tolist(), comment)) # components elif arg[1] in ["Mx", "My", "Mz", "Ms"]: if done_comp == 0: done_comp = 1 comments = "x-component", "y-component", "z-component" for data, comment in zip(ana.components(vf), comments): vtk.point_data.append( pyvtk.Scalars(data.tolist(), comment, lookup_table)) # magnitude of magnitisation Mmag = ana.magnitude(vf) vtk.point_data.append( pyvtk.Scalars(Mmag.tolist(), "Magnitude", lookup_table)) elif arg[1] in ["xy", "xz", "yz"]: if done_angles == 0: done_angles = 1 # in-plane angles comments = ("xy in-plane angle", "yz in-plane angle", "xz in-plane angle") for data, comment in zip(ana.plane_angles(vf), comments): vtk.point_data.append( pyvtk.Scalars(data.tolist(), comment, lookup_table)) else: print("only xy, xz, Mx, My, Mz, divergence, Ms, or 'all' \ allowed after -a or --add") print("Current choice is {}".format(arg)) print(__doc__) sys.exit(1) # # eventually, write the file # print("saving file ({:s})".format(outfile)) vtk.tofile(outfile, format=vtk_data) print("finished conversion (execution time {:5.3s} seconds)".format( str(time.time() - start_time)))
def ovf2vtk_main(): start_time = time.time() banner_doc = 70*"-"+\ "\novf2vtk --- converting ovf files to vtk files"+"\n"+\ "Hans Fangohr, Richard Boardman, University of Southampton\n"""+70*"-" #extract command line arguments additions,params = getopt.getopt( sys.argv[1:], 'Vvhbta:', ["verbose","help","add=","binary","text","ascii","surface-effects","version","datascale=","posscale="] ) #Note (fangohr 30/12/2006 20:52): the use of getopt is historic, #and so is the use of the name 'additions'. #default value surfaceEffects = False datascale = 0.0 #0.0 has special meaning -- see help text posscale = 0.0 #0.0 has special meaning -- see help text #provide data from getopt.getopt (additions) in form of hash table options = {} for item in additions: if item[1]=='': options[item[0]] = None else: options[item[0]] = item[1] keys = options.keys() if "--surface-effects" in keys: surfaceEffects = True if "--posscale" in keys: posscale = float(options["--posscale"]) if "--datascale" in keys: datascale = float(options["--datascale"]) if "-v" in keys or "--verbose" in keys: print "running in verbose mode" debug = True else: debug = False if "-h" in keys or "--help" in keys: print __doc__ sys.exit(0) if "-V" in keys or "--version" in keys: print "This is version %s." % ovf2vtk.__version__ sys.exit(0) if len( params ) == 0: print __doc__ print "ERROR: An input file (and an output file need to be specified)." sys.exit(1) else: infile = params[0] if len( params ) == 1: print __doc__ print "ERROR: An input file AND an output file need to be specified." print "specify output file" sys.exit(1) else: outfile = params[1] # okay: it seems the essential parameters are given. Let's check for others: print banner_doc if debug: print "infile = ", infile print "outfile = ",outfile print "additions= ",additions print "options = ",options print "datascale=",datascale print "posscale=",posscale #read data from infile vf = read_structured_omf_file( infile, debug ) #compute magnitude for all cells Ms = magnitude( vf ) # Compute number of cells with non-zero Ms (rpb01r) Ms_num_of_nonzeros = Numeric.sum( Numeric.not_equal( Ms, 0.0 ) ) print "(%5.2f%% of %d cells filled)" % (100.0*Ms_num_of_nonzeros/len(Ms), len(Ms)) #read metadata in data file ovf_run = analyze( infile ) #scale magnetisation data as required: if datascale == 0.0: scale = max( Ms ) print "Will scale data down by %f" % scale else: scale = datascale vf = Numeric.divide( vf, scale ) datatitle = ovf_run["Title:"]+"/%g" % (scale) # #need x, y and z vectors for vtk format # #taking actual spacings for dx, dy and dz results generally in #poor visualisation results (in particular for thin films, one #would like to have some magnification in z-direction). Also:vtk #is not happy with positions on the 10e-9 scale, so one better #scales this to something closer to unity. #extract dimensions from file dimensions = ( int( ovf_run["xnodes:"] ), \ int( ovf_run["ynodes:"] ), \ int( ovf_run["znodes:"] )) if posscale != 0.0: #scale data by given factor #find dx, dy, dz in SI units: Lx = abs(float(ovf_run["xmax:"])-float(ovf_run["xmin:"])) Ly = abs(float(ovf_run["ymax:"])-float(ovf_run["ymin:"])) Lz = abs(float(ovf_run["zmax:"])-float(ovf_run["zmin:"])) dx = Lx / float( ovf_run["xnodes:"] ) dy = Ly / float( ovf_run["ynodes:"] ) dz = Lz / float( ovf_run["znodes:"] ) #find scale factor that OOMMF uses for xstepsize and xnodes, #etc. (Don't know how to get this directly.) xscale = Lx / (float( ovf_run["xnodes:"])*float(ovf_run["xstepsize:"])) yscale = Ly / (float( ovf_run["ynodes:"])*float(ovf_run["ystepsize:"])) zscale = Lz / (float( ovf_run["znodes:"])*float(ovf_run["zstepsize:"])) #extract x, y and z positions from ovf file. xbasevector = [None] * dimensions[0] #create empty vector for i in range( dimensions[0] ): #data is stored for 'centre' of each cuboid, therefore (i+0.5) xbasevector[i] = float( ovf_run["xbase:"] ) +\ (i+0.5) *float( ovf_run["xstepsize:"] )*xscale ybasevector = [None]* dimensions[1] for i in range( dimensions[1] ): ybasevector[i] = float( ovf_run["ybase:"] ) + (i+0.5) *float( ovf_run["ystepsize:"] )*yscale zbasevector = [None]* dimensions[2] for i in range( dimensions[2] ): zbasevector[i] = float( ovf_run["zbase:"] ) + (i+0.5) *float( ovf_run["zstepsize:"] )*zscale #finally, convert list to numerix (need to have this consistent) xbasevector = Numeric.array(xbasevector)/float(posscale) ybasevector = Numeric.array(ybasevector)/float(posscale) zbasevector = Numeric.array(zbasevector)/float(posscale) else: #posscale == 0.0 # #this generally looks better: # xbasevector = Numeric.arange( dimensions[0] ) ybasevector = Numeric.arange( dimensions[1] ) zbasevector = Numeric.arange( dimensions[2] ) # # write ascii or binary vtk-file (default is binary) # vtk_data = 'binary' if '--ascii' in keys or '-t' in keys or '--text' in keys: vtk_data = 'ascii' if debug: print "switching to ascii vtk-data" if '--binary' in keys or '-b' in keys: vtk_data = 'binary' if debug: print "switching to binary vtk-data" # #and now open vtk-file # vtkfilecomment = "Output from ovf2vtk (version %s), %s, infile=%s. " % (ovf2vtk.__version__,\ time.asctime(),\ infile) vtkfilecomment += "Calling command line was '%s' executed in '%s'" % (" ".join(sys.argv),\ os.getcwd()) vtk = pyvtk.VtkData( pyvtk.RectilinearGrid(xbasevector.tolist(),ybasevector.tolist(),zbasevector.tolist()), vtkfilecomment, pyvtk.PointData(pyvtk.Vectors( vf.tolist(), datatitle ) ), format=vtk_data) # # now compute all the additional data such as angles, etc # # check whether we should do all keys = map(lambda x:x[1], additions) if "all" in keys: additions = [] for add in add_features: additions.append(("--add",add)) # when ovf2vtk was re-written using Numeric, I had to group # certain operations to make them fast. Now some switches are # unneccessary. (fangohr 25/08/2003 01:35) # To avoid executing the # same code again, we remember what we have computed already: done_angles = 0 done_comp = 0 for add in additions: if add[0]=="-a" or add[0]=="--add": print "working on",add data=[] #compute observables that need more than one field value, i.e. div, rot if add[1][0:6] == "divrot": #rotation = vorticity, curl (div, rot, rotx, roty, rotz, rotmag) = divergence_and_curl( vf, surfaceEffects, ovf_run ) comment = "curl, x-comp" vtk.point_data.append( pyvtk.Scalars( rotx.tolist() , comment , lookup_table='default') ) Comment = "curl, y-comp" vtk.point_data.append( pyvtk.Scalars( roty.tolist() , comment , lookup_table='default') ) comment = "curl, z-comp" vtk.point_data.append( pyvtk.Scalars( rotz.tolist() , comment , lookup_table='default') ) comment = "curl, magnitude" vtk.point_data.append( pyvtk.Scalars( rotmag.tolist(), comment , lookup_table='default') ) comment = "curl" vtk.point_data.append( pyvtk.Vectors( rot.tolist() , comment ) ) comment = "divergence" vtk.point_data.append( pyvtk.Scalars( div.tolist() , comment , lookup_table='default') ) done_div_rot = True elif add[1] in ["Mx","My","Mz","Ms"]: # components if not done_comp: done_comp = 1 comments = "x-component", "y-component", "z-component" for data, comment in zip( components( vf ), comments): vtk.point_data.append( pyvtk.Scalars( data.tolist(), comment,lookup_table='default' ) ) # magnitude of magnitisation Mmag = magnitude( vf ) vtk.point_data.append( pyvtk.Scalars(Mmag.tolist(), "Magnitude",lookup_table='default' ) ) elif add[1] in ["xy","xz","yz"]: if not done_angles: done_angles = 1 # in-plane angles comments = "xy in-plane angle", "yz in-plane angle", "xz in-plane angle" for data, comment in zip( plane_angles( vf ), comments): vtk.point_data.append( pyvtk.Scalars( data.tolist(), comment, lookup_table='default' ) ) else: print "only xy, xz, Mx, My, Mz, divergence, Ms, or 'all' allowed after -a or --add" print "Current choice is",add print __doc__ sys.exit(1) # #eventually, write the file # print "saving file (%s)" % (outfile) vtk.tofile(outfile,format=vtk_data) print "finished conversion (execution time %5.3s seconds)" % (time.time()-start_time)