/*{{{ 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; }
int main(int argc, char **argv) { SETUP EEG; ELECTLOC *Channels=(ELECTLOC *)NULL; TEEG TagType; int ntags; long SizeofHeader; /* no. of bytes in header of source file */ enum NEUROSCAN_SUBTYPES SubType; /* This tells, once and for all, the file type */ int errflag=0, c; enum {EVENTLIST_NONE, EVENTLIST_SYNAMPS, EVENTLIST_AVG_Q} event_list=EVENTLIST_NONE; enum {EVENTPOS_POINTS, EVENTPOS_MSEC, EVENTPOS_SEC} eventpos_type=EVENTPOS_POINTS; char *filename; FILE *SCAN; int NoOfChannels, channel; int filearg; /*{{{ Process command line*/ mainargv=argv; while ((c=getopt(argc, argv, "eEms"))!=EOF) { switch (c) { case 'e': event_list=EVENTLIST_SYNAMPS; break; case 'E': event_list=EVENTLIST_AVG_Q; break; case 'm': eventpos_type=EVENTPOS_MSEC; break; case 's': eventpos_type=EVENTPOS_SEC; break; case '?': default: errflag++; continue; } } if (argc-optind<END_OF_ARGS || errflag>0) { fprintf(stderr, "Usage: %s [options] synamps_filename1 synamps_filename2 ...\n" " Options are:\n" "\t-e: Output the event table in NeuroScan format\n" "\t-E: Output the event table in avg_q format\n" "\t-m: avg_q Marker positions should be output in milliseconds\n" "\t-s: avg_q Marker positions should be output in seconds\n" , argv[0]); exit(1); } for (filearg=SYNAMPSFILE; argc-optind-filearg>=END_OF_ARGS; filearg++) { filename=MAINARG(filearg); SCAN=fopen(filename,"rb"); if(SCAN==NULL) { fprintf(stderr, "%s: Can't open file %s\n", argv[0], filename); continue; } if (read_struct((char *)&EEG, sm_SETUP, SCAN)==0) { fprintf(stderr, "%s: Short file %s\n", argv[0], filename); continue; } #ifndef LITTLE_ENDIAN change_byteorder((char *)&EEG, sm_SETUP); #endif if (strncmp(&EEG.rev[0],"Version",7)!=0) { fprintf(stderr, "%s: %s is not a NeuroScan file\n", argv[0], filename); continue; } /* The actual criteria to decide upon the file type (average, continuous etc) * by the header have been moved to neurohdr.h because it's black magic... */ SubType=NEUROSCAN_SUBTYPE(&EEG); if (event_list==EVENTLIST_NONE) { printf("NeuroScan File %s: File type is `%s'\n\n", filename, neuroscan_subtype_names[SubType]); print_structcontents((char *)&EEG, sm_SETUP, smd_SETUP, stdout); } if (EEG.ChannelOffset<=1) EEG.ChannelOffset=sizeof(short); /*{{{ Allocate channel header*/ if ((Channels=(ELECTLOC *)malloc(EEG.nchannels*sizeof(ELECTLOC)))==NULL) { fprintf(stderr, "%s: Error allocating Channels list\n", argv[0]); exit(1); } /*}}} */ if (event_list==EVENTLIST_NONE) { printf("\nCHANNEL HEADERS" "\n---------------\n"); } /* For minor_rev<4, 32 electrode structures were hardcoded - but the data is * there for all the channels... */ NoOfChannels = (EEG.minor_rev<4 ? 32 : EEG.nchannels); for (channel=0; channel<NoOfChannels; channel++) { read_struct((char *)&Channels[channel], sm_ELECTLOC, SCAN); #ifndef LITTLE_ENDIAN change_byteorder((char *)&Channels[channel], sm_ELECTLOC); #endif if (event_list==EVENTLIST_NONE) { printf("\nChannel number %d:\n", channel+1); print_structcontents((char *)&Channels[channel], sm_ELECTLOC, smd_ELECTLOC, stdout); } } if (EEG.minor_rev<4) { NoOfChannels = EEG.nchannels; /* Copy the channel descriptors over from the first 32: */ for (; channel<NoOfChannels; channel++) { memcpy(&Channels[channel], &Channels[channel%32], sizeof(ELECTLOC)); } } SizeofHeader = ftell(SCAN); if (event_list==EVENTLIST_AVG_Q) { long int const NumSamples = (EEG.EventTablePos - SizeofHeader)/NoOfChannels/sizeof(short); printf("# NeuroScan File %s: File type is `%s'\n# Sfreq=%d\n# NumSamples=%ld\n", filename, neuroscan_subtype_names[SubType], EEG.rate, NumSamples); } switch(SubType) { case NST_CONTINUOUS: case NST_SYNAMPS: /*{{{ Read the events header and array*/ if (event_list==EVENTLIST_NONE) { printf("\nEVENT TABLE HEADER" "\n------------------\n"); } fseek(SCAN,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, SCAN)) { fprintf(stderr, "%s: Error reading event table header\n", argv[0]); exit(1); } # ifndef LITTLE_ENDIAN change_byteorder((char *)&TagType, sm_TEEG); # endif if (event_list==EVENTLIST_NONE) { print_structcontents((char *)&TagType, sm_TEEG, smd_TEEG, stdout); } if (TagType.Teeg==TEEG_EVENT_TAB1 || TagType.Teeg==TEEG_EVENT_TAB2) { struct_member * const sm_EVENT=(TagType.Teeg==TEEG_EVENT_TAB1 ? sm_EVENT1 : sm_EVENT2); struct_member_description * const smd_EVENT=(TagType.Teeg==TEEG_EVENT_TAB1 ? smd_EVENT1 : smd_EVENT2); EVENT2 event; int tag; int TrigVal; int KeyBoard; int KeyPad; int code; enum NEUROSCAN_ACCEPTVALUES Accept; ntags=TagType.Size/sm_EVENT[0].offset; /* sm_EVENT[0].offset is the size of the structure in file. */ if (event_list==EVENTLIST_NONE) { printf("\nEVENT TABLE (Type %d)" "\n--------------------\n", TagType.Teeg); } for (tag=0; tag<ntags; tag++) { if (1!=read_struct((char *)&event, sm_EVENT, SCAN)) { fprintf(stderr, "%s: Can't access event table header, CNT file is probably corrupted.\n", argv[0]); exit(1); } # ifndef LITTLE_ENDIAN change_byteorder((char *)&event, sm_EVENT); # endif TrigVal=event.StimType &0xff; KeyBoard=event.KeyBoard&0xf; KeyPad=Event_KeyPad_value(event); Accept=Event_Accept_value(event); /* The `accept' values NAV_DCRESET and NAV_STARTSTOP always occur alone, * while the NAV_REJECT and NAV_ACCEPT enclose rejected CNT blocks and * might occur within a marker as well (at least NAV_REJECT). */ code=TrigVal-KeyPad+neuroscan_accept_translation[Accept]; if (code==0) { code= -((KeyBoard+1)<<4); } switch(event_list) { case EVENTLIST_NONE: print_structcontents((char *)&event, sm_EVENT, smd_EVENT, stdout); printf("\n"); break; case EVENTLIST_SYNAMPS: if (code!=0) printf("%4d %4d %4d 0 0.0000 %ld\n", tag+1, TrigVal, KeyBoard+KeyPad, event.Offset); break; case EVENTLIST_AVG_Q: if (code!=0) { long const pos=(event.Offset-SizeofHeader)/sizeof(short)/EEG.nchannels; if (Accept==NAV_REJECT && code!=neuroscan_accept_translation[NAV_REJECT]) { printf("#"); } switch (eventpos_type) { case EVENTPOS_POINTS: printf("%ld %d\n", pos, code); break; case EVENTPOS_MSEC: printf("%.8gms %d\n", ((float)pos)/EEG.rate*1000, code); break; case EVENTPOS_SEC: printf("%.8gs %d\n", ((float)pos)/EEG.rate, code); break; } } break; } } } else { fprintf(stderr, "%s: Unknown tag type %d\n", argv[0], TagType.Teeg); exit(1); } /*}}} */ break; case NST_EPOCHS: { NEUROSCAN_EPOCHED_SWEEP_HEAD sweephead; int epoch, code; if (event_list==EVENTLIST_NONE) { printf("\nEPOCHED SWEEP HEADERS" "\n---------------------\n"); } for (epoch=0; epoch<EEG.compsweeps; epoch++) { long const filepos=epoch*(sm_NEUROSCAN_EPOCHED_SWEEP_HEAD[0].offset+EEG.pnts*EEG.nchannels*sizeof(short))+SizeofHeader; /* sm_NEUROSCAN_EPOCHED_SWEEP_HEAD[0].offset is sizeof(NEUROSCAN_EPOCHED_SWEEP_HEAD) on those other systems... */ fseek(SCAN,filepos,SEEK_SET); read_struct((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD, SCAN); # ifndef LITTLE_ENDIAN change_byteorder((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD); # endif code=(sweephead.type!=0 ? sweephead.type : -sweephead.response); switch(event_list) { case EVENTLIST_NONE: printf("\nEpoch number %d:\n", epoch+1); print_structcontents((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD, smd_NEUROSCAN_EPOCHED_SWEEP_HEAD, stdout); break; case EVENTLIST_SYNAMPS: /* The fourth item is actually `acc'(uracy) (of response, -1=no resp), but let's use it for the accept value now */ printf("%4d %4d %4d %d 0.0000 %ld\n", epoch+1, sweephead.type, sweephead.response, sweephead.accept, filepos); break; case EVENTLIST_AVG_Q: { long const pos=epoch*EEG.pnts; if (sweephead.accept==0) { printf("#"); } switch (eventpos_type) { case EVENTPOS_POINTS: printf("%ld %d\n", pos, code); break; case EVENTPOS_MSEC: printf("%gms %d\n", ((float)pos)/EEG.rate*1000, code); break; case EVENTPOS_SEC: printf("%gs %d\n", ((float)pos)/EEG.rate, code); break; } } break; } } } break; default: break; } free(Channels); fclose(SCAN); } return 0; }