Matmap Documentation


[documentation home]
Contents

Using timeseries (TS) in the matlab environment
Reading data
Writing Data
Calibrating data
Creating new timeseries objects
Maintaining the TS array

Using timeseries (TS) in the matlab environment

This section will shortly describe how to read and write and change timeseries data in matlab using the matmap system. In the system a timeseries object is considered to consist of  a number of leads having one time signal. In order to represent the time series a structured matrix is used whose fields represent the different properties of the  timeseries. In matlab it is not necesarry to prescribe which properties an object needs to have, fields can be added whenever new properties need to be added. In order to have coherent objects a series of properties is predefined and need to be there for the software to use the data. Most of the functions are written in such a way that whenever a field is missing it will ignore that field and use some kind of default.

The fields that currently can be found in a TS (timeseries) object are the following

filename: The name of the file. This field is mainly for the internal organisation of the software. It becomes useful when processing large amounts of data. Whenever a filename is set it can be used for saving the file. Note: that the filename must be an new filename in order for the software to automatically save files. A safety mechanism prevents the software from overwriting old files.

newfileext: In case a file is being processed a new extension can be rendered by adding a short string here. This extension will be added before the '.tsdf' extension. In case a completely new filename needs to be given to the file, clear the filename field and add the new name to the newfileext field.  (Suggestions for better naming conventions are welcome!) Note, that when writing a file a new filename can always be entered manually in which case the filename and newfileext field are completely ignored.

label: A string containing the label entered when the data wa recorded. This label can be changed, but it is strongly recommended to keep the original label as it describes some of the physiology under which the data was recorded.

potvals: A matrix with all the potential values. This is the actual data!! The matrix format is number of leads X number of frames. The data in this matrix can be of the type double for tsdf files or unsigned integers for acq files.

numleads: The number of leads. This field will be generated by the reader, but is not used by the software. Please do not use this field in the code. Instead use the size of the potvals matrix. (the field exists for backwards compatibility, but maybe removed in the future)

numframes:
The number of frames. This field will be generated by the reader, but is not used by the software. Please do not use this field in the code. Instead use the size of the potvals matrix. (the field exists for backwards compatibility, but maybe removed in the future)

leadinfo: Information on the quality of the leads. This is a unit32 vector with the bits representing different attributes of the leads:
bit 1 indicates a bad channel, bit 2 indicates a blank channel and bit 3 indicates that the data has be interpolated. It is up to the software to decide whether to set these bits. The only functions setting any of these bits are the interpolation algorithms.

unit: The unit of the data. The software will recognise most of the units and transform them in the proper code stored in the tsdf format. If it is not  a valid  value an unknown unit will be entered. This will not affect the code in most cases. This field is only updated when rendering intergration maps or performing the calibration from integer data to real valued data.

geom: Not used anymore will be removed in future version.
 
geomfile: A data string stored in the tsdf fileformat but not used by the software.

audit: The audit string. Most functions will add an audit string to tell in which way the data has been altered.

expid: Another string stored in the TSDF fileformat with the ID of the experiment.

text: A field containing extra information added during the experiments. Often this field remains empty as there is no additional data entered during the experiment.

All these fields are spelled using a lower case.

Before describing how to access these fields in matlab another concept has to be covered, namely the notion of global variables and cell arrays. One of the crucial points is to be able to process multiple data sets at once (this will speed up the processing time). For this purpose multiple timeseries objects can be stored at the same time. In order to group multiple timeseries, a cell array is used. A cell array is nothing more than a collection of arrays in this case structured arrays containing the different timeseries fields (e.g. potvals) as discussed above. Each cell of the cell array contains a full description of a timeseries, e.g. if the cell array has four cells it can hold the descriptions of four timeseries objects.

To complicate matters further (this is the last difficulty), a timeseries can occupy a considerable amount of memory. Since matlab does not know the concept of pointers, data is copied every time a function is called. With multiple layers of function calls this leads to a large overhead in memory consumption, which may stall the computer. To avoid all these troubles all together, the data is stored in a global called TS, which is accesible for all functions without the need of additional copies.

