00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "io_matlab.h"
00022
00023 #ifdef MATIO
00024 #include <matio.h>
00025
00026
00027
00028 double get_double_from_struct_field( matvar_t *eeg, const char *name, int struct_array_index );
00029
00045 EEG* read_eeglab_file( const char *file ){
00046 mat_t *mat;
00047 matvar_t *meeg;
00048 matvar_t *tmp, *tmp2, *event, *epoch;
00049 int nfields;
00050 int c,i,j;
00051 EEG *eeg;
00052 int nbchan, ntrials, n;
00053
00054 dprintf("Reading file: '%s'\n", file);
00055 mat = Mat_Open( file, MAT_ACC_RDONLY);
00056 if( !mat ){
00057 errprintf("Error opening MATLAB file '%s'\n", file );
00058 return NULL;
00059 }
00060 meeg = Mat_VarRead( mat, "EEG" );
00061 if( meeg->class_type!=MAT_C_STRUCT ){
00062 errprintf("EEG does not appear to be a struct\n" );
00063 return NULL;
00064 }
00065 nfields = Mat_VarGetNumberOfFields( meeg );
00066 #ifdef DEBUG
00067 dprintf( "There are %i fields in the EEG struct\n", nfields );
00068 for( i=1; i<=nfields; i++ ){
00069 tmp = Mat_VarGetStructField( meeg, &i, BY_INDEX, 0 );
00070 dprintf("Found field: '%s'\n", tmp->name);
00071 }
00072 #endif
00073
00074
00075 nbchan = (int)get_double_from_struct_field( meeg, "nbchan",0 );
00076 ntrials= (int)get_double_from_struct_field( meeg, "trials",0 );
00077 n = (int)get_double_from_struct_field( meeg, "pnts",0 );
00078 dprintf("dim=(%i,%i,%i)\n", nbchan,ntrials,n);
00079 eeg = eeg_init( nbchan, ntrials, n );
00080
00081
00082 eeg->filename=(char*)malloc( (strlen(file)+2)*sizeof(char) );
00083 strcpy( eeg->filename, file );
00084
00085
00086 tmp = Mat_VarGetStructField( meeg, "comments", BY_NAME, 0 );
00087 eeg->comment=(char*)malloc( tmp->dims[0]*sizeof(char) );
00088 for( i=0; i<tmp->dims[0]+1; i++ ){
00089 eeg->comment[i]='\0';
00090 }
00091 memcpy( eeg->comment, tmp->data, tmp->dims[0]*sizeof(char));
00092
00093
00094 eeg->sampling_rate = get_double_from_struct_field( meeg, "srate", 0);
00095
00096
00097 tmp = Mat_VarGetStructField( meeg, "times", BY_NAME, 0 );
00098 if( tmp->dims[1]==0 && ntrials == 1){
00099 dprintf("Continuous data, skipping times-array\n");
00100 } else if( tmp->dims[1]!=n ){
00101 errprintf("times-array should be of length n: %i != %i\n", tmp->dims[1], n );
00102 eeg_free( eeg );
00103 return NULL;
00104 } else {
00105 if( tmp->data_size != sizeof(double) ){
00106 errprintf("times is not double format, %i!=%li\n", tmp->data_size, sizeof(double));
00107 eeg_free( eeg );
00108 return NULL;
00109 }
00110 eeg->times=array_new2( DOUBLE, 1, n );
00111 memcpy(eeg->times->data, tmp->data, n*sizeof(double) );
00112 }
00113
00114
00115 eeg->chaninfo = (ChannelInfo*)malloc( nbchan*sizeof(ChannelInfo) );
00116 tmp = Mat_VarGetStructField( meeg, "chanlocs", BY_NAME, 0 );
00117 dprintf("chanlocs: %i,%i\n", tmp->dims[0], tmp->dims[1]);
00118
00119 for( i=0; i<nbchan; i++ ){
00120 tmp2 = Mat_VarGetStructField( tmp, "labels", BY_NAME, i );
00121 eeg->chaninfo[i].num = i;
00122 eeg->chaninfo[i].num_chans = nbchan;
00123 strcpy(eeg->chaninfo[i].label, (char*)tmp2->data);
00124 eeg->chaninfo[i].x = get_double_from_struct_field( tmp, "X", i);
00125 eeg->chaninfo[i].y = get_double_from_struct_field( tmp, "Y", i);
00126 eeg->chaninfo[i].z = get_double_from_struct_field( tmp, "Z", i);
00127 }
00128
00129
00130 tmp = Mat_VarGetStructField( meeg, "data", BY_NAME, 0 );
00131 if( ntrials==1 ) {
00132 if( tmp->dims[0]!=nbchan || tmp->dims[1]!=n ){
00133 errprintf("(nbchan,n)=(%i,%i), should be (%i,%i)\n",
00134 tmp->dims[0], tmp->dims[1], nbchan, n );
00135 eeg_free( eeg );
00136 return NULL;
00137 }
00138 } else if( tmp->dims[0]!=nbchan || tmp->dims[1]!=n || tmp->dims[2]!=ntrials ){
00139 errprintf("(nbchan,ntrials,n)=(%i,%i,%i), should be (%i,%i,%i)\n",
00140 tmp->dims[0], tmp->dims[2], tmp->dims[1], nbchan, ntrials, n );
00141 eeg_free( eeg );
00142 return NULL;
00143 }
00144 if( tmp->data_size != sizeof(float) ){
00145 errprintf("data is not in float format, sizeof(data)=%i, sizeof(float)=%li\n",
00146 tmp->data_size, sizeof(float));
00147 eeg_free( eeg );
00148 return NULL;
00149 }
00150 float x;
00151 for( c=0; c<nbchan; c++ ){
00152 for( i=0; i<ntrials; i++ ){
00153 for( j=0; j<n; j++ ){
00154 x=((float*)tmp->data)[ c + (j*nbchan) + (i*n*nbchan) ];
00155 array_INDEX3(eeg->data,double,c,i,j) = (double)x;
00156 }
00157 }
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 dprintf("Finished reading '%s'\n", file );
00191
00192 return eeg;
00193 }
00194
00204 Array* read_array_matlab( const char *file, const char *varname ){
00205 mat_t *mfile;
00206 matvar_t *marr=NULL;
00207
00208 dprintf("Reading variable '%s' from file: '%s'\n", varname, file);
00209 mfile = Mat_Open( file, MAT_ACC_RDONLY);
00210 if( !mfile ){
00211 errprintf("Error opening MATLAB file '%s'\n", file );
00212 return NULL;
00213 }
00214
00215 if( varname ){
00216 marr = Mat_VarRead( mfile, varname );
00217 } else {
00218 marr = Mat_VarReadNext( mfile );
00219 }
00220 Mat_Close( mfile );
00221 dprintf("Done\n");
00222
00223 if( !marr ){
00224 errprintf("Something is wrong, could not read variable\n");
00225 return NULL;
00226 }
00227 Array *out=array_new( DOUBLE, marr->rank, marr->dims );
00228
00229 ulong i;
00230 uint *index=(uint*)malloc( out->ndim*sizeof(uint));
00231 for( i=0; i<marr->nbytes/marr->data_size; i++ ){
00232 array_calc_colindex( i, out->size, out->ndim, index );
00233
00234 switch( marr->data_type ){
00235 case MAT_T_INT8:
00236 *((double*)array_index(out,index))=(double)(*(int8_t*)(marr->data+(i*marr->data_size)));
00237 break;
00238 case MAT_T_UINT8:
00239 *((double*)array_index(out,index))=(double)(*(uint8_t*)(marr->data+(i*marr->data_size)));
00240 break;
00241 case MAT_T_INT16:
00242 *((double*)array_index(out,index))=(double)(*(int16_t*)(marr->data+(i*marr->data_size)));
00243 break;
00244 case MAT_T_UINT16:
00245 *((double*)array_index(out,index))=(double)(*(uint16_t*)(marr->data+(i*marr->data_size)));
00246 break;
00247 case MAT_T_INT32:
00248 *((double*)array_index(out,index))=(double)(*(int32_t*)(marr->data+(i*marr->data_size)));
00249 break;
00250 case MAT_T_UINT32:
00251 *((double*)array_index(out,index))=(double)(*(uint32_t*)(marr->data+(i*marr->data_size)));
00252 break;
00253 case MAT_T_INT64:
00254 *((double*)array_index(out,index))=(double)(*(int64_t*)(marr->data+(i*marr->data_size)));
00255 break;
00256 case MAT_T_UINT64:
00257 *((double*)array_index(out,index))=(double)(*(uint64_t*)(marr->data+(i*marr->data_size)));
00258 break;
00259 case MAT_T_SINGLE:
00260 *((double*)array_index(out,index))=(double)(*(float*)(marr->data+(i*marr->data_size)));
00261 break;
00262 case MAT_T_DOUBLE:
00263 *((double*)array_index(out,index))=(double)(*(double*)(marr->data+(i*marr->data_size)));
00264 break;
00265 default:
00266 errprintf("Unknown Data-Type in MATLAB-file!\n");
00267 break;
00268 }
00269 }
00270 free(index);
00271
00272 return out;
00273 }
00274
00275 double get_double_from_struct_field( matvar_t *eeg, const char *name, int struct_array_index ){
00276 matvar_t *tmp;
00277
00278 tmp = Mat_VarGetStructField( eeg, (char*)name, BY_NAME, struct_array_index );
00279 if( tmp->rank != 1 && tmp->dims[0]<1 ){
00280 errprintf("field '%s' wrong, rank=%i,tmp->dims[0]=%i\n",name, tmp->rank,tmp->dims[0] );
00281 return -1;
00282 }
00283 dprintf( "found: %s=%f\n", name, (((double*)tmp->data)[0]) );
00284 return (((double*)tmp->data)[0]);
00285 }
00286
00287
00288
00289
00290
00291
00303 int write_eeglab_file( EEG* eeg, const char *file ){
00304 mat_t *mfile;
00305 matvar_t *meeg=NULL;
00306 if( !(mfile=Mat_Create( file, NULL )) ){
00307 errprintf("Could not open '%s' for writing\n", file);
00308 return -1;
00309 }
00310
00311
00312
00313
00314 Mat_VarWrite( mfile, meeg, 0 );
00315 return 0;
00316 }
00317
00330 int write_array_matlab( const Array *a, const char *varname, const char *file, bool append ){
00331 mat_t *mfile;
00332 matvar_t *marr=NULL;
00333 int i;
00334
00335 if( append ){
00336 if( !(mfile=Mat_Open( file, MAT_ACC_RDWR )) ){
00337 errprintf("Could not open '%s', creating new file\n", file);
00338 }
00339 }
00340
00341 if( !mfile ){
00342 if( !(mfile=Mat_Create( file, NULL )) ){
00343 errprintf("Could not open '%s' for writing\n", file);
00344 return -1;
00345 }
00346 }
00347
00348 int ndim = MAX(2, a->ndim);
00349 int *size = (int*)malloc( ndim*sizeof(int));
00350 if( a->ndim==1 ){
00351 size[0]=1;
00352 size[1]=a->size[0];
00353 } else {
00354 memcpy( size, a->size, ndim*sizeof(int));
00355 }
00356 dprintf("Writing to file '%s' variable '%s', ndim=%i\n", file, varname, ndim);
00357
00358
00359 Array *b=array_convert_rowcolmajor( (Array*)a, TRUE );
00360
00361
00362 Array *c=array_new( DOUBLE, b->ndim, b->size );
00363 for( i=0; i<array_NUMEL(b); i++ ){
00364 array_dtype_to_double( array_INDEXMEM1(c,i), array_INDEXMEM1(b,i), b->dtype );
00365 }
00366 array_free( b );
00367
00368
00369 marr = Mat_VarCreate( varname, MAT_C_DOUBLE, MAT_T_DOUBLE,
00370 ndim, size, c->data, MEM_CONSERVE
00371 );
00372
00373 dprintf("mfile=%p, marr=%p, rank=%i,\n", mfile, marr, marr->rank );
00374 int succ=Mat_VarWrite( mfile, marr, 0 );
00375 dprintf("done writing with succ=%i\n", succ);
00376
00377 Mat_Close( mfile );
00378 Mat_VarFree( marr );
00379 array_free( c );
00380 free( size );
00381
00382 return 0;
00383 }
00384 #endif
00385
00386