00001 #include "eeg.h"
00002 #include "helper.h"
00003 #include "mathadd.h"
00004
00005
00012 EEG* eeg_init ( int nbchan, int ntrials, int nsamples ){
00013 EEG *eeg;
00014
00015 dprintf("init\n");
00016 MALLOC( eeg, 1, EEG );
00017 eeg->nbchan = nbchan;
00018 eeg->ntrials= ntrials;
00019 eeg->n = nsamples;
00020 eeg->sampling_rate = -1;
00021
00022 dprintf("alloc data\n");
00023 eeg->times=NULL;
00024 eeg->data = array_new2( DOUBLE, 3, nbchan, ntrials, nsamples );
00025 eeg->filename=NULL;
00026
00027 eeg->comment=NULL;
00028 eeg->chaninfo=NULL;
00029
00030 eeg->markers=NULL;
00031 eeg->marker_type=NULL;
00032 eeg->marker_types=NULL;
00033
00034 eeg->additional=NULL;
00035 eeg->nbytes_additional=0;
00036
00037 return eeg;
00038 }
00043 void eeg_free( EEG *eeg ){
00044 safer_free( eeg->filename );
00045 safer_free( eeg->comment );
00046 array_free( eeg->times);
00047 array_free( eeg->data );
00048 array_free( eeg->markers );
00049 array_free( eeg->marker_type );
00050 slist_free( eeg->marker_types );
00051 if( eeg->additional )
00052 free( eeg->additional );
00053 safer_free( eeg->chaninfo );
00054 safer_free( eeg );
00055 }
00056
00057
00062 void eeg_append_comment( EEG *eeg, const char *comment ){
00063 if( !eeg->comment ){
00064 eeg->comment = (char*) malloc( (strlen(comment)+1)*sizeof(char) );
00065 strcpy( eeg->comment, comment );
00066 } else {
00067 eeg->comment = (char*) realloc( eeg->comment, (strlen(eeg->comment)+strlen(comment)+2)*sizeof(char) );
00068 strcpy( eeg->comment+strlen(eeg->comment), comment );
00069 }
00070 }
00071
00077 void eeg_print( FILE *out, const EEG *eeg, int preview ){
00078 int i;
00079 fprintf(out,
00080 "EEG:\n"
00081 " filename = '%s'\n"
00082 " comment = '%s'\n"
00083 " nbchan = %i\n"
00084 " ntrials = %i\n"
00085 " n = %i\n"
00086 " sampling_rate = %f\n",
00087 (eeg->filename)?(eeg->filename):"<NULL>",
00088 (eeg->comment)?(eeg->comment):"<NULL>",
00089 eeg->nbchan, eeg->ntrials,
00090 eeg->n, eeg->sampling_rate);
00091 if( eeg->times!=NULL ){
00092 fprintf(out,
00093 " times[0] = %f\n", array_INDEX1( eeg->times,double,0));
00094 fprintf(out,
00095 " times[n-1] = %f\n", array_INDEX1( eeg->times,double,eeg->n-1));
00096 } else {
00097 fprintf(out,
00098 " times[0] = <NULL>\n");
00099 }
00100 fprintf(out,
00101 " chaninfo = \n");
00102 if( eeg->chaninfo ){
00103 for( i=0; i<eeg->nbchan; i++ ){
00104 fprintf( out, " ");
00105 print_channelinfo( out, &(eeg->chaninfo[i]) );
00106 }
00107 } else {
00108 fprintf( out, " <NULL>\n");
00109 }
00110 fprintf( out, " data = \n" );
00111 array_print( eeg->data, preview, out );
00112
00113 }
00114
00115 #ifdef FIXEEG
00116
00119 bool eeg_cmp_depth( const EEG *eeg1, const EEG *eeg2 ){
00120 if( strcmp( eeg1->filename, eeg2->filename ) ){
00121 dprintf("Filenames to not match: %s != %s\n", eeg1->filename,
00122 eeg2->filename );
00123 return FALSE;
00124 }
00125 if( strcmp( eeg1->comment, eeg2->comment ) ){
00126 dprintf("Comments to not match: %s != %s\n", eeg1->comment,
00127 eeg2->comment );
00128 return FALSE;
00129 }
00130 if( eeg1->nbchan!=eeg2->nbchan ||
00131 eeg1->ntrials!=eeg2->ntrials ||
00132 eeg1->n!=eeg2->n ){
00133 dprintf("Main params do not match: (%i,%i,%i) != (%i,%i,%i)\n",
00134 eeg1->nbchan, eeg2->nbchan,
00135 eeg1->ntrials, eeg2->ntrials,
00136 eeg1->n, eeg2->n );
00137 return FALSE;
00138 }
00139 if( cmpdouble( eeg1->sampling_rate, eeg2->sampling_rate, 2 ) ){
00140 dprintf("sampling rate is different: %f!=%f\n", eeg1->sampling_rate,
00141 eeg2->sampling_rate );
00142 }
00143
00144
00145 return TRUE;
00146 }
00147
00152 EEG* eeg_init_markers ( int nmarkers_per_trial, EEG *eeg ){
00153 int i, j;
00154 eeg->nmarkers= (unsigned int*) malloc( eeg->ntrials*sizeof(unsigned int) );
00155 eeg->markers = (unsigned int**)malloc( eeg->ntrials*sizeof(unsigned int*) );
00156 eeg->marker_labels=(char***) malloc(eeg->ntrials*sizeof(char**) );
00157 for( i=0; i<eeg->ntrials; i++ ){
00158 eeg->nmarkers[i] = nmarkers_per_trial;
00159 eeg->markers[i] = (unsigned int*) malloc( nmarkers_per_trial*sizeof(unsigned int) );
00160 eeg->marker_labels[i] = (char**) malloc( nmarkers_per_trial*sizeof(char*) );
00161 for( j=0; j<nmarkers_per_trial; j++ ){
00162 eeg->marker_labels[i][j] = (char*)malloc( MAX_LABEL_LENGTH*sizeof(char) );
00163 sprintf( eeg->marker_labels[i][j], "Marker %i", j );
00164 }
00165 }
00166 return eeg;
00167 }
00168
00178 EEG* eeg_extract_channels( EEG* eeg, const int *channels, int nchannels, bool alloc ){
00179 EEG *outeeg;
00180 int c, i;
00181 int minus_nchannels;
00182
00183
00184 if( alloc ){
00185 outeeg = eeg_clone( eeg, EEG_CLONE_ALL );
00186 } else {
00187 outeeg = eeg;
00188 }
00189
00190 minus_nchannels = nchannels;
00191 for( c=0; c<nchannels; c++ ){
00192 if( channels[c]<0 || channels[c]>=outeeg->nbchan ){
00193 warnprintf("Skipping invalid channel '%i'\n", channels[c] );
00194 minus_nchannels--;
00195 continue;
00196 }
00197 }
00198
00199 for( c=0; c<outeeg->nbchan; c++ ){
00200 if( !isin_intarray( channels, nchannels, c ) ){
00201 if( outeeg->data ){
00202 dprintf("free data for channel '%i'\n", c );
00203 for( i=0; i<outeeg->ntrials; i++ )
00204 safer_free( outeeg->data[c][i] );
00205 safer_free( outeeg->data[c] );
00206 outeeg->data[c] = NULL;
00207 }
00208
00209 if( outeeg->chaninfo ){
00210 dprintf("mark chaninfo for channel '%i' for deletion\n", c );
00211 outeeg->chaninfo[c].num=-1;
00212 }
00213 }
00214 }
00215
00216
00217 bool moved;
00218 for( c=0; c<outeeg->nbchan; c++ ){
00219 moved=FALSE;
00220 if( !outeeg->data[c] ){
00221 for( i=c+1; i<outeeg->nbchan; i++ ){
00222 outeeg->data[i-1] = outeeg->data[i];
00223 }
00224 moved=TRUE;
00225 }
00226
00227 if( outeeg->chaninfo ){
00228 if( outeeg->chaninfo[c].num==-1 ){
00229 for( i=c+1; i<outeeg->nbchan; i++ ){
00230 memcpy( &(outeeg->chaninfo[i-1]), &(outeeg->chaninfo[i]),
00231 sizeof(ChannelInfo) );
00232 }
00233 moved=TRUE;
00234 }
00235 }
00236 if( moved ) {
00237 c--;
00238 outeeg->nbchan--;
00239 }
00240 }
00241
00242 outeeg->nbchan=minus_nchannels;
00243
00244 return outeeg;
00245 }
00246
00259 int eeg_check( EEG *eeg, int flags ){
00260 return -1;
00261 }
00262
00272 EEG* eeg_extract_trials ( EEG* eeg, const int *trials, int ntrials, bool alloc ){
00273 EEG *outeeg;
00274 int c,i,j;
00275 int minus_ntrials;
00276
00277 if( alloc ){
00278 outeeg = eeg_clone( eeg, EEG_CLONE_ALL );
00279 } else {
00280 outeeg = eeg;
00281 }
00282
00283 minus_ntrials = ntrials;
00284 for( i=0; i<ntrials; i++ ){
00285 if( trials[i]<0 || trials[i]>=outeeg->ntrials ){
00286 warnprintf("Skipping invalid Trial '%i'\n", trials[i] );
00287 minus_ntrials--;
00288 continue;
00289 }
00290 }
00291
00292 for( i=0; i<outeeg->ntrials; i++ ){
00293 if( !isin_intarray( trials, ntrials, i) ){
00294 dprintf("Removing data for trial '%i'\n", i);
00295 for( c=0; c<outeeg->nbchan; c++ ){
00296 safer_free( outeeg->data[c][i] );
00297 outeeg->data[c][i]=NULL;
00298 }
00299
00300 dprintf("Removing markers for trial '%i'\n", i);
00301 if( outeeg->markers ){
00302 safer_free( outeeg->markers[i] );
00303 outeeg->markers[i] = NULL;
00304 }
00305
00306 if( outeeg->marker_labels ){
00307 for( j=0; j<outeeg->nmarkers[i]; j++ ){
00308 safer_free( outeeg->marker_labels[i][j] );
00309 }
00310 safer_free( outeeg->marker_labels[i] );
00311 outeeg->marker_labels[i]=NULL;
00312 }
00313 if(outeeg->nmarkers )
00314 outeeg->nmarkers[i] = 0;
00315 }
00316 }
00317
00318
00319 bool moved;
00320 for( i=0; i<outeeg->ntrials; i++ ){
00321 moved=FALSE;
00322 for( c=0; c<outeeg->nbchan; c++ ){
00323 if( !outeeg->data[c][i] ){
00324 for( j=i+1; j<outeeg->ntrials; j++ ){
00325 outeeg->data[c][j-1] = outeeg->data[c][j];
00326 }
00327 moved=TRUE;
00328 }
00329 }
00330
00331 if( outeeg->markers[i]==NULL ){
00332 for( j=i+1; j<outeeg->ntrials; j++ ){
00333 outeeg->markers[j-1] = outeeg->markers[j];
00334 outeeg->nmarkers[j-1] = outeeg->nmarkers[j];
00335 if( outeeg->marker_labels ){
00336 outeeg->marker_labels[j-1] = outeeg->marker_labels[j];
00337 }
00338 }
00339 moved=TRUE;
00340 }
00341
00342 if( moved ) {
00343 i--;
00344 outeeg->ntrials--;
00345 }
00346 }
00347
00348 outeeg->ntrials = minus_ntrials;
00349 return outeeg;
00350 }
00351
00352
00353
00361 char* eeg_sprint( char *out, const EEG *eeg, int preview ){
00362 char *outptr;
00363 int adv;
00364 int c,i,j;
00365 int n=10000;
00366 if( out==ALLOC_IN_FCT ){
00367 out = (char*) malloc( n*sizeof(char));
00368 }
00369 outptr=out;
00370 adv=sprintf(outptr,
00371 "EEG:\n"
00372 " filename = '%s'\n"
00373 " comment = '%s'\n"
00374 " nbchan = %i\n"
00375 " ntrials = %i\n"
00376 " n = %i\n"
00377 " sampling_rate = %f\n",
00378 (eeg->filename)?(eeg->filename):"<NULL>",
00379 (eeg->comment)?(eeg->comment):"<NULL>",
00380 eeg->nbchan, eeg->ntrials,
00381 eeg->n, eeg->sampling_rate);
00382 outptr+=adv;
00383 if( eeg->times!=NULL ){
00384 adv=sprintf(outptr,
00385 " times[0] = %f\n", eeg->times[0]);
00386 outptr+=adv;
00387 adv=sprintf(outptr,
00388 " times[n-1] = %f\n", eeg->times[eeg->n-1]);
00389 outptr+=adv;
00390 } else {
00391 adv=sprintf(outptr,
00392 " times[0] = <NULL>\n");
00393 outptr+=adv;
00394 }
00395 adv=sprintf(outptr,
00396 " chaninfo = %p\n", eeg->chaninfo);
00397 outptr+=adv;
00398 adv=sprintf( outptr, " data = \n" );
00399 outptr+=adv;
00400 if( eeg->data!=NULL ){
00401 for( c=0; c<MIN(eeg->nbchan,preview); c++ ){
00402 for( i=0; i<MIN(eeg->ntrials, preview); i++ ){
00403 for( j=0; j<MIN(eeg->n, preview); j++ ){
00404 adv=sprintf(outptr,
00405 " [%i][%i][%i] = %f\n", c,i,j,eeg->data[c][i][j] );
00406 outptr+=adv;
00407 }
00408 }
00409 }
00410 } else {
00411 adv=sprintf(outptr,
00412 " data = <NULL>\n");
00413 outptr+=adv;
00414 }
00415
00416 adv=sprintf(outptr, " markers = \n");
00417 outptr+=adv;
00418 if( eeg->markers ){
00419 for( i=0; i<MIN( eeg->ntrials, preview ); i++ ){
00420 for( j=0; j<MIN( eeg->nmarkers[i], preview ); j++ ){
00421 adv=sprintf(outptr, " [%i][%i] = %i\n", i,j, eeg->markers[i][j] );
00422 outptr+=adv;
00423 }
00424 }
00425 } else {
00426 adv=sprintf(outptr, " <NULL>\n");
00427 outptr+=adv;
00428 }
00429
00430 adv=sprintf(outptr, " marker_labels = \n");
00431 outptr+=adv;
00432 if( eeg->marker_labels ){
00433 for( i=0; i<MIN(eeg->ntrials, preview ); i++ ){
00434 for( j=0; j<MIN(eeg->nmarkers[i], preview ); j++ ){
00435 adv=sprintf(outptr, " [%i][%i] = %s\n", i,j, eeg->marker_labels[i][j] );
00436 outptr+=adv;
00437 }
00438 }
00439 } else {
00440 adv=sprintf(outptr,
00441 " <NULL>\n");
00442 outptr+=adv;
00443 }
00444 return out;
00445 }
00446
00453 EEG* eeg_clone( const EEG *eeg, int flags ){
00454 EEG *clone;
00455 int c, i, j;
00456 dprintf("start init\n");
00457 clone = eeg_init( eeg->nbchan, eeg->ntrials, eeg->n );
00458 dprintf("...done\n");
00459 if( eeg->filename ){
00460 clone->filename = (char*) malloc( (strlen( eeg->filename )+1)*sizeof(char) );
00461 strcpy( clone->filename, eeg->filename );
00462 }
00463 if( eeg->comment ){
00464 clone->comment = (char*) malloc( (strlen( eeg->comment )+1)*sizeof(char) );
00465 strcpy( clone->comment, eeg->comment );
00466 }
00467 clone->sampling_rate = eeg->sampling_rate;
00468 if( eeg->times ){
00469 clone->times = (double*) malloc( eeg->n*sizeof(double) );
00470 memcpy( clone->times, eeg->times, eeg->n*sizeof(double) );
00471 }
00472 dprintf("stuff done\n");
00473
00474 if( !(flags & EEG_CLONE_NODATA) ){
00475 for( c=0; c<eeg->nbchan; c++ ){
00476 for( i=0; i<eeg->ntrials; i++ ){
00477 for( j=0; j<eeg->n; j++ ){
00478 clone->data[c][i][j] = eeg->data[c][i][j];
00479 }
00480 }
00481 }
00482 }
00483 if( !(flags & EEG_CLONE_NOCHANINFO) ){
00484 if( eeg->chaninfo ){
00485 clone->chaninfo = (ChannelInfo*) malloc( eeg->ntrials*sizeof(ChannelInfo) );
00486 for( i=0; i<eeg->ntrials; i++ ){
00487 memcpy( &(clone->chaninfo[i]), &(eeg->chaninfo[i]), sizeof(ChannelInfo) );
00488 }
00489 }
00490 }
00491 if( !(flags & EEG_CLONE_NOMARKERS) ){
00492 if( eeg->nmarkers ){
00493 clone->nmarkers = (unsigned int*)malloc( eeg->ntrials*sizeof(unsigned int) );
00494 memcpy( clone->nmarkers, eeg->nmarkers, eeg->ntrials*sizeof(unsigned int) );
00495 }
00496
00497 if( eeg->markers ){
00498 clone->markers = (unsigned int**)malloc( eeg->ntrials*sizeof(unsigned int*) );
00499 for( i=0; i<eeg->ntrials; i++ ){
00500 clone->markers[i] =(unsigned int*) malloc( eeg->nmarkers[i]*sizeof(unsigned int) );
00501 memcpy( clone->markers[i], eeg->markers[i], eeg->nmarkers[i]*sizeof(unsigned int) );
00502 }
00503 }
00504
00505 if( eeg->marker_labels ){
00506 clone->marker_labels = (char ***)malloc( eeg->ntrials*sizeof(char**) );
00507 for( i=0; i<eeg->ntrials; i++ ){
00508 clone->marker_labels[i] =(char**)malloc( eeg->nmarkers[i]*sizeof(char*) );
00509 for( j=0; j<eeg->nmarkers[i]; j++ ){
00510 clone->marker_labels[i][j] = (char*) malloc( (strlen( eeg->marker_labels[i][j])+1)*sizeof(char) );
00511 strcpy( clone->marker_labels[i][j], eeg->marker_labels[i][j] );
00512 }
00513 }
00514 }
00515 }
00516
00517 return clone;
00518 }
00519
00520
00521 #endif
00522
00523
00524 void print_channelinfo( FILE* out, const ChannelInfo *c ){
00525 fprintf( out, "Channel No. %i/%i - '%s' at (%.2f, %.2f, %.2f)\n",
00526 c->num, c->num_chans, c->label, c->x, c->y, c->z );
00527 }