Extending READUNV


READUNV can easily be extended to import datasets that are not natively supported. To do so, simply create an m-file named using the convention readunv_XXXX.m, where XXXX is the Universal dataset number you wish to support. For example, the file to read dataset 180 would be called readunv_180.m. Each time READUNV is invoked, it will search for files in your MATLAB path that follow this format. You cannot override any of the datasets currently supported by READUNV. If any of these files match a dataset currently supported by READUNV, they will be ignored and you will receive a warning message.

Every time READUNV encounters a dataset supported by a custom routine, it will store the output in a new cell of the cell array output by READUNV. The contents of the cell will be the contents of the output from yourreadunv_XXXX.m function.

The following sections describe the functions that you can use to read data from the Universal file. You are also provided with an example function that shows you how to use several of the provided function calls.

READUNV API Function Calls

Several functions are provided to access the Universal file. These functions utilize buffered reads for increased performance, so you should use these rather than the MATLAB-provided fread, frwrite,fscanf, etc. Using these functions will result in unpredictable behavior. The functions provided for your use are listed below. These functions can be accessed by using function handles, which requires the use of the fevalcommand.

The following functions are summarized in the following table, and are described in more detail below.

unv_getl Read lines from a Universal file.
unv_scanf Scan lines with the specified format to get up to a specified number of values.
unv_scands Scan to the end of the dataset using with the specified format.
unv_err Display an error message and terminate the Universal file read.
e_sscanf Scan floating point data and return the results in a numeric vector.

unv_getl

Read lines from the Universal file.

Usage:     line=unv_getl(n)

n is the number of lines to read. If n is not specified, it defaults to 1. line is a character array containing the lines read. It is a single vector, and line breaks consist of newline characters embedded in the string. If the end of the file is found before reading all n lines, an error results.

unv_scanf

Scan lines with the specified format to get up to a specified number of values.

Usage:     [x,xcount]=unv_scanf(s,nc,nl)

This function is intended to be used with numeric data. s is the specified format (i.e. '%d' or '%e'). If the format is specified as '%e', it will call e_sscanf internally. nc is the number of values to read, and nl is the maximum number of lines to read. x is a vector of numeric values read, and xcount is a count of the number of values read. If the end of the file is found before finding the end of the dataset, an error results.

unv_scands

Scan to the end of the dataset using with the specified format.

Usage:     [x,xcount,nlread]=unv_scands(s)

This function is intended to be used for numeric data. It is a very efficient way to read in an entire dataset. s is the specified format (i.e. '%d' or '%e'). x is a vector of numeric values read. xcount is a count of the number of values read, and nlread is a count of the number of lines read. Both xcount and nlread should be checked for consistency and expected values. If the end of the file is found before finding the end of the dataset, an error results.

unv_err

Display an error message and terminate the Universal file read.

Usage:     unv_err(s)

This function should be called if an error condition (such as an unexpected number of values read) is found when reading the Universal file. s is the string containing the error message to be displayed.

e_sscanf

Scan floating point data and return the results in a numeric vector.

Usage:     [a,...]=e_sscanf(s,...)

This function expects a string s as input. The input and output arguments follow the calling convention of the MATLAB builtin functionsscanf. e_sscanf is simply a wrapper that ensures that double-precision floating point representations using D are converted to E so that the numbers can be correctly converted by sscanf.

Function Format

The function header for your supplied universal reader function has a specific number of input and output arguments.  The function header must follow the form

function out=readunv_180(fh,uid_cur,ufact_cur,uid,ufact);

fh is a structure containing function handles for the available functions described in the previous section.  Each field of the structure matches the function name, and the content of each field is the function handle to that function. You will use fevalto call each function, as described below. uid_cur is a scalar containing the number of the current units in the MATLAB session as specified by setunits. ufact_cur is a 4x1 vector containing the scale factors for the current units set. The contents of ufact_cur are defined by getunits. uid and ufact contain the units number and scale factors for the current units set specified by dataset 164 in the Universal file. These units factors are useful for converting the Universal file contents to the current units system when importing.

