Beispiel #1
0
/*{{{  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;
}
Beispiel #2
0
static int luaC_lunum_transpose(lua_State *L)
{
  const Array *A = lunum_checkarray1(L, 1); // the array to transpose

  /* copy transposed shape and size to B */
  Array B = array_new_zeros(A->size, A->dtype);
  array_resize_t(&B, A->shape, A->ndims);
  array_transpose(A, &B);

  lunum_pusharray1(L, &B);

  return 1;

}
Beispiel #3
0
/*{{{  write_rec(transform_info_ptr tinfo) {*/
METHODDEF DATATYPE *
write_rec(transform_info_ptr tinfo) {
 struct write_rec_storage *local_arg=(struct write_rec_storage *)tinfo->methods->local_storage;
 transform_argument *args=tinfo->methods->arguments;
 FILE *outfptr=local_arg->outfptr;
 short *inbuf;
 array myarray;

 if (tinfo->itemsize!=1) {
  ERREXIT(tinfo->emethods, "write_rec: Only itemsize=1 is supported.\n");
 }
 if (args[ARGS_CLOSE].is_set) {
  write_rec_open_file(tinfo);
  outfptr=local_arg->outfptr;
 }
 /*{{{  Write epoch*/
 tinfo_array(tinfo, &myarray);
 /* We read the data point by point, i.e. channels fastest */
 array_transpose(&myarray);
 /* Within the record, writing is non-interlaced, ie points fastest */
 do {
  do {
   inbuf=local_arg->outbuf+local_arg->samples_per_record*myarray.current_element+local_arg->current_sample;
   *inbuf= (short int)rint(array_scan(&myarray)/local_arg->resolution);
   if (!local_arg->overflow_has_occurred && (*inbuf<local_arg->digmin || *inbuf>local_arg->digmax)) {
    TRACEMS(tinfo->emethods, 0, "write_rec: Some output values exceed digitization bits!\n");
    local_arg->overflow_has_occurred=TRUE;
   }
#ifndef LITTLE_ENDIAN
   Intel_int16(inbuf);
#endif
  } while (myarray.message==ARRAY_CONTINUE);
  if (++local_arg->current_sample>=local_arg->samples_per_record) {
   if ((int)fwrite(local_arg->outbuf, sizeof(short), tinfo->nr_of_channels*local_arg->samples_per_record, outfptr)!=tinfo->nr_of_channels*local_arg->samples_per_record) {
    ERREXIT(tinfo->emethods, "write_rec: Write error on data file.\n");
   }
   /* If nr_of_records was -1 (can only happen while appending),
    * leave it that way */
   if (local_arg->nr_of_records>=0) local_arg->nr_of_records++;
   local_arg->current_sample=0L;
  }
 } while (myarray.message!=ARRAY_ENDOFSCAN);
 /*}}}  */
 if (args[ARGS_CLOSE].is_set) write_rec_close_file(tinfo);
 return tinfo->tsdata;	/* Simply to return something `useful' */
}
Beispiel #4
0
/*{{{  write_vitaport(transform_info_ptr tinfo) {*/
METHODDEF DATATYPE *
write_vitaport(transform_info_ptr tinfo) {
    struct write_vitaport_storage *local_arg=(struct write_vitaport_storage *)tinfo->methods->local_storage;
    array myarray;
    int channel;

    /*{{{  Assert that epoch size didn't change & itemsize==1*/
    if (tinfo->itemsize!=1) {
        ERREXIT(tinfo->emethods, "write_vitaport: Only itemsize=1 is supported.\n");
    }
    if (local_arg->fileheader.knum!=tinfo->nr_of_channels) {
        ERREXIT2(tinfo->emethods, "write_vitaport: nr_of_channels was %d, now %d\n", MSGPARM(local_arg->fileheader.knum), MSGPARM(tinfo->nr_of_channels));
    }
    /*}}}  */

    if (tinfo->data_type==FREQ_DATA) tinfo->nr_of_points=tinfo->nroffreq;

    tinfo_array(tinfo, &myarray);
    array_transpose(&myarray); /* channels are the elements: Temp file is interlaced */
    do {
        channel=0;
        do {
            DATATYPE dat=array_scan(&myarray);
            if (fwrite(&dat, sizeof(DATATYPE), 1, local_arg->channelfile)!=1) {
                ERREXIT(tinfo->emethods, "write_vitaport: Error writing temp file.\n");
            }
            /* Keep track of the scaling... */
            if (dat>local_arg->channelmax[channel]) local_arg->channelmax[channel]=dat;
            if (dat<local_arg->channelmin[channel]) local_arg->channelmin[channel]=dat;
            channel++;
        } while (myarray.message==ARRAY_CONTINUE);
    } while (myarray.message!=ARRAY_ENDOFSCAN);

    if (tinfo->triggers.buffer_start!=NULL) {
        struct trigger *intrig=(struct trigger *)tinfo->triggers.buffer_start+1;
        while (intrig->code!=0) {
            push_trigger(&local_arg->triggers,local_arg->total_points+intrig->position,intrig->code,intrig->description);
            intrig++;
        }
    }

    local_arg->total_points+=tinfo->nr_of_points;

    return tinfo->tsdata;	/* Simply to return something `useful' */
}
Beispiel #5
0
/*{{{  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;
}
Beispiel #6
0
/*{{{  write_synamps(transform_info_ptr tinfo) {*/
METHODDEF DATATYPE *
write_synamps(transform_info_ptr calltinfo) {
 struct write_synamps_storage *local_arg=(struct write_synamps_storage *)calltinfo->methods->local_storage;
 transform_argument *args=calltinfo->methods->arguments;
 NEUROSCAN_EPOCHED_SWEEP_HEAD sweephead;
 long tsdata_step, tsdata_steps, tsdata_stepwidth;
 array myarray;
 /* Note that 'tinfo' instead of 'tinfoptr' is used here so that we don't have to modify 
  * all of the older code which stored only one epoch */
 transform_info_ptr tinfo=calltinfo;

 if (args[ARGS_LINKED].is_set) {
  /* Go to the start: */
  for (; tinfo->previous!=NULL; tinfo=tinfo->previous);
 }
 for (; tinfo!=NULL; tinfo=tinfo->next) {
  DATATYPE * const orig_tsdata=tinfo->tsdata;
 /*{{{  Assert that epoch size didn't change & itemsize==1*/
 if (tinfo->itemsize!=1) {
  ERREXIT(tinfo->emethods, "write_synamps: Only itemsize=1 is supported.\n");
 }
 if (local_arg->EEG.nchannels!=tinfo->nr_of_channels) {
  ERREXIT2(tinfo->emethods, "write_synamps: nr_of_channels was %d, now %d\n", MSGPARM(local_arg->EEG.nchannels), MSGPARM(tinfo->nr_of_channels));
 }
 /*}}}  */

 if (tinfo->data_type==FREQ_DATA) {
  tinfo->nr_of_points=tinfo->nroffreq;
  tsdata_steps=tinfo->nrofshifts;
  tsdata_stepwidth=tinfo->nr_of_channels*tinfo->nroffreq*tinfo->itemsize;
 } else {
  tsdata_steps=1;
  tsdata_stepwidth=0;
 }
 for (tsdata_step=0; tsdata_step<tsdata_steps; tinfo->tsdata+=tsdata_stepwidth, tsdata_step++) {
 switch (local_arg->output_format) {
  case FORMAT_EEGFILE:
 if (local_arg->EEG.pnts!=tinfo->nr_of_points) {
  ERREXIT2(tinfo->emethods, "write_synamps: nr_of_points was %d, now %d\n", MSGPARM(local_arg->EEG.pnts), MSGPARM(tinfo->nr_of_points));
 }
 /*{{{  Set sweephead values*/
 sweephead.accept=1;
 sweephead.type=254;
 sweephead.correct=0;
 sweephead.rt=0;
 sweephead.response=0;
 if (tinfo->condition>0) {
  sweephead.type=tinfo->condition&0xff;
 } else if (tinfo->condition<0 && (-tinfo->condition)<=0xf) {
  sweephead.type=0;
  sweephead.response= -tinfo->condition;
 } else {
  /* KeyBoard event: Do it the same way 'Edit' does when epoching,
   * mapping F1 to type=1 and so on (overlap with stim codes, but they
   * should know how they want it...) */
  sweephead.type= (-tinfo->condition)>>4;
 }
 /*}}}  */
 /*{{{  Write sweephead struct*/
# ifndef LITTLE_ENDIAN
 change_byteorder((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD);
# endif
 write_struct((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD, local_arg->SCAN);
# ifndef LITTLE_ENDIAN
 change_byteorder((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD);
# endif
 /*}}}  */
 local_arg->EEG.nsweeps++;	/* This gets patched into the header by write_synamps_exit */
 local_arg->EEG.compsweeps++;
 local_arg->EEG.acceptcnt++;
   break;
  case FORMAT_AVGFILE:
   if (local_arg->EEG.NumSamples!=0) {
    ERREXIT(tinfo->emethods, "write_synamps: Only a single epoch may be written to an .AVG file!\n");
   }
  case FORMAT_CNTFILE:
   if (tinfo->triggers.buffer_start!=NULL) {
    struct trigger *intrig=(struct trigger *)tinfo->triggers.buffer_start+1;
    while (intrig->code!=0) {
     push_trigger(&local_arg->triggers,local_arg->EEG.NumSamples+intrig->position,intrig->code,intrig->description);
     intrig++;
    }
   }
   local_arg->EEG.NumSamples+=tinfo->nr_of_points;
   break;
 }

 tinfo_array(tinfo, &myarray);
 if (local_arg->output_format==FORMAT_AVGFILE) {
  /* points are the elements */
  float *pdata, * const buffer=(float *)malloc(myarray.nr_of_elements*sizeof(float));
  const char *fill="\0\0\0\0\0";
  if (buffer==NULL) {
   ERREXIT(tinfo->emethods, "write_synamps: Error allocating AVGFILE buffer\n");
  }
  do {
   int const channel=myarray.current_vector;
   /* Write the `5-byte channel header that is no longer used' */
   fwrite(fill, 1, 5, local_arg->SCAN);
   pdata=buffer;
   do {
    *pdata=NEUROSCAN_FLOATCONV(&local_arg->Channels[channel], array_scan(&myarray));
# ifndef LITTLE_ENDIAN
    Intel_float(pdata);
# endif
    pdata++;
   } while (myarray.message==ARRAY_CONTINUE);
   if ((int)fwrite(buffer,sizeof(float),myarray.nr_of_elements,local_arg->SCAN)!=myarray.nr_of_elements) {
    ERREXIT(tinfo->emethods, "write_synamps: Error writing data point\n");
   }
  } while (myarray.message!=ARRAY_ENDOFSCAN);
  free(buffer);
 } else {
 int16_t * const buffer=(int16_t *)malloc(myarray.nr_of_vectors*sizeof(int16_t));
 if (buffer==NULL) {
  ERREXIT(tinfo->emethods, "write_synamps: Error allocating buffer\n");
 }
 array_transpose(&myarray);	/* channels are the elements */
 do {
  int channel=0;
  do {
   DATATYPE hold=array_scan(&myarray), hold2;
   /* Code anything exceeding the representable range, including +-Inf, as min/max representable value. */
   hold2=NEUROSCAN_SHORTCONV(&local_arg->Channels[channel], hold);
   if (hold2< -32768) hold2= -32768;
   else if (hold2> 32767) hold2= 32767;
   buffer[channel]=(int16_t)hold2;
# ifndef LITTLE_ENDIAN
   Intel_int16(&buffer[channel]);
# endif
   channel++;
  } while (myarray.message==ARRAY_CONTINUE);
  if ((int)fwrite(buffer,sizeof(int16_t),myarray.nr_of_elements,local_arg->SCAN)!=myarray.nr_of_elements) {
   ERREXIT(tinfo->emethods, "write_synamps: Error writing data point\n");
  }
 } while (myarray.message!=ARRAY_ENDOFSCAN);
 free(buffer);
 }
 } /* FREQ_DATA shifts loop */
 tinfo->tsdata=orig_tsdata;
  if (!args[ARGS_LINKED].is_set) {
   break;
  }
 } /* Linked epochs loop */

 return calltinfo->tsdata;	/* Simply to return something `useful' */
}
Beispiel #7
0
/*{{{  scale_by(transform_info_ptr tinfo)*/
METHODDEF DATATYPE *
scale_by(transform_info_ptr tinfo) {
 struct scale_by_storage *local_arg=(struct scale_by_storage *)tinfo->methods->local_storage;
 DATATYPE factor;
 int itempart;
 array indata;

 tinfo_array(tinfo, &indata);
 switch (local_arg->type) {
  /* Operations which are done on maps */
  case SCALE_BY_XDATA:
  case SCALE_BY_INVXDATA:
   if (tinfo->xdata==NULL) create_xaxis(tinfo, NULL);
  case SCALE_BY_NORMALIZE:
  case SCALE_BY_INVNORM:
  case SCALE_BY_INVSQUARENORM:
  case SCALE_BY_INVSUM:
  case SCALE_BY_INVMAX:
  case SCALE_BY_INVMAXABS:
  case SCALE_BY_INVQUANTILE:
   array_transpose(&indata);	/* Vectors are maps */
   if (local_arg->have_channel_list) {
    ERREXIT(tinfo->emethods, "scale_by: Channel subsets are not supported for map operations.\n");
   }
   break;

  /* Operations which are done on channels */
  case SCALE_BY_INVPOINTNORM:
  case SCALE_BY_INVPOINTSQUARENORM:
  case SCALE_BY_INVPOINTSUM:
  case SCALE_BY_INVPOINTMAX:
  case SCALE_BY_INVPOINTMAXABS:
  case SCALE_BY_INVPOINTQUANTILE:
  case SCALE_BY_FACTOR:
   break;

  /* Operations which involve a special but constant factor */
  case SCALE_BY_PI:
   local_arg->factor= M_PI;
   break;
  case SCALE_BY_INVPI:
   local_arg->factor= 1.0/M_PI;
   break;
  case SCALE_BY_SFREQ:
   local_arg->factor= tinfo->sfreq;
   break;
  case SCALE_BY_INVSFREQ:
   local_arg->factor= 1.0/tinfo->sfreq;
   break;
  case SCALE_BY_NR_OF_POINTS:
   local_arg->factor= (tinfo->data_type==FREQ_DATA ? tinfo->nroffreq : tinfo->nr_of_points);
   break;
  case SCALE_BY_INVNR_OF_POINTS:
   local_arg->factor= 1.0/(tinfo->data_type==FREQ_DATA ? tinfo->nroffreq : tinfo->nr_of_points);
   break;
  case SCALE_BY_NR_OF_CHANNELS:
   local_arg->factor= tinfo->nr_of_channels;
   break;
  case SCALE_BY_INVNR_OF_CHANNELS:
   local_arg->factor= 1.0/tinfo->nr_of_channels;
   break;
  case SCALE_BY_NROFAVERAGES:
   local_arg->factor= tinfo->nrofaverages;
   break;
  case SCALE_BY_INVNROFAVERAGES:
   local_arg->factor= 1.0/tinfo->nrofaverages;
   break;
  case SCALE_BY_SQRTNROFAVERAGES:
   local_arg->factor= sqrt(tinfo->nrofaverages);
   break;
  case SCALE_BY_INVSQRTNROFAVERAGES:
   local_arg->factor= 1.0/sqrt(tinfo->nrofaverages);
   break;
 }

 for (itempart=local_arg->fromitem; itempart<=local_arg->toitem; itempart++) {
  array_use_item(&indata, itempart);
  do {
   if (local_arg->have_channel_list && !is_in_channellist(indata.current_vector+1, local_arg->channel_list)) {
    array_nextvector(&indata);
    continue;
   }
   switch (local_arg->type) {
    case SCALE_BY_NORMALIZE:
    case SCALE_BY_INVNORM:
    case SCALE_BY_INVPOINTNORM:
     factor=array_abs(&indata);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVSQUARENORM:
    case SCALE_BY_INVPOINTSQUARENORM:
     factor=array_square(&indata);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVSUM:
    case SCALE_BY_INVPOINTSUM:
     factor=array_sum(&indata);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVMAX:
    case SCALE_BY_INVPOINTMAX:
     factor=array_max(&indata);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVMAXABS:
    case SCALE_BY_INVPOINTMAXABS: {
     DATATYPE amax=fabs(array_scan(&indata)), hold;
     while (indata.message==ARRAY_CONTINUE) {
      hold=fabs(array_scan(&indata));
      if (hold>amax) amax=hold;
     }
     factor=amax;
     }
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     array_previousvector(&indata);
     break;
    case SCALE_BY_INVQUANTILE:
    case SCALE_BY_INVPOINTQUANTILE:
     factor=array_quantile(&indata,local_arg->factor);
     if (factor==0.0) factor=1.0;
     factor=1.0/factor;
     break;
    case SCALE_BY_XDATA:
     factor=tinfo->xdata[indata.current_vector];
     break;
    case SCALE_BY_INVXDATA:
     factor=1.0/tinfo->xdata[indata.current_vector];
     break;
    case SCALE_BY_PI:
    case SCALE_BY_INVPI:
    case SCALE_BY_SFREQ:
    case SCALE_BY_INVSFREQ:
    case SCALE_BY_NR_OF_POINTS:
    case SCALE_BY_INVNR_OF_POINTS:
    case SCALE_BY_NR_OF_CHANNELS:
    case SCALE_BY_INVNR_OF_CHANNELS:
    case SCALE_BY_NROFAVERAGES:
    case SCALE_BY_INVNROFAVERAGES:
    case SCALE_BY_SQRTNROFAVERAGES:
    case SCALE_BY_INVSQRTNROFAVERAGES:
    case SCALE_BY_FACTOR:
     factor=local_arg->factor;
     break;
    default:
     continue;
   }
   array_scale(&indata, factor);
  } while (indata.message!=ARRAY_ENDOFSCAN);
 }

 return tinfo->tsdata;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
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;
}
Beispiel #11
0
/*{{{  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;
}
Beispiel #12
0
/*{{{  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;
}
Beispiel #13
0
/*{{{  writeasc(transform_info_ptr tinfo) {*/
METHODDEF DATATYPE *
writeasc(transform_info_ptr calltinfo) {
    struct writeasc_storage *local_arg=(struct writeasc_storage *)calltinfo->methods->local_storage;
    transform_argument *args=calltinfo->methods->arguments;
    int i, channel, itempart;
    long tsdata_step, tsdata_steps, tsdata_stepwidth;
    FILE *outfptr=local_arg->outfptr;
    /* Note that 'tinfo' instead of 'tinfoptr' is used here so that we don't have to modify
     * all of the older code which stored only one epoch */
    transform_info_ptr tinfo=calltinfo;

    if (args[ARGS_CLOSE].is_set) {
        writeasc_open_file(calltinfo);
        outfptr=local_arg->outfptr;
    }
    if (args[ARGS_LINKED].is_set) {
        /* Go to the start: */
        for (; tinfo->previous!=NULL; tinfo=tinfo->previous);
    }
    for (; tinfo!=NULL; tinfo=tinfo->next) {
        DATATYPE * const orig_tsdata=tinfo->tsdata;
        if (tinfo->xdata==NULL) create_xaxis(tinfo,NULL);
        if (tinfo->data_type==FREQ_DATA) {
            tinfo->nr_of_points=tinfo->nroffreq;
            tsdata_steps=tinfo->nrofshifts;
            tsdata_stepwidth=tinfo->nr_of_channels*tinfo->nroffreq*tinfo->itemsize;
        } else {
            tsdata_steps=1;
            tsdata_stepwidth=0;
        }
        for (tsdata_step=0; tsdata_step<tsdata_steps; tinfo->tsdata+=tsdata_stepwidth, tsdata_step++) {
            if (tinfo->data_type==FREQ_DATA && tsdata_steps>1) {
                /* Multiple data sets to be written: Construct a different z_value for each. */
                if (tinfo->basetime==0.0) {
                    /* Assigning the same latency to all shifts would not be optimal... */
                    tinfo->z_label="Nr";
                    tinfo->z_value=tsdata_step+1;
                } else {
                    tinfo->z_label="Lat[ms]";
                    tinfo->z_value=(tsdata_step*tinfo->basetime+(tinfo->windowsize-tinfo->beforetrig)/tinfo->sfreq)*1000;
                }
            }
            if (args[ARGS_BINARY].is_set) {
                /*{{{  Write binary*/
                char outbuf[OUTBUFSIZE], *inoutbuf;
                int len;

                fwrite((void *)&tinfo->nr_of_channels, sizeof(int), 1, outfptr);
                fwrite((void *)&tinfo->nr_of_points, sizeof(int), 1, outfptr);
                if (tinfo->itemsize<=0) tinfo->itemsize=1;
                fwrite((void *)&tinfo->itemsize, sizeof(int), 1, outfptr);
                fwrite((void *)&tinfo->multiplexed, sizeof(int), 1, outfptr);

                *outbuf='\0';
                inoutbuf=outbuf;
                if (tinfo->nrofaverages>0) {
                    snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), "Nr_of_averages=%d;", tinfo->nrofaverages);
                    inoutbuf+=strlen(inoutbuf);
                }
                if (tinfo->sfreq!=local_arg->sfreq) {
                    snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), "Sfreq=%f;", (float)tinfo->sfreq);
                    inoutbuf+=strlen(inoutbuf);
                }
                if (tinfo->beforetrig!=local_arg->beforetrig) {
                    snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), "BeforeTrig=%d;", tinfo->beforetrig);
                    inoutbuf+=strlen(inoutbuf);
                }
                if (tinfo->leaveright!=local_arg->leaveright) {
                    snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), "Leaveright=%d;", tinfo->leaveright);
                    inoutbuf+=strlen(inoutbuf);
                }
                if (tinfo->condition!=0) {
                    snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), "Condition=%d;", tinfo->condition);
                    inoutbuf+=strlen(inoutbuf);
                }
                if (tinfo->triggers.buffer_start!=NULL) {
                    struct trigger *intrig=(struct trigger *)tinfo->triggers.buffer_start;
                    snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), "Triggers=%ld", intrig->position);
                    inoutbuf+=strlen(inoutbuf);
                    intrig++;
                    while (intrig->code!=0) {
                        snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), ",%ld:%d", intrig->position, intrig->code);
                        inoutbuf+=strlen(inoutbuf);
                        intrig++;
                    }
                    *inoutbuf++=';';
                }
                if (tinfo->comment!=NULL) {
                    snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), "%s", tinfo->comment);
                    inoutbuf+=strlen(inoutbuf);
                }
                if (tinfo->z_label!=NULL) {
                    snprintf(inoutbuf, OUTBUFSIZE-(inoutbuf-outbuf), "%s%s=%g", ZAXIS_DELIMITER, tinfo->z_label, tinfo->z_value);
                    inoutbuf+=strlen(inoutbuf);
                }
                len=inoutbuf-outbuf+1;
                len+=strlen(tinfo->xchannelname)+1;
                for (channel=0; channel<tinfo->nr_of_channels; channel++) {
                    len+=strlen(tinfo->channelnames[channel])+1;
                }
                fwrite((void *)&len, sizeof(int), 1, outfptr);

                fwrite((void *)outbuf, strlen(outbuf)+1, 1, outfptr);
                fwrite((void *)tinfo->xchannelname, strlen(tinfo->xchannelname)+1, 1, outfptr);
                for (channel=0; channel<tinfo->nr_of_channels; channel++) {
                    fwrite((void *)tinfo->channelnames[channel], strlen(tinfo->channelnames[channel])+1, 1, outfptr);
                }
                fwrite((void *)tinfo->probepos, sizeof(double), 3*tinfo->nr_of_channels, outfptr);
                fwrite((void *)tinfo->xdata, sizeof(DATATYPE), tinfo->nr_of_points, outfptr);

                fwrite((void *)tinfo->tsdata, sizeof(DATATYPE), tinfo->nr_of_channels*tinfo->nr_of_points*tinfo->itemsize, outfptr);
                /* 6 ints: channels/points/items/multiplexed/len_of_string_section/skipback */
                len+=6*sizeof(int)+3*tinfo->nr_of_channels*sizeof(double)+tinfo->nr_of_points*(1+tinfo->nr_of_channels*tinfo->itemsize)*sizeof(DATATYPE);
                fwrite((void *)&len, sizeof(int), 1, outfptr);
                /*}}}  */
            } else {
                /*{{{  Write ascii*/
                array myarray;

                if (tinfo->nrofaverages>0) fprintf(outfptr, "Nr_of_averages=%d;", tinfo->nrofaverages);
                if (tinfo->sfreq!=local_arg->sfreq) fprintf(outfptr, "Sfreq=%f;", (float)tinfo->sfreq);
                if (tinfo->beforetrig!=local_arg->beforetrig) fprintf(outfptr, "BeforeTrig=%d;", tinfo->beforetrig);
                if (tinfo->leaveright!=local_arg->leaveright) fprintf(outfptr, "Leaveright=%d;", tinfo->leaveright);
                if (tinfo->condition!=0) fprintf(outfptr, "Condition=%d;", tinfo->condition);
                if (tinfo->triggers.buffer_start!=NULL) {
                    struct trigger *intrig=(struct trigger *)tinfo->triggers.buffer_start;
                    fprintf(outfptr, "Triggers=%ld", intrig->position);
                    intrig++;
                    while (intrig->code!=0) {
                        fprintf(outfptr, ",%ld:%d", intrig->position, intrig->code);
                        intrig++;
                    }
                    fprintf(outfptr, ";");
                }
                if (tinfo->comment!=NULL) fprintf(outfptr, "%s", tinfo->comment);
                if (tinfo->z_label!=NULL) fprintf(outfptr, "%s%s=%g", ZAXIS_DELIMITER, tinfo->z_label, tinfo->z_value);
                fprintf(outfptr,"\nchannels=%d, points=%d", tinfo->nr_of_channels, tinfo->nr_of_points);
                if (tinfo->itemsize<=1) {
                    tinfo->itemsize=1;	/* Make sure the itemsize is at least 1 */
                } else {
                    fprintf(outfptr, ", itemsize=%d", tinfo->itemsize);
                }
                fprintf(outfptr, "\n%s", tinfo->xchannelname);
                for (channel=0; channel<tinfo->nr_of_channels; channel++) {
                    char buffer[MAX_CHANNEL_LEN+1], *inbuf;
                    strncpy(buffer, tinfo->channelnames[channel], MAX_CHANNEL_LEN);
                    buffer[MAX_CHANNEL_LEN]='\0';
                    /* Some characters can become hazardous, so we change them... */
                    for (inbuf=buffer; *inbuf!='\0'; inbuf++) {
                        if (strchr(" \t\n", *inbuf)!=NULL) *inbuf='_';
                    }
                    fprintf(outfptr, "\t%s", buffer);
                }
                for (i=0; i<3; i++) {
                    fprintf(outfptr, "\n-");
                    for (channel=0; channel<tinfo->nr_of_channels; channel++) {
                        fprintf(outfptr, "\t%g", tinfo->probepos[channel*3+i]);
                    }
                }
                fprintf(outfptr, "\n");

                tinfo_array(tinfo, &myarray);
                array_transpose(&myarray); /* Outer loop is for points */
                i=0;
                do {
                    fprintf(outfptr, "%g", tinfo->xdata[i]);
                    do {
                        if (tinfo->itemsize==1) {
                            fprintf(outfptr, "\t%g", array_scan(&myarray));
                        } else {
                            DATATYPE *itemptr=ARRAY_ELEMENT(&myarray);
                            fprintf(outfptr, "\t(%g", *itemptr++);
                            for (itempart=1; itempart<tinfo->itemsize; itempart++) {
                                fprintf(outfptr, "\t%g", *itemptr++);
                            }
                            fprintf(outfptr, ")");
                            array_advance(&myarray);
                        }
                    } while (myarray.message==ARRAY_CONTINUE);
                    fprintf(outfptr, "\n");
                    i++;
                } while (myarray.message!=ARRAY_ENDOFSCAN);
                /*}}}  */
            }
        } /* FREQ_DATA shifts loop */
        tinfo->tsdata=orig_tsdata;
        if (!args[ARGS_LINKED].is_set) {
            break;
        }
    } /* Linked epochs loop */
    if (args[ARGS_CLOSE].is_set) writeasc_close_file(tinfo);
    return calltinfo->tsdata;	/* Simply to return something `useful' */
}