Compose-3015: Read Data from Text Files
This tutorial demonstrates how to extract nodal positions from the LS-DYNA input file, truck.key. This file can be found in <install>/tutorials/.
OML contains a set of commands that operate on string data types. You can use a combination of the string tools and file reading commands to read data from arbitrary text files.
Define the Target Variables
- Start Compose.
-
In a new script, type the following commands, adjusting the file path to the
appropriate location of the file. The vector nodeListcontains
the node ID’s at which to read the x, y, z coordinates. The list is then sorted
numerically in ascending order. The matrix
nodesInfo
is initialized to the appropriate size to contain all the requested data.fileName=‘<INSERT_PATH>/truck.key’; nodeList = [1, 211, 57, 5]; nodeList = sort(nodeList); nodeInfo = zeros(length(nodeList),3);
Create the General Structure to Read the File
The following code segment opens a file for reading, reads through the file one
line at a time until the end of the file, and then closes the file. The body
within the while loop, which currently contains only the
instruction to read the next line of the file, contains the set of commands to
be performed upon each line. The commands to be added are presented in the
following steps, but the code segment provided here is general enough to read
any file. Add these lines to your script, run the file, and check for the
displayed message, indicating a successful completion.
[fid, message] = fopen(fileName, 'r');
line = fgetl(fid);
while ~feof(fid)
line = fgetl(fid);
end
disp('Finished reading the file')
Add Control Structures to Parse Data Lines
-
The input file structure contains nodal data in a so-called block format.
Blocks of data are indicated by a specific keyword (beginning with the character
‘*’
in LS-DYNA), and the data follows on subsequent lines until another keyword is encountered. Nodal data begins with the keyword *NODE. Within the nodal data block, each line contains the information for a given node: the first eight characters within the line contain the node ID, and next three 16-character groups contain the x-y-z coordinates, respectively. The first logical control to add is to determine if the reader is currently within a *NODE block. For this purpose, a Boolean variable, nodeOn, is created to contain the test of whether the most recently read keyword is *NODE. First, define the variable with a default value of false. Before the while control block, type the command:nodeOn = false;
-
Within the while block and before the read command, add
controls to test the status of this Boolean variable. The value of
nodeOn begins
false
. The status is changed totrue
when the current line contains the text *NODE. See the topic strfind in the Reference Guide for more details on the string find command. For this example, however, it is sufficient to note that the command returns an empty value if the search is unsuccessful.if nodeOn == true %process node data line else search = strfind(line,'*NODE') if ~isempty(search) nodeOn = true; end end
Process and Store the Requested Nodal Data
-
When processing data lines that are within the
node
block, there are three possible cases that must be handled: (1) skip comment lines which are indicated by‘$’
, (2) identify the end of the block if the data on the line is a keyword to indicate the start of a new block, and (3) process a line of node data. Note that case (3) is required when (1) and (2) are false. The following code segment placed within thenodeOn == true
block properly handles the three cases above.search=strfind(line,’$’); if ~isempty(search) line = fgetl(fid); continue; end search = strfind(line,'*'); if ~isempty(search) nodeOn = false; else %proper node line End
-
When processing a node line, the first step is to determine the ID. This
information is contained in the first eight characters of the line, which can be
extracted using the loop command. Note that this command
returns a string, and you need to use the str2num function to
force the data type to a number. This ID can then be tested against the
requested list of IDs contained in the vector nodeList using
the command eq function, which returns a vector of 0’s
(
false
) and 1’s (true) indicating each entry’s equality. Any 1’s in the vector, which can be quickly summed, indicate that the current node ID is requested. Type the following code segment to add this logic to your script:node = str2num(line(1:8)); boolean = eq(nodeList,node); if sum(boolean) > 0 %store this node’s data end
-
Finally, if the node has a requested ID, the following code can extract the
data from the x,y, and z coordinate fields and store them in the matrix
nodeInfo
. Add the following lines, save your script, and run it. Compare the values stored onnodeInfo
to the data within the text file.x = str2num(line(9:24)); y = str2num(line(25:40)); z = str2num(line(41:56)); for ix = 1:length(nodeList) if boolean(ix) == 1 nodeInfo(ix,:) = [ x, y, z]; end end
- Please refer to read_txt.txt file in the <installation folder>/tutorials/ for the complete script.