int CreateStructVariable(void *pvApiCtx, int iVar, matvar_t *matVariable, int * parent, int item_position) { char **fieldNames = NULL; int nbFields = 0; int fieldIndex = 0; int K = 0; int prodDims = 0; int valueIndex = 0; matvar_t *fieldMatVar = NULL; matvar_t ** allData = NULL; int * cell_addr = NULL; int * cell_entry_addr = NULL; int type; SciErr sciErr; int *piDims = NULL; int i = 0; /* Fields of the struct */ nbFields = 2; /* "st" "dims" */ nbFields += Mat_VarGetNumberOfFields(matVariable); fieldNames = (char**) MALLOC(sizeof(char*) * nbFields); if (fieldNames == NULL) { Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable"); return FALSE; } fieldNames[0] = strdup("st"); if (fieldNames[0] == NULL) { Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable"); return FALSE; } fieldNames[1] = strdup("dims"); if (fieldNames[1] == NULL) { Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable"); return FALSE; } for (fieldIndex = 1; fieldIndex < nbFields - 1; fieldIndex++) { fieldMatVar = Mat_VarGetStructField(matVariable, &fieldIndex, MAT_BY_INDEX, 0); fieldNames[fieldIndex + 1] = strdup(fieldMatVar->name); if (fieldNames[fieldIndex + 1] == NULL) { Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable"); return FALSE; } } /* Returned mlist initialization */ if (parent == NULL) { sciErr = createMList(pvApiCtx, iVar, nbFields, &cell_addr); if (sciErr.iErr) { printError(&sciErr, 0); return 0; } } else { sciErr = createMListInList(pvApiCtx, iVar, parent, item_position, nbFields, &cell_addr); if (sciErr.iErr) { printError(&sciErr, 0); return 0; } } /* FIRST LIST ENTRY: fieldnames */ sciErr = createMatrixOfStringInList(pvApiCtx, iVar, cell_addr, 1, 1, nbFields, fieldNames); if (sciErr.iErr) { printError(&sciErr, 0); return 0; } /* SECOND LIST ENTRY: Dimensions (int32 type) */ if (nbFields == 2) /* Empty struct must have size 0x0 in Scilab */ { matVariable->dims[0] = 0; matVariable->dims[1] = 0; } piDims = (int *) MALLOC(matVariable->rank * sizeof(int)); for (i = 0 ; i < matVariable->rank ; ++i) { piDims[i] = (int)matVariable->dims[i]; } if (matVariable->rank == 2) /* Two dimensions */ { sciErr = createMatrixOfInteger32InList(pvApiCtx, iVar, cell_addr, 2, 1, matVariable->rank, piDims); if (sciErr.iErr) { printError(&sciErr, 0); return 0; } } else /* 3 or more dimensions -> Scilab HyperMatrix */ { type = I_INT32; CreateHyperMatrixVariable(pvApiCtx, iVar, MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE, &type, &matVariable->rank, piDims, (double*)matVariable->data, NULL, cell_addr, 2); } FREE(piDims); /* ALL OTHER ENTRIES: Fields data */ prodDims = 1; for (K = 0; K < matVariable->rank; K++) { prodDims *= (int)matVariable->dims[K]; } allData = (matvar_t**) (matVariable->data); if (prodDims == 1) /* Scalar struct */ { for (fieldIndex = 0; fieldIndex < nbFields - 2; fieldIndex++) { /* Create list entry in the stack */ if (!CreateMatlabVariable(pvApiCtx, iVar, allData[fieldIndex], cell_addr, fieldIndex + 3)) /* Could not Create Variable */ { if (allData[fieldIndex]->class_type != 0) /* class is 0 for not initialized fields */ { sciprint("Do not know how to read a variable of class %d.\n", allData[fieldIndex]->class_type); } } } } else { for (fieldIndex = 0; fieldIndex < nbFields - 2; fieldIndex++) { sciErr = createListInList(pvApiCtx, iVar, cell_addr, fieldIndex + 3, prodDims, &cell_entry_addr); if (sciErr.iErr) { printError(&sciErr, 0); return 0; } for (valueIndex = 0; valueIndex < prodDims; valueIndex++) { /* Create list entry in the stack */ if (!CreateMatlabVariable(pvApiCtx, iVar, allData[(fieldIndex) + (nbFields - 2)*valueIndex], cell_entry_addr, valueIndex + 1)) /* Could not Create Variable */ { if (allData[(fieldIndex) + (nbFields - 2)*valueIndex]->class_type != 0) /* class is 0 for not initialized fields */ { sciprint("Do not know how to read a variable of class %d.\n", allData[(fieldIndex) + (nbFields - 2)*valueIndex]->class_type); } } } } } freeArrayOfString(fieldNames, nbFields); return TRUE; }
static void print_default(matvar_t *matvar) { if ( NULL == matvar ) return; switch ( matvar->class_type ) { case MAT_C_DOUBLE: case MAT_C_SINGLE: case MAT_C_INT64: case MAT_C_UINT64: case MAT_C_INT32: case MAT_C_UINT32: case MAT_C_INT16: case MAT_C_UINT16: case MAT_C_INT8: case MAT_C_UINT8: { if ( matvar->rank == 2 ) print_default_numeric_2d(matvar); else if ( matvar->rank == 3 ) print_default_numeric_3d(matvar); break; } case MAT_C_CHAR: case MAT_C_SPARSE: Mat_VarPrint(matvar, printdata); break; case MAT_C_STRUCT: { matvar_t **fields = (matvar_t **)matvar->data; int nfields; int i; size_t nmemb; if ( matvar->name ) Mat_Message(" Name: %s", matvar->name); Mat_Message(" Rank: %d", matvar->rank); if ( matvar->rank == 0 ) return; Mat_Message("Class Type: Structure"); nfields = Mat_VarGetNumberOfFields(matvar); nmemb = matvar->dims[0]; for ( i = 1; i < matvar->rank; i++ ) nmemb *= matvar->dims[i]; if ( nfields > 0 && nmemb < 1 ) { char * const *fieldnames = Mat_VarGetStructFieldnames(matvar); Mat_Message("Fields[%d] {", nfields); indent++; for ( i = 0; i < nfields; i++ ) Mat_Message(" Name: %s", fieldnames[i]); indent--; Mat_Message("}"); } else if ( nfields > 0 && nmemb > 0 ) { Mat_Message("Fields[%d] {", nfields); indent++; for ( i = 0; i < nfields*nmemb; i++ ) print_default(fields[i]); indent--; Mat_Message("}"); } break; } case MAT_C_CELL: { matvar_t **cells = (matvar_t **)matvar->data; size_t ncells; int i; if ( matvar->name ) Mat_Message(" Name: %s", matvar->name); Mat_Message(" Rank: %d", matvar->rank); if ( matvar->rank == 0 ) return; ncells = matvar->dims[0]; for ( i = 1; i < matvar->rank; i++ ) ncells *= matvar->dims[i]; Mat_Message("Class Type: Cell Array"); Mat_Message("{"); indent++; for ( i = 0; i < ncells; i++ ) print_default(cells[i]); indent--; Mat_Message("}"); break; } default: Mat_Message("Empty"); } }
/** \brief read EEG struct from EEGlab (MATLAB) .set-file. This reader uses MatIO to parse EEGlab files and construct a LibEEGTools EEG struct. It was developed with EEGlab version 6.01b. Currently, the EEGlab set must be "epoched", that means that the data must be three-dimensional with channels x n x trials. Continuous data is not yet supported and the reader will fail. The reader currently works only if the storage is in single .set file (as opposed to a pair of .set and .dat file). \param file eeglab .set file \return the EEG struct */ EEG* read_eeglab_file( const char *file ){ mat_t *mat; matvar_t *meeg; /* contains the struct 'EEG' from EEGlab */ matvar_t *tmp, *tmp2, *event, *epoch; int nfields; int c,i,j; EEG *eeg; int nbchan, ntrials, n; dprintf("Reading file: '%s'\n", file); mat = Mat_Open( file, MAT_ACC_RDONLY); if( !mat ){ errprintf("Error opening MATLAB file '%s'\n", file ); return NULL; } meeg = Mat_VarRead( mat, "EEG" ); if( meeg->class_type!=MAT_C_STRUCT ){ errprintf("EEG does not appear to be a struct\n" ); return NULL; } nfields = Mat_VarGetNumberOfFields( meeg ); #ifdef DEBUG dprintf( "There are %i fields in the EEG struct\n", nfields ); for( i=1; i<=nfields; i++ ){ /* MATLAB 1-relative indices */ tmp = Mat_VarGetStructField( meeg, &i, BY_INDEX, 0 ); dprintf("Found field: '%s'\n", tmp->name); } #endif /* dimensions */ nbchan = (int)get_double_from_struct_field( meeg, "nbchan",0 ); ntrials= (int)get_double_from_struct_field( meeg, "trials",0 ); n = (int)get_double_from_struct_field( meeg, "pnts",0 ); dprintf("dim=(%i,%i,%i)\n", nbchan,ntrials,n); eeg = eeg_init( nbchan, ntrials, n ); /* filename */ eeg->filename=(char*)malloc( (strlen(file)+2)*sizeof(char) ); strcpy( eeg->filename, file ); /* comments */ tmp = Mat_VarGetStructField( meeg, "comments", BY_NAME, 0 ); eeg->comment=(char*)malloc( tmp->dims[0]*sizeof(char) ); for( i=0; i<tmp->dims[0]+1; i++ ){ eeg->comment[i]='\0'; } memcpy( eeg->comment, tmp->data, tmp->dims[0]*sizeof(char)); /* sampling rate */ eeg->sampling_rate = get_double_from_struct_field( meeg, "srate", 0); /* times */ tmp = Mat_VarGetStructField( meeg, "times", BY_NAME, 0 ); if( tmp->dims[1]==0 && ntrials == 1){ // continuous data dprintf("Continuous data, skipping times-array\n"); } else if( tmp->dims[1]!=n ){ errprintf("times-array should be of length n: %i != %i\n", tmp->dims[1], n ); eeg_free( eeg ); return NULL; } else { if( tmp->data_size != sizeof(double) ){ errprintf("times is not double format, %i!=%li\n", tmp->data_size, sizeof(double)); eeg_free( eeg ); return NULL; } eeg->times=array_new2( DOUBLE, 1, n ); memcpy(eeg->times->data, tmp->data, n*sizeof(double) ); } /* channel info */ eeg->chaninfo = (ChannelInfo*)malloc( nbchan*sizeof(ChannelInfo) ); tmp = Mat_VarGetStructField( meeg, "chanlocs", BY_NAME, 0 ); dprintf("chanlocs: %i,%i\n", tmp->dims[0], tmp->dims[1]); for( i=0; i<nbchan; i++ ){ tmp2 = Mat_VarGetStructField( tmp, "labels", BY_NAME, i ); eeg->chaninfo[i].num = i; eeg->chaninfo[i].num_chans = nbchan; strcpy(eeg->chaninfo[i].label, (char*)tmp2->data); eeg->chaninfo[i].x = get_double_from_struct_field( tmp, "X", i); eeg->chaninfo[i].y = get_double_from_struct_field( tmp, "Y", i); eeg->chaninfo[i].z = get_double_from_struct_field( tmp, "Z", i); } /* data */ tmp = Mat_VarGetStructField( meeg, "data", BY_NAME, 0 ); if( ntrials==1 ) { // continuous data if( tmp->dims[0]!=nbchan || tmp->dims[1]!=n ){ errprintf("(nbchan,n)=(%i,%i), should be (%i,%i)\n", tmp->dims[0], tmp->dims[1], nbchan, n ); eeg_free( eeg ); return NULL; } } else if( tmp->dims[0]!=nbchan || tmp->dims[1]!=n || tmp->dims[2]!=ntrials ){ errprintf("(nbchan,ntrials,n)=(%i,%i,%i), should be (%i,%i,%i)\n", tmp->dims[0], tmp->dims[2], tmp->dims[1], nbchan, ntrials, n ); eeg_free( eeg ); return NULL; } if( tmp->data_size != sizeof(float) ){ errprintf("data is not in float format, sizeof(data)=%i, sizeof(float)=%li\n", tmp->data_size, sizeof(float)); eeg_free( eeg ); return NULL; } float x; for( c=0; c<nbchan; c++ ){ for( i=0; i<ntrials; i++ ){ for( j=0; j<n; j++ ){ x=((float*)tmp->data)[ c + (j*nbchan) + (i*n*nbchan) ]; array_INDEX3(eeg->data,double,c,i,j) = (double)x; } } } /* TODO CONTINUE HERE */ /* /\* markers *\/ */ /* epoch = Mat_VarGetStructField( meeg, "epoch", BY_NAME, 0 ); */ /* if( epoch->dims[0] == 0 || epoch->dims[1] < ntrials ){ */ /* warnprintf("no epoch field, or wrong dimensions (%i,%i), skipping...\n", */ /* epoch->dims[0],epoch->dims[1]); */ /* } else { */ /* eeg->nmarkers = (unsigned int*) malloc( ntrials*sizeof(unsigned int) ); */ /* eeg->markers = (unsigned int**) malloc( ntrials*sizeof(unsigned int*) ); */ /* eeg->marker_labels = (char***) malloc( ntrials*sizeof(char**) ); */ /* for( i=0; i<ntrials; i++ ){ */ /* tmp = Mat_VarGetStructField( epoch, "eventlatency", BY_NAME, i ); */ /* tmp2 = Mat_VarGetStructField( epoch, "eventtype", BY_NAME, i ); */ /* dprintf("%i, %i\n", i, tmp->dims[1]); */ /* eeg->nmarkers[i] = tmp->dims[1]; */ /* eeg->markers[i] = (unsigned int*) malloc( eeg->nmarkers[i]*sizeof(unsigned int) ); */ /* eeg->marker_labels[i] = (char**) malloc( eeg->nmarkers[i]*sizeof(char*) ); */ /* for( j=0; j<eeg->nmarkers[i]; j++ ){ */ /* /\* label *\/ */ /* event = Mat_VarGetCell( tmp2, j ); /\* MATLAB index *\/ */ /* eeg->marker_labels[i][j] = (char*)malloc( (strlen((char*)event->data)+1)*sizeof(char) ); */ /* strcpy( eeg->marker_labels[i][j], (char*)event->data ); */ /* /\* latency *\/ */ /* event = Mat_VarGetCell( tmp, j ); /\* MATLAB index *\/ */ /* eeg->markers[i][j] = closest_index( eeg->times, n, ((double*)event->data)[0] ); */ /* } */ /* } */ /* } */ dprintf("Finished reading '%s'\n", file ); return eeg; }