This TS global is defined by the matmap script and can hold several timeseries (i.e. it is a cell array). This TS cell array is defined as a one dimensional array and the index numbers are used to specify the timeseries. The first time series will be loaded into the first cell, the next will be created in the second cell and so on. In case a time series is deleted its cell will be filled with an empty array. If later on a new time series has to be created, these empty spots may be used to store new timeseries.

Examples of using the TS array

Data can be loaded into the TS array as follows:

>> newindex = ioReadTS('mytsdffile.tsdf')
This will load the data of the tsdf file into a structured matrix and this structured matrix is put into the cell array called TS. The newindex number the function is returning is the position of the data in the TS array. (If this is the first file newindex will be one)

To get an overview of the data just loaded:
>> TS{newindex}
This will list all the fields of this timeseries object

In order to look at a specific lead one may type the following:
>> plot(TS{newindex}.potvals(1,:))
This will plot the data of the first lead. In this case the function plot just plots the vector it received on in a figure. This example also illustrates how to access a field in a time series. The (1,:) behind the time series speficies the 1st row, which is the data of the first channels.

The data can also be put in a separate vector:
>> channel1 = TS{newindex}.potvals(1,:)

Similarly data can be altered, e.g. changing the audit string:
>> TS{newindex}.audit = 'my own audit string'

In case the structured array with the timeseries data needs to be put in a separate variable:
>> timeseriesdata = TS{newindex}



Reading data

Most of the functionality needed for reading data into the TS array is contained in the function ioReadTS(filename). This function supports reading most of the CVRTI native fileformats like .acq, .tsdf, .tsdfc,  and .data files.

For example, in order to load a file called mydata.tsdf use the following statement

>> newindex = ioReadTS('mydata.tsdf')
This will load the data contained in mydata.tsdf into the TS global.

Currently this function needs the extension of the filename in order to choose the proper reader. It cannot yet detect by itself what kind of fileformat a certain file is using and uses the filename extension to determine the fileformat.

ACQ files

There is support for the raw acquistion files called '.acq'. In order to read these files properly a mapping and a calibration file have to be added to load all of these into the TS array use the following:

>> index = ioReadTS('mydata.acq','calibration.cal','mappingfile.mapping')
As long as extension are used the reader will know what to do with the files and thence the order does not matter. A newer form of calibration files are supported as well, called '.cal8'. Since the multiplexer contains 8 gain settings this file stores up to eight calibration values for each gain setting one calibration value.

TSDFC files


In the file formats used at CVRTI, there are container files which specify additional options for the tsdf files. These container files can be read as well:

>> index = ioReadTS('mydata.tsdf','mycontainer.tsdfc');
This will read the data stored in the containers. Currently only fiducials are stored in these containers. Adding a container file will cause the creation of two additional fields in the timeseries structure:

fids: A structured array containing the different fiducials. This field is structured again with fields: value (a time instant), type (the type of the fiducial), fidset (to which fiducial set does it belong). The latter fidset indicator is normally generated by Everett and indicates to which group of fiducials it belongs. In matlab this indicator can be set, but it is advised to keep it zero. In the latter case matlab will generate a fiducial set, which can be used by other software packages such as Everett.

fidset: A description of a fiducial set, this structure contains a cell array with different fiducials sets. Since fiducial sets are automatically generated, no further description follows. Loading data generated by Everett will illustrate which fields exist and what data can be stored here. Use this field only if the data has to be displayed in a certain way in the Everett package, otherwise ignore the fidset array all together. (There is no important data stored in this one anyway).


Multiple TSDF files

The ioReadTS function is fully vectorized, multiple files can be read at once and even wildcards can be used:

>> indices = ioReadTS('mydata-003?.tsdf');
This will read all files that conform the wildcard pattern

or

>> indices  = ioReadTS('mydata-0001.tsdf','mydata-0002.tsdf');
This will read two files at the same time


Reading files without the TS global

More recently support has been added to circumvent the TS array all together and the  ioReadTSdata(filename) will read the data  directly into a variable:

>> data = ioReadTSdata('mydata.tsdf')
>> data{1}
This will make a local cell array with all the different time series specified in the 'mydata.tsdf' file. In this case there is only one time series, but there are occasions that there are more than one time series and hence the data is returned as a cell array, so multiple timeseries can be returned at once. The ioReadTSdata function has the same functionality and input options as the ioReadTS function.




Writing Data

Like reading data, there is also a function for Writing data. This function is called ioWriteTS(filename,TSindex).

For example when the data is stored in TS{2}:
>> ioWriteTS(2,'mynewtsdf.tsdf')
This will write the data into a TSDF file.

When there fiducials as well, data can be written into a container file as well
>> ioWriteTS(2,'mynewtsdf.tsdf','mycontainerfile.tsdfc')
This will create the container file if needed and add the fiducials in the container file.

In case a file is being overwritten the function will always prompt whether the file can be overwritten. In case of an automated script this is often annoying. Use the following stop the function from asking whether it can overwrite a file.
>> ioWriteTS(2,'mynewtsdf.tsdf','noprompt')

In case the filename field contains the same name as the new filename, its original is being overwritten. This is often not wanted and hence the software won't allow this unless explicitly instructed:
>> ioWriteTS(2,'mynewtsdf.tsdf','noprompt','oworiginal')
This will release all safely mechanisms!

The time series data can be written directly without the TS array as well
>> ioWriteTS(data,'mynewtsf.tsdf')


Calibrating data

In order to calibrate a timeseries (reading acq files) a calibration file need to be created. This calibration file is created out of the calibration recordings made at the start of the end of an experiment. In order to calibrate a signal use the following function sigCalibrate8(). This function will render the newer '.cal8' files which can be used directly with ioReadTS(). The function can be used as follows:

>> sigCalibrate8('calibfile1.acq','calibfile2.acq','mymappingfile.mapping','newcal8file.cal8')
Here calibfile1.acq and calibfile2.acq contain the calibration settings for different gain settings or calibration signal strength. The function figures out automatically what it has to do and writes a new calibration file. Note, it needs a mapping to order the channels in the proper order. In this sense the calibration file is compatible with the old '.cal' files

In case one wants to see what calibration values are used, the sigCalibrate8() function also returns the calibration settings:
>> cal = sigCalibrate8('calibfile1.acq','calibfile2.acq','mymappingfile.mapping','newcal8file.cal8')
Now cal is a [N times 8] matrix with calibration settings for each gain setting

Calibrating the data itself is done while loading the data:
>> index = ioReadTS('mydata.acq','calibration.cal8','mymappingfile.mapping')


Creating new timeseries objects


A new timeseries object can be generate by creating a new structure on the TS array. The function tsNewinit(numofentries) will create a new empty structure on the TS array, so one does not need to worry which fields need to be created.

For example:
>> newindex = tsNewInit(1)
Will create a new time series object

The next thing is to create data and add data to the object e.g.
>> data = rand(10,30);
>> TS{newindex}.potvals = data;
These two statements will create the data and add them to the time series.

To write them to a tsdf file is now a simple step
>> ioWriteTS('myfilename.tsdf',newindex)


Maintaining the TS array

Creating a new entry on the TS array

Space on the TS array can be found by using the function tsNew(numberofcells):
>> indices = tsNew(2);
this will return two indices that are currently not in use. This will not reserve the space until something is put into the cells.
Hence calling tsNew twice without adding any data to the fields will find the same empty spots in the TS array

In case space on the TS array needs to be reserved use the function tsNewInit(numberofcells):
>> indices = tsNewInit(2);
This will create empty time series structures that will be added to the TS array


Removing entries from the TS array


Entries can be remove by tsClear(indexnumbers).
>> tsClear(indices);
To clear all fields at once use
>> tsClear


Using TS array in functions

When using the TS array in a function, make sure to declare TS global:
>> global TS;
In case TS is not declared global, matlab will assume it is a local variable, which is different from the global TS in the global workspace.


[documentation home]