out can be defined however you like. The contents of out will be assigned to a cell in the cell array output by READUNV.

Calling the READUNV API functions

Since the READUNV API functions are internal to READUNV, the only way to have access to them is to use the function handles supplied in the input argument fh. You can use feval to call these functions. For example, if you wanted to call unv_scanf, instead of calling it this way:

[x,xcount]=unv_scanf(s,nc,nl);

Using feval, you would call it this way:

[x,xcount]=feval(fh.unv_scanf,s,nc,nl);

Example

The following example shows how to use the API to read dataset 180, which is the Y2K mapping dataset written to the top of each Universal file exported by I-deas Master Series. Dataset 180 looks like the following, which has been truncated for brevity. The full dataset is 100 lines long.

-1
180
00 2000
01 2001
02 2002
...
68 2068
69 2069
70 1970
71 1971
...
98 1998
99 1999
-1

 

The following m-file, which can also be found in the examples directory of your IMAT installation, highlights several of the functions that can be used to read the datasets.

01
02

03

04

05

06

07

08

09

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

function out=readunv_180(fh,uid_cur,ufact_cur,uid,ufact);
% Read UNV dataset 180
%
% This example m-file provides a sample of how to write a Universal dataset plugin
% for READUNV.  It reads dataset 180, which is the Y2K mapping dataset written to
% the top of each Universal file written by I-deas Master Series.

% Update the progress dialog to specify the dataset currently being processed


ideas_progress(2,'Reading dataset 180 ...');

% Read a single line from the file to the string 'line'
% Display an error message and stop processing if the line is empty


line=feval(fh.unv_getl,1);
if
 isempty(line), feval(fh.unv_err,'Incomplete dataset 180');, end

% Convert the line into a number using sscanf.  We will use READUNV's e_sscanf function,
% which will also convert double-precision exponential format (1.0D+00) to E format, so
% the MATLAB sscanf function will work properly.  e_sscanf takes the same arguments as the
% builtin MATLAB sscanf function.


[a,count]=feval(fh.e_sscanf,line,'%d',2);
if
count~=2, feval(fh.unv_err,'Incomplete dataset 180');, end

% Read up to 8 values from 4 lines using the '%d' format
% Print an error message and stop processing if 8 values were not read


[b,count]=feval(fh.unv_scanf,'%d',8,4);
if
 count~=8, feval(fh.unv_err,'Incomplete dataset 180');, end
b=reshape(b,2,[]);

% Read the entire dataset using the '%d' format.  This is the most efficient way to read
% the dataset.  Display error messages and stop processing if the incorrect number of values
% or lines were read.


[x,xcount,nlread]=feval(fh.unv_scands,'%d');
if
 xcount~=190, feval(fh.unv_err,'Incomplete dataset 180');, end
if
 nlread~=95, feval(fh.unv_err,'Incomplete dataset 180');, end

% Build the output and return


out=[a'; b'; reshape(x,2,[])'];
return
;

 

Line 1 is the function declaration.  The listed arguments are required, even if they are not used inside of the function.

Line 10 is a useful call that updates the string displayed in the progress dialog. You should call this to specify that you are beginning to read the specific dataset.

Line 15 called unv_getl, and line 16 displays an error message if an unexpected string (empty) is returned.

Line 23 called e_sscanf to convert the string read in line 15 to a vector of numbers. Line 24 displays an error message if an unexpected number of values is returned.

Line 29 called unv_scanf to read 4 lines into the numeric vector b. It expects a total of 8 integers ('%d' format). Line 30 displays an error message if an unexpected number of values is returned. Line 31 reshapes the output to a 2x4 matrix.

Line 37 called unv_scands to read the rest of the dataset into a numeric vector. This function is the only one that needed to be called to read in this dataset, but the others were used to provide more examples. Lines 38 and 39 display an error message if an unexpected number of values is returned.

Line 43 assembles the dataset into a 100x2 matrix containing the data stored in dataset 180.