void UI_RAW2EDFapp::gobuttonpressed() { int i, j, k, r, hdl, chns, sf, *buf, datarecords, tmp, straightbinary, samplesize, skipblocksize, skipbytes, skipblockcntr, bytecntr, big_endian; char str[256], path[MAX_PATH_LENGTH]; double phys_max; long long d_offset; FILE *inputfile; sf = SamplefreqSpinbox->value(); raw2edf_var->sf = sf; chns = SignalsSpinbox->value(); raw2edf_var->chns = chns; phys_max = PhysicalMaximumSpinbox->value(); raw2edf_var->phys_max = phys_max; straightbinary = EncodingCombobox->currentIndex(); raw2edf_var->straightbinary = straightbinary; big_endian = EndiannessCombobox->currentIndex(); raw2edf_var->endianness = big_endian; samplesize = SampleSizeSpinbox->value(); raw2edf_var->samplesize = samplesize; d_offset = OffsetSpinbox->value(); raw2edf_var->offset = d_offset; skipblocksize = skipblocksizeSpinbox->value(); raw2edf_var->skipblocksize = skipblocksize; skipbytes = skipbytesSpinbox->value(); raw2edf_var->skipbytes = skipbytes; strcpy(raw2edf_var->phys_dim, PhysicalDimensionLineEdit->text().toLatin1().data()); remove_leading_spaces(raw2edf_var->phys_dim); remove_trailing_spaces(raw2edf_var->phys_dim); if(!(strlen(PatientnameLineEdit->text().toLatin1().data()))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a subjectname."); messagewindow.exec(); return; } if(!(strlen(RecordingLineEdit->text().toLatin1().data()))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a recording description."); messagewindow.exec(); return; } strcpy(path, QFileDialog::getOpenFileName(0, "Open data file", QString::fromLocal8Bit(recent_opendir), "All files (*)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH); inputfile = fopeno(path, "rb"); if(inputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for reading."); messagewindow.exec(); return; } remove_extension_from_filename(path); strcat(path, ".edf"); hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_EDFPLUS, chns); if(hdl<0) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for writing.\nedfopen_file_writeonly()"); messagewindow.exec(); fclose(inputfile); return; } for(i=0; i<chns; i++) { if(edf_set_samplefrequency(hdl, i, sf)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_samplefrequency()"); messagewindow.exec(); fclose(inputfile); return; } } if(samplesize == 2) { for(i=0; i<chns; i++) { if(edf_set_digital_maximum(hdl, i, 32767)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_digital_maximum()"); messagewindow.exec(); fclose(inputfile); return; } } for(i=0; i<chns; i++) { if(edf_set_digital_minimum(hdl, i, -32768)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_digital_minimum()"); messagewindow.exec(); fclose(inputfile); return; } } } if(samplesize == 1) { for(i=0; i<chns; i++) { if(edf_set_digital_maximum(hdl, i, 255)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_digital_maximum()"); messagewindow.exec(); fclose(inputfile); return; } } for(i=0; i<chns; i++) { if(edf_set_digital_minimum(hdl, i, -256)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_digital_minimum()"); messagewindow.exec(); fclose(inputfile); return; } } } for(i=0; i<chns; i++) { if(edf_set_physical_maximum(hdl, i, phys_max)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_physical_maximum()"); messagewindow.exec(); fclose(inputfile); return; } } for(i=0; i<chns; i++) { if(edf_set_physical_minimum(hdl, i, -phys_max)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_physical_minimum()"); messagewindow.exec(); fclose(inputfile); return; } } for(i=0; i<chns; i++) { if(edf_set_physical_dimension(hdl, i, raw2edf_var->phys_dim)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_physical_dimension()"); messagewindow.exec(); fclose(inputfile); return; } } for(i=0; i<chns; i++) { sprintf(str, "ch. %i", i + 1); if(edf_set_label(hdl, i, str)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_label()"); messagewindow.exec(); fclose(inputfile); return; } } if(edf_set_startdatetime(hdl, StartDatetimeedit->date().year(), StartDatetimeedit->date().month(), StartDatetimeedit->date().day(), StartDatetimeedit->time().hour(), StartDatetimeedit->time().minute(), StartDatetimeedit->time().second())) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_startdatetime()"); messagewindow.exec(); fclose(inputfile); edfclose_file(hdl); return; } buf = (int *)malloc(sizeof(int) * sf * chns); if(buf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "malloc()"); messagewindow.exec(); fclose(inputfile); edfclose_file(hdl); return; } // printf("samplefrequency: %14i Hz\n" // "channels: %14i\n" // "physical maximum: %14.6f uV\n" // "straightbinary: %14i\n" // "samplesize: %14i byte(s)\n" // "offset: %14lli bytes\n" // "skip blocksize: %14i bytes\n" // "skip bytes: %14i bytes\n\n", // sf, // chns, // phys_max, // straightbinary, // samplesize, // d_offset, // skipblocksize, // skipbytes); fseeko(inputfile, d_offset, SEEK_SET); datarecords = 0; union{ int one[1]; signed short two[2]; char four[4]; } var; skipblockcntr = 0; bytecntr = 0; while(1) { for(j=0; j<sf; j++) { for(k=0; k<chns; k++) { // tmp = fgetc(inputfile); // if(tmp == EOF) // { // goto END_1; // } // // tmp += (fgetc(inputfile) * 256); // // buf[j + (k * sf)] = tmp - 32768; if(samplesize == 2) { tmp = fgetc(inputfile); if(tmp == EOF) { goto END_1; } bytecntr++; // printf("1: skipblockcntr is %i tmp is %02X bytecntr is %i\n", skipblockcntr, tmp, bytecntr); if(skipblocksize) { if(++skipblockcntr > skipblocksize) { for(r=0; r<skipbytes; r++) { tmp = fgetc(inputfile); if(tmp == EOF) { goto END_1; } // bytecntr++; // printf("2: skipblockcntr is %i tmp is %02X bytecntr is %i\n", skipblockcntr, tmp, bytecntr); } skipblockcntr = 1; } } if(big_endian) { var.four[1] = tmp; } else { var.four[0] = tmp; } } if(samplesize == 1) { var.four[0] = 0; } tmp = fgetc(inputfile); if(tmp == EOF) { goto END_1; } // bytecntr++; // printf("3: skipblockcntr is %i tmp is %02X bytecntr is %i\n", skipblockcntr, tmp, bytecntr); if(skipblocksize) { if(++skipblockcntr > skipblocksize) { for(r=0; r<skipbytes; r++) { tmp = fgetc(inputfile); if(tmp == EOF) { goto END_1; } bytecntr++; // printf("4: skipblockcntr is %i tmp is %02X bytecntr is %i\n", skipblockcntr, tmp, bytecntr); } skipblockcntr = 1; } } if(big_endian && (samplesize == 2)) { var.four[0] = tmp; } else { var.four[1] = tmp; } if(straightbinary) { var.two[0] -= 32768; } if(samplesize == 1) { var.two[0] >>= 8; } buf[j + (k * sf)] = var.two[0]; } } if(edf_blockwrite_digital_samples(hdl, buf)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Write error during conversion.\nedf_blockwrite_digital_samples()"); messagewindow.exec(); edfclose_file(hdl); fclose(inputfile); free(buf); return; } datarecords++; // if(datarecords == 1) break; }
void UI_RAW2EDFapp::savebuttonpressed() { char path[MAX_PATH_LENGTH], str[128]; FILE *outputfile; raw2edf_var->sf = SamplefreqSpinbox->value(); raw2edf_var->chns = SignalsSpinbox->value(); raw2edf_var->phys_max = PhysicalMaximumSpinbox->value(); raw2edf_var->straightbinary = EncodingCombobox->currentIndex(); raw2edf_var->endianness = EndiannessCombobox->currentIndex(); raw2edf_var->samplesize = SampleSizeSpinbox->value(); raw2edf_var->offset = OffsetSpinbox->value(); raw2edf_var->skipblocksize = skipblocksizeSpinbox->value(); raw2edf_var->skipbytes = skipbytesSpinbox->value(); strcpy(raw2edf_var->phys_dim, PhysicalDimensionLineEdit->text().toLatin1().data()); remove_leading_spaces(raw2edf_var->phys_dim); remove_trailing_spaces(raw2edf_var->phys_dim); path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, "binary_to_edf.template"); strcpy(path, QFileDialog::getSaveFileName(0, "Save parameters", QString::fromLocal8Bit(path), "Template files (*.template *.TEMPLATE)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(recent_savedir, path, MAX_PATH_LENGTH); outputfile = fopeno(path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for writing."); messagewindow.exec(); return; } fprintf(outputfile, "<?xml version=\"1.0\"?>\n<" PROGRAM_NAME "_raw2edf_template>\n"); fprintf(outputfile, " <sf>%i</sf>\n", raw2edf_var->sf); fprintf(outputfile, " <chns>%i</chns>\n", raw2edf_var->chns); fprintf(outputfile, " <phys_max>%i</phys_max>\n", raw2edf_var->phys_max); fprintf(outputfile, " <straightbinary>%i</straightbinary>\n", raw2edf_var->straightbinary); fprintf(outputfile, " <endianness>%i</endianness>\n", raw2edf_var->endianness); fprintf(outputfile, " <samplesize>%i</samplesize>\n", raw2edf_var->samplesize); fprintf(outputfile, " <offset>%i</offset>\n", raw2edf_var->offset); fprintf(outputfile, " <skipblocksize>%i</skipblocksize>\n", raw2edf_var->skipblocksize); fprintf(outputfile, " <skipbytes>%i</skipbytes>\n", raw2edf_var->skipbytes); xml_strcpy_encode_entity(str, raw2edf_var->phys_dim); fprintf(outputfile, " <phys_dim>%s</phys_dim>\n", str); fprintf(outputfile, "</" PROGRAM_NAME "_raw2edf_template>\n"); fclose(outputfile); }
double DLL_FUNC get_time_from_string( double initial_jd, const char *time_str, const int time_format, int *is_ut) { const double J2000 = 2451544.5; /* 1.0 Jan 2000 = JD 2451544.5 */ const int calendar = (time_format & CALENDAR_MASK); /* Certain solar-lunar calendars can have 13 months in a year: */ const int max_month = ((calendar == CALENDAR_HEBREW || calendar == CALENDAR_CHINESE) ? 13 : 12); int iday, month, hour, minute, n_bytes; int ival, i, colon_found = 0, is_bc = 0; int am_pm_indicator = AM_PM_UNSET; long year; double sec, dday; double rval = 0., offset = 0., tval; char buff[80]; char symbol = 0; char *str = buff; if( is_ut) *is_ut = 0; while( *time_str == ' ') /* skip leading spaces */ time_str++; if( strlen( time_str) >= sizeof( buff) || !*time_str) return( initial_jd); /* check/avoid possible buffer overflow */ /* Ensure spaces between letters and digits. For example, */ /* if time_str="11Nov 1918", set str="11 Nov 1918". */ /* 'Q' is an exception to avoid '1q' becoming '1 q'. */ *str = tolower( *time_str++); i = 1; while( (size_t)i < sizeof( buff) - 1 && *time_str) { if( (isalpha( *time_str) && isdigit( time_str[-1])) || (isdigit( *time_str) && isalpha( time_str[-1]))) if( *time_str != 'q' && *time_str != 'Q') str[i++] = ' '; str[i++] = (char)tolower( *time_str++); } str[i] = '\0'; remove_trailing_spaces( str); while( *str && (tval = collect_time_offset( str)) != 0.) { remove_trailing_spaces( str); offset += tval; } i = strlen( str); if( i > 1) { const int phase = get_phase_idx( str + i - 2); if( phase != PHASE_IDX_UNDEFINED) { str[i - 2] = '\0'; rval = get_time_from_string( initial_jd, str, time_format, NULL); if( rval && is_ut) *is_ut = 1; return( set_from_lunar( phase, rval) + offset); } } is_bc = check_for_bc( str); if( *str == 'j') /* decimal JD */ { /* may begin with 'j' or 'jd' */ if( str[1] == 'd') str++; rval = atof( str + 1); if( rval && is_ut) *is_ut = 1; } if( *str == 'y') /* decimal years */ rval = J2000 + (atof( str + 1) - 2000.) * 365.25; if( !memcmp( str, "mjd", 3)) /* modified JD */ { rval = atof( str + 3) + 2400000.5; if( is_ut) *is_ut = 1; } if( !memcmp( str, "now", 3)) { static const double jan_1970 = 2440587.5; str += 3; while( *str == ' ') str++; initial_jd = jan_1970 + (double)time( NULL) / 86400.; } if( !*str) rval = initial_jd; if( rval) return( rval + offset); /* The common European format of separating day/month/year */ /* with .s causes trouble, because the code wants to see */ /* those as decimal numbers. So if the input string starts */ /* with three integers separated by dots, we change both */ /* dots to '/' characters, then proceed normally: */ if( sscanf( str, "%d.%d.%d%n", &iday, &month, &hour, &n_bytes) == 3) for( i = 0; i < n_bytes; i++) if( str[i] == '.') str[i] = '/'; sec = split_time( initial_jd, &year, &month, &iday, &hour, &minute, calendar); /* FITS times are always in the form YYYY-MM-DDTHH:MM:SS, */ /* sometimes followed by .S. This is handled separately, */ /* in part to ensure that the month and day don't get */ /* swapped around: they are _always_ in that order. Also */ /* note that after spaces are added and the 'T' lowercased, */ /* it actually reads YYYY-MM-DD t HH:MM:SS. */ i = strlen( str); if( i > 18 && str[11] == 't') if( str[4] == '-' && str[7] == '-' && str[15] == ':') { symbol = 'f'; sscanf( str, "%ld-%d-%d", &year, &month, &iday); } if( i >= 4) { const char *search_text[4] = { " am", " a.m.", " pm", " p.m." }; int j; for( j = 0; j < 4; j++) { const int slen = 3 + ((j & 1) << 1); if( !strcmp( str + i - slen, search_text[j])) { i -= slen; str[i] = '\0'; am_pm_indicator = (j >= 2 ? AM_PM_SET_TO_PM : AM_PM_SET_TO_AM); j = 4; /* break out of loop */ } } } /* If the input text ends with something containing ':'s, */ /* assume there is a time to be extracted. Back up along the */ /* string, looking for the start of the time string (which */ /* may be the beginning of the string, or just after a space, */ /* or (for FITS input) just after a 'T'... for simplicity, */ /* that last test just checks for any alphabetical char.) */ for( i = strlen( str); i && str[i - 1] != ' ' && !isalpha( str[i - 1]); i--) if( str[i - 1] == ':') colon_found = 1; if( strcmp( str + i, ":")) { const int saved_hour = hour; minute = hour = 0; sec = 0.; if( colon_found) { double dminute = 0.; if( str[i] != ':') { sscanf( str + i, "%d:%lf:%lf", &hour, &dminute, &sec); sec += dminute * 60.; if( am_pm_indicator == AM_PM_SET_TO_AM) if( hour == 12) hour = 0; if( am_pm_indicator == AM_PM_SET_TO_PM) if( hour != 12) hour += 12; } else /* :MM:SS means "leave the hour unchanged" */ { hour = saved_hour; sscanf( str + i + 1, "%lf:%lf", &dminute, &sec); sec += dminute * 60.; } } } if( colon_found) /* lop the time off, leaving only the date: */ str[i ? i - 1 : 0] = '\0'; dday = (double)iday; i = 0; if( *str && symbol != 'f') { for( i = 1; str[i] && !strchr( "-:/ ", str[i]); i++) ; symbol = str[i]; } switch( symbol) { case 'f': /* FITS-format time: see above */ break; case ':': /* time of day */ break; case '-': /* dash-delimited such as '2009-01-20' */ case ' ': /* space-delimited format such as "25 dec 1980" */ case '/': /* common day/month/year dividing symbol */ { int month_found = 0, n_fields_found = 2; int year_found = 0, day_found = 0; char tstr[80]; double ivals[3]; memcpy( tstr, str, i); tstr[i] = '\0'; ival = month_name_to_index( tstr); if( ival) /* month given first, such as 'jan 25' */ { month_found = 1; ivals[0] = (double)ival; } else { ivals[0] = atof( tstr); if( strchr( tstr, '.')) /* decimal day given */ day_found = 1; } str += i + 1; for( i = 0; str[i] && str[i] != symbol && str[i] != ' '; i++) ; memcpy( tstr, str, i); tstr[i] = '\0'; str += i; ival = month_name_to_index( tstr); if( ival) /* month given second, such as '25-jan' */ { month_found = 2; ivals[1] = (double)ival; } else { ivals[1] = atof( tstr); if( strchr( tstr, '.')) /* decimal day given */ day_found = 2; } if( *str == symbol) /* maybe a third field was entered, but */ { /* could be a time; check for a ':' */ str++; if( sscanf( str, "%79s", tstr) == 1) if( (ival = month_name_to_index( tstr)) != 0) { month_found = 3; n_fields_found = 3; ivals[2] = (double)ival; str += strlen( tstr); } if( n_fields_found == 2) if( sscanf( str, "%lf%n", &ivals[2], &n_bytes) == 1) if( str[n_bytes] != ':') { str += n_bytes; if( strchr( tstr, '.')) day_found = 3; n_fields_found = 3; } } /* if one of the fields is negative, or if it's */ /* greater than 32 and is the largest entry, it */ /* can be assumed to be the year: */ for( i = 0; i < n_fields_found; i++) if( ivals[i] < 0.) { year_found = i + 1; /* if we see a negative number, */ i = n_fields_found; /* we can stop looking further: */ } else if( ivals[i] > 32.) if( !year_found || ivals[i] > ivals[year_found - 1]) year_found = i + 1; if( year_found || n_fields_found == 2) for( i = 0; i < n_fields_found; i++) if( ivals[i] > (double)max_month + .0001 && ivals[i] < 32. && i + 1 != year_found) day_found = i + 1; if( n_fields_found == 2) { if( month_found) { double dval = ivals[2 - month_found]; month = (int)ivals[month_found - 1]; if( dval > .999 && dval < 32.) dday = dval; else year = (int)dval; } else if( year_found) /* year/day of year format: */ { year = (int)ivals[year_found - 1]; month = 1; dday = ivals[2 - year_found]; } else if( day_found) /* day/month, order is clear from */ { /* the day being > 12 or having a decimal*/ dday = ivals[day_found - 1]; month = (int)ivals[2 - day_found]; } else /* can't tell what's day/month/year solely from input: */ if( (time_format & FULL_CTIME_MONTH_DAY) || symbol == 'f') { month = (int)ivals[0]; dday = (int)ivals[1]; } else /* day/month */ { month = (int)ivals[1]; dday = (int)ivals[0]; } } else /* three fields entered: */ { const int year_first = (time_format & FULL_CTIME_YEAR_FIRST); if( !year_found) { if( !month_found) { if( !day_found || day_found == 2) { year_found = (year_first ? 1 : 3); if( !day_found) /* must rely solely on time format */ { /* settings; no fields autofound */ day_found = (year_first ? 2 : 1); if( (time_format & FULL_CTIME_MONTH_DAY) || symbol == 'f') day_found++; /* ymd or mdy case */ } } else /* if day is 1st or last, year is last or 1st */ year_found = 4 - day_found; } else if( !day_found) /* only the month was found: */ { if( month_found == 2) year_found = (year_first ? 1 : 3); else /* if month is 1st or last, year must be last/1st */ year_found = 4 - month_found; } } else /* year_found... */ if( !month_found && !day_found) /* ...but nothing else */ { if( (time_format & FULL_CTIME_MONTH_DAY) || symbol == 'f') month_found = (year_found == 1 ? 2 : 1); else day_found = (year_found == 1 ? 2 : 1); } /* We now have the year nailed down. If either the day */ /* or month is still not nailed down, we can find it */ /* easily, since the 'found' values must sum up to 6: */ if( !day_found) day_found = 6 - year_found - month_found; else if( !month_found) month_found = 6 - year_found - day_found; year = (int)floor( ivals[year_found - 1] + .5); dday = ivals[day_found - 1]; month = (int)( ivals[month_found - 1] + .5); } if( year > 0 && year < 100 && !is_bc) if( time_format & FULL_CTIME_TWO_DIGIT_YEAR) year += (year < 40 ? 2000 : 1900); } break; case '\0': /* no dividing symbols found */ if( *str) { ival = month_name_to_index( str); if( ival) month = ival; else if( (ival = day_of_week_name_to_index( str)) >= 0) { ival -= ((long)(initial_jd + 1.5)) % 7; if( ival < -3) ival += 7; else if( ival > 3) ival -= 7; dday += ival; } else { n_bytes = 0; if( sscanf( str, "%d%n", &ival, &n_bytes) == 1) { double tval = 0.; str += n_bytes; if( *str == '.') /* also a fractional part to this: */ { int n_bytes_in_fraction; sscanf( str, "%lf%n", &tval, &n_bytes_in_fraction); str += n_bytes_in_fraction; } tval += (double)ival; switch( n_bytes) { case 1: case 2: /* reset day */ dday = tval; break; case 3: /* reset day of year */ dday = tval; month = 1; break; case 4: /* reset year, which may be */ case 5: /* four or five digits long */ if( (double)ival == tval) { /* set 1 Jan of the year */ dday = 1.; month = 1; year = ival; } else /* true decimal year */ return( J2000 + (tval - 2000.) * 365.25 + offset); break; case 7: /* JD */ if( is_ut) *is_ut = 1; return( tval + offset); case 6: /* YYMMDD(.DD) */ case 8: /* YYYYMMDD(.DD) */ year = ival / 10000L; if( n_bytes == 6) year += (year < 40 ? 2000 : 1900); month = (ival / 100) % 100L; dday = (double)( ival % 100L); dday += tval - (double)ival; break; } } else /* couldn't make sense of input text */ return( 0.); } } break; default: return( 0.); // break; } if( is_bc) year = 1 - year; iday = (int)dday; dday -= (double)iday; rval = (double)dmy_to_day( iday, month, year, calendar) + dday - .5 + (double)hour / 24. + (double)minute / 1440. + sec / 86400.; return( rval + offset); }