/*{{{ export_point(transform_info_ptr tinfo) {*/ METHODDEF DATATYPE * export_point(transform_info_ptr tinfo) { struct export_point_info *exp_info=(struct export_point_info *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; array_dump_format format=(args[ARGS_MATLAB].is_set ? ARRAY_MATLAB : ARRAY_ASCII); int channel, itempart, i; double *channelpos; array myarray, newarray; if (exp_info->pointno<0 || exp_info->pointno>=tinfo->nr_of_points) { ERREXIT1(tinfo->emethods, "export_point: Point number %d is out of range.\n", MSGPARM(exp_info->pointno)); } TRACEMS2(tinfo->emethods, 1, "export_point: Exporting point number %d to file %s\n", MSGPARM(exp_info->pointno), MSGPARM(args[ARGS_OFILE].arg.s)); if (args[ARGS_CLOSE].is_set) export_file_open(tinfo); tinfo_array(tinfo, &myarray); myarray.current_element=exp_info->pointno; if (exp_info->channelcoords_to_display==0 && tinfo->itemsize==1) { /*{{{ Don't need to build new array, just access tinfo*/ newarray=myarray; array_transpose(&newarray); array_setto_vector(&newarray); /* Select only one element */ array_transpose(&newarray); /*}}} */ } else { /*{{{ Build new array containing the data*/ newarray.nr_of_vectors=myarray.nr_of_vectors; newarray.nr_of_elements=exp_info->channelcoords_to_display+tinfo->itemsize; newarray.element_skip=1; if (array_allocate(&newarray)==NULL) { ERREXIT(tinfo->emethods, "export_point: Can't allocate output array\n"); } for (channel=0; channel<tinfo->nr_of_channels; channel++) { channelpos=tinfo->probepos+3*channel; for (i=0; i<exp_info->channelcoords_to_display; i++) { array_write(&newarray, channelpos[i]); } myarray.current_vector=channel; for (itempart=0; itempart<tinfo->itemsize; itempart++) { array_use_item(&myarray, itempart); array_write(&newarray, READ_ELEMENT(&myarray)); } } /*}}} */ } array_dump(exp_info->file, &newarray, format); if (newarray.nr_of_elements>1) array_free(&newarray); if (args[ARGS_CLOSE].is_set) export_file_close(tinfo); return tinfo->tsdata; }
int output_gamma() { int size = terms_prim; int gamma_total_size = terms_prim; array_write(&gamma_total_size, gamma_data_file, &gamma_[0][0]); return 0; }
/*{{{ recode(transform_info_ptr tinfo) {*/ METHODDEF DATATYPE * recode(transform_info_ptr tinfo) { struct recode_storage *local_arg=(struct recode_storage *)tinfo->methods->local_storage; transform_info_ptr const tinfoptr=tinfo; array myarray; int itempart; int shift, nrofshifts=1; DATATYPE *save_tsdata; tinfo_array(tinfoptr, &myarray); /* The channels are the vectors */ save_tsdata=myarray.start; if (tinfoptr->data_type==FREQ_DATA) { nrofshifts=tinfoptr->nrofshifts; } for (shift=0; shift<nrofshifts; shift++) { myarray.start=save_tsdata+shift*tinfo->nroffreq*tinfo->nr_of_channels*tinfo->itemsize; array_setreadwrite(&myarray); for (itempart=local_arg->fromitem; itempart<=local_arg->toitem; itempart++) { array_use_item(&myarray, itempart); do { if (local_arg->have_channel_list && !is_in_channellist(myarray.current_vector+1, local_arg->channel_list)) { array_nextvector(&myarray); continue; } do { DATATYPE hold=READ_ELEMENT(&myarray); struct blockdef *inblocks=local_arg->blockdefs; while (inblocks!=NULL) { if (isnan(inblocks->fromstart) && isnan(hold)) { /* Recode NaN values */ hold=inblocks->tostart; } else if (hold>=inblocks->fromstart && hold<=inblocks->fromend) { if (inblocks->fromend==inblocks->fromstart || inblocks->toend==inblocks->tostart) { hold=inblocks->tostart; } else { hold=((hold-inblocks->fromstart)/(inblocks->fromend-inblocks->fromstart))*(inblocks->toend-inblocks->tostart)+inblocks->tostart; } break; } if (inblocks->last_block) break; inblocks++; } array_write(&myarray, hold); } while (myarray.message==ARRAY_CONTINUE); } while (myarray.message==ARRAY_ENDOFVECTOR); } } return tinfo->tsdata; }
/*{{{ raw_fft(transform_info_ptr tinfo) {*/ METHODDEF DATATYPE * raw_fft(transform_info_ptr tinfo) { int i; array myarray, fftarray; long datasize, fftsize; if (tinfo->itemsize==2) { /*{{{ Do the inverse transform*/ if (tinfo->data_type==TIME_DATA) { tinfo->nroffreq=tinfo->nr_of_points; tinfo->nrofshifts=1; } datasize=tinfo->nroffreq; fftsize=datasize-3; for (i=0; fftsize>>=1; i++); fftsize=1<<(i+2); if (datasize!=fftsize/2+1 || tinfo->nrofshifts!=1) { ERREXIT(tinfo->emethods, "raw_fft: Input spectra must have 2^n+1 frequencies, 2 items and 1 shift\n"); } fftarray.nr_of_elements=fftsize; fftarray.element_skip=1; fftarray.nr_of_vectors=tinfo->nr_of_channels; if (array_allocate(&fftarray)==NULL) { ERREXIT(tinfo->emethods, "raw_fft: Error allocating memory\n"); } /* We access tsdata as 1-item data already now (this makes copying easier) */ tinfo->itemsize=1; tinfo->nr_of_points*=2; tinfo->data_type=TIME_DATA; tinfo_array(tinfo, &myarray); do { myarray.current_element=0; myarray.current_vector=fftarray.current_vector; realfft(ARRAY_ELEMENT(&myarray), fftsize, -1); do { array_write(&fftarray, array_scan(&myarray)); } while (fftarray.message==ARRAY_CONTINUE); } while (fftarray.message==ARRAY_ENDOFVECTOR); tinfo->nr_of_points=fftarray.nr_of_elements; /*}}} */ } else {
/*{{{ rereference(transform_info_ptr tinfo)*/ METHODDEF DATATYPE * rereference(transform_info_ptr tinfo) { struct rereference_args_struct *rereference_args=(struct rereference_args_struct *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; int itempart; transform_info_ptr const tinfoptr=tinfo; array indata; tinfo_array(tinfoptr, &indata); array_transpose(&indata); /* Vector=map */ for (itempart=0; itempart<tinfoptr->itemsize-tinfoptr->leaveright; itempart++) { array_use_item(&indata, itempart); do { DATATYPE mean=0; int n=0; do { if (is_in_channellist(indata.current_element+1, rereference_args->refchannel_numbers)) { mean+=array_scan(&indata); n++; } else { array_advance(&indata); } } while (indata.message==ARRAY_CONTINUE); mean/=n; array_previousvector(&indata); do { if ((args[ARGS_EXCLUDEOTHER].is_set && !is_in_channellist(indata.current_element+1, rereference_args->refchannel_numbers)) || is_in_channellist(indata.current_element+1, rereference_args->excludechannel_numbers)) { array_advance(&indata); } else { array_write(&indata, READ_ELEMENT(&indata)-mean); } } while (indata.message==ARRAY_CONTINUE); } while (indata.message!=ARRAY_ENDOFSCAN); } return tinfo->tsdata; }
GLOBAL struct source_desc * var_random_srcmodule(transform_info_ptr tinfo, char **args) { int n_harmonics, n_noisedips, i, n_dipoles; char **inargs=args; DATATYPE *memptr; float random_pos=0.0, random_moment=0.0; double freq_default=0.1; struct source_desc *sourcep; struct dipole_desc *dipolep; if (args==(char **)NULL) { ERREXIT(tinfo->emethods, "var_random_srcmodule: Usage: var_random_dipoles ( n_harmonics n_noisedips )\n"); } if (*inargs!=NULL) n_harmonics=atoi(*inargs++); if (*inargs!=NULL) n_noisedips=atoi(*inargs++); if (inargs-args!=2) { ERREXIT(tinfo->emethods, "var_random_srcmodule: Need at least two arguments ( n_harmonics n_noisedips )\n"); } n_dipoles=n_harmonics+n_noisedips; if ((sourcep=(struct source_desc *)malloc(sizeof(struct source_desc)+(sizeof(struct dipole_desc)+3*3*sizeof(DATATYPE))*n_dipoles))==NULL) { ERREXIT(tinfo->emethods, "var_random_srcmodule: Error allocating memory\n"); } sourcep->nrofsources=n_dipoles; dipolep=sourcep->dipoles=(struct dipole_desc *)(sourcep+1); memptr=(DATATYPE *)(dipolep+n_dipoles); for (i=0; i<n_dipoles; i++, dipolep++, memptr+=9) { dipolep->position.start=memptr; dipolep->dip_moment.start=memptr+3; dipolep->initial_moment.start=memptr+6; /*{{{ Read switchable options: FREQ_DEFAULT, RANDOM_POS, RANDOM_MOMENT keyword*/ if (*inargs!=NULL && strcmp(*inargs, "FREQ_DEFAULT")==0) { if (*++inargs!=NULL) { freq_default=atof(*inargs); inargs++; } } if (*inargs!=NULL && strcmp(*inargs, "RANDOM_POS")==0) { if (*++inargs!=NULL) { random_pos=atof(*inargs); inargs++; } } if (*inargs!=NULL && strcmp(*inargs, "RANDOM_MOMENT")==0) { if (*++inargs!=NULL) { random_moment=atof(*inargs); inargs++; } } /*}}} */ dipolep->position.nr_of_elements=dipolep->dip_moment.nr_of_elements=dipolep->initial_moment.nr_of_elements=3; dipolep->position.nr_of_vectors=dipolep->dip_moment.nr_of_vectors=dipolep->initial_moment.nr_of_vectors=1; dipolep->position.element_skip=dipolep->dip_moment.element_skip=dipolep->initial_moment.element_skip=1; dipolep->position.vector_skip=dipolep->dip_moment.vector_skip=dipolep->initial_moment.vector_skip=3; array_setreadwrite(&dipolep->position); array_setreadwrite(&dipolep->dip_moment); array_setreadwrite(&dipolep->initial_moment); array_reset(&dipolep->position); array_reset(&dipolep->dip_moment); array_reset(&dipolep->initial_moment); /* The parameter is the frequency relative to half the sampling frequency: */ dipolep->time[1]=M_PI*readval(tinfo, &inargs, freq_default); if (dipolep->time[1]<=0) { ERREXIT1(tinfo->emethods, "var_random_srcmodule: Frequency==%d\n", MSGPARM(dipolep->time[1])); } if (random_pos>0.0) { float x, y, z; sphere_random(random_pos, &x, &y, &z); array_write(&dipolep->position, readval(tinfo, &inargs, x)); array_write(&dipolep->position, readval(tinfo, &inargs, y)); array_write(&dipolep->position, readval(tinfo, &inargs, z)); } else { array_write(&dipolep->position, readval(tinfo, &inargs, 1)); array_write(&dipolep->position, readval(tinfo, &inargs, 1)); array_write(&dipolep->position, readval(tinfo, &inargs, 7.5)); } if (random_moment>0.0) { float x, y, z; sphere_random(random_moment, &x, &y, &z); array_write(&dipolep->dip_moment, readval(tinfo, &inargs, x)); array_write(&dipolep->dip_moment, readval(tinfo, &inargs, y)); array_write(&dipolep->dip_moment, readval(tinfo, &inargs, z)); } else { array_write(&dipolep->dip_moment, readval(tinfo, &inargs, 1)); array_write(&dipolep->dip_moment, readval(tinfo, &inargs, 0)); array_write(&dipolep->dip_moment, readval(tinfo, &inargs, 0)); } if (i<n_harmonics) { /*{{{ Set harmonic behaviour*/ dipolep->time_function_init= &harmonic_time_init; dipolep->time_function= &harmonic_time; dipolep->time_function_exit= &harmonic_time_exit; /*}}} */ } else { /*{{{ Set noise behaviour*/ dipolep->time_function_init= &noise_time_init; dipolep->time_function= &noise_time; dipolep->time_function_exit= &noise_time_exit; /*}}} */ } } return sourcep; }
/*{{{ read_neurofile(transform_info_ptr tinfo) {*/ METHODDEF DATATYPE * read_neurofile(transform_info_ptr tinfo) { struct read_neurofile_storage *local_arg=(struct read_neurofile_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; array myarray; FILE *infile=local_arg->infile; Bool not_correct_trigger=FALSE; long trigger_point, file_start_point, file_end_point; char *innamebuf; int channel; char *description=NULL; if (local_arg->epochs--==0) return NULL; tinfo->beforetrig=local_arg->beforetrig; tinfo->aftertrig=local_arg->aftertrig; tinfo->nr_of_points=local_arg->beforetrig+local_arg->aftertrig; tinfo->nr_of_channels=local_arg->nr_of_channels; tinfo->nrofaverages=1; if (tinfo->nr_of_points<=0) { ERREXIT1(tinfo->emethods, "read_neurofile: Invalid nr_of_points %d\n", MSGPARM(tinfo->nr_of_points)); } /*{{{ Find the next window that fits into the actual data*/ /* This is just for the Continuous option (no trigger file): */ file_end_point=local_arg->current_point-1; do { if (args[ARGS_CONTINUOUS].is_set) { /* Simulate a trigger at current_point+beforetrig */ file_start_point=file_end_point+1; trigger_point=file_start_point+tinfo->beforetrig; file_end_point=trigger_point+tinfo->aftertrig-1; if (local_arg->points_in_file>0 && file_end_point>=local_arg->points_in_file) return NULL; local_arg->current_trigger++; local_arg->current_point+=tinfo->nr_of_points; tinfo->condition=0; } else do { tinfo->condition=read_neurofile_read_trigger(tinfo, &trigger_point, &description); if (tinfo->condition==0) return NULL; /* No more triggers in file */ file_start_point=trigger_point-tinfo->beforetrig+local_arg->offset; file_end_point=trigger_point+tinfo->aftertrig-1-local_arg->offset; if (local_arg->trigcodes==NULL) { not_correct_trigger=FALSE; } else { int trigno=0; not_correct_trigger=TRUE; while (local_arg->trigcodes[trigno]!=0) { if (local_arg->trigcodes[trigno]==tinfo->condition) { not_correct_trigger=FALSE; break; } trigno++; } } } while (not_correct_trigger || file_start_point<0 || (local_arg->points_in_file>0 && file_end_point>=local_arg->points_in_file)); } while (--local_arg->fromepoch>0); if (description==NULL) { TRACEMS3(tinfo->emethods, 1, "read_neurofile: Reading around tag %d at %d, condition=%d\n", MSGPARM(local_arg->current_trigger), MSGPARM(trigger_point), MSGPARM(tinfo->condition)); } else { TRACEMS4(tinfo->emethods, 1, "read_neurofile: Reading around tag %d at %d, condition=%d, description=%s\n", MSGPARM(local_arg->current_trigger), MSGPARM(trigger_point), MSGPARM(tinfo->condition), MSGPARM(description)); } /*{{{ Handle triggers within the epoch (option -T)*/ if (args[ARGS_TRIGTRANSFER].is_set) { int trigs_in_epoch, code; long trigpoint; long const old_current_trigger=local_arg->current_trigger; char *thisdescription; /* First trigger entry holds file_start_point */ push_trigger(&tinfo->triggers, file_start_point, -1, NULL); read_neurofile_reset_triggerbuffer(tinfo); for (trigs_in_epoch=1; (code=read_neurofile_read_trigger(tinfo, &trigpoint, &thisdescription))!=0;) { if (trigpoint>=file_start_point && trigpoint<=file_end_point) { push_trigger(&tinfo->triggers, trigpoint-file_start_point, code, thisdescription); trigs_in_epoch++; } } push_trigger(&tinfo->triggers, 0, 0, NULL); /* End of list */ local_arg->current_trigger=old_current_trigger; } /*}}} */ fseek(infile, file_start_point*tinfo->nr_of_channels, SEEK_SET); /*{{{ Configure myarray*/ myarray.element_skip=tinfo->itemsize=1; tinfo->multiplexed=TRUE; myarray.nr_of_elements=tinfo->nr_of_channels; myarray.nr_of_vectors=tinfo->nr_of_points; if (array_allocate(&myarray)==NULL || (tinfo->channelnames=(char **)malloc(tinfo->nr_of_channels*sizeof(char *)))==NULL || (innamebuf=(char *)malloc(local_arg->stringlength))==NULL || (tinfo->comment=(char *)malloc(strlen((char *)local_arg->seq.comment)+(1+17+1)))==NULL) { ERREXIT(tinfo->emethods, "read_neurofile: Error allocating data\n"); } /*}}} */ sprintf(tinfo->comment, "%s %02d/%02d/%02d,%02d:%02d:%02d", local_arg->seq.comment, local_arg->seq.month, local_arg->seq.day, local_arg->seq.year, local_arg->seq.hour, local_arg->seq.minute, local_arg->seq.second); for (channel=0; channel<tinfo->nr_of_channels; channel++) { strcpy(innamebuf, (char *)local_arg->seq.elnam[channel]); tinfo->channelnames[channel]=innamebuf; innamebuf+=strlen(innamebuf)+1; } do { signed char exponent; short delta; if (fread(&exponent, sizeof(exponent), 1, infile)!=1) { ERREXIT(tinfo->emethods, "read_neurofile: Error reading data\n"); } delta=exponent; exponent&=0x03; if (exponent==0x03) { delta>>=2; } else { delta=(delta&0xfffc)<<(exponent*2); } local_arg->last_values[myarray.current_element]+=delta; array_write(&myarray, local_arg->last_values[myarray.current_element]*local_arg->factor); } while (myarray.message!=ARRAY_ENDOFSCAN);
/*{{{ project(transform_info_ptr tinfo)*/ METHODDEF DATATYPE * project(transform_info_ptr tinfo) { struct project_args_struct *project_args=(struct project_args_struct *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; DATATYPE *retvalue=tinfo->tsdata; array indata, scalars, *vectors= &project_args->vectors; int itempart, itemparts=tinfo->itemsize-tinfo->leaveright; if (project_args->project_mode==PROJECT_MODE_MULTIPLY) { if (!(tinfo->nr_of_channels==vectors->nr_of_vectors ||(tinfo->nr_of_channels==1 && tinfo->itemsize==vectors->nr_of_vectors))) { ERREXIT(tinfo->emethods, "project: Number of scalars and maps doesn't match!\n"); } } else { if (vectors->nr_of_elements!=tinfo->nr_of_channels) { ERREXIT2(tinfo->emethods, "project: %d channels in epoch, but %d channels in project file.\n", MSGPARM(tinfo->nr_of_channels), MSGPARM(vectors->nr_of_elements)); } } array_reset(vectors); tinfo_array(tinfo, &indata); array_transpose(&indata); /* Vectors are maps */ /* Be sure that different output items are adjacent... */ scalars.nr_of_elements=vectors->nr_of_vectors; switch (project_args->project_mode) { case PROJECT_MODE_SCALAR: scalars.nr_of_vectors=tinfo->nr_of_points; scalars.element_skip=itemparts; break; case PROJECT_MODE_SSP: case PROJECT_MODE_SSPS: scalars.nr_of_vectors=1; scalars.element_skip=1; break; case PROJECT_MODE_MULTIPLY: scalars=indata; if (tinfo->nr_of_channels!=vectors->nr_of_vectors) { /* Ie, one channel and weights in the items: Convert from 1 element to * itemsize elements */ scalars.element_skip=1; scalars.nr_of_elements=tinfo->itemsize; itemparts=1; } indata.element_skip=itemparts; indata.nr_of_elements=vectors->nr_of_elements; /* New number of channels */ indata.nr_of_vectors=scalars.nr_of_vectors; /* New number of points */ if (array_allocate(&indata)==NULL) { ERREXIT(tinfo->emethods, "project: Can't allocate new indata array\n"); } break; } if (project_args->project_mode==PROJECT_MODE_MULTIPLY) { array_transpose(vectors); /* Now the elements are the subspace dimensions */ for (itempart=0; itempart<itemparts; itempart++) { array_use_item(&indata, itempart); array_use_item(&scalars, itempart); do { /*{{{ Build the signal subspace vector*/ do { array_write(&indata, array_multiply(vectors, &scalars, MULT_SAMESIZE)); } while (indata.message==ARRAY_CONTINUE); /*}}} */ } while (indata.message!=ARRAY_ENDOFSCAN); } array_transpose(vectors); } else { if (array_allocate(&scalars)==NULL) { ERREXIT(tinfo->emethods, "project: Can't allocate scalars array\n"); } for (itempart=0; itempart<itemparts; itempart++) { array_use_item(&indata, itempart); if (project_args->project_mode==PROJECT_MODE_SCALAR) { array_use_item(&scalars, itempart); } do { /*{{{ Calculate the projection scalars*/ do { /* With all vectors in turn: */ DATATYPE product=0.0; do { if (project_args->channel_list!=NULL && !is_in_channellist(vectors->current_element+1, project_args->channel_list)) { array_advance(vectors); array_advance(&indata); } else { product+=array_scan(&indata)*array_scan(vectors); } } while (vectors->message==ARRAY_CONTINUE); array_write(&scalars, product); if (scalars.message==ARRAY_CONTINUE) array_previousvector(&indata); } while (scalars.message==ARRAY_CONTINUE); /*}}} */ switch (project_args->project_mode) { case PROJECT_MODE_SCALAR: break; case PROJECT_MODE_SSP: /*{{{ Build the signal subspace vector*/ array_transpose(vectors); /* Now the elements are the subspace dimensions */ array_previousvector(&indata); do { array_write(&indata, array_multiply(vectors, &scalars, MULT_VECTOR)); } while (indata.message==ARRAY_CONTINUE); array_transpose(vectors); /*}}} */ break; case PROJECT_MODE_SSPS: /*{{{ Subtract the signal subspace vector*/ array_transpose(vectors); /* Now the elements are the subspace dimensions */ array_previousvector(&indata); do { array_write(&indata, READ_ELEMENT(&indata)-array_multiply(vectors, &scalars, MULT_VECTOR)); } while (indata.message==ARRAY_CONTINUE); array_transpose(vectors); /*}}} */ break; default: /* Can't happen, just to keep the compiler happy... */ ERREXIT(tinfo->emethods, "project: This cannot happen!\n"); break; } } while (indata.message!=ARRAY_ENDOFSCAN); } } /*{{{ Prepare tinfo to reflect the data structure returned*/ switch (project_args->project_mode) { case PROJECT_MODE_SCALAR: if (args[ARGS_USE_CHANNELS].is_set) { tinfo->nr_of_channels=vectors->nr_of_vectors; tinfo->itemsize=itemparts; } else { tinfo->nr_of_channels=1; tinfo->itemsize=itemparts*vectors->nr_of_vectors; } tinfo->length_of_output_region=scalars.nr_of_elements*scalars.element_skip*scalars.nr_of_vectors; tinfo->leaveright=0; tinfo->multiplexed=TRUE; if (tinfo->channelnames!=NULL) { free_pointer((void **)&tinfo->channelnames[0]); free_pointer((void **)&tinfo->channelnames); } free_pointer((void **)&tinfo->probepos); create_channelgrid(tinfo); retvalue=scalars.start; break; case PROJECT_MODE_SSP: case PROJECT_MODE_SSPS: array_free(&scalars); retvalue=tinfo->tsdata; break; case PROJECT_MODE_MULTIPLY: /* Note that we don't free `scalars' because it just points to the original tsdata! */ /* Have to set this correctly so that copy_channelinfo works... */ tinfo->nr_of_channels=indata.nr_of_elements; copy_channelinfo(tinfo, project_args->save_side_tinfo.channelnames, project_args->save_side_tinfo.probepos); tinfo->nr_of_points=indata.nr_of_vectors; tinfo->itemsize=indata.element_skip; tinfo->length_of_output_region=tinfo->nr_of_channels*tinfo->nr_of_points*tinfo->itemsize; retvalue=indata.start; tinfo->multiplexed=TRUE; break; } /*}}} */ return retvalue; }
int main(int argc, char **argv) { FILE *fp; surfspline_desc sspline; int err, npoints, itempart=0; int binary_output=FALSE, matlab_output=FALSE, mtv_output=FALSE, interpolate_only=FALSE; float fbuf, external_value=0.0; DATATYPE f, x, y, xmin, xmax, ymin, ymax, xstep, ystep; array index; pid_t pid; char outname[L_tmpnam], inname[L_tmpnam], **inargs, *infile; /*{{{ Read command line args*/ for (inargs=argv+1; inargs-argv<argc && **inargs=='-'; inargs++) { switch(inargs[0][1]) { case 'B': binary_output=TRUE; break; case 'I': if (inargs[0][2]!='\0') { itempart=atoi(*inargs+2); } break; case 'i': interpolate_only=TRUE; if (inargs[0][2]!='\0') { external_value=atof(*inargs+2); } break; case 'M': matlab_output=TRUE; break; case 'm': mtv_output=TRUE; break; default: fprintf(stderr, "%s: Ignoring unknown option %s\n", argv[0], *inargs); continue; } } if (argc-(inargs-argv)!=3) { fprintf(stderr, "Usage: %s array_filename degree npoints\n" "Options:\n" " -Iitem: Use item number item as z-axis (2+item'th column); default: 0\n" " -i[value]: Interpolate only; set external values to value (default: 0.0)\n" " -B: Binary output (gnuplot floats)\n" " -M: Matlab output (x, y vectors and z matrix)\n" " -m: Plotmtv output\n" , argv[0]); return -1; } infile= *inargs++; if ((fp=fopen(infile, "r"))==NULL) { fprintf(stderr, "Can't open %s\n", infile); return -2; } array_undump(fp, &sspline.inpoints); fclose(fp); if (sspline.inpoints.message==ARRAY_ERROR) { fprintf(stderr, "Error in array_undump\n"); return -3; } if (sspline.inpoints.nr_of_elements<3+itempart) { fprintf(stderr, "Not enough columns in array %s\n", *(inargs-1)); return -3; } sspline.degree=atoi(*inargs++);; npoints=atoi(*inargs++); /*}}} */ /*{{{ Get the index of qhull point pairs by running qhull*/ tmpnam(outname); tmpnam(inname); if ((pid=fork())==0) { /* I'm the child */ #define LINEBUF_SIZE 128 char linebuf[LINEBUF_SIZE]; array tmp_array; /*{{{ Dump xy positions to tmp file inname*/ tmp_array.nr_of_elements=2; tmp_array.nr_of_vectors=sspline.inpoints.nr_of_vectors; tmp_array.element_skip=1; if (array_allocate(&tmp_array)==NULL) { fprintf(stderr, "Error allocating tmp_array\n"); return -4; } array_reset(&sspline.inpoints); do { array_write(&tmp_array, array_scan(&sspline.inpoints)); array_write(&tmp_array, array_scan(&sspline.inpoints)); array_nextvector(&sspline.inpoints); } while (tmp_array.message!=ARRAY_ENDOFSCAN); if ((fp=fopen(inname, "w"))==NULL) { fprintf(stderr, "Can't open %s\n", inname); return -5; } array_dump(fp, &tmp_array, ARRAY_ASCII); fclose(fp); array_free(&tmp_array); /*}}} */ snprintf(linebuf, LINEBUF_SIZE, "qhull C0 i b <%s >%s", inname, outname); execl("/bin/sh", "sh", "-c", linebuf, 0); #undef LINEBUF_SIZE } else { wait(NULL); } unlink(inname); if ((fp=fopen(outname, "r"))==NULL) { fprintf(stderr, "Can't open %s\n", outname); return -6; } array_undump(fp, &index); fclose(fp); unlink(outname); /*}}} */ /*{{{ Find min, max and mean coordinates*/ array_transpose(&sspline.inpoints); array_reset(&sspline.inpoints); xmin=array_min(&sspline.inpoints); ymin=array_min(&sspline.inpoints); array_reset(&sspline.inpoints); xmax=array_max(&sspline.inpoints); ymax=array_max(&sspline.inpoints); array_reset(&sspline.inpoints); xmean=array_mean(&sspline.inpoints); ymean=array_mean(&sspline.inpoints); xstep=(xmax-xmin)/npoints; ystep=(ymax-ymin)/npoints; array_transpose(&sspline.inpoints); array_reset(&sspline.inpoints); /*}}} */ /*{{{ Copy itempart to 3rd location if necessary*/ /* Note: For this behavior it is essential that array_surfspline * will accept vectors of any size >=3 and only process the first three * elements ! */ if (itempart>0) { DATATYPE hold; do { sspline.inpoints.current_element=2+itempart; hold=READ_ELEMENT(&sspline.inpoints); sspline.inpoints.current_element=2; WRITE_ELEMENT(&sspline.inpoints, hold); array_nextvector(&sspline.inpoints); } while (sspline.inpoints.message!=ARRAY_ENDOFSCAN); } /*}}} */ /*{{{ Do surface spline*/ if ((err=array_surfspline(&sspline))!=0) { fprintf(stderr, "Error %d in array_surfspline\n", err); return err; } xmin-=xstep; xmax+=2*xstep; ymin-=ystep; ymax+=2*ystep; if (binary_output) { /*{{{ Gnuplot binary output*/ int n_xval=(xmax-xmin)/xstep+1, n; /* Number of x values */ fbuf=n_xval; fwrite(&fbuf, sizeof(float), 1, stdout); for (fbuf=xmin, n=0; n<n_xval; fbuf+=xstep, n++) { /* x values */ fwrite(&fbuf, sizeof(float), 1, stdout); } for (y=ymin; y<=ymax; y+=ystep) { fbuf=y; fwrite(&fbuf, sizeof(float), 1, stdout); for (x=xmin, n=0; n<n_xval; x+=xstep, n++) { if (interpolate_only && !is_inside(&index, &sspline.inpoints, x, y)) { f=external_value; } else { f=array_fsurfspline(&sspline, x, y); } fbuf=f; fwrite(&fbuf, sizeof(float), 1, stdout); } } /*}}} */ } else if (matlab_output) { /*{{{ Matlab output*/ array xm, ym, zm; xm.nr_of_elements=ym.nr_of_elements=1; xm.nr_of_vectors=zm.nr_of_elements=(xmax-xmin)/xstep+1; ym.nr_of_vectors=zm.nr_of_vectors=(ymax-ymin)/ystep+1; xm.element_skip=ym.element_skip=zm.element_skip=1; array_allocate(&xm); array_allocate(&ym); array_allocate(&zm); if (xm.message==ARRAY_ERROR || ym.message==ARRAY_ERROR || zm.message==ARRAY_ERROR) { fprintf(stderr, "Error allocating output arrays\n"); return -7; } x=xmin; do { array_write(&xm, x); x+=xstep; } while (xm.message!=ARRAY_ENDOFSCAN); y=ymin; do { array_write(&ym, y); x=xmin; do { if (interpolate_only && !is_inside(&index, &sspline.inpoints, x, y)) { f=external_value; } else { f=array_fsurfspline(&sspline, x, y); } array_write(&zm, f); x+=xstep; } while (zm.message==ARRAY_CONTINUE); y+=ystep; } while (zm.message!=ARRAY_ENDOFSCAN); array_dump(stdout, &xm, ARRAY_MATLAB); array_dump(stdout, &ym, ARRAY_MATLAB); array_dump(stdout, &zm, ARRAY_MATLAB); array_free(&xm); array_free(&ym); array_free(&zm); /*}}} */ } else if (mtv_output) { /*{{{ Plotmtv output*/ array zm; DATATYPE zmin=FLT_MAX, zmax= -FLT_MAX; zm.nr_of_elements=(xmax-xmin)/xstep+1; zm.nr_of_vectors=(ymax-ymin)/ystep+1; zm.element_skip=1; array_allocate(&zm); if (zm.message==ARRAY_ERROR) { fprintf(stderr, "Error allocating output arrays\n"); return -7; } y=ymin; do { x=xmin; do { if (interpolate_only && !is_inside(&index, &sspline.inpoints, x, y)) { f=external_value; } else { f=array_fsurfspline(&sspline, x, y); } array_write(&zm, f); if (f<zmin) zmin=f; if (f>zmax) zmax=f; x+=xstep; } while (zm.message==ARRAY_CONTINUE); y+=ystep; } while (zm.message!=ARRAY_ENDOFSCAN); /*{{{ Print file header*/ printf( "# Output of Spline_Gridder (C) Bernd Feige 1995\n\n" "$ DATA=CONTOUR\n\n" "%% toplabel = \"Spline_Gridder output\"\n" "%% subtitle = \"File: %s\"\n\n" "%% interp = 0\n" "%% contfill = on\n" "%% meshplot = off\n\n" "%% xmin = %g xmax = %g\n" "%% ymin = %g ymax = %g\n" "%% zmin = %g zmax = %g\n" "%% nx = %d\n" "%% ny = %d\n" , infile, xmin, xmax, ymin, ymax, zmin, zmax, zm.nr_of_elements, zm.nr_of_vectors); /*}}} */ array_dump(stdout, &zm, ARRAY_MATLAB); array_free(&zm); /*}}} */ } else { /*{{{ Gnuplot output*/ for (x=xmin; x<=xmax; x+=xstep) { for (y=ymin; y<=ymax; y+=ystep) { if (interpolate_only && !is_inside(&index, &sspline.inpoints, x, y)) { f=external_value; } else { f=array_fsurfspline(&sspline, x, y); } printf("%g %g %g\n", x, y, f); } printf("\n"); } /*}}} */ } /*}}} */ return 0; }
GLOBAL void array_copy(array *array1, array *array2) { do { array_write(array2, array_scan(array1)); } while (array1->message!=ARRAY_ENDOFSCAN && array2->message!=ARRAY_ENDOFSCAN); }
/* freiburg_get_segment returns 0 on success and -1 on out-of-input-bounds */ LOCAL int freiburg_get_segment(transform_info_ptr tinfo, array *toarray) { struct read_freiburg_storage *local_arg=(struct read_freiburg_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; /* Well, again... It appears that at some time, there was a bug in KL's * programs resulting in ZEROES inserted before every new block, ie every * 513 data points... No indication of that in the header (`blockluecke' or * such, still don't know what that value means)... End of broadcast... */ do { /* If this is FALSE at the start, it will never become TRUE... */ int everything_was_zero=args[ARGS_ZEROCHECK].is_set; /* NOTE: The first time through, the values in last_values_buf are not * initialized. It should be assumed that the values in the very first point * read are NOT marked as differences, but with BT's Nxxx files, it's * different at the start of a `Block' if there was saturation as well... */ short *in_last_values_buf=local_arg->last_values_buf; const Bool no_last_values=local_arg->no_last_values; do { short oldword= *in_last_values_buf; int nextchar=fgetc(local_arg->infile); unsigned short word; DATATYPE floatval; if (nextchar==EOF) return -1; if (nextchar&0x0080 || no_last_values) { /* data is a whole short */ word=(((unsigned int)nextchar)<<8)+(((unsigned int)fgetc(local_arg->infile))&0x00ff); if ((word&0x4000)==0) { word&=0x7fff; /* Make positive if bit 14 clear */ } } else { /* data is relative to oldword */ unsigned short byte=(unsigned short)nextchar; if (byte&0x0040) { /* Negative difference */ byte|=0xffc0; } else { /* Positive difference */ byte&=0x003f; } word=(unsigned short)((short)oldword+(short)byte); /* Signed addition */ } if (word!=0) everything_was_zero=FALSE; *(unsigned short *)in_last_values_buf=word; floatval= *in_last_values_buf++; if (local_arg->uV_per_bit!=NULL) floatval*=local_arg->uV_per_bit[toarray->current_element]; array_write(toarray, floatval); } while (toarray->message==ARRAY_CONTINUE); if (everything_was_zero) { array_previousvector(toarray); local_arg->zero_idiotism_encountered=TRUE; } else { break; } } while (TRUE); local_arg->current_point++; local_arg->no_last_values=FALSE; return 0; }
METHODDEF DATATYPE * read_freiburg(transform_info_ptr tinfo) { struct read_freiburg_storage *local_arg=(struct read_freiburg_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; struct freiburg_channels_struct *in_channels=local_arg->in_channels; array myarray; FILE *infile; int i, point, channel; int trial_not_accepted; long length_of_data; short header[FREIBURG_HEADER_LENGTH/sizeof(short)]; char const *last_sep=strrchr(args[ARGS_IFILE].arg.s, PATHSEP); char const *last_component=(last_sep==NULL ? args[ARGS_IFILE].arg.s : last_sep+1); char comment[MAX_COMMENTLEN]; tinfo->nrofaverages=1; if (args[ARGS_CONTINUOUS].is_set) { /*{{{ Read an epoch from a continuous file*/ infile=local_arg->infile; if (local_arg->epochs--==0) return NULL; /*{{{ Configure myarray*/ myarray.element_skip=tinfo->itemsize=1; myarray.nr_of_vectors=tinfo->nr_of_points=local_arg->epochlength; myarray.nr_of_elements=tinfo->nr_of_channels=local_arg->nr_of_channels; if (array_allocate(&myarray)==NULL) { ERREXIT(tinfo->emethods, "read_freiburg: Error allocating data\n"); } tinfo->multiplexed=TRUE; /*}}} */ do { do { if (local_arg->segment_table.buffer_start!=NULL && local_arg->current_point%SEGMENT_LENGTH==0) { int const segment=local_arg->current_point/SEGMENT_LENGTH; long const nr_of_segments=local_arg->segment_table.current_length/sizeof(long); if (segment>=nr_of_segments) { array_free(&myarray); return NULL; } fseek(infile, ((long *)local_arg->segment_table.buffer_start)[segment], SEEK_SET); local_arg->no_last_values=TRUE; } if (freiburg_get_segment(tinfo, &myarray)!=0) { array_free(&myarray); return NULL; } } while (myarray.message!=ARRAY_ENDOFSCAN); } while (--local_arg->fromepoch>0); snprintf(comment, MAX_COMMENTLEN, "%s %s %02d/%02d/%04d,%02d:%02d:%02d", (local_arg->continuous_type==SLEEP_BT_TYPE ? "sleep_BT" : "sleep_KL"), last_component, local_arg->btfile.start_month, local_arg->btfile.start_day, local_arg->btfile.start_year, local_arg->btfile.start_hour, local_arg->btfile.start_minute, local_arg->btfile.start_second); tinfo->sfreq=local_arg->sfreq; /*}}} */ } else /*{{{ Read an epoch from a single (epoched or averaged) file*/ do { /* Return here if trial was not accepted */ trial_not_accepted=FALSE; if (local_arg->epochs--==0 || (local_arg->average_mode && local_arg->current_trigger>=1)) return NULL; if (local_arg->average_mode) { /*{{{ Prepare reading an averaged file*/ if((infile=fopen(args[ARGS_IFILE].arg.s,"rb"))==NULL) { ERREXIT1(tinfo->emethods, "read_freiburg: Can't open file %s\n", MSGPARM(args[ARGS_IFILE].arg.s)); } fseek(infile, 0, SEEK_END); length_of_data=ftell(infile)-FREIBURG_HEADER_LENGTH; local_arg->current_trigger++; snprintf(comment, MAX_COMMENTLEN, "Freiburg-avg %s", last_component); /*}}} */ } else { /*{{{ Build pathname of the single trial to read*/ /* A directory name was given. */ char const * const expnumber=args[ARGS_IFILE].arg.s+strlen(args[ARGS_IFILE].arg.s)-2; #ifdef __GNUC__ #define NEWFILENAME_SIZE (strlen(args[ARGS_IFILE].arg.s)+strlen(last_component)+20) #else #define NEWFILENAME_SIZE MAX_PATHLEN #endif char newfilename[NEWFILENAME_SIZE]; do { /* Files from which only the parameter part exists are rejected */ int div100=local_arg->current_trigger/100, mod100=local_arg->current_trigger%100; snprintf(newfilename, NEWFILENAME_SIZE, "%s%c%s%02d%c%c%s%02d%02d", args[ARGS_IFILE].arg.s, PATHSEP, last_component, div100, PATHSEP, tolower(expnumber[-1]), expnumber, div100, mod100); TRACEMS1(tinfo->emethods, 1, "read_freiburg: Constructed filename %s\n", MSGPARM(newfilename)); if((infile=fopen(newfilename,"rb"))==NULL) { if (local_arg->current_trigger==0) { ERREXIT1(tinfo->emethods, "read_freiburg: Can't open file %s\n", MSGPARM(newfilename)); } else { return NULL; } } fseek(infile, 0, SEEK_END); length_of_data=ftell(infile)-FREIBURG_HEADER_LENGTH; local_arg->current_trigger++; } while (length_of_data==0 || --local_arg->fromepoch>0); snprintf(comment, MAX_COMMENTLEN, "Freiburg-raw %s", last_component); /*}}} */ } /*{{{ Read the 64-Byte header*/ fseek(infile, 0, SEEK_SET); fread(header, 1, FREIBURG_HEADER_LENGTH, infile); for (i=0; i<18; i++) { # ifdef LITTLE_ENDIAN Intel_int16((uint16_t *)&header[i]); # endif TRACEMS2(tinfo->emethods, 3, "read_freiburg: Header %02d: %d\n", MSGPARM(i), MSGPARM(header[i])); } /*}}} */ if (local_arg->average_mode) { if ((length_of_data/sizeof(short))%local_arg->nr_of_channels!=0) { ERREXIT2(tinfo->emethods, "read_freiburg: length_of_data=%d does not fit with nr_of_channels=%d\n", MSGPARM(length_of_data), MSGPARM(local_arg->nr_of_channels)); } tinfo->nr_of_points=(length_of_data/sizeof(short))/local_arg->nr_of_channels; local_arg->sfreq=(args[ARGS_SFREQ].is_set ? args[ARGS_SFREQ].arg.d : 200.0); /* The most likely value */ } else { local_arg->nr_of_channels=header[14]; /* Note: In a lot of experiments, one point MORE is available in the data * than specified in the header, but this occurs erratically. We could only * check for this during decompression, but that's probably too much fuss. */ tinfo->nr_of_points=header[16]/header[15]; local_arg->sfreq=(args[ARGS_SFREQ].is_set ? args[ARGS_SFREQ].arg.d : 1000.0/header[15]); } tinfo->sfreq=local_arg->sfreq; /*{{{ Parse arguments that can be in seconds*/ local_arg->offset=(args[ARGS_OFFSET].is_set ? gettimeslice(tinfo, args[ARGS_OFFSET].arg.s) : 0); /*}}} */ tinfo->beforetrig= -local_arg->offset; tinfo->aftertrig=tinfo->nr_of_points+local_arg->offset; /*{{{ Configure myarray*/ myarray.element_skip=tinfo->itemsize=1; myarray.nr_of_vectors=tinfo->nr_of_points; myarray.nr_of_elements=tinfo->nr_of_channels=local_arg->nr_of_channels; if (array_allocate(&myarray)==NULL) { ERREXIT(tinfo->emethods, "read_freiburg: Error allocating data\n"); } tinfo->multiplexed=TRUE; /*}}} */ fseek(infile, FREIBURG_HEADER_LENGTH, SEEK_SET); if (local_arg->average_mode) { /*{{{ Read averaged epoch*/ for (point=0; point<tinfo->nr_of_points; point++) { #ifdef __GNUC__ short buffer[tinfo->nr_of_channels]; #else short buffer[MAX_NR_OF_CHANNELS]; #endif if ((int)fread(buffer, sizeof(short), tinfo->nr_of_channels, infile)!=tinfo->nr_of_channels) { ERREXIT1(tinfo->emethods, "read_freiburg: Error reading data point %d\n", MSGPARM(point)); } for (channel=0; channel<tinfo->nr_of_channels; channel++) { # ifdef LITTLE_ENDIAN Intel_int16((uint16_t *)&buffer[channel]); # endif array_write(&myarray, (DATATYPE)buffer[channel]); } } /*}}} */ } else { /*{{{ Read compressed single trial*/ # ifdef DISPLAY_ADJECTIVES char *adjektiv_ende=strchr(((char *)header)+36, ' '); if (adjektiv_ende!=NULL) *adjektiv_ende='\0'; printf("Single trial: nr_of_points=%d, nr_of_channels=%d, Adjektiv=%s\n", tinfo->nr_of_points, tinfo->nr_of_channels, ((char *)header)+36); # endif local_arg->infile=infile; do { if (freiburg_get_segment(tinfo, &myarray)!=0) { TRACEMS1(tinfo->emethods, 0, "read_freiburg: Decompression out of bounds for trial %d - skipped\n", MSGPARM(local_arg->current_trigger-1)); array_free(&myarray); trial_not_accepted=TRUE; break; } } while (myarray.message!=ARRAY_ENDOFSCAN); /*}}} */ } fclose(infile); } while (trial_not_accepted); /*}}} */ /*{{{ Look for a Freiburg channel setup for this number of channels*/ /* Force create_channelgrid to really allocate the channel info anew. * Otherwise, free_tinfo will free someone else's data ! */ tinfo->channelnames=NULL; tinfo->probepos=NULL; if (local_arg->channelnames!=NULL) { copy_channelinfo(tinfo, local_arg->channelnames, NULL); } else { while (in_channels->nr_of_channels!=0 && in_channels->nr_of_channels!=tinfo->nr_of_channels) in_channels++; if (in_channels->nr_of_channels==0) { TRACEMS1(tinfo->emethods, 1, "read_freiburg: Don't have a setup for %d channels.\n", MSGPARM(tinfo->nr_of_channels)); } else { copy_channelinfo(tinfo, in_channels->channelnames, NULL); } } create_channelgrid(tinfo); /* Create defaults for any missing channel info */ /*}}} */ if ((tinfo->comment=(char *)malloc(strlen(comment)+1))==NULL) { ERREXIT(tinfo->emethods, "read_freiburg: Error allocating comment memory\n"); } strcpy(tinfo->comment, comment); if (local_arg->zero_idiotism_warned==FALSE && local_arg->zero_idiotism_encountered) { TRACEMS(tinfo->emethods, 0, "read_freiburg: All-zero data points have been encountered and omitted!\n"); local_arg->zero_idiotism_warned=TRUE; } tinfo->z_label=NULL; tinfo->tsdata=myarray.start; tinfo->length_of_output_region=tinfo->nr_of_channels*tinfo->nr_of_points; tinfo->leaveright=0; tinfo->data_type=TIME_DATA; return tinfo->tsdata; }
/*{{{ project_init(transform_info_ptr tinfo)*/ METHODDEF void project_init(transform_info_ptr tinfo) { struct project_args_struct *project_args=(struct project_args_struct *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; transform_info_ptr side_tinfo= &project_args->side_tinfo; array *vectors= &project_args->vectors; growing_buf buf; #define BUFFER_SIZE 80 char buffer[BUFFER_SIZE]; side_tinfo->methods= &project_args->methods; side_tinfo->emethods=tinfo->emethods; select_readasc(side_tinfo); growing_buf_init(&buf); growing_buf_allocate(&buf, 0); if (args[ARGS_FROMEPOCH].is_set) { snprintf(buffer, BUFFER_SIZE, "-f %ld ", args[ARGS_FROMEPOCH].arg.i); growing_buf_appendstring(&buf, buffer); } if (args[ARGS_EPOCHS].is_set) { project_args->epochs=args[ARGS_EPOCHS].arg.i; if (project_args->epochs<=0) { ERREXIT(tinfo->emethods, "project_init: The number of epochs must be positive.\n"); } } else { project_args->epochs=1; } snprintf(buffer, BUFFER_SIZE, "-e %d ", project_args->epochs); growing_buf_appendstring(&buf, buffer); growing_buf_appendstring(&buf, args[ARGS_PROJECTFILE].arg.s); if (!buf.can_be_freed || !setup_method(side_tinfo, &buf)) { ERREXIT(tinfo->emethods, "project_init: Error setting readasc arguments.\n"); } project_args->points=(args[ARGS_POINTS].is_set ? args[ARGS_POINTS].arg.i : 1); project_args->nr_of_item=(args[ARGS_NROFITEM].is_set ? args[ARGS_NROFITEM].arg.i : 0); project_args->orthogonalize_vectors_first=args[ARGS_ORTHOGONALIZE].is_set; if (args[ARGS_SUBSPACE].is_set) { project_args->project_mode=PROJECT_MODE_SSP; } else if (args[ARGS_SUBTRACT_SUBSPACE].is_set) { project_args->project_mode=PROJECT_MODE_SSPS; } else if (args[ARGS_MULTIPLY].is_set) { project_args->project_mode=PROJECT_MODE_MULTIPLY; } else { project_args->project_mode=PROJECT_MODE_SCALAR; } if (args[ARGS_CHANNELNAMES].is_set) { project_args->channel_list=expand_channel_list(tinfo, args[ARGS_CHANNELNAMES].arg.s); if (project_args->channel_list==NULL) { ERREXIT(tinfo->emethods, "project_init: Zero channels were selected by -N!\n"); } } else { project_args->channel_list=NULL; } (*side_tinfo->methods->transform_init)(side_tinfo); /*{{{ Read first project_file epoch and allocate vectors array accordingly*/ if ((side_tinfo->tsdata=(*side_tinfo->methods->transform)(side_tinfo))==NULL) { ERREXIT(tinfo->emethods, "project_init: Can't get the first project epoch.\n"); } if (project_args->project_mode==PROJECT_MODE_MULTIPLY) { /* Save channel names and positions for later */ project_args->save_side_tinfo.nr_of_channels=side_tinfo->nr_of_channels; copy_channelinfo(&project_args->save_side_tinfo, side_tinfo->channelnames, side_tinfo->probepos); } if (project_args->points==0) project_args->points=side_tinfo->nr_of_points; if (project_args->points>side_tinfo->nr_of_points) { ERREXIT1(tinfo->emethods, "project_init: There are only %d points in the project_file epoch.\n", MSGPARM(side_tinfo->nr_of_points)); } if (args[ARGS_AT_XVALUE].is_set) { project_args->nr_of_point=find_pointnearx(side_tinfo, (DATATYPE)atof(args[ARGS_NROFPOINT].arg.s)); } else { project_args->nr_of_point=gettimeslice(side_tinfo, args[ARGS_NROFPOINT].arg.s); } vectors->nr_of_vectors=project_args->epochs*project_args->points; vectors->nr_of_elements=side_tinfo->nr_of_channels; vectors->element_skip=1; if (array_allocate(vectors)==NULL) { ERREXIT(tinfo->emethods, "project_init: Error allocating vectors memory\n"); } /*}}} */ do { /*{{{ Copy [points] vectors from project_file to vectors array*/ array indata; int point; if (vectors->nr_of_elements!=side_tinfo->nr_of_channels) { ERREXIT(side_tinfo->emethods, "project_init: Varying channel numbers in project file!\n"); } if (project_args->nr_of_point>=side_tinfo->nr_of_points) { ERREXIT2(side_tinfo->emethods, "project_init: nr_of_point=%d, nr_of_points=%d\n", MSGPARM(project_args->nr_of_point), MSGPARM(side_tinfo->nr_of_points)); } if (project_args->nr_of_item>=side_tinfo->itemsize) { ERREXIT2(side_tinfo->emethods, "project_init: nr_of_item=%d, itemsize=%d\n", MSGPARM(project_args->nr_of_item), MSGPARM(side_tinfo->itemsize)); } for (point=0; point<project_args->points; point++) { tinfo_array(side_tinfo, &indata); array_transpose(&indata); /* Vector = map */ if (vectors->nr_of_elements!=indata.nr_of_elements) { ERREXIT(side_tinfo->emethods, "project_init: vector size doesn't match\n"); } indata.current_vector=project_args->nr_of_point+point; array_setto_vector(&indata); array_use_item(&indata, project_args->nr_of_item); array_copy(&indata, vectors); } /*}}} */ free_tinfo(side_tinfo); } while ((side_tinfo->tsdata=(*side_tinfo->methods->transform)(side_tinfo))!=NULL); if (vectors->message!=ARRAY_ENDOFSCAN) { ERREXIT1(tinfo->emethods, "project_init: Less than %d epochs in project file\n", MSGPARM(vectors->nr_of_vectors)); } /*{{{ Set unused channels to zero if requested*/ if (args[ARGS_ZERO_UNUSEDCOEFFICIENTS].is_set) { if (project_args->channel_list!=NULL) { do { do { if (is_in_channellist(vectors->current_element+1, project_args->channel_list)) { array_advance(vectors); } else { array_write(vectors, 0.0); } } while (vectors->message==ARRAY_CONTINUE); } while (vectors->message!=ARRAY_ENDOFSCAN); } else { ERREXIT(tinfo->emethods, "project_init: Option -z only makes sense in combination with -N!\n"); } } /*}}} */ /*{{{ De-mean vectors if requested*/ if (args[ARGS_CORRELATION].is_set) { do { DATATYPE mean=0.0; int nrofaverages=0; do { if (project_args->channel_list!=NULL && !is_in_channellist(vectors->current_element+1, project_args->channel_list)) { array_advance(vectors); } else { mean+=array_scan(vectors); nrofaverages++; } } while (vectors->message==ARRAY_CONTINUE); mean/=nrofaverages; array_previousvector(vectors); do { array_write(vectors, READ_ELEMENT(vectors)-mean); } while (vectors->message==ARRAY_CONTINUE); } while (vectors->message!=ARRAY_ENDOFSCAN); } /*}}} */ /*{{{ Orthogonalize vectors if requested*/ if (project_args->orthogonalize_vectors_first) { array_make_orthogonal(vectors); if (vectors->message==ARRAY_ERROR) { ERREXIT(tinfo->emethods, "project_init: Error orthogonalizing projection vectors\n"); } } /*}}} */ if (!args[ARGS_NONORMALIZATION].is_set) { /*{{{ Normalize vectors*/ do { DATATYPE length=0.0; do { if (project_args->channel_list!=NULL && !is_in_channellist(vectors->current_element+1, project_args->channel_list)) { array_advance(vectors); } else { const DATATYPE hold=array_scan(vectors); length+=hold*hold; } } while (vectors->message==ARRAY_CONTINUE); length=sqrt(length); array_previousvector(vectors); if (length==0.0) { ERREXIT1(tinfo->emethods, "project_init: Vector %d has zero length !\n", MSGPARM(vectors->current_vector)); } array_scale(vectors, 1.0/length); } while (vectors->message!=ARRAY_ENDOFSCAN); /*}}} */ } /*{{{ Dump vectors if requested*/ if (args[ARGS_DUMPVECTORS].is_set) { FILE * const fp=fopen(args[ARGS_DUMPVECTORS].arg.s, "w"); if (fp==NULL) { ERREXIT1(tinfo->emethods, "project_init: Error opening output file >%s<.\n", MSGPARM(args[ARGS_DUMPVECTORS].arg.s)); } array_transpose(vectors); /* We want one vector to be one column */ array_dump(fp, vectors, ARRAY_MATLAB); array_transpose(vectors); fclose(fp); } /*}}} */ (*side_tinfo->methods->transform_exit)(side_tinfo); free_methodmem(side_tinfo); growing_buf_free(&buf); tinfo->methods->init_done=TRUE; }
LOCAL void noise_time(struct dipole_desc *dipole) { double scale=((double)rand())/(RAND_MAX/2)-1; do { array_write(&dipole->dip_moment, array_scan(&dipole->initial_moment)*scale); } while (dipole->dip_moment.message==ARRAY_CONTINUE); }
void array_fill( array *arr, const void *src ) { int i; for ( i = 0; i < arr->length; i++ ) array_write( arr, i, src ); }
/*{{{ read_synamps_get_singlepoint(transform_info_ptr tinfo, array *toarray) {*/ LOCAL int read_synamps_get_singlepoint(transform_info_ptr tinfo, array *toarray) { struct read_synamps_storage *local_arg=(struct read_synamps_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; if (local_arg->current_point>=local_arg->EEG.NumSamples) return -1; read_synamps_seek_point(tinfo, local_arg->current_point); switch(local_arg->SubType) { case NST_DCMES: { /* DC-MES data is unsigned, and the marker channel is skipped: */ unsigned short *pdata=(unsigned short *)local_arg->buffer+local_arg->current_point-local_arg->first_point_in_buffer+1; int channel=0; do { *pdata^=0x8000; /* Exclusive or to convert to signed... */ if (args[ARGS_NOBADCHANS].is_set && local_arg->Channels[channel].bad) { toarray->message=ARRAY_CONTINUE; } else { array_write(toarray, NEUROSCAN_CONVSHORT(&local_arg->Channels[channel], *((signed short *)pdata))); } pdata+=local_arg->EEG.ChannelOffset/local_arg->bytes_per_sample; channel++; } while (toarray->message==ARRAY_CONTINUE); } break; case NST_CONT0: case NST_CONTINUOUS: case NST_SYNAMPS: { int channel=0; do { DATATYPE val; if (args[ARGS_NOBADCHANS].is_set && local_arg->Channels[channel].bad) { toarray->message=ARRAY_CONTINUE; } else { if (local_arg->bytes_per_sample==2) { int16_t * const pdata=((int16_t *)local_arg->buffer)+local_arg->current_point-local_arg->first_point_in_buffer+channel; # ifndef LITTLE_ENDIAN Intel_int16(pdata); # endif val=NEUROSCAN_CONVSHORT(&local_arg->Channels[channel],*pdata); } else if (local_arg->bytes_per_sample==4) { int32_t * const pdata=((int32_t *)local_arg->buffer)+local_arg->current_point-local_arg->first_point_in_buffer+channel; # ifndef LITTLE_ENDIAN Intel_int32(pdata); # endif val=NEUROSCAN_CONVSHORT(&local_arg->Channels[channel],*pdata); } else { ERREXIT(tinfo->emethods, "read_synamps: Unknown bytes_per_sample\n"); } array_write(toarray, val); } channel++; } while (toarray->message==ARRAY_CONTINUE); } break; default: ERREXIT1(tinfo->emethods, "read_synamps_get_singlepoint: Format `%s' is not yet supported\n", MSGPARM(neuroscan_subtype_names[local_arg->SubType])); break; } local_arg->current_point++; return 0; }
/*{{{ normalize_channelbox(transform_info_ptr tinfo) {*/ METHODDEF DATATYPE * normalize_channelbox(transform_info_ptr tinfo) { struct normalize_channelbox_storage *local_arg=(struct normalize_channelbox_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; transform_info_ptr const tinfoptr=tinfo; int channel, xmaxchan, xminchan, ymaxchan, yminchan, zmaxchan, zminchan; DATATYPE value, value2, xmax, ymax, zmax, xmin, ymin, zmin, xmid, ymid, zmid; DATATYPE tval[9]; double phi; array myarray, t; local_arg->view_from_left=FALSE; /*{{{ Construct array myarray*/ myarray.start=(DATATYPE *)tinfoptr->probepos; myarray.nr_of_elements=3; myarray.nr_of_vectors=tinfoptr->nr_of_channels; myarray.vector_skip=3; myarray.element_skip=1; array_setreadwrite_double(&myarray); /*}}} */ /*{{{ Swap x and y if data set is 'Roma' (x=left->right)*/ if (strncmp(tinfo->comment, "Roma ", 5)==0) { /* This is the trace that vp2mfx leaves in Roma files. Though generality * lacks, this seems unavoidable in this module */ array_reset(&myarray); do { value=array_scan(&myarray); value2=array_scan(&myarray); myarray.current_element=0; array_write(&myarray, value2); array_write(&myarray, -value); array_advance(&myarray); } while (myarray.message!=ARRAY_ENDOFSCAN); } /*}}} */ /*{{{ Find min and max values of the box*/ array_reset(&myarray); xmax=xmin=array_scan(&myarray); ymax=ymin=array_scan(&myarray); zmax=zmin=array_scan(&myarray); xmaxchan=xminchan=ymaxchan=yminchan=zmaxchan=zminchan=0; channel=1; do { value=array_scan(&myarray); if (value>xmax) { xmax=value; xmaxchan=channel; } if (value<xmin) { xmin=value; xminchan=channel; } value=array_scan(&myarray); if (value>ymax) { ymax=value; ymaxchan=channel; } if (value<ymin) { ymin=value; yminchan=channel; } value=array_scan(&myarray); if (value>zmax) { zmax=value; zmaxchan=channel; } if (value<zmin) { zmin=value; zminchan=channel; } channel++; } while (myarray.message!=ARRAY_ENDOFSCAN); # ifdef DEBUG printf("zmaxchan=%s, xmaxchan=%s\n", tinfoptr->channelnames[zmaxchan], tinfoptr->channelnames[xmaxchan]); # endif /*}}} */ /*{{{ Subtract midpoint*/ xmid=(xmax+xmin)/2; ymid=(ymax+ymin)/2; zmid=(zmax+zmin)/2; # ifdef DEBUG printf("xmid=%g, ymid=%g, zmid=%g\n", xmid, ymid, zmid); # endif array_reset(&myarray); do { array_write(&myarray, READ_ELEMENT(&myarray)-xmid); array_write(&myarray, READ_ELEMENT(&myarray)-ymid); array_write(&myarray, READ_ELEMENT(&myarray)-zmid); } while (myarray.message!=ARRAY_ENDOFSCAN); /*}}} */ /*{{{ Construct array t to be used for rotations*/ t.start=tval; t.nr_of_elements=3; t.nr_of_vectors=3; t.element_skip=1; t.vector_skip=3; array_setreadwrite(&t); /*}}} */ /*{{{ rotate zmaxchan about the x axis by its angle to the y axis (maximize y)*/ /* By this rotation, the z component of zmaxchan is removed. */ array_reset(&t); myarray.current_vector=zmaxchan; myarray.current_element=1; value=array_scan(&myarray); /* y value */ value2=READ_ELEMENT(&myarray); /* z value */ value/=sqrt(value*value+value2*value2); phi=(value2>0 ? -acos(value) : acos(value)); # ifdef DEBUG printf("z=%g, cos phi=%g=%g, phi=%g\n", value2, value, cos(phi), phi); # endif array_write(&t, 1.0); array_write(&t, 0.0); array_write(&t, 0.0); array_write(&t, 0.0); array_write(&t, cos(phi)); array_write(&t, sin(phi)); array_write(&t, 0.0); array_write(&t, -sin(phi)); array_write(&t, cos(phi)); array_transpose(&t); array_reset(&myarray); do { DATATYPE x, y, z; x=array_multiply(&t, &myarray, MULT_SAMESIZE); y=array_multiply(&t, &myarray, MULT_SAMESIZE); z=array_multiply(&t, &myarray, MULT_SAMESIZE); array_previousvector(&myarray); array_write(&myarray, x); array_write(&myarray, y); array_write(&myarray, z); } while (myarray.message!=ARRAY_ENDOFSCAN); /*}}} */ /*{{{ rotate zmaxchan about the z axis by its angle to the y axis (maximize y)*/ /* Now remove the x component of zmaxchan. Coordinates should be 0, z, 0 */ array_reset(&t); myarray.current_element=0; myarray.current_vector=zmaxchan; value2=array_scan(&myarray); /* x value */ value=READ_ELEMENT(&myarray); /* y value */ value/=sqrt(value*value+value2*value2); phi=(value2>0 ? -acos(value) : acos(value)); # ifdef DEBUG printf("z=%g, cos phi=%g=%g, phi=%g\n", value2, value, cos(phi), phi); # endif array_write(&t, cos(phi)); array_write(&t, sin(phi)); array_write(&t, 0.0); array_write(&t, -sin(phi)); array_write(&t, cos(phi)); array_write(&t, 0.0); array_write(&t, 0.0); array_write(&t, 0.0); array_write(&t, 1.0); if (value2<0.0) array_transpose(&t); array_reset(&myarray); do { DATATYPE x, y, z; x=array_multiply(&t, &myarray, MULT_SAMESIZE); y=array_multiply(&t, &myarray, MULT_SAMESIZE); z=array_multiply(&t, &myarray, MULT_SAMESIZE); array_previousvector(&myarray); array_write(&myarray, x); array_write(&myarray, y); array_write(&myarray, z); } while (myarray.message!=ARRAY_ENDOFSCAN); /*}}} */ /*{{{ rotate xmaxchan about the y axis by its angle to the x axis (maximize x)*/ /* This is the only rotation that will leave zmaxchan at its position */ array_reset(&t); myarray.current_element=0; myarray.current_vector=(args[ARGS_DECIDE_LEFTRIGHT].is_set && ymid>0.0 ? local_arg->view_from_left=TRUE,xminchan : xmaxchan); value=array_scan(&myarray); /* x value */ array_advance(&myarray); value2=READ_ELEMENT(&myarray); /* z value */ value/=sqrt(value*value+value2*value2); phi=(value2>0 ? -acos(value) : acos(value)); # ifdef DEBUG printf("z=%g, cos phi=%g=%g, phi=%g\n", value2, value, cos(phi), phi); # endif array_write(&t, cos(phi)); array_write(&t, 0.0); array_write(&t, -sin(phi)); array_write(&t, 0.0); array_write(&t, 1.0); array_write(&t, 0.0); array_write(&t, sin(phi)); array_write(&t, 0.0); array_write(&t, cos(phi)); if (value2<0.0) array_transpose(&t); array_reset(&myarray); do { DATATYPE x, y, z; x=array_multiply(&t, &myarray, MULT_SAMESIZE); y=array_multiply(&t, &myarray, MULT_SAMESIZE); z=array_multiply(&t, &myarray, MULT_SAMESIZE); array_previousvector(&myarray); array_write(&myarray, x); array_write(&myarray, y); array_write(&myarray, z); } while (myarray.message!=ARRAY_ENDOFSCAN); /*}}} */ return tinfo->tsdata; }
/*{{{ trim(transform_info_ptr tinfo) {*/ METHODDEF DATATYPE * trim(transform_info_ptr tinfo) { struct trim_storage *local_arg=(struct trim_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; int item, shift, nrofshifts=1; long nr_of_input_ranges,nr_of_ranges; long output_points; long rangeno, current_output_point=0; const Bool collapse=args[ARGS_COLLAPSE].is_set || args[ARGS_COLLAPSE_Q].is_set; const DATATYPE collapse_quantile=(args[ARGS_COLLAPSE].is_set&&args[ARGS_COLLAPSE].arg.i==COLLAPSE_BY_MEDIAN ? 0.5 : (args[ARGS_COLLAPSE_Q].is_set ? args[ARGS_COLLAPSE_Q].arg.d/100.0 : 0.0)); array myarray, newarray; DATATYPE *oldtsdata; DATATYPE *new_xdata=NULL; growing_buf ranges, tokenbuf; growing_buf triggers; growing_buf_init(&ranges); growing_buf_init(&tokenbuf); growing_buf_init(&triggers); if (tinfo->data_type==FREQ_DATA) { tinfo->nr_of_points=tinfo->nroffreq; nrofshifts=tinfo->nrofshifts; } /*{{{ Parse the ranges argument */ nr_of_input_ranges=growing_buf_count_tokens(&local_arg->rangearg); if (nr_of_input_ranges<=0 || nr_of_input_ranges%2!=0) { ERREXIT(tinfo->emethods, "trim: Need an even number of arguments >=2\n"); } nr_of_input_ranges/=2; output_points=0; growing_buf_allocate(&ranges, 0); growing_buf_allocate(&tokenbuf, 0); growing_buf_get_firsttoken(&local_arg->rangearg,&tokenbuf); while (tokenbuf.current_length>0) { struct range thisrange; if (args[ARGS_USE_CHANNEL].is_set) { int const channel=find_channel_number(tinfo,args[ARGS_USE_CHANNEL].arg.s); if (channel>=0) { DATATYPE const minval=get_value(tokenbuf.buffer_start, NULL); growing_buf_get_nexttoken(&local_arg->rangearg,&tokenbuf); DATATYPE const maxval=get_value(tokenbuf.buffer_start, NULL); array indata; tinfo_array(tinfo, &indata); indata.current_vector=channel; thisrange.offset= -1; /* Marks no start recorded yet */ do { DATATYPE const currval=indata.read_element(&indata); if (currval>=minval && currval<=maxval) { if (thisrange.offset== -1) { thisrange.offset=indata.current_element; thisrange.length= 1; } else { thisrange.length++; } } else { if (thisrange.offset!= -1) { growing_buf_append(&ranges, (char *)&thisrange, sizeof(struct range)); output_points+=(collapse ? 1 : thisrange.length); thisrange.offset= -1; } } array_advance(&indata); } while (indata.message==ARRAY_CONTINUE); if (thisrange.offset!= -1) { growing_buf_append(&ranges, (char *)&thisrange, sizeof(struct range)); output_points+=(collapse ? 1 : thisrange.length); } } else { ERREXIT1(tinfo->emethods, "set xdata_from_channel: Unknown channel name >%s<\n", MSGPARM(args[ARGS_USE_CHANNEL].arg.s)); } } else { if (args[ARGS_USE_XVALUES].is_set) { if (tinfo->xdata==NULL) create_xaxis(tinfo, NULL); thisrange.offset=decode_xpoint(tinfo, tokenbuf.buffer_start); growing_buf_get_nexttoken(&local_arg->rangearg,&tokenbuf); thisrange.length=decode_xpoint(tinfo, tokenbuf.buffer_start)-thisrange.offset+1; } else { thisrange.offset=gettimeslice(tinfo, tokenbuf.buffer_start); growing_buf_get_nexttoken(&local_arg->rangearg,&tokenbuf); thisrange.length=gettimeslice(tinfo, tokenbuf.buffer_start); if (thisrange.length==0) { thisrange.length=tinfo->nr_of_points-thisrange.offset; } } if (thisrange.length<=0) { ERREXIT1(tinfo->emethods, "trim: length is %d but must be >0.\n", MSGPARM(thisrange.length)); } growing_buf_append(&ranges, (char *)&thisrange, sizeof(struct range)); output_points+=(collapse ? 1 : thisrange.length); } growing_buf_get_nexttoken(&local_arg->rangearg,&tokenbuf); } /*}}} */ nr_of_ranges=ranges.current_length/sizeof(struct range); if (nr_of_ranges==0) { TRACEMS(tinfo->emethods, 0, "trim: No valid ranges selected, rejecting epoch.\n"); return NULL; } TRACEMS2(tinfo->emethods, 1, "trim: nr_of_ranges=%ld, output_points=%ld\n", MSGPARM(nr_of_ranges), MSGPARM(output_points)); newarray.nr_of_vectors=tinfo->nr_of_channels*nrofshifts; newarray.nr_of_elements=output_points; newarray.element_skip=tinfo->itemsize; if (array_allocate(&newarray)==NULL) { ERREXIT(tinfo->emethods, "trim: Error allocating memory.\n"); } oldtsdata=tinfo->tsdata; if (tinfo->xdata!=NULL) { /* Store xchannelname at the end of xdata, as in create_xaxis(); otherwise we'll have * a problem after free()'ing xdata... */ new_xdata=(DATATYPE *)malloc(output_points*sizeof(DATATYPE)+strlen(tinfo->xchannelname)+1); if (new_xdata==NULL) { ERREXIT(tinfo->emethods, "trim: Error allocating xdata memory.\n"); } } if (tinfo->triggers.buffer_start!=NULL) { struct trigger trig= *(struct trigger *)tinfo->triggers.buffer_start; growing_buf_allocate(&triggers, 0); /* Record the file position... */ if (collapse) { /* Make triggers in subsequent append() work as expected at least with * continuous reading */ trig.position=local_arg->current_epoch*nr_of_ranges; trig.code= -1; } growing_buf_append(&triggers, (char *)&trig, sizeof(struct trigger)); } for (rangeno=0; rangeno<nr_of_ranges; rangeno++) { struct range *rangep=((struct range *)(ranges.buffer_start))+rangeno; long const old_startpoint=(rangep->offset>0 ? rangep->offset : 0); long const new_startpoint=(rangep->offset<0 ? -rangep->offset : 0); /*{{{ Transfer the data*/ if (old_startpoint<tinfo->nr_of_points /* Skip this explicitly if no "real" point needs copying (length confined within negative offset) * since otherwise an endless loop can result as the stop conditions below look at the array * states and no array is touched... */ && new_startpoint<rangep->length) for (item=0; item<tinfo->itemsize; item++) { array_use_item(&newarray, item); for (shift=0; shift<nrofshifts; shift++) { tinfo_array(tinfo, &myarray); array_use_item(&myarray, item); do { DATATYPE sum=0.0; long reached_length=new_startpoint; myarray.current_element= old_startpoint; if (collapse) { newarray.current_element=current_output_point; newarray.message=ARRAY_CONTINUE; /* Otherwise the loop below may finish promptly... */ if (args[ARGS_COLLAPSE].is_set) switch (args[ARGS_COLLAPSE].arg.i) { case COLLAPSE_BY_HIGHEST: sum= -FLT_MAX; break; case COLLAPSE_BY_LOWEST: sum= FLT_MAX; break; default: break; } } else { newarray.current_element=current_output_point+new_startpoint; } if (collapse && collapse_quantile>0.0) { array helparray=myarray; helparray.ringstart=ARRAY_ELEMENT(&myarray); helparray.current_element=helparray.current_vector=0; helparray.nr_of_vectors=1; helparray.nr_of_elements=rangep->length; sum=array_quantile(&helparray,collapse_quantile); myarray.message=ARRAY_CONTINUE; } else do { if (reached_length>=rangep->length) break; if (args[ARGS_COLLAPSE].is_set) { DATATYPE const hold=array_scan(&myarray); switch (args[ARGS_COLLAPSE].arg.i) { case COLLAPSE_BY_SUMMATION: case COLLAPSE_BY_AVERAGING: sum+=hold; break; case COLLAPSE_BY_HIGHEST: if (hold>sum) sum=hold; break; case COLLAPSE_BY_LOWEST: if (hold<sum) sum=hold; break; default: break; } } else { array_write(&newarray, array_scan(&myarray)); } reached_length++; } while (newarray.message==ARRAY_CONTINUE && myarray.message==ARRAY_CONTINUE); if (collapse) { if (args[ARGS_COLLAPSE].is_set && args[ARGS_COLLAPSE].arg.i==COLLAPSE_BY_AVERAGING && item<tinfo->itemsize-tinfo->leaveright) sum/=reached_length; array_write(&newarray, sum); } if (newarray.message==ARRAY_CONTINUE) { array_nextvector(&newarray); } if (myarray.message==ARRAY_CONTINUE) { array_nextvector(&myarray); } } while (myarray.message==ARRAY_ENDOFVECTOR); tinfo->tsdata+=myarray.nr_of_vectors*myarray.nr_of_elements*myarray.element_skip; } tinfo->tsdata=oldtsdata; } /*}}} */ if (new_xdata!=NULL) { /*{{{ Transfer xdata*/ DATATYPE sum=0.0; long reached_length=new_startpoint; long point, newpoint; if (collapse) { newpoint=current_output_point; } else { newpoint=current_output_point+new_startpoint; } for (point=old_startpoint; point<tinfo->nr_of_points && reached_length<rangep->length; point++) { if (collapse) { sum+=tinfo->xdata[point]; } else { new_xdata[newpoint]=tinfo->xdata[point]; newpoint++; } reached_length++; } if (collapse) { /* Summation of x axis values does not appear to make sense, so we always average: */ new_xdata[newpoint]=sum/reached_length; } /*}}} */ /* Save xchannelname to the end of new_xdata */ strcpy((char *)(new_xdata+output_points),tinfo->xchannelname); } if (tinfo->triggers.buffer_start!=NULL) { /* Collect triggers... */ struct trigger *intrig=(struct trigger *)tinfo->triggers.buffer_start+1; while (intrig->code!=0) { if (intrig->position>=old_startpoint && intrig->position<old_startpoint+rangep->length) { struct trigger trig= *intrig; if (collapse) { trig.position=current_output_point; } else { trig.position=intrig->position-old_startpoint+current_output_point; } growing_buf_append(&triggers, (char *)&trig, sizeof(struct trigger)); } intrig++; } } current_output_point+=(collapse ? 1 : rangep->length); } if (new_xdata!=NULL) { free(tinfo->xdata); tinfo->xdata=new_xdata; tinfo->xchannelname=(char *)(new_xdata+output_points); } if (tinfo->triggers.buffer_start!=NULL) { struct trigger trig; /* Write end marker */ trig.position=0; trig.code=0; growing_buf_append(&triggers, (char *)&trig, sizeof(struct trigger)); growing_buf_free(&tinfo->triggers); tinfo->triggers=triggers; } tinfo->multiplexed=FALSE; tinfo->nr_of_points=output_points; if (tinfo->data_type==FREQ_DATA) { tinfo->nroffreq=tinfo->nr_of_points; } else { tinfo->beforetrig-=((struct range *)(ranges.buffer_start))->offset; tinfo->aftertrig=output_points-tinfo->beforetrig; } tinfo->length_of_output_region=tinfo->nr_of_points*tinfo->nr_of_channels*tinfo->itemsize*nrofshifts; local_arg->current_epoch++; growing_buf_free(&tokenbuf); growing_buf_free(&ranges); return newarray.start; }
int main(int argc, char *argv[]) { int i=1, start=0, end=0, freqno; DATATYPE *new_tsdata, hold; array D; OPT_DTYPE ax, bx, cx, fa, fb, fc, xmin, sumsq, weight, sumweight, ave, min_power, optimize_arg, *points; optimize_struct ostruct; struct minfunc_struct mfs; struct transform_info_struct firsttinfo; transform_info_ptr tinfo, tinfo_next; struct transform_methods_struct methods[2]; struct external_methods_struct emethod; tinfo= &firsttinfo; /*{{{ Process command line*/ while (*argv[1]=='-') { switch (argv[1][1]) { } argv++; argc--; } if (argc!=3) { fprintf(stderr, "Usage: %s ascdatafile outfile\n" , argv[0]); return 1; } if (start<0) start=0; if (end<=0) end=start; /*}}} */ clear_external_methods(&emethod); firsttinfo.methods= methods; firsttinfo.emethods= &emethod; /*{{{ Read all data sets*/ select_readasc(tinfo); (*tinfo->methods->transform_defaults)(tinfo); firsttinfo.filename=argv[1]; firsttinfo.epochs= -1; firsttinfo.fromepoch=1; (*tinfo->methods->transform_init)(tinfo); if (start!=0) { while (i<start) { (*tinfo->methods->transform)(tinfo); i++; } } while ((end==0 || i<=end) && (*tinfo->methods->transform)(tinfo)!=NULL) { if ((tinfo_next=malloc(sizeof(struct transform_info_struct)))==NULL) { ERREXIT(&emethod, "similarity: Error malloc'ing tinfo struct\n"); } *(tinfo_next)=firsttinfo; tinfo_next->previous=tinfo; tinfo_next->next=NULL; tinfo->next=tinfo_next; tinfo=tinfo_next; i++; } /* The last tinfo structure was allocated in vein, throw away */ tinfo=tinfo->previous; free(tinfo->next); tinfo->next=NULL; (*firsttinfo.methods->transform_exit)(&firsttinfo); /*}}} */ points=malloc(2*firsttinfo.nr_of_channels*sizeof(OPT_DTYPE)); for (freqno=0; freqno<firsttinfo.nr_of_channels; freqno++) { /*{{{ Construct symmetrical function*/ sumweight=ave=0.0; min_power=1e10; for (i=0, tinfo= &firsttinfo; tinfo!=NULL; tinfo=tinfo->next, i++) { tinfo_array(tinfo, &D); array_transpose(&D); array_reset(&D); D.current_vector=freqno; D.current_element=i; hold=array_readelement(&D); D.current_element=0; do { points[D.current_element*2]=100*channel_distance(tinfo, i, D.current_element); points[D.current_element*2+1]=array_scan(&D)/hold; } while (D.message==ARRAY_CONTINUE); ostruct.function= &minfunc; mfs.nr_of_points=firsttinfo.nr_of_channels; mfs.points=points; ostruct.fixed_args=(void *)&mfs; ostruct.num_opt_args=1; ostruct.opt_args=(void *)&optimize_arg; ax=0.1; bx=12; opt_mnbrak(&ostruct, &ax, &bx, &cx, &fa, &fb, &fc); sumsq=opt_brent(&ostruct, ax, bx, cx, 1e-4, &xmin); # ifdef VERBOSE printf("%d %g %g %g\n", i, xmin, sumsq, hold); # endif weight= 1.0/sumsq; sumweight+=weight; ave+=weight*xmin; if (hold<min_power) min_power=hold; } ave/=sumweight; # ifdef VERBOSE printf("Consensus: %g %g\n", ave, min_power); # endif /*}}} */ /*{{{ Subtract symmetrical function*/ for (i=0, tinfo= &firsttinfo; tinfo!=NULL; tinfo=tinfo->next, i++) { tinfo_array(tinfo, &D); array_transpose(&D); array_reset(&D); D.current_vector=freqno; D.current_element=0; do { hold= min_power*distfun(100*channel_distance(tinfo, i, D.current_element), ave); array_write(&D, array_readelement(&D)-hold); } while (D.message==ARRAY_CONTINUE); } /*}}} */ } free(points); /*{{{ Write all data sets*/ tinfo= &firsttinfo; select_extract_item(tinfo); /* Output real part only */ (*tinfo->methods->transform_defaults)(tinfo); tinfo->methods->local_storage=(void *)0; (*tinfo->methods->transform_init)(tinfo); tinfo->methods++; select_writeasc(tinfo); (*tinfo->methods->transform_defaults)(tinfo); tinfo->outfname=argv[2]; tinfo->methods->local_storage=(void *)1; (*tinfo->methods->transform_init)(tinfo); for (; tinfo!=NULL; tinfo=tinfo->next) { tinfo->outfptr=firsttinfo.outfptr; tinfo->methods=methods; if ((new_tsdata=(*tinfo->methods->transform)(tinfo))==NULL) { ERREXIT(tinfo->emethods, "extract_item failed !\n"); } free(tinfo->tsdata); tinfo->tsdata=new_tsdata; tinfo->methods++; (*tinfo->methods->transform)(tinfo); } tinfo= &firsttinfo; tinfo->methods=methods; (*tinfo->methods->transform_exit)(tinfo); tinfo->methods++; (*tinfo->methods->transform_exit)(tinfo); /*}}} */ return 0; }