/*{{{ write_rec_open_file(transform_info_ptr tinfo) {*/ LOCAL void write_rec_open_file(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=NULL; if (strcmp(args[ARGS_OFILE].arg.s, "stdout")==0) outfptr=stdout; else if (strcmp(args[ARGS_OFILE].arg.s, "stderr")==0) outfptr=stderr; local_arg->appendmode=args[ARGS_APPEND].is_set; if (local_arg->appendmode) { /*{{{ Append mode open if cofile exists and is of non-zero length*/ if (outfptr==NULL) { if ((outfptr=fopen(args[ARGS_OFILE].arg.s, "r+b"))!=NULL) { fseek(outfptr, 0L, SEEK_END); if (ftell(outfptr)==0L) { local_arg->appendmode=FALSE; /* If at start: write header */ } } } /*}}} */ } if (outfptr==NULL) { /*{{{ Open the REC file in truncate mode*/ local_arg->appendmode=FALSE; /* write header */ if ((outfptr=fopen(args[ARGS_OFILE].arg.s, "wb"))==NULL) { ERREXIT1(tinfo->emethods, "write_rec_open_file: Can't open %s\n", MSGPARM(args[ARGS_OFILE].arg.s)); } /*}}} */ } local_arg->outfptr=outfptr; if (local_arg->appendmode) { /* Read rather than write header in append mode */ fseek(outfptr, 0L, SEEK_SET); if (read_struct((char *)&local_arg->fheader, sm_REC_file, outfptr)==0) { ERREXIT1(tinfo->emethods, "write_rec_open_file: Can't read header in file %s\n", MSGPARM(args[ARGS_OFILE].arg.s)); } # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->fheader, sm_REC_file); # endif local_arg->nr_of_records=atoi(local_arg->fheader.nr_of_records); fseek(outfptr, 0L, SEEK_END); } else { /*{{{ Write header*/ REC_channel_header channelheader; const long channelheader_length=CHANNELHEADER_SIZE_PER_CHANNEL*tinfo->nr_of_channels; int channel; short dd, mm, yy, yyyy, hh, mi, ss; char numbuf[NUMBUF_LENGTH]; setlocale(LC_NUMERIC, "C"); /* Print fractional numbers with decimal point */ #define fileheader local_arg->fheader memset(&fileheader, ' ', sizeof(REC_file_header)); copy_nstring(fileheader.version, "0", sizeof(fileheader.version)); if (args[ARGS_PATIENT].is_set) copy_nstring(fileheader.patient, args[ARGS_PATIENT].arg.s, sizeof(fileheader.patient)); if (args[ARGS_RECORDING].is_set) copy_nstring(fileheader.recording, args[ARGS_RECORDING].arg.s, sizeof(fileheader.recording)); if (args[ARGS_DATETIME].is_set) { char * const comma=strchr(args[ARGS_DATETIME].arg.s, ','); if (comma==NULL) { ERREXIT(tinfo->emethods, "write_rec_open_file: Datetime format is dd.mm.yy,hh.mi.ss !\n"); } copy_nstring(fileheader.startdate, args[ARGS_DATETIME].arg.s, sizeof(fileheader.startdate)); copy_nstring(fileheader.starttime, comma+1, sizeof(fileheader.starttime)); } else if (tinfo->comment!=NULL) { if (!args[ARGS_RECORDING].is_set) copy_nstring(fileheader.recording, tinfo->comment, sizeof(fileheader.recording)); if (comment2time(tinfo->comment, &dd, &mm, &yy, &yyyy, &hh, &mi, &ss)) { snprintf(numbuf, NUMBUF_LENGTH, "%02d.%02d.%02d", dd, mm, yy); copy_nstring(fileheader.startdate, numbuf, sizeof(fileheader.startdate)); snprintf(numbuf, NUMBUF_LENGTH, "%02d.%02d.%02d", hh, mi, ss); copy_nstring(fileheader.starttime, numbuf, sizeof(fileheader.starttime)); } } if (*fileheader.startdate==' ') { /* Date/time weren't set otherwise: */ copy_nstring(fileheader.startdate, "00.00.00", sizeof(fileheader.startdate)); copy_nstring(fileheader.starttime, "00.00.00", sizeof(fileheader.starttime)); } snprintf(numbuf, NUMBUF_LENGTH, "%ld", sm_REC_file[0].offset+channelheader_length); copy_nstring(fileheader.bytes_in_header, numbuf, sizeof(fileheader.bytes_in_header)); copy_nstring(fileheader.data_format_version, (args[ARGS_DATA_FORMAT_VERSION].is_set ? args[ARGS_DATA_FORMAT_VERSION].arg.s : "write_rec file"), sizeof(fileheader.data_format_version)); local_arg->nr_of_records=0; copy_nstring(fileheader.nr_of_records, "-1", sizeof(fileheader.nr_of_records)); snprintf(numbuf, NUMBUF_LENGTH, "%g", ((double)local_arg->samples_per_record)/tinfo->sfreq); copy_nstring(fileheader.duration_s, numbuf, sizeof(fileheader.duration_s)); snprintf(numbuf, NUMBUF_LENGTH, "%d", tinfo->nr_of_channels); copy_nstring(fileheader.nr_of_channels, numbuf, sizeof(fileheader.nr_of_channels)); #ifndef LITTLE_ENDIAN change_byteorder((char *)&fileheader, sm_REC_file); #endif write_struct((char *)&fileheader, sm_REC_file, outfptr); #ifndef LITTLE_ENDIAN change_byteorder((char *)&fileheader, sm_REC_file); #endif #undef fileheader if ((channelheader.label=(char (*)[16])malloc(channelheader_length))==NULL) { ERREXIT(tinfo->emethods, "write_rec_open_file: Error allocating channelheader memory\n"); } channelheader.transducer=(char (*)[80])(channelheader.label+tinfo->nr_of_channels); channelheader.dimension=(char (*)[8])(channelheader.transducer+tinfo->nr_of_channels); channelheader.physmin=(char (*)[8])(channelheader.dimension+tinfo->nr_of_channels); channelheader.physmax=(char (*)[8])(channelheader.physmin+tinfo->nr_of_channels); channelheader.digmin=(char (*)[8])(channelheader.physmax+tinfo->nr_of_channels); channelheader.digmax=(char (*)[8])(channelheader.digmin+tinfo->nr_of_channels); channelheader.prefiltering=(char (*)[80])(channelheader.digmax+tinfo->nr_of_channels); channelheader.samples_per_record=(char (*)[8])(channelheader.prefiltering+tinfo->nr_of_channels); channelheader.reserved=(char (*)[32])(channelheader.samples_per_record+tinfo->nr_of_channels); memset(channelheader.label, ' ', channelheader_length); for (channel=0; channel<tinfo->nr_of_channels; channel++) { copy_nstring(channelheader.dimension[channel], "uV", sizeof(channelheader.dimension[channel])); copy_nstring(channelheader.label[channel], tinfo->channelnames[channel], sizeof(channelheader.label[channel])); snprintf(numbuf, NUMBUF_LENGTH, "%g", (double)local_arg->digmin*local_arg->resolution); copy_nstring(channelheader.physmin[channel], numbuf, sizeof(channelheader.physmin[channel])); snprintf(numbuf, NUMBUF_LENGTH, "%g", (double)local_arg->digmax*local_arg->resolution); copy_nstring(channelheader.physmax[channel], numbuf, sizeof(channelheader.physmax[channel])); snprintf(numbuf, NUMBUF_LENGTH, "%ld", local_arg->digmin); copy_nstring(channelheader.digmin[channel], numbuf, sizeof(channelheader.digmin[channel])); snprintf(numbuf, NUMBUF_LENGTH, "%ld", local_arg->digmax); copy_nstring(channelheader.digmax[channel], numbuf, sizeof(channelheader.digmax[channel])); snprintf(numbuf, NUMBUF_LENGTH, "%ld", local_arg->samples_per_record); copy_nstring(channelheader.samples_per_record[channel], numbuf, sizeof(channelheader.samples_per_record[channel])); } setlocale(LC_NUMERIC, ""); /* Reset locale to environment */ if (tinfo->nr_of_channels!=(int)fwrite((void *)channelheader.label, CHANNELHEADER_SIZE_PER_CHANNEL, tinfo->nr_of_channels, local_arg->outfptr)) { ERREXIT(tinfo->emethods, "write_rec_open_file: Error writing channel headers\n"); } free(channelheader.label); /*}}} */ } }
/*{{{ write_synamps_init(transform_info_ptr tinfo) {*/ METHODDEF void write_synamps_init(transform_info_ptr tinfo) { struct write_synamps_storage *local_arg=(struct write_synamps_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; double xmin, xmax, ymin, ymax; int NoOfChannels=tinfo->nr_of_channels; int channel; growing_buf_init(&local_arg->triggers); local_arg->output_format=(args[ARGS_OUTPUTFORMAT].is_set ? (enum output_formats)args[ARGS_OUTPUTFORMAT].arg.i : FORMAT_EEGFILE); local_arg->SCAN=fopen(args[ARGS_OFILE].arg.s, "r+b"); if (!args[ARGS_APPEND].is_set || local_arg->SCAN==NULL) { /* target does not exist*/ /*{{{ Create file*/ if (local_arg->SCAN!=NULL) fclose(local_arg->SCAN); /*{{{ Calculate the span in x-y channel positions*/ xmin=ymin= FLT_MAX; xmax=ymax= -FLT_MAX; for (channel=0; channel<tinfo->nr_of_channels; channel++) { const double this_x=tinfo->probepos[3*channel], this_y=tinfo->probepos[3*channel+1]; if (this_x>xmax) xmax=this_x; if (this_x<xmin) xmin=this_x; if (this_y>ymax) ymax=this_y; if (this_y<ymin) ymin=this_y; } if (xmax==xmin) { xmax+=0.5; xmin-=0.5; } if (ymax==ymin) { ymax+=0.5; ymin-=0.5; } /*}}} */ if ((local_arg->SCAN=fopen(args[ARGS_OFILE].arg.s, "wb"))==NULL) { ERREXIT1(tinfo->emethods, "write_synamps_init: Can't open %s\n", MSGPARM(args[ARGS_OFILE].arg.s)); } /*{{{ Many settings, taken from example files...*/ strcpy(local_arg->EEG.rev, "Version 3.0"); local_arg->EEG.AdditionalFiles=local_arg->EEG.NextFile=local_arg->EEG.PrevFile=0; switch (local_arg->output_format) { case FORMAT_EEGFILE: local_arg->EEG.review = 1; local_arg->EEG.savemode=NSM_EEGF; local_arg->EEG.type = NTY_EPOCHED; local_arg->EEG.ContinousType=0; local_arg->EEG.nsweeps=local_arg->EEG.compsweeps=local_arg->EEG.acceptcnt=0; break; case FORMAT_CNTFILE: local_arg->EEG.review = 1; local_arg->EEG.savemode=NSM_CONT; local_arg->EEG.type = 0; local_arg->EEG.ContinousType=NST_SYNAMPS-NST_CONT0; local_arg->EEG.nsweeps=1; local_arg->EEG.compsweeps=local_arg->EEG.acceptcnt=0; break; case FORMAT_AVGFILE: local_arg->EEG.review = 0; local_arg->EEG.savemode=NSM_AVGD; local_arg->EEG.type = NTY_AVERAGED; local_arg->EEG.ContinousType=0; local_arg->EEG.nsweeps=local_arg->EEG.compsweeps=local_arg->EEG.acceptcnt=(tinfo->nrofaverages>0 ? tinfo->nrofaverages : 1); break; } /* Since the comment can be of arbitrary length and thus also larger than the * rest of the header, we should limit ourselves to the size of the id field */ strncpy(local_arg->EEG.id, tinfo->comment, sizeof(local_arg->EEG.id)); /* The date is coded in the comment, and read_synamps appends the date and time * from the corresponding fields and the contents of the id field, so that * the comment2time reader could be confused by the two date/time fields if we * would not somehow invalidate remnants of the date field here... */ {char *slash; while ((slash=strchr(local_arg->EEG.id, '/'))!=NULL) { *slash='|'; } } strcpy(local_arg->EEG.oper, "Unspecified"); strcpy(local_arg->EEG.doctor, "Unspecified"); strcpy(local_arg->EEG.referral, "Unspecified"); strcpy(local_arg->EEG.hospital, "Unspecified"); strcpy(local_arg->EEG.patient, "Unspecified"); local_arg->EEG.age = 0; local_arg->EEG.sex = 'U'; local_arg->EEG.hand = 'U'; strcpy(local_arg->EEG.med, "Unspecified"); strcpy(local_arg->EEG.category, "Unspecified"); strcpy(local_arg->EEG.state, "Unspecified"); strcpy(local_arg->EEG.label, "Unspecified"); {short dd, mm, yy, yyyy, hh, mi, ss; if (comment2time(tinfo->comment, &dd, &mm, &yy, &yyyy, &hh, &mi, &ss)) { char buffer[16]; /* Must be long enough to fit date (10) and time (12) +1 */ /* This is necessary because the date field was devised for 2-digit years. * With 4-digit years it uses all 10 bytes and the trailing zero * does not fit in any more. */ snprintf(buffer, 16, "%02d/%02d/%04d", mm, dd, yyyy); strncpy(local_arg->EEG.date, buffer, sizeof(local_arg->EEG.date)); snprintf(buffer, 16, "%02d:%02d:%02d", hh, mi, ss); strncpy(local_arg->EEG.time, buffer, sizeof(local_arg->EEG.time)); } } local_arg->EEG.rejectcnt = 0; local_arg->EEG.pnts=(tinfo->data_type==FREQ_DATA ? tinfo->nroffreq : tinfo->nr_of_points); local_arg->EEG.nchannels=NoOfChannels; local_arg->EEG.avgupdate=1; local_arg->EEG.domain=(tinfo->data_type==FREQ_DATA ? 1 : 0); local_arg->EEG.variance=0; local_arg->EEG.rate=(uint16_t)rint(tinfo->sfreq); if (tinfo->data_type==FREQ_DATA) { /* I know that this field is supposed to contain the taper window size in %, but we need some way to store basefreq and 'rate' is only integer... */ local_arg->EEG.SpectWinLength=tinfo->basefreq; } if (local_arg->EEG.rate==0) { local_arg->EEG.rate=1; TRACEMS(tinfo->emethods, 0, "write_synamps_init: Rate was zero, corrected to 1!\n"); } local_arg->EEG.scale=3.4375; /* This is a common sensitivity factor, used if sensitivities for channels are zero */ local_arg->EEG.veogcorrect=0; local_arg->EEG.heogcorrect=0; local_arg->EEG.aux1correct=0; local_arg->EEG.aux2correct=0; local_arg->EEG.veogtrig=15; /* Trigger threshold in percent of the maximum */ local_arg->EEG.heogtrig=10; local_arg->EEG.aux1trig=10; local_arg->EEG.aux2trig=10; local_arg->EEG.veogchnl=find_channel_number(tinfo, "VEOG"); local_arg->EEG.heogchnl=find_channel_number(tinfo, "HEOG"); local_arg->EEG.veogdir=0; /* 0=positive, 1=negative */ local_arg->EEG.veog_n=10; /* "Number of points per waveform", really: minimum acceptable # averages */ local_arg->EEG.heog_n=10; local_arg->EEG.veogmaxcnt=(int16_t)rint(0.3*tinfo->sfreq); /* "Number of observations per point", really: event window size in points */ local_arg->EEG.heogmaxcnt=(int16_t)rint(0.5*tinfo->sfreq); local_arg->EEG.AmpSensitivity=10; /* External Amplifier gain */ local_arg->EEG.baseline=0; local_arg->EEG.reject=0; local_arg->EEG.trigtype=2; /* 2=Port */ local_arg->EEG.trigval=255; /* Hold */ local_arg->EEG.dir=0; /* Invert (negative up)=0 */ local_arg->EEG.dispmin= -1; /* displayed y range */ local_arg->EEG.dispmax= +1; local_arg->EEG.DisplayXmin=local_arg->EEG.AutoMin=local_arg->EEG.rejstart=local_arg->EEG.offstart=local_arg->EEG.xmin= -tinfo->beforetrig/tinfo->sfreq; local_arg->EEG.DisplayXmax=local_arg->EEG.AutoMax=local_arg->EEG.rejstop=local_arg->EEG.offstop=local_arg->EEG.xmax= tinfo->aftertrig/tinfo->sfreq; local_arg->EEG.zmin=0.0; local_arg->EEG.zmax=0.1; strcpy(local_arg->EEG.ref, "A1-A2"); strcpy(local_arg->EEG.screen, "--------"); local_arg->EEG.CalMode=2; local_arg->EEG.CalMethod=0; local_arg->EEG.CalUpdate=1; local_arg->EEG.CalBaseline=0; local_arg->EEG.CalSweeps=5; local_arg->EEG.CalAttenuator=1; local_arg->EEG.CalPulseVolt=1; local_arg->EEG.CalPulseStart=0; local_arg->EEG.CalPulseStop=0; local_arg->EEG.CalFreq=10; strcpy(local_arg->EEG.taskfile, "--------"); strcpy(local_arg->EEG.seqfile, "--------"); /* Otherwise tries to read a seqfile */ local_arg->EEG.HeadGain=150; local_arg->EEG.FspFValue=2.5; local_arg->EEG.FspBlockSize=200; local_arg->EEG.fratio=1.0; local_arg->EEG.minor_rev=12; /* Necessary ! Otherwise a different file structure is assumed... */ local_arg->EEG.eegupdate=1; local_arg->EEG.xscale=local_arg->EEG.yscale=0; local_arg->EEG.xsize=40; local_arg->EEG.ysize=20; local_arg->EEG.ACmode=0; local_arg->EEG.XScaleValue=XSCALEVALUE; local_arg->EEG.XScaleInterval=XSCALEINTERVAL; local_arg->EEG.YScaleValue=YSCALEVALUE; local_arg->EEG.YScaleInterval=YSCALEINTERVAL; local_arg->EEG.ScaleToolX1=20; local_arg->EEG.ScaleToolY1=170; local_arg->EEG.ScaleToolX2=23.1535; local_arg->EEG.ScaleToolY2=153.87; local_arg->EEG.port=715; local_arg->EEG.NumSamples=0; local_arg->EEG.FilterFlag=0; local_arg->EEG.LowCutoff=4; local_arg->EEG.LowPoles=2; local_arg->EEG.HighCutoff=50; local_arg->EEG.HighPoles=2; local_arg->EEG.FilterType=3; local_arg->EEG.FilterDomain=1; local_arg->EEG.SnrFlag=0; local_arg->EEG.CoherenceFlag=0; local_arg->EEG.ContinousSeconds=4; local_arg->EEG.ChannelOffset=sizeof(int16_t); local_arg->EEG.AutoCorrectFlag=0; local_arg->EEG.DCThreshold='F'; /*}}} */ /*{{{ Write SETUP structure*/ # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->EEG, sm_SETUP); # endif write_struct((char *)&local_arg->EEG, sm_SETUP, local_arg->SCAN); # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->EEG, sm_SETUP); # endif /*}}} */ if ((local_arg->Channels=(ELECTLOC *)calloc(NoOfChannels,sizeof(ELECTLOC)))==NULL) { ERREXIT(tinfo->emethods, "write_synamps_init: Error allocating Channels list\n"); } for (channel=0; channel<NoOfChannels; channel++) { /*{{{ Settings in the channel structure*/ strncpy(local_arg->Channels[channel].lab, tinfo->channelnames[channel],sizeof(local_arg->Channels[channel].lab)); local_arg->Channels[channel].reference=0; local_arg->Channels[channel].skip=0; local_arg->Channels[channel].reject=0; local_arg->Channels[channel].display=1; local_arg->Channels[channel].bad=0; local_arg->Channels[channel].n=(local_arg->output_format==FORMAT_AVGFILE ? local_arg->EEG.acceptcnt : (local_arg->output_format==FORMAT_CNTFILE ? 0 : 1)); local_arg->Channels[channel].avg_reference=0; local_arg->Channels[channel].ClipAdd=0; local_arg->Channels[channel].x_coord= (tinfo->probepos[3*channel ]-xmin)/(xmax-xmin)*RANGE_TO_COVER+XOFFSET; local_arg->Channels[channel].y_coord=((ymax-tinfo->probepos[3*channel+1])/(ymax-ymin)*RANGE_TO_COVER+YOFFSET)/3; local_arg->Channels[channel].veog_wt=0; local_arg->Channels[channel].veog_std=0; local_arg->Channels[channel].heog_wt=0; local_arg->Channels[channel].heog_std=0; local_arg->Channels[channel].baseline=0; local_arg->Channels[channel].Filtered=0; local_arg->Channels[channel].sensitivity=204.8/args[ARGS_CONVFACTOR].arg.d; /* This arranges for conv_factor to act as the expected product before integer truncation */ local_arg->Channels[channel].Gain=5; local_arg->Channels[channel].HiPass=0; /* 0=DC */ local_arg->Channels[channel].LoPass=4; local_arg->Channels[channel].Page=0; local_arg->Channels[channel].Size=0; local_arg->Channels[channel].Impedance=0; local_arg->Channels[channel].PhysicalChnl=channel; /* Channel mapping */ local_arg->Channels[channel].Rectify=0; local_arg->Channels[channel].calib=1.0; /*}}} */ /*{{{ Write ELECTLOC struct*/ # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->Channels[channel], sm_ELECTLOC); # endif write_struct((char *)&local_arg->Channels[channel], sm_ELECTLOC, local_arg->SCAN); # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->Channels[channel], sm_ELECTLOC); # endif /*}}} */ } local_arg->SizeofHeader = ftell(local_arg->SCAN); TRACEMS2(tinfo->emethods, 1, "write_synamps_init: Creating file %s, format `%s'\n", MSGPARM(args[ARGS_OFILE].arg.s), MSGPARM(neuroscan_subtype_names[NEUROSCAN_SUBTYPE(&local_arg->EEG)])); /*}}} */ } else { /*{{{ Append to file*/ enum NEUROSCAN_SUBTYPES SubType; if (read_struct((char *)&local_arg->EEG, sm_SETUP, local_arg->SCAN)==0) { ERREXIT(tinfo->emethods, "write_synamps_init: Can't read file header.\n"); } # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->EEG, sm_SETUP); # endif NoOfChannels = local_arg->EEG.nchannels; /*{{{ Allocate channel header*/ if ((local_arg->Channels=(ELECTLOC *)malloc(NoOfChannels*sizeof(ELECTLOC)))==NULL) { ERREXIT(tinfo->emethods, "write_synamps_init: Error allocating Channels list\n"); } /*}}} */ for (channel=0; channel<NoOfChannels; channel++) { if (read_struct((char *)&local_arg->Channels[channel], sm_ELECTLOC, local_arg->SCAN)==0) { ERREXIT(tinfo->emethods, "write_synamps_init: Can't read channel headers.\n"); } # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->Channels[channel], sm_ELECTLOC); # endif } local_arg->SizeofHeader = ftell(local_arg->SCAN); SubType=NEUROSCAN_SUBTYPE(&local_arg->EEG); switch (SubType) { case NST_EPOCHS: if (local_arg->output_format!=FORMAT_EEGFILE) { TRACEMS(tinfo->emethods, 0, "write_synamps_init: Appending to epoch file, discarding option -c\n"); local_arg->output_format=FORMAT_EEGFILE; } fseek(local_arg->SCAN, 0, SEEK_END); break; case NST_CONTINUOUS: case NST_SYNAMPS: { TEEG TagType; EVENT1 event; if (local_arg->output_format!=FORMAT_CNTFILE) { TRACEMS(tinfo->emethods, 0, "write_synamps_init: Appending to continuous file, assuming option -c\n"); local_arg->output_format=FORMAT_CNTFILE; } fseek(local_arg->SCAN, local_arg->EEG.EventTablePos, SEEK_SET); /* Here we face two evils in one header: Coding enums as chars and * allowing longs at odd addresses. Well... */ if (1==read_struct((char *)&TagType, sm_TEEG, local_arg->SCAN)) { # ifndef LITTLE_ENDIAN change_byteorder((char *)&TagType, sm_TEEG); # endif if (TagType.Teeg==TEEG_EVENT_TAB1) { /*{{{ Read the event table*/ int tag; int const ntags=TagType.Size/sm_EVENT1[0].offset; /* sm_EVENT1[0].offset is sizeof(EVENT1) in the file. */ for (tag=0; tag<ntags; tag++) { if (1!=read_struct((char *)&event, sm_EVENT1, local_arg->SCAN)) { ERREXIT(tinfo->emethods, "write_synamps_init: Can't read an event table entry.\n"); break; } # ifndef LITTLE_ENDIAN change_byteorder((char *)&event, sm_EVENT1); # endif { int const TrigVal=event.StimType &0xff; int const KeyBoard=event.KeyBoard&0xf; int const KeyPad=Event_KeyPad_value(event); int const Accept=Event_Accept_value(event); int code=TrigVal-KeyPad+neuroscan_accept_translation[Accept]; if (code==0) { code= -((KeyBoard+1)<<4); } push_trigger(&local_arg->triggers,offset2point(tinfo, event.Offset),code,NULL); } } /*}}} */ } else { ERREXIT(tinfo->emethods, "write_synamps_init: Type 2 events are not yet supported.\n"); } } else { ERREXIT(tinfo->emethods, "write_synamps_init: Can't read the event table header.\n"); } fseek(local_arg->SCAN, local_arg->EEG.EventTablePos, SEEK_SET); } break; default: ERREXIT1(tinfo->emethods, "write_synamps: Cannot append to file type `%s'\n", MSGPARM(neuroscan_subtype_names[SubType])); break; } /* Conformance to the incoming epochs is checked in write_synamps */ TRACEMS1(tinfo->emethods, 1, "write_synamps_init: Appending to file %s\n", MSGPARM(args[ARGS_OFILE].arg.s)); /*}}} */ } tinfo->methods->init_done=TRUE; }
/*{{{ write_vitaport_init(transform_info_ptr tinfo) {*/ METHODDEF void write_vitaport_init(transform_info_ptr tinfo) { struct write_vitaport_storage *local_arg=(struct write_vitaport_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; int channel, NoOfChannels=tinfo->nr_of_channels; int tempnamelength, tempnum; short dd, mm, yy, yyyy, hh, mi, ss; char const *lastslash; struct stat statbuff; growing_buf_init(&local_arg->triggers); if ((local_arg->outfile=fopen(args[ARGS_OFILE].arg.s, "wb"))==NULL) { ERREXIT1(tinfo->emethods, "write_vitaport_init: Can't open %s\n", MSGPARM(args[ARGS_OFILE].arg.s)); } /*{{{ Initialize the file header*/ local_arg->fileheader.Sync=VITAPORT_SYNCMAGIC; local_arg->fileheader.chnoffs=sm_vitaport_fileheader[0].offset+sm_vitaportII_fileheader[0].offset+sm_vitaportII_fileext[0].offset; local_arg->fileext.chdlen=sm_vitaport_channelheader[0].offset+sm_vitaportIIrchannelheader[0].offset; local_arg->fileheader.hdlen=local_arg->fileheader.chnoffs+NoOfChannels*local_arg->fileext.chdlen+2; local_arg->fileheader.hdtyp=HDTYP_VITAPORT2; local_arg->fileheader.knum=NoOfChannels; if (comment2time(tinfo->comment, &dd, &mm, &yy, &yyyy, &hh, &mi, &ss)) { local_arg->fileheaderII.Hour=hh; local_arg->fileheaderII.Minute=mi; local_arg->fileheaderII.Second=ss; local_arg->fileheaderII.Day=dd; local_arg->fileheaderII.Month=mm; local_arg->fileheaderII.Year=yy; convert_tohex(&local_arg->fileheaderII.Hour); convert_tohex(&local_arg->fileheaderII.Minute); convert_tohex(&local_arg->fileheaderII.Second); convert_tohex(&local_arg->fileheaderII.Day); convert_tohex(&local_arg->fileheaderII.Month); convert_tohex(&local_arg->fileheaderII.Year); } local_arg->fileheaderII.Sysvers=56; local_arg->fileheaderII.scnrate=(short int)rint(VITAPORT_CLOCKRATE/tinfo->sfreq); local_arg->fileext.swvers=311; local_arg->fileext.hwvers=1286; local_arg->fileext.recorder= -1; local_arg->fileext.timer1=0; local_arg->fileext.sysflg12=512; /*}}} */ /*{{{ Initialize channel temp files and storage*/ lastslash=strrchr(args[ARGS_OFILE].arg.s, PATHSEP); if (lastslash==NULL) lastslash=args[ARGS_OFILE].arg.s-1; /* Up to slash, 8.3 for name, 1 for null */ tempnamelength=lastslash-args[ARGS_OFILE].arg.s+(1+8+1+3+1); if ((local_arg->channelfilename=(char *)malloc(tempnamelength))==NULL || (local_arg->channelmax=(DATATYPE *)malloc(NoOfChannels*sizeof(DATATYPE)))==NULL || (local_arg->channelmin=(DATATYPE *)malloc(NoOfChannels*sizeof(DATATYPE)))==NULL || (local_arg->channelheaders=(struct vitaport_channelheader *)malloc(NoOfChannels*sizeof(struct vitaport_channelheader)))==NULL || (local_arg->channelheadersII=(struct vitaportIIrchannelheader *)malloc(NoOfChannels*sizeof(struct vitaportIIrchannelheader)))==NULL) { ERREXIT(tinfo->emethods, "write_vitaport_init: Error allocating memory\n"); } tempnum=0; do { /* While the targeted tempfile already exists... */ strncpy(local_arg->channelfilename, args[ARGS_OFILE].arg.s, lastslash-args[ARGS_OFILE].arg.s+1); local_arg->channelfilename[lastslash-args[ARGS_OFILE].arg.s+1]='\0'; sprintf(local_arg->channelfilename+strlen(local_arg->channelfilename), "%08d.tmp", tempnum); tempnum++; } while (stat(local_arg->channelfilename, &statbuff)==0); if ((local_arg->channelfile=fopen(local_arg->channelfilename, "wb"))==NULL) { ERREXIT1(tinfo->emethods, "write_vitaport_init: Can't open temp file %s\n", MSGPARM(local_arg->channelfilename)); } for (channel=0; channel<NoOfChannels; channel++) { local_arg->channelmax[channel]= -FLT_MAX; local_arg->channelmin[channel]= FLT_MAX; strncpy(local_arg->channelheaders[channel].kname, tinfo->channelnames[channel], 6); strcpy(local_arg->channelheaders[channel].kunit, "uV"); local_arg->channelheaders[channel].datype=VP_DATYPE_SIGNED; local_arg->channelheaders[channel].dasize=VP_DATATYPE_SHORT; local_arg->channelheaders[channel].scanfc=1; local_arg->channelheaders[channel].fltmsk=0; local_arg->channelheaders[channel].stofac=1; local_arg->channelheaders[channel].resvd1=0; local_arg->channelheaders[channel].resvd2=0; local_arg->channelheadersII[channel].mval=1000; local_arg->channelheadersII[channel].chflg=1; local_arg->channelheadersII[channel].hpass=0; local_arg->channelheadersII[channel].ampl=1; local_arg->channelheadersII[channel].tpass=0; } /*}}} */ local_arg->total_points=0; local_arg->sfreq=tinfo->sfreq; tinfo->methods->init_done=TRUE; }