def readFormatFile(filename): """ Read a format file and return a dictionary. The each line of the format file should be of the form: "variable name" @ file_id -> column_id, file_id -> column_id, ... It means that the "column_id"-th column(s) of file(s) with "file_id" corresponds to (components of) data with name "variable name". If no "->" is found, then all "file_id" are assumed to be 1. Those lines without "@" will be skipped. The return dictionary is of the format: {"variable name": [[file_id, column_id],...]} """ # global control_variables D = {} for aLine in open(filename): if "@" not in aLine: # skip those lines without "@": print( "vtk_converter::readFormatFile warning: no @ symbol found in the line:\n" + aLine + "\n and it will be skipped.\n") continue [name, column_mapping] = [x.strip() for x in aLine.split("@")] if name == "skip": # this is a control variable control_variables.to_skip = dict( [[int(y) for y in stringToNumbers(x, "->")] for x in column_mapping.split(",")]) else: D[name] = [[int(y) for y in stringToNumbers(x, "->")] for x in column_mapping.split(",")] return D
def convertToVtk(output_file, format_file, file_list, structured="auto"): """ Convert data given in the list "file_list" to "output_file". The name of "output_file" should contain a "%d" string for time slicing (t=0 if not included). Format of the files are defined in "format_file" (see readFormatFile function). The variable "x", "y", "z" are used to defined (unstructured) grids. The variable "t" is used to slice the data file: everytime its value changes, a new file "output_file % index" will be used for the output. """ file_list = FLL([file_list]) # to make it more user friendly: for single file there need no "[]" around it fmt = readFormatFile(format_file) # raw format D = fmtToMapping(fmt) # regulated format t_id = 0 # controls the time-slice of the output # open files fids = [open(x) for x in file_list] # skip lines for skip_fid in control_variables.to_skip.keys(): [ fids[skip_fid - 1].readline() for i in range(control_variables.to_skip[skip_fid]) ] # fid-1 b/c indices start from 0 firstline_flag = 1 [grid, scalars, vectors] = initialDataLists(D) # grid is the collection of grid points, it is of the form [[x,y,z],...], the missed variables will be set to 0. scalars and vectors are nested lists, they has the format scalars=[[[#,#,...],[#,#,...],...],vectors=[[[#,#,#],[#,#,#],...],...] aStringLine = [x.readline() for x in fids] aLine = [stringToNumbers(y, ",") for y in aStringLine] # read one line from all files, then convert to nested lists. For example, if the 1st file has 2 columns and the 2nd has 1, then aLine will be like [[#,#],[#]] while aStringLine[ 0] != "": # total number of read rows is determined by the number of rows of the first file if aLine[0] != []: # not a comment-only line new_time = D["t"](aLine) if firstline_flag: old_time = new_time # skip the 1st line firstline_flag = 0 # no longer the 1st line if new_time != old_time: # time step changed! dumpVtk(output_file % t_id, grid, scalars, vectors, D, structured) # output current slice old_time = new_time # update current time [grid, scalars, vectors] = initialDataLists(D) # clear buffer fillData(grid, scalars, vectors, D, aLine) # add newly read line t_id = t_id + 1 # advance to the next time step else: # time step kept; keep filling data fillData(grid, scalars, vectors, D, aLine) aStringLine = [x.readline() for x in fids] aLine = [stringToNumbers(y, ",") for y in aStringLine] # read one line from all files, then convert to nested lists. For example, if the 1st file has 2 columns and the 2nd has 1, then aLine will be like [[#,#],[#]] dumpVtk(output_file % t_id, grid, scalars, vectors, D, structured) # the final output print("Finished. Thanks for using vtk_converter. Zhi Qiu 2011")
def readFormatFile(filename): """ Read a format file and return a dictionary. The each line of the format file should be of the form: "variable name" @ file_id -> column_id, file_id -> column_id, ... It means that the "column_id"-th column(s) of file(s) with "file_id" corresponds to (components of) data with name "variable name". If no "->" is found, then all "file_id" are assumed to be 1. Those lines without "@" will be skipped. The return dictionary is of the format: {"variable name": [[file_id, column_id],...]} """ # global control_variables D = {}; for aLine in open(filename): if "@" not in aLine: # skip those lines without "@": print("vtk_converter::readFormatFile warning: no @ symbol found in the line:\n"+aLine+"\n and it will be skipped.\n"); continue; [name, column_mapping] = [x.strip() for x in aLine.split("@")]; if name=="skip": # this is a control variable control_variables.to_skip = dict([[int(y) for y in stringToNumbers(x,"->")] for x in column_mapping.split(",")]); else: D[name] = [[int(y) for y in stringToNumbers(x,"->")] for x in column_mapping.split(",")]; return D;
def convertToVtk(output_file, format_file, file_list, structured="auto"): """ Convert data given in the list "file_list" to "output_file". The name of "output_file" should contain a "%d" string for time slicing (t=0 if not included). Format of the files are defined in "format_file" (see readFormatFile function). The variable "x", "y", "z" are used to defined (unstructured) grids. The variable "t" is used to slice the data file: everytime its value changes, a new file "output_file % index" will be used for the output. """ file_list = FLL([file_list]); # to make it more user friendly: for single file there need no "[]" around it fmt = readFormatFile(format_file); # raw format D = fmtToMapping(fmt); # regulated format t_id = 0;# controls the time-slice of the output # open files fids = [open(x) for x in file_list]; # skip lines for skip_fid in control_variables.to_skip.keys(): [fids[skip_fid-1].readline() for i in range(control_variables.to_skip[skip_fid])] # fid-1 b/c indices start from 0 firstline_flag = 1; [grid, scalars, vectors] = initialDataLists(D); # grid is the collection of grid points, it is of the form [[x,y,z],...], the missed variables will be set to 0. scalars and vectors are nested lists, they has the format scalars=[[[#,#,...],[#,#,...],...],vectors=[[[#,#,#],[#,#,#],...],...] aStringLine = [x.readline() for x in fids]; aLine = [stringToNumbers(y,",") for y in aStringLine]; # read one line from all files, then convert to nested lists. For example, if the 1st file has 2 columns and the 2nd has 1, then aLine will be like [[#,#],[#]] while aStringLine[0]!="": # total number of read rows is determined by the number of rows of the first file if aLine[0]!=[]: # not a comment-only line new_time=D["t"](aLine); if firstline_flag: old_time=new_time; # skip the 1st line firstline_flag=0; # no longer the 1st line if new_time!=old_time: # time step changed! dumpVtk(output_file % t_id, grid, scalars, vectors, D, structured); # output current slice old_time = new_time; # update current time [grid, scalars, vectors] = initialDataLists(D); # clear buffer fillData(grid, scalars, vectors, D, aLine); # add newly read line t_id=t_id+1; # advance to the next time step else: # time step kept; keep filling data fillData(grid, scalars, vectors, D, aLine); aStringLine = [x.readline() for x in fids]; aLine = [stringToNumbers(y,",") for y in aStringLine]; # read one line from all files, then convert to nested lists. For example, if the 1st file has 2 columns and the 2nd has 1, then aLine will be like [[#,#],[#]] dumpVtk(output_file % t_id, grid, scalars, vectors, D, structured); # the final output print("Finished. Thanks for using vtk_converter. Zhi Qiu 2011");