4-7. Managing data with MUSTIG
The data worked on can be generated inside MUSTIG, either by using a scalar or vectorial Value module, or by using Library macros (Dirac, Sine wave, Noise,...) that can be combined to create the desired signal. They may also be imported from the outside by reading data files with MUSTIG. The modules operating on files are in the File box of the Library.
External data can of course be imported and processed by MUSTIG. Standard 1d or 2D binary data files can be read using macros proposed in the libraries. Elementary modules are available to create custom macros in order to adapt to more specific data file formats.
One of the simplest mean is to use the "Cut and Paste" between applications for the formatted data : for instance, you copy the data from a spreadsheet, and you paste them inside a Value module in the edition mode (see Editing a text). However, only small amounts of data can be imported this way.
Formatted ASCII data files, whatever complex they may be, can be read using modules operating on character strings (see Reading a character string). These modules are in the Charact box of the Library.
The ASCII Read/li/co macro from the Files section of the Library allows to directly read most 1D or 2D ASCII files.
The operators for reading binary files cover all the usual file types (IEEE Format). You can start reading anywhere inside the file, choose the type of the data to read (see Types of data) and the number of samples of read. These macros are in the File box in the Library : check their online help (Alt+H) to know their characteristics.
If you must read more peculiar files (with text headers for instance), you can modify the proposed macros or even create custom ones using the elementary modules found in the File / Base modules section of the Library.
Note that if you used a C or Fortran routine to read data from a very peculiar format before purchasing MUSTIG, it may be more convenient to interface your routine with MUSTIG using the external interface facilities (see Interfacing an external routine).
The data acquisition systems being very specific, there is no dedicated operator for data acquisition in the standard version on the library.
SoundBlasterTM boards
The standard PC version of MUSTIG features specific macros for managing SoundBlasterTM boards. This allows to develop low-cost real time data processing applications.
ComputerBoardsTM boards
An optional interface has been developed to create data acquisition and processing systems from the ComputerBoardsTM boards. This interface allows to quickly build operational and user-friendly real-time applications : data acquisition, online control, data processing.
DSP Boards
A real-time DSP board (OROS-AU32) has also been interfaced with MUSTIG, allowing to create reliable real-time processing systems. A second DSP board is currently being adapted for MUSTIG.
Other boards
If you want to use MUSTIG to acquire data from other boards, you may create an interface from the specific C programming libraries provided by most board developers : just write custom routines and interface them with MUSTIG (see Interfacing an external routine).
Data produced by MUSTIG can of course be exported to data files or other applications.
Exporting formatted data using the clipboard
The "cut and paste" (Ctrl+C / Ctrl+V) facility allows to directly export small amounts of text data into word processing, drawing or spreadsheet software.
You can directly write binary files in the standard IEEE 1D or 2D formats. If you want to write your data with a custom format, e.g. to adapt to other software, use the provided base modules. All these elements are in the File section of the Library.
ASCII data may be formatted using the character string processing modules available in the Charact section of the Library.
The more frequent data type in MUSTIG is the 32-bit ( = 4 bytes) floating point real number (or "R4"). It is the default type of data produced by the Value module and by macros building signals in the Inputs section of the standard library.
Another floating data type is the 64-bit double precision floating point real (or "R8").
The "64-bit complex" (or "C8") type is the default complex type. The extended version is the 128-bit double precision complex (or "C16").
The "32-bit integer" (or "I4") type is the default integer type. It is used to perform logical or arithmetical operations. This type, as well as the "64-bit complex integer " (or "CI8") type is used for the absolute addressing of the pixels in drawing windows.
Other types are available, but mainly for interfacing with data files or external routines : 8-bit integer (or "I1"), 16-bit integer (or "I2").
The Finite Arithmetic option allows to specify the size of the data bit-by-bit (from 1 to 64 bits) at any point of the graph. This makes MUSTIG a powerful instrument for electronic design.
Setting the type produced by a scalar input module
The Value scalar input module in the Inputs section of the Library produces a 4-byte real number by default. This real data may then be converted into an integer of a double precision real number, or any other type required by your application.
You may however directly produce a 4-byte integer (I4) or a double precision real number (R8) from the scalar input module by using any of the following letters before the value :
d |
Double-precision real number |
i |
4-byte integer number |
Examples are shown below :
What is the precision of the calculations ?
The data type on the output of a module depends on the types of the data at input. For instance, the addition of a real and a complex gives a complex.
It may also depend on the characteristics of the support of the input variable : for instance, the inverse Fourier transform gives a real or a complex according to the symmetry ( "half" character) of the input or not.
On the contrary, this type, which is the same for all the points of a signal, does not depend on the values of the input. For instance, one cannot envisage that the square-root of a number be of real or complex type according to the sign of the input real number.
You may want to convert data from one type into another, either to limit precision or to comply with the type of data required by a macro. Modules are available in the Elementary operations section of the Library to convert data when required :
Fix1 |
Converts a real number into a 1-bit integer (I1) |
Fix2 |
Converts a real number into a 2-bit integer (I2) |
Fix |
Converts a real number into a 4-bit integer (I4) |
Float |
Converts an integer or a double-precision real (R8) into a 4-bit real (R4), converts a double-precision complex (C16) into a single-precision complex (C8) |
Float8 |
Converts the input into a double-precision real (R8), converts a complex into a double-precision complex (C16) |
nsFloat |
Same as Float for unsigned input data. |
You may also build complex numbers from both the real and the imaginary parts, or on the contrary extract the real and imaginary parts of a complex number. Dedicated modules are in the Complex section of the Library :
|
Extracts the real part of the input complex number |
|
Extracts the imaginary part of the input complex number |
|
Builds a complex from its real part (top input) and its imaginary part (left input) |
|
Expands a real number into a complex with zero imaginary part |
Shifting bits to limit precision
Although the integer arithmetic operations are performed on 32-bit integers, it is possible to make simulations in any precision by adding limiting macros made of logical operators. For instance, you can limit the accuracy at any place inside the graph by dropping a given number of low order bits by making a Shift towards right followed by a Shift towards left of the same amount. The Shift module is in the Elementary operations / Logical operations section of the Library.
However, if your applications need to perform such operations often, we strongly recommend that you use the Finite Arithmetic option. This powerful option allows to set the precision of the data at any point of the graph, between 1 and 64 bits. This size may be specified for floating point numbers as well (e.g. 13 bits including 7 after the floating point). The Finite Arithmetic option is very easy to use and allows to quickly develop and optimize electronic devices.
Specific modules in the Charact section of the Library allow to enter, read, process and write strings.
The empty module with a specific border allows to enter a string. Slide the module into your program an hit Shift+Ctrl+Click to enter the string. You may change the font, size and style of the string using commands from the Fonts menu on the top bar.
However you cannot mix several types or sizes or fonts inside a string input module.
You may use one or several of the special following characters to explicitly format the input string :
\t |
Tabulation |
\n |
Line Feed |
The Tabulation and Line Feed characters may also be entered directly using the dedicated key on the keyboard. Two examples of formatted input string are shown below :
You may produce the ASCII character associated with a given integer by using the Char module :
Strings are viewed using the scalar output module (??????? Module in the Outputs section of the Library). Resize the module appropriately to view the whole string.
The characteristics of the input text are not taken into account, only the content of the string is. Thus, you may change the size, font and style of the text displayed by using commands in the Fonts menu on the top bar.
In the example below, the bold Courrier input string is viewed in italic Helvetica letters :
Adding a Line Feed to a string
The End Line module in the Charact section of the Library adds the 'Carriage Return' symbol to a string, as shown in the example below :
Concatenating two strings into a single one
Strings may be concatenated using the standard addition module in the front panel of the Library :
Again, only the content of the string is copied, the fonts, styles and sizes of the strings are not taken into account. Please note that no space is inserted between the two sub-strings : they are strictly concatenated. You may of course terminate the string passed to the left pin of the adder by a space character to insert one between both strings.
You may extract a sub-string embedded in a larger string by using the Read_Field module in the Charact section of the Library. The same module is used to extract pattern from a file. Check out the online help of the module to know the exact function of each pin.
The module reads a pattern defined by an editable format, made of the maximum number of characters to read, followed by a separator. The separators are :
\t |
Tabulation |
\r |
Return |
\n |
Line Feed (Carriage return) |
The module reads the pattern from the start position on the left pin and returns both the extracted string and the position of the character following the string. The latter can in turn be used to read the next formatted field. If the extracted string is a number, you must convert if before using it as a number (see Converting a string into a number).
An example of use is shown below :
Converting a string into a number
Strings made of numbers may be converted into numerical values using the Convert module in the Charact section of the Library. The type of data on the output pin is defined by the editable format, which follows the syntax of the C language :
%f |
Produces a real number |
%lf |
Produces a double-precision real number |
%d |
Produces an integer |
Examples are shown below :
Converting a number into a string
Numerical values may be converted into strings using the Format module in the Charact section of the Library. The string on the output pin is defined by the editable format, which follows the syntax of the C language : key-letters indicate the type of the input data and an optional numerical field sets the number of characters of the output string.
%f |
Reads the value as a real number |
%lf |
Reads as a double-precision real number |
%i |
Reads as an integer |
%li |
Reads as an long integer |
Spaces are generated if the indicated number of characters is larger than the length of the input value. Examples are shown below :
Converting an integer into a string of binary digits
You may also convert an integer into a string made of its successive bits using the bits module in the Charact section of the Library :
Extracting a variable name into a string
You can extract the name of a variable at any point of the graph, in order for instance to include it in comment texts or curves. If the name of the variable changes in the graph, it will also change accordingly :
Calculating the length of a string
The length of a string (in number of characters) may be calculated using the Nbytes? module in the Charact section of the Library :
The same module is used to get the total length (in bytes) of a previously open file.
Checking whether two strings are equal
The standard equality checking module proposed in the Elementary operations / Logical operations section of the Library can be used to check if two strings are strictly equal. Be aware that the comparison is case sensitive :
Getting the ASCII code of a character
The Fix module in the Charact section of the Library returns the ASCII code of the first character in the input string :
Transforming a formatted string into a vector of strings
The Strings/nc macro in the Charact section of the Library allows to split a single input string, made of several lines separated by a line feed, into a vector of strings. Each element of the output vector contains one line of the input string. The name of the created variable (/nc by default) may of course be edited and changed (see Editing a module).
The maximum number of elements in the output vector is set by double-clicking on the macro.
The example below starts with a string containing four lines separated by a carriage return. The Strings module thus produces a vector depending of variable /nc and containing four elements equal to the four lines.
Example : Reading a formatted data file or string
The character string processing module can be combined to read formatted ASCII data files, no matter how complex they are. Suppose you want to read the following data file named DataFile.txt :
First Experience
Number of samples : 3
10.4
6.023e2
-503e-2
End
You can build a MUSTIG program to read the header, read the number of samples, create a vector of the appropriate length, and read the values. An example of such a program is shown below. In addition to merely reading the data, it also extracts a part of the header and reformats it into a string that can then be displayed in Image windows for instance (see Image windows).
You may also use the ready made ASCII Read/li/co macro from the Files section of the Library. The intermediate control panel of this macro allows to set the number of lines to skip at the beginning of the data file (header), and the maximum number of lines and columns. The actual number of lines and columns is automatically calculated :
The header and the data are directly passed to the MUSTIG environment, as shown in the program below :