DEFINITION MODULE MatFile;
(*******************************************************************
Module MatFile (Version 2.0)
Copyright (c) 1990-2006 by Andreas Fischlin, Olivier Roth and
ETH Zurich.
Purpose Read matrices from file.
Remarks This module is part of the Mat-library, which forms
part of the RAMSES package.
Programming
o Design
Andreas Fischlin 08/09/1995
Olivier Roth 24/04/1990
o Implementation
Andreas Fischlin 08/09/1995
ETH Zurich
Systems Ecology
CHN E 35.1
Universitaetstrasse 16
8092 Zurich
SWITZERLAND
URLs:
<mailto:RAMSES@env.ethz.ch>
<http://www.sysecol.ethz.ch>
<http://www.sysecol.ethz.ch/SimSoftware/RAMSES>
Last revision of definition: 24/04/1996 AF
*******************************************************************)
FROM DMConversions IMPORT RealFormat;
FROM DMFiles IMPORT TextFile;
FROM Matrices IMPORT Matrix;
(********************************)
(*##### Matrix Formats #####*)
(********************************)
(*==================================================================
The syntax of a matrix to be stored on a file is
(in EBNF, comments in double quotes):
matrix ::= headers row {row} matrixEnd.
headers ::= string {eleSep string} rowSep.
row ::= real {eleSep real} rowSep.
eleSep ::= CHAR. "not contained in string nor real"
rowSep ::= CHAR. "not contained in string nor real"
string ::= {CHAR}. "not eleSep nor rowSep"
matrixEnd ::= "too short row" | EOF.
real ::= see DMConversions
For more details see also the comments for routine ReadMatrix
below.
==================================================================*)
(*-----------------------*)
(*===== Formats =====*)
(*-----------------------*)
TYPE
MatFormIn = RECORD
eleSep, rowSep: CHAR;
END(*MatFormIn*);
(*
MatFormIn describes the input format in which a matrix isread
from a file. "eleSep" is a single char which is skipped and
serves as a delimiter between matrix elements, similarily rowSep
delimits end of rows (typically DMFiles.EOL). Defaults: eleSep =
11C (i.e. ASCII horizontal tabulator), rowSep = "DMFiles.EOL".
*)
MatFormOut = RECORD
realF : RealFormat;
len, dec : CARDINAL;
missVal,
rowBeg,
eleSep,
rowEnd,
eOM : ARRAY[0..63] OF CHAR;
END(*RECORD*);
(*
MatFormOut describes the format in which a matrix is written to
files. "realF" will be applied to every number, "len" stands
for the length of the field for the real number (including
decimal digits and decimal point), "dec" stands for the number
of decimal digits. "missVal" is the string which is written to
the file if an undefined value is contained in the matrix (<=>
IsUndefREAL(element(i,j)) = TRUE) and this string is used to
encode missing values. "rowBeg" is the string written at the
begin of every row (typically empty string), "eleSep" is a
string (typically just TAB) which is written after each matrix
element except at the end of a row, and rowEnd is the string
which is written at the end of a row (typically DMFiles.EOL).
"eOM" stands for 'end of matrix' and may contain any string
which is appended after writing the last row of the matrix and
always terminated with a EOL.
Defaults: realF = DMConversions.FixedFormat,
len, dec = 10, 3, missVal = "N",
rowBeg = "", eleSep = "" (ASCII horizontal tabulator),
rowEnd = "DMFiles.EOL", eOM = "".
Note, not any format in which a matrix can be written to a file
can also be read back by using ReadMatrix. However, matrices in
the default formats can be easily reread, since rowBeg = "",
eleSep as well as rowEnd are just one char (see also comments
for routine ReadMatrix below).
*)
(*---------------------------------------*)
(*===== Managing Matrix Formats =====*)
(*---------------------------------------*)
PROCEDURE SetMatFormIn ( mf: MatFormIn );
PROCEDURE GetMatFormIn ( VAR mf: MatFormIn );
PROCEDURE SetMatFormOut ( mf: MatFormOut );
PROCEDURE GetMatFormOut ( VAR mf: MatFormOut );
PROCEDURE ResetFormats;
(* Resets the current input as well as the output format to the
defaults (see above) *)
(*****************************************)
(*##### Input/Output operations #####*)
(*****************************************)
(*-------------------------------*)
(*===== Error Constants =====*)
(*-------------------------------*)
CONST
(* Error constants possibly returned by following routines (see also
module Errors for other codes): *)
(* reading errors *)
fileEmpty = 208;
rowEmpty = 209;
unknownMatrix = 210;
openFExpected = 211;
insuffMemForCreateM = 212;
wrongMDimensions = 213;
missOrWrongReal = 214;
incompleteReading = 215;
(* access, writing errors *)
eleOutOfDims = 220;
rowOutOfDims = 221;
matWithUndefReals = 229;
(*-----------------------*)
(*===== Reading =====*)
(*-----------------------*)
PROCEDURE ReadMatrix (VAR f: TextFile; VAR theM: Matrix;
leaveOpen: BOOLEAN;
VAR done: BOOLEAN; VAR resCode: INTEGER);
(*
Reads a matrix from file f using the currently set matrix
input format (see routine SetMatFormIn). The file f may
already be open or not. If the file is already open, an
attempt is made to read a matrix starting from the current
file position. In case the file is not open, an attempt
is made to open a file for reading with the name specified in
the field filename. From the reading position till the end of
matrix the file's content must conform exactly to the syntax
of a matrix (see above).
Non legal real numbers will be stored as
DMConversions.UndefREAL. This allows for encoding of missing
values with "N" or any other non-blank character.
In each data row there must be exactly the same number of
real numbers as there were headers in the first line, again
separated by element separators (typically TAB). In
particular note, an empty line or otherwise incomplete data
row will also be interpreted as the matrixEnd. Typically this
is an empty line or an EOM symbol (in the latter case a
matrix must not consist of only one column, or the end of
matrix will not be properly recognized).
In case there are too many data in the file, the reading
process will not be successfully completed (done = FALSE,
resCode = insuffMemForCreateM). However, if this is the
only reason for failure, theM exists, the headers are read,
and the dimensions of theM let you learn about the size of
the data matrix stored in the file (GetMatrixDim from module
MatDeclare). IMPORTANT WARNING: The matrix data are not
initialized and there is no data memory allocated for the
matrix! Thus you have to first adjust the dimensions of
theM correctly and to fitting dimensions before otherwise
operating on it.
If leaveOpen = TRUE the file is left open and the
file position will be just before matrixEnd, i.e. at the
begin of the line containting the matrix end.
done returns whether there were any errors encountered,
resCode decodes the type of error. Use e.g.
Errors.DisplayLastError to learn about the actual error(s)
detected. Note, since syntactically wrong real numbers can be
interpreted as missing values, missing values will always
lead to a warning message (resCode<>Errors.allOk) but done is
still true.
*)
PROCEDURE ReadRow (VAR f : TextFile; theM: Matrix; rowNr: INTEGER;
VAR done: BOOLEAN; VAR resCode: INTEGER);
(*
Reads the row rowNr of matrix theM from file f using the
currently set matrix input format (see routine SetMatFormIn).
Precondition and Postcondition: f is open, theM exists and
rowNr fits within the dimensions of theM. Any data already
contained in theM will be overwritten by those read from f,
unless done = FALSE. For possible error conditions see
routine ReadMatrix above.
*)
PROCEDURE ReadEle (VAR f: TextFile; VAR x: REAL;
VAR done: BOOLEAN; VAR resCode: INTEGER);
(*
Reads a matrix element from file f using the currently set
matrix input format (see routine SetMatFormIn). Precondition
and Postcondition: f is open. For possible error conditions
see routine ReadMatrix above.
*)
PROCEDURE ReadTitle (VAR f: TextFile; VAR title: ARRAY OF CHAR;
VAR done: BOOLEAN; VAR resCode: INTEGER);
(*
Reads a string, for instance holding the title of a matrix,
using the currently set matrix input format (see routine
SetMatFormIn) (actually reads everything till rowSep
encountered, i.e. reads over eleSep). Precondition and
Postcondition: f is open.
*)
(*-----------------------*)
(*===== Writing =====*)
(*-----------------------*)
PROCEDURE WriteMatrix (VAR f: TextFile; VAR theM: Matrix;
withHeaders, leaveOpen: BOOLEAN;
VAR mWritten: BOOLEAN; VAR resCode: INTEGER);
(*
Writes matrix theM onto file f using the currently set
matrix output format (see routine SetMatFormOut) for the data
contained in theM. withHeaders controls whether or not the headers for
the columns are written at the begin of the data section.
See ReadMatrix for meaning of remaining parameters.
*)
PROCEDURE WriteMatrixData (VAR f: TextFile; theM: Matrix);
(*
Similar to WriteMatrix but assumes that a file has already been
opened and writes only just the matrix data, i.e. numbers according
to the current dimensions of the matrix theM
*)
PROCEDURE WriteRow (VAR f : TextFile; theM: Matrix; rowNr: INTEGER;
VAR done: BOOLEAN; VAR resCode: INTEGER);
(*
Writes the row rowNr of matrix theM onto file f using the
currently set matrix output format (see routine
SetMatFormOut). Precondition and Postcondition: f is open.
For possible error conditions see routine ReadMatrix above.
*)
PROCEDURE WriteEle (VAR f : TextFile; theM: Matrix; row,col: INTEGER;
VAR done: BOOLEAN; VAR resCode: INTEGER);
(*
Writes the element row,col of matrix theM onto file f using
the currently set matrix output format (see routine
SetMatFormOut). Precondition and Postcondition: f is open.
For possible error conditions see routine ReadMatrix above.
*)
PROCEDURE WriteTitle (VAR f: TextFile; title: ARRAY OF CHAR;
VAR done: BOOLEAN; VAR resCode: INTEGER);
(*
Writes a string, for instance holding the title of a matrix ,
using the currently set matrix output format (see routine
SetMatFormOut). Precondition and Postcondition: f is open.
For possible error conditions see routine ReadMatrix above.
*)
(*
The following procedures should actually be provided by
module MatAccess. For the time being they are offered from
this module.
*)
PROCEDURE SetColHeader(m: Matrix; col: INTEGER; head: ARRAY OF CHAR);
PROCEDURE GetColHeader(m: Matrix; col: INTEGER; VAR head: ARRAY OF CHAR);
(*
Assigns or returns a column header (head) for the column col of the
matrix m. Note that ReadMatrix automatically assigns the column
headers, which can then be conveniently retrieved with GetColHeader.
*)
END MatFile.