Mega Code Archive

 
Categories / Delphi / Files
 

Creating Matlab files

Title: Creating Matlab files Question: Matlab is a versatil tool to analyse and plot / display data of all kind of measurements. In our lab we use Delphi console applications to batch preprocess the raw measurement data and Delphi vcl application to control Matlab as a data analysis and plotting engine. After preprocessing the data is written in Matlab readable files for further analysis. The core routines to produce such Matlab files are presented here as a unit uMat. As an example - to give you an idea of how to use the routines - I present you a MatLab file structure we currently use, and the Delphi type's and var's and code necessary to create such a file. Answer: {--------------------------------------------------------------------------- u M a t a library of basic procedures necessary to create Matlab files For a complete description of the Matlab 5 format see http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf --------------------------------------------------------------------------- Author: F. Honegger Balance International Innovations GmbH Switzerland Edit History: Who When What -------------------------------------------------------------------------- FHO 08.12.2001 Creation Dependencies on other units: see uses clause Important: compile with $N+ --------------------------------------------------------------------------} unit uMat; interface uses Classes, Sysutils; const miInt8 = 01; miUInt8 = 02; miInt16 = 03; miUInt16 = 04; miInt32 = 05; miUInt32 = 06; miSingle = 07; miDouble = 09; miInt64 = 12; miuInt64 = 13; miMatrix = 14; mxCellC = 1; mxStructC = 2; mxObjectC = 3; mxCharC = 4; mxSparseC = 5; mxDoubleC = 6; mxSingleC = 7; mxInt8C = 8; mxUInt8C = 9; mxInt16C = 10; mxUInt16C = 11; mxInt32C = 12; mxUInt32C = 13; type TMtlIntegerVector=array of Integer; TMtlSmallIntVector=array of SmallInt; TMtlWordVector=array of Word; TMtlByteVector = array of byte; TMtlDoubleVector =array of double; TMtlSingleVector =array of Single; TMtlIntegerMatrix=array of TMtlIntegerVector; TMtlSmallIntMatrix=array of TMtlSmallIntVector; TMtlWordMatrix=array of TMtlWordVector; TMtlByteMatrix = array of TMtlByteVector; TMtlDoubleMatrix =array of TMtlDoubleVector; TMtlSingleMatrix =array of TMtlSingleVector; EMtlHeaderError = class(Exception) end; procedure WriteMTLFileHeader(TargetStream:TStream); procedure WriteMtlTag(TargetStream:TStream;aDataType,aSize:Cardinal); procedure PrimeMtlTag(TargetStream:TStream;aDataType:Cardinal); procedure CompleteMtlTag; procedure WriteMtlArrayFlags(TargetStream:TStream;aClass,aFlags:byte); procedure WriteMtlDimmensions(TargetStream:TStream;aDim:Array of Integer); procedure WriteMtlStrucNames(TargetStream:TStream;const aNam:array of string); function GetVecDim(asRow:boolean;size:integer):TMtlIntegerVector; function GetMatDim(rows,colums:integer):TMtlIntegerVector; procedure WriteMtlName(TargetStream:TStream;const aName:String); procedure WriteMtlVarDouble(TargetStream:TStream; const name: String;const a:double); procedure WriteMtlVecVarDouble(asRow:boolean;TargetStream:TStream; const name: String;const a:array of double); procedure WriteMtlMatVarDouble(TargetStream:TStream; const name: String;const a:array of TMtlDoubleVector); procedure WriteMtlVarSingle(TargetStream:TStream; const name: String;const a:Single); procedure WriteMtlVecVarSingle(asRow:boolean;TargetStream:TStream; const name: String;const a:array of Single); procedure WriteMtlMatVarSingle(TargetStream:TStream; const name: String;const a:array of TMtlSingleVector); procedure WriteMtlVarInteger(TargetStream:TStream; const name: String;const a:Integer); procedure WriteMtlVecVarInteger(asRow:boolean;TargetStream:TStream; const name: String;const a:array of Integer); procedure WriteMtlMatVarInteger(TargetStream:TStream; const name: String;const a:array of TMtlIntegerVector); procedure WriteMtlVarSmallInt(TargetStream:TStream; const name: String;const a:SmallInt); procedure WriteMtlVecVarSmallInt(asRow:boolean;TargetStream:TStream; const name: String;const a:array of SmallInt); procedure WriteMtlMatVarSmallInt(TargetStream:TStream; const name: String;const a:array of TMtlSmallIntVector); procedure WriteMtlVarWord(TargetStream:TStream; const name: String;const a:Word); procedure WriteMtlVecVarWord(asRow:boolean;TargetStream:TStream; const name: String;const a:array of Word); procedure WriteMtlMatVarWord(TargetStream:TStream; const name: String;const a:array of TMtlWordVector); procedure WriteMtlVarByte(TargetStream:TStream; const name: String;const a:Byte); procedure WriteMtlVecVarByte(asRow:boolean;TargetStream:TStream; const name: String;const a:array of Byte); procedure WriteMtlMatVarByte(TargetStream:TStream; const name: String;const a:array of TMtlByteVector); procedure WriteMtlVarString(TargetStream:TStream; const name: String;const a:String); procedure WriteMtlVecVarString(TargetStream:TStream; const name: String;const a:array of String); implementation Uses Windows, Math; function PadCh(const s : string; Ch : Char; Len: Integer) : string; {-Return a string right-padded to length len with ch} var Slen: Integer; begin Result:=s; SLen:=Length(s); if SLen SetLength(Result,Len); FillChar(Result[Succ(Slen)], Len-Slen, Ch); end; end; function Pad(const s : string; Len: Integer) : string; {-Return a string right-padded to length len with blanks} begin Pad := PadCh(s, ' ', Len); end; procedure WriteMTLFileHeader(TargetStream:TStream); const cHeaderText='MATLAB 5.0 MAT-file, Platform: PCWIN, Created on: %s %s by %s'; cID=$4d490100; var s:string; i:dword; dnow:TDateTime; begin dnow:=Now; s:=pad(format(cHeaderText,[TimeToStr(dnow),DateToStr(dnow),ExtractFileName(paramstr(0))]),124); TargetStream.Write(s[1],length(s)); i:=cId; TargetStream.Write(i,SizeOf(i)); end; Type TMtlTag=packed record DataType, Size:cardinal; end; TMtlArrayFlags=packed record mxClass:Byte; Flags:Byte; Undef:Word; Undefined:cardinal; end; procedure WriteMtlTag(TargetStream:TStream;aDataType,aSize:Cardinal); var MtlTag:TMtlTag; begin with MtlTag do begin DataType :=aDataType; Size :=aSize; end; TargetStream.Write(MtlTag,SizeOf(MtlTag)); end; type TTagState=record FilPos:integer; DatTyp:integer; TrgtStream:Tstream; end; var MtlTagStateStack:array of TTagState; procedure PrimeMtlTag(TargetStream:TStream;aDataType:Cardinal); var slen:integer; begin slen:=length(MtlTagStateStack); SetLength(MtlTagStateStack,slen+1); with MtlTagStateStack[slen] do begin FilPos:=TargetStream.Position; DatTyp:=aDataType; TrgtStream:=TargetStream; end; WriteMtlTag(TargetStream,aDataType,0); end; procedure CompleteMtlTag; var nFilePos:integer; slen:integer; begin if Length(MtlTagStateStack)=0 then raise EMtlHeaderError.Create('PrimeMtlTag must be called before CompleteMtlTag'); slen:=Length(MtlTagStateStack)-1; with MtlTagStateStack[slen] do begin nFilePos:=TrgtStream.Position; TrgtStream.Seek(FilPos,soFromBeginning); WriteMtlTag(TrgtStream,DatTyp,nFilePos-FilPos-8); TrgtStream.Seek(nFilePos,soFromBeginning); TrgtStream:=nil; end; SetLength(MtlTagStateStack,slen); end; procedure WriteMtlCompressedTag(TargetStream:TStream;aDataType,aSize:cardinal; const aData); var MtlTag:TMtlTag; begin with MtlTag do begin DataType :=asize shl 16 + aDataType; Fillchar(Size,SizeOf(Size),0); move(aData,Size,aSize); end; TargetStream.Write(MtlTag,SizeOf(MtlTag)); end; procedure WriteMtlArrayFlags(TargetStream:TStream;aClass,aFlags:byte); var AMtlFlags:TMtlArrayFlags; MtlTag:TMtlTag; begin with MtlTag do begin DataType :=miUint32; Size :=8; end; TargetStream.Write(MtlTag,SizeOf(MtlTag)); FillChar(AMtlFlags,SizeOf(AMtlFlags),0); with AMtlFlags do begin Flags :=aFlags; mxClass:=aClass; end; TargetStream.Write(AMtlFlags,SizeOf(AMtlFlags)); end; procedure WriteMtlPadding(TargetStream:TStream;aStrucSize:cardinal); var Padding:array of byte; padSize:integer; begin //pad to mod 8 padSize:=aStrucSize mod 8; if padSize=0 then exit; SetLength(Padding,8-padSize); FillChar(Padding[0],length(Padding),0); TargetStream.Write(Padding[0],length(Padding)); end; procedure WriteMtlDimmensions(TargetStream:TStream;aDim:Array of Integer); var MtlTag:TMtlTag; begin with MtlTag do begin DataType :=miInt32; Size :=SizeOf(Integer)*length(aDim); end; TargetStream.Write(MtlTag,SizeOf(MtlTag)); TargetStream.Write(aDim[0],MtlTag.Size); WriteMtlPadding(TargetStream,MtlTag.Size); end; procedure WriteMtlStrucNames(TargetStream:TStream;const aNam:array of string); var MtlTag:TMtlTag; s:string; i:integer; begin with MtlTag do begin DataType :=4 shl 16 + miInt32; Size :=32; end; //strucname size TargetStream.Write(MtlTag,SizeOf(MtlTag)); with MtlTag do begin DataType :=miInt8; Size :=length(anam)*32; end; //size of name block TargetStream.Write(MtlTag,SizeOf(MtlTag)); SetLength(s,32); //names for i:=0 to length(anam)-1 do begin fillchar(s[1],length(s),0); move(anam[i][1],s[1],min(length(anam[i]),32)); TargetStream.Write(s[1],length(s)); end; end; procedure WriteMtlName(TargetStream:TStream;const aName:String); var MtlTag:TMtlTag; begin with MtlTag do begin if length(aName) WriteMtlCompressedTag(TargetStream,miInt8,length(aName),aName[1]); Exit; end else begin DataType :=miInt8; Size :=SizeOf(Byte)*Length(aName); end; end; TargetStream.Write(MtlTag,SizeOf(MtlTag)); TargetStream.Write(aName[1],MtlTag.Size); WriteMtlPadding(TargetStream,MtlTag.Size); end; procedure WriteMtlVecDouble(TargetStream:TStream; a:array of double); var Size:cardinal; begin Size:=length(a)*SizeOf(Double); WriteMtlTag(TargetStream,miDouble,Size); TargetStream.Write(a[0],Size); end; procedure WriteMtlMatDouble(TargetStream:TStream; a:array of TMtlDoubleVector); var Size:cardinal; i:integer; begin Size:=length(a[0])*length(a)*SizeOf(Double); WriteMtlTag(TargetStream,miDouble,Size); Size:=length(a[0])*SizeOf(Double); for i:=0 to length(a)-1 do TargetStream.Write(a[i][0],Size); end; procedure WriteMtlVecSingle(TargetStream:TStream; a:array of single); var Size:cardinal; begin Size:=length(a); if Size WriteMtlCompressedTag(TargetStream,miSingle,Size*SizeOf(a[0]),a[0]); exit; end; Size:=Size*SizeOf(Single); WriteMtlTag(TargetStream,miSingle,Size); TargetStream.Write(a[0],Size); WriteMtlPadding(TargetStream,Size); end; procedure WriteMtlMatSingle(TargetStream:TStream; a:array of TMtlSingleVector); var TotSize,VecSize:cardinal; i:integer; begin TotSize:=length(a[0])*length(a)*SizeOf(Single); WriteMtlTag(TargetStream,miSingle,TotSize); VecSize:=length(a[0])*SizeOf(Single); for i:=0 to length(a)-1 do TargetStream.Write(a[i][0],VecSize); WriteMtlPadding(TargetStream,TotSize); end; procedure WriteMtlVecInteger(TargetStream:TStream; a:array of integer); var Size:cardinal; begin Size:=length(a); if Size WriteMtlCompressedTag(TargetStream,miInt32,Size*SizeOf(a[0]),a[0]); exit; end; Size:=Size*SizeOf(Integer); WriteMtlTag(TargetStream,miInt32,Size); TargetStream.Write(a[0],Size); WriteMtlPadding(TargetStream,Size); end; procedure WriteMtlMatInteger(TargetStream:TStream; a:array of TMtlIntegerVector); var TotSize,VecSize:cardinal; i:integer; begin TotSize:=length(a[0])*length(a)*SizeOf(Integer); WriteMtlTag(TargetStream,miInt32,TotSize); VecSize:=length(a[0])*SizeOf(Integer); for i:=0 to length(a)-1 do TargetStream.Write(a[i][0],VecSize); WriteMtlPadding(TargetStream,TotSize); end; procedure WriteMtlVecSmallInt(TargetStream:TStream; a:array of Smallint); var Size:cardinal; begin Size:=length(a); if Size WriteMtlCompressedTag(TargetStream,miInt16,Size*SizeOf(a[0]),a[0]); exit; end; Size:=Size*SizeOf(SmallInt); WriteMtlTag(TargetStream,miInt16,Size); TargetStream.Write(a[0],Size); WriteMtlPadding(TargetStream,Size); end; procedure WriteMtlMatSmallInt(TargetStream:TStream; a:array of TMtlSmallIntVector); var TotSize,VecSize:cardinal; i:integer; begin TotSize:=length(a[0])*length(a)*SizeOf(SmallInt); WriteMtlTag(TargetStream,miInt16,TotSize); VecSize:=length(a[0])*SizeOf(SmallInt); for i:=0 to length(a)-1 do TargetStream.Write(a[i][0],VecSize); WriteMtlPadding(TargetStream,TotSize); end; procedure WriteMtlVecWord(TargetStream:TStream; a:array of Word); var Size:cardinal; begin Size:=length(a); if Size WriteMtlCompressedTag(TargetStream,miUInt16,Size*SizeOf(a[0]),a[0]); exit; end; Size:=Size*SizeOf(SmallInt); WriteMtlTag(TargetStream,miUInt16,Size); TargetStream.Write(a[0],Size); WriteMtlPadding(TargetStream,Size); end; procedure WriteMtlMatWord(TargetStream:TStream; a:array of TMtlWordVector); var TotSize,VecSize:cardinal; i:integer; begin TotSize:=length(a[0])*length(a)*SizeOf(Word); WriteMtlTag(TargetStream,miUInt16,TotSize); VecSize:=length(a[0])*SizeOf(Word); for i:=0 to length(a)-1 do TargetStream.Write(a[i][0],VecSize); WriteMtlPadding(TargetStream,TotSize); end; procedure WriteMtlVecByte(TargetStream:TStream; a:array of byte); var Size:cardinal; begin Size:=length(a)*SizeOf(a[0]); if Size WriteMtlCompressedTag(TargetStream,miUInt8,Size*SizeOf(a[0]),a[0]); exit; end; Size:=Size*SizeOf(Byte); WriteMtlTag(TargetStream,miUInt8,Size); TargetStream.Write(a[0],Size); WriteMtlPadding(TargetStream,Size); end; procedure WriteMtlMatByte(TargetStream:TStream; a:array of TMtlByteVector); var TotSize,VecSize:cardinal; i:integer; begin TotSize:=length(a[0])*length(a)*SizeOf(Byte); WriteMtlTag(TargetStream,miUInt8,TotSize); VecSize:=length(a[0])*SizeOf(Byte); for i:=0 to length(a)-1 do TargetStream.Write(a[i][0],VecSize); WriteMtlPadding(TargetStream,TotSize); end; procedure WriteMtlVecString(TargetStream:TStream; a:string); var Size:cardinal; i:integer; wa:array of word; begin SetLength(wa,length(a)); for i:=0 to length(wa)-1 do wa[i]:=ord(a[i+1]); Size:=length(a)*SizeOf(word); if Size WriteMtlCompressedTag(TargetStream,miUInt16,Size,wa[0]); exit; end; WriteMtlTag(TargetStream,miUInt16,Size); TargetStream.Write(wa[0],Size); WriteMtlPadding(TargetStream,Size); end; function GetVecDim(asRow:boolean;size:integer):TMtlIntegerVector; begin SetLength(Result,2); if asRow then begin Result[0]:=1; Result[1]:=size; end else begin Result[0]:=size; Result[1]:=1; end; end; function GetMatDim(rows,colums:integer):TMtlIntegerVector; begin SetLength(Result,2); Result[0]:=Colums; Result[1]:=Rows; end; procedure WriteMtlVarDouble(TargetStream:TStream; const name: String;const a:double); begin WriteMtlVecVarDouble(True,TargetStream,name,a); end; procedure WriteMtlVecVarDouble(asRow:boolean;TargetStream:TStream; const name: String;const a:array of double); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxDoubleC,0); WriteMtlDimmensions(TargetStream,GetVecDim(asRow,length(a))); WriteMtlName(TargetStream,name); WriteMtlVecDouble(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlMatVarDouble(TargetStream:TStream; const name: String;const a:array of TMtlDoubleVector); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxDoubleC,0); WriteMtlDimmensions(TargetStream,GetMatDim(length(a),length(a[0]))); WriteMtlName(TargetStream,name); WriteMtlMatDouble(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlVarSingle(TargetStream:TStream; const name: String;const a:Single); begin WriteMtlVecVarSingle(True,TargetStream,name,a); end; procedure WriteMtlVecVarSingle(asRow:boolean;TargetStream:TStream; const name: String;const a:array of Single); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxSingleC,0); WriteMtlDimmensions(TargetStream,GetVecDim(asRow,length(a))); WriteMtlName(TargetStream,name); WriteMtlVecSingle(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlMatVarSingle(TargetStream:TStream; const name: String;const a:array of TMtlSingleVector); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxSingleC,0); WriteMtlDimmensions(TargetStream,GetMatDim(length(a),length(a[0]))); WriteMtlName(TargetStream,name); WriteMtlMatSingle(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlVarInteger(TargetStream:TStream; const name: String;const a:integer); begin WriteMtlVecVarInteger(True,TargetStream,name,a); end; procedure WriteMtlVecVarInteger(asRow:boolean;TargetStream:TStream; const name: String;const a:array of Integer); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxInt32C,0); WriteMtlDimmensions(TargetStream,GetVecDim(asRow,length(a))); WriteMtlName(TargetStream,name); WriteMtlVecInteger(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlMatVarInteger(TargetStream:TStream; const name: String;const a:array of TMtlIntegerVector); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxInt32C,0); WriteMtlDimmensions(TargetStream,GetMatDim(length(a),length(a[0]))); WriteMtlName(TargetStream,name); WriteMtlMatInteger(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlVarSmallInt(TargetStream:TStream; const name: String;const a:Smallint); begin WriteMtlVecVarSmallInt(True,TargetStream,name,a); end; procedure WriteMtlVecVarSmallInt(asRow:boolean;TargetStream:TStream; const name: String;const a:array of SmallInt); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxInt16C,0); WriteMtlDimmensions(TargetStream,GetVecDim(asRow,length(a))); WriteMtlName(TargetStream,name); WriteMtlVecSmallInt(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlMatVarSmallInt(TargetStream:TStream; const name: String;const a:array of TMtlSmallIntVector); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxInt16C,0); WriteMtlDimmensions(TargetStream,GetMatDim(length(a),length(a[0]))); WriteMtlName(TargetStream,name); WriteMtlMatSmallInt(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlVarWord(TargetStream:TStream; const name: String;const a:Word); begin WriteMtlVecVarWord(True,TargetStream,name,a); end; procedure WriteMtlVecVarWord(asRow:boolean;TargetStream:TStream; const name: String;const a:array of Word); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxUInt16C,0); WriteMtlDimmensions(TargetStream,GetVecDim(asRow,length(a))); WriteMtlName(TargetStream,name); WriteMtlVecWord(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlMatVarWord(TargetStream:TStream; const name: String;const a:array of TMtlWordVector); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxUInt16C,0); WriteMtlDimmensions(TargetStream,GetMatDim(length(a),length(a[0]))); WriteMtlName(TargetStream,name); WriteMtlMatWord(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlVarByte(TargetStream:TStream; const name: String;const a:Byte); begin WriteMtlVecVarByte(True,TargetStream,name,a); end; procedure WriteMtlVecVarByte(asRow:boolean;TargetStream:TStream; const name: String;const a:array of Byte); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxUInt8C,0); WriteMtlDimmensions(TargetStream,GetVecDim(asRow,length(a))); WriteMtlName(TargetStream,name); WriteMtlVecByte(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlMatVarByte(TargetStream:TStream; const name: String;const a:array of TMtlByteVector); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxUInt8C,0); WriteMtlDimmensions(TargetStream,GetMatDim(length(a),length(a[0]))); WriteMtlName(TargetStream,name); WriteMtlMatByte(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlVarString(TargetStream:TStream; const name: String;const a:String); begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxCharC,0); WriteMtlDimmensions(TargetStream,GetVecDim(True,length(a))); WriteMtlName(TargetStream,name); WriteMtlVecString(TargetStream,a); CompleteMtlTag; end; procedure WriteMtlVecVarString(TargetStream:TStream; const name: String;const a:array of String); var i:integer; begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxCellC,0); WriteMtlDimmensions(TargetStream,GetVecDim(False,length(a))); WriteMtlName(TargetStream,name); for i:=0 to length(a)-1 do begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxCharC,0); WriteMtlDimmensions(TargetStream,GetVecDim(True,length(a[i]))); WriteMtlName(TargetStream,''); WriteMtlVecString(TargetStream,a[i]); CompleteMtlTag; end; CompleteMtlTag; end; end. //----------- end of unit, cut here ------------------------------------------ Example ======= Matlab View of the file to be produced ====================================== 1. Variable enumeration: The following variables are hold within the file adc mrk stat trials exclude samprate stim ws 2. Variable descriptions: 2.1. adc: ADC Channel descriptions adc has the structure of an array of channel description. A channel description is a record consisting of n: the channel name u: the channel unit of measure sf: a scaling factor to scale to u access the items as follows (i,k,10 being channel indices) adc(1).n adc(k).u adc(10).sf etc. 2.2. mrk: Marker description mrk is a structure consisting of a string array and unit of measure string channel description. n: array with the marker names name u: string with the unit of measure access the items as follows (1,i being marker indices) mrk.n(1) mrk.n(i) mrk.u etc. 2.3. samprate: Frequency descriptions samprate is structure consisting of the following items adc, a structure describing the adc sampling rates mrk, a structure describing the marker sampling rates numtrials, the number of trials of the experiment adc and mrk have the same substructur that consists of to numbers frame, the sampling frequency scan, the inter channel/marker collection frequency access the items as follows samprate.numtrials samprate.adc.frame samprate.mrk.scan etc. 2.4. trials: Original data trials is an array of the following trial structure adc, a matrix with the adc channel values, each row is a channel dig, a integer row vector with the digital output information of the ODAU mrk, an array of the following structure for each marker x,y,z, row vectors with the 3 space components of the marker Nan, a integer row vector with indices of missing data points of the marker Spike, a integer row vector with indices of the data points identified as being part of a spike adcfname, a string with the corresponding ODAU source file name mrkfname, a string with the corresponding OptoTrak source file name adcdattim, date and time as within the ODAU source file mrkdattim, date and time as within the OptpTrak source file access the items as follows (i,k being trial indices, m,n being marker/channel indices and h,j being point indices) trials(i).mrkdattim trials(k).adc(m,j) trials(i).mrk(m).x trials(i).mrk(m).y(j) trials(k).mrk.Nan etc. 2.5. exclude: Data to be excluded exclude is structured in three parts trial, is an integer array of the trials to be excluded completely adc, is an array of the following structure no, is the index of the channel trial, is a integer array of the trials to be excluded for the corresponding channel. mrk, is an array of the same structure as adc no, is the index of the marker trial, is a integer array of the trials to be excluded for the corresponding marker. 2.6. stat: Average data stat is a structure with the following structures adc, average ODAU data adc itself is a array of structure, where mean, is a matrix containing the average channels as rows std, is a matrix containing the corresponding std, and count, an integer array holds the number of trials within the means mrk, averaged OptoTrak data mrk itself is a matrix of structure, where the markers are aligned in a row for each trial. mean, is a structure of three row vectors x,y,z. The same structure has std, the corresponding stds. count, is the number of trials within the mean access the items as follows (i,k being stimulus indices, m,n being marker/channel indices and h,j being point indices) stat.adc(i).mean(m,j) stat.adc(i).std(m,j) stat.adc(i).std(m,j) stat.adc(i).count(m) stat.mrk(i,m).mean.x(j) stat.mrk(k.n).std.z(h) stat.mrk(k.n).count etc. 2.7. stim: The description of the stimuli stim is an array of the following structure that holds for each stimulus the following information. name, a string holding, then name of the stimulus trials,an array of integer holding the numbers of the trials that correspond to the stimulus access the items as follows (i,k being stimulus indices) stim(j).name stim(k).trials(:), etc. 2.8. ws: Average built information ws is a structure with the following string information name, the name of the workstation the averaging was done user, the user who was logged in while averaging datim, date and time when average was done description, the description string from the .ndo file (subject name) Delphi view =========== Sample code to produce a matlab .mat file of the above structure that can be loaded with the standard matlab load command Type declaration necessary to build corresponding delphi data memory structures. type TADCDesc= record n:String; u:String; sf:double; end; TStimDesc= record Name:string; Trials:array of integer; end; TMarkerChannel=record x:TMtlSingleVector; y:TMtlSingleVector; z:TMtlSingleVector; Nan:TMtlIntegerVector; Spike:TMtlIntegerVector; end; TMarkerTrial=array of TMarkerChannel; TTrial= record adc:TMtlSingleMatrix; mrk:TMarkerTrial; dig:TMtlWordVector; voltageFilNam:String; markerFilNam:String; adcDateTime:String; mrkDateTime:String; end; TAdcTrialStat= record mean: TMtlDoubleMatrix; std: TMtlDoubleMatrix; count: TMtlIntegerVector; end; TMarkerPos = record x:TMtlDoubleVector; y:TMtlDoubleVector; z:TMtlDoubleVector; end; TMarkerStat= record mean:TMarkerPos; std:TMarkerPos; count: Integer; end; TMarkerTrialStat= Array of TMarkerStat; TSampRate=record frame: integer; scan: integer; end; TSampRates=record chan:TSampRate; mrk:TSampRate; NumTrials:integer; end; TMrkDesc=record n:Array Of String; u:string; end; The variables that are used to hold the data. var //odau ADCDesc: array of TADCDesc; StimDesc: array of TStimDesc; AdcTrialStat: array of TAdcTrialStat; MrkTrialStat: array of TMarkerTrialStat; TrialArray: array of Ttrial; SampRate: TsampRates; Description: String; //opto MrkDesc: TMrkDesc; //both ExcludeList: TExtendedExcludeList; procedure CreateMatlabFile(const fname:string;EstMinimalSize:integer); var ErrMes:String; k,i,iErr:Integer; TargetStream:TMemoryStream; StrucNames:array of string; begin TargetStream:=TMemoryStream.Create; TargetStream.SetSize(EstMinimalSize); try WriteMTLFileHeader(TargetStream); //ws info PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,'ws'); SetLength(StrucNames,4); StrucNames[0]:='name'; StrucNames[1]:='user'; StrucNames[2]:='datim'; StrucNames[3]:='description'; WriteMtlStrucNames(TargetStream,StrucNames); WriteMtlVarString(TargetStream,'',ComputerName); WriteMtlVarString(TargetStream,'',UserName); WriteMtlVarString(TargetStream,'',DateTimeToStr(now)); WriteMtlVarString(TargetStream,'',Description); CompleteMtlTag; //AdcDesc Structure PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,length(AdcDesc))); WriteMtlName(TargetStream,'adc'); SetLength(StrucNames,3); StrucNames[0]:='n'; StrucNames[1]:='u'; StrucNames[2]:='sf'; WriteMtlStrucNames(TargetStream,StrucNames); for i:=0 to length(AdcDesc)-1 do begin WriteMtlVarString(TargetStream,'',AdcDesc[i].n); WriteMtlVarString(TargetStream,'',AdcDesc[i].u); WriteMtlVarDouble(TargetStream,'',AdcDesc[i].sf); end; CompleteMtlTag; //MrkDesc Structure PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,'mrk'); SetLength(StrucNames,2); StrucNames[0]:='n'; StrucNames[1]:='u'; WriteMtlStrucNames(TargetStream,StrucNames); WriteMtlVecVarString(TargetStream,'',MrkDesc.n); WriteMtlVarString(TargetStream,'',MrkDesc.u); CompleteMtlTag; //StimDesc Structure PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,length(StimDesc))); WriteMtlName(TargetStream,'stim'); SetLength(StrucNames,2); StrucNames[0]:='name'; StrucNames[1]:='trials'; WriteMtlStrucNames(TargetStream,StrucNames); for i:=0 to length(StimDesc)-1 do begin WriteMtlVarString(TargetStream,'',StimDesc[i].Name); WriteMtlVecVarInteger(True,TargetStream,'',StimDesc[i].Trials); end; CompleteMtlTag; //SampRate Structure; PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,'samprate'); SetLength(StrucNames,3); StrucNames[0]:='adc'; StrucNames[1]:='mrk'; StrucNames[2]:='numtrials'; WriteMtlStrucNames(TargetStream,StrucNames); PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,''); SetLength(StrucNames,2); StrucNames[0]:='frame'; StrucNames[1]:='scan'; WriteMtlStrucNames(TargetStream,StrucNames); WriteMtlVarInteger(TargetStream,'',SampRate.chan.frame); WriteMtlVarInteger(TargetStream,'',SampRate.chan.scan); CompleteMtlTag; PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,''); SetLength(StrucNames,2); StrucNames[0]:='frame'; StrucNames[1]:='scan'; WriteMtlStrucNames(TargetStream,StrucNames); WriteMtlVarInteger(TargetStream,'',SampRate.mrk.frame); WriteMtlVarInteger(TargetStream,'',SampRate.mrk.scan); CompleteMtlTag; WriteMtlVarInteger(TargetStream,'',SampRate.NumTrials); CompleteMtlTag; //Exclude lists PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,'exclude'); SetLength(StrucNames,3); StrucNames[0]:='trial'; StrucNames[1]:='adc'; StrucNames[2]:='mrk'; WriteMtlStrucNames(TargetStream,StrucNames); WriteMtlVecVarInteger(true,TargetStream,'',ExcludeList.TrialExclude); PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,length(ExcludeList.ChannelExclude))); WriteMtlName(TargetStream,''); SetLength(StrucNames,2); StrucNames[0]:='no'; StrucNames[1]:='trial'; WriteMtlStrucNames(TargetStream,StrucNames); for i:=0 to length(ExcludeList.ChannelExclude)-1 do begin WriteMtlVarInteger(TargetStream,'',ExcludeList.ChannelExclude[i].ChNo); WriteMtlVecVarInteger(true,TargetStream,'',ExcludeList.ChannelExclude[i].Exclude); end; CompleteMtlTag; PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,length(ExcludeList.MarkerExclude))); WriteMtlName(TargetStream,''); SetLength(StrucNames,2); StrucNames[0]:='no'; StrucNames[1]:='trial'; WriteMtlStrucNames(TargetStream,StrucNames); for i:=0 to length(ExcludeList.MarkerExclude)-1 do begin WriteMtlVarInteger(TargetStream,'',ExcludeList.MarkerExclude[i].ChNo); WriteMtlVecVarInteger(true,TargetStream,'',ExcludeList.MarkerExclude[i].Exclude); end; CompleteMtlTag; CompleteMtlTag; //Stat Structure PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,'stat'); SetLength(StrucNames,2); StrucNames[0]:='adc'; StrucNames[1]:='mrk'; WriteMtlStrucNames(TargetStream,StrucNames); //adc PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,length(AdcTrialStat))); WriteMtlName(TargetStream,''); SetLength(StrucNames,3); StrucNames[0]:='mean'; StrucNames[1]:='std'; StrucNames[2]:='count'; WriteMtlStrucNames(TargetStream,StrucNames); for i:=0 to length(AdcTrialStat)-1 do begin WriteMtlMatVarDouble(TargetStream,'',AdcTrialStat[i].mean); WriteMtlMatVarDouble(TargetStream,'',AdcTrialStat[i].std); WriteMtlVecVarInteger(false,TargetStream,'',AdcTrialStat[i].count); end; CompleteMtlTag; //mrk PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(Length(MrkDesc.N),length(MrkTrialStat))); WriteMtlName(TargetStream,''); SetLength(StrucNames,3); StrucNames[0]:='mean'; StrucNames[1]:='std'; StrucNames[2]:='count'; WriteMtlStrucNames(TargetStream,StrucNames); for k:=0 to Length(MrkDesc.N)-1 do begin for i:=0 to length(MrkTrialStat)-1 do begin PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,''); SetLength(StrucNames,3); StrucNames[0]:='x'; StrucNames[1]:='y'; StrucNames[2]:='z'; WriteMtlStrucNames(TargetStream,StrucNames); WriteMtlVecVarDouble(true,TargetStream,'',MrkTrialStat[i][k].mean.x); WriteMtlVecVarDouble(true,TargetStream,'',MrkTrialStat[i][k].mean.y); WriteMtlVecVarDouble(true,TargetStream,'',MrkTrialStat[i][k].mean.z); CompleteMtlTag; PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,1)); WriteMtlName(TargetStream,''); SetLength(StrucNames,3); StrucNames[0]:='x'; StrucNames[1]:='y'; StrucNames[2]:='z'; WriteMtlStrucNames(TargetStream,StrucNames); WriteMtlVecVarDouble(true,TargetStream,'',MrkTrialStat[i][k].std.x); WriteMtlVecVarDouble(true,TargetStream,'',MrkTrialStat[i][k].std.y); WriteMtlVecVarDouble(true,TargetStream,'',MrkTrialStat[i][k].std.z); CompleteMtlTag; WriteMtlVarInteger(TargetStream,'',MrkTrialStat[i][k].count); end; end; CompleteMtlTag; CompleteMtlTag; //trials PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,length(TrialArray))); WriteMtlName(TargetStream,'trials'); SetLength(StrucNames,7); StrucNames[0]:='adc'; StrucNames[1]:='dig'; StrucNames[2]:='mrk'; StrucNames[3]:='adcfname'; StrucNames[4]:='mrkfname'; StrucNames[5]:='adcdattim'; StrucNames[6]:='mrkdattim'; WriteMtlStrucNames(TargetStream,StrucNames); for i:=0 to length(TrialArray)-1 do begin WriteMtlMatVarSingle(TargetStream,'',TrialArray[i].ADC); WriteMtlVecVarWord(True,TargetStream,'',TrialArray[i].Dig); PrimeMtlTag(TargetStream,miMatrix); WriteMtlArrayFlags(TargetStream,mxStructC,0); WriteMtlDimmensions(TargetStream,GetMatDim(1,length(TrialArray[i].mrk))); WriteMtlName(TargetStream,''); SetLength(StrucNames,5); StrucNames[0]:='x'; StrucNames[1]:='y'; StrucNames[2]:='z'; StrucNames[3]:='Nan'; StrucNames[4]:='Spike'; WriteMtlStrucNames(TargetStream,StrucNames); for k:=0 to length(TrialArray[i].mrk)-1 do begin WriteMtlVecVarSingle(True,TargetStream,'',TrialArray[i].mrk[k].x); WriteMtlVecVarSingle(True,TargetStream,'',TrialArray[i].mrk[k].y); WriteMtlVecVarSingle(True,TargetStream,'',TrialArray[i].mrk[k].z); WriteMtlVecVarInteger(True,TargetStream,'',TrialArray[i].mrk[k].Nan); WriteMtlVecVarInteger(True,TargetStream,'',TrialArray[i].mrk[k].Spike); end; CompleteMtlTag; WriteMtlVarString(TargetStream,'',TrialArray[i].voltageFilNam); WriteMtlVarString(TargetStream,'',TrialArray[i].markerFilNam); WriteMtlVarString(TargetStream,'',TrialArray[i].adcDateTime); WriteMtlVarString(TargetStream,'',TrialArray[i].mrkDateTime); end; CompleteMtlTag; TargetStream.SetSize(TargetStream.Position); try TargetStream.SaveToFile(fname); except on e:EWriteError do begin CleanUpFile(fname); e.Message:=fname+' ['+e.message+']'; raise; end; on e:EFCreateError do begin e.Message:=fname+' ['+e.message+']'; raise; end; end; finally TargetStream.Free; end; end;