From: Michal MalĂ˝ Date: Thu, 18 Aug 2016 22:08:40 +0000 (+0200) Subject: Read timing data from the file instead of guessing from the sampling X-Git-Url: https://gitweb.devoid-pointer.net/?a=commitdiff_plain;h=ba3e2d6f33b2f5e068c14bb0e87cfc207b9a30ad;p=libHPCS.git Read timing data from the file instead of guessing from the sampling rate --- diff --git a/libhpcs.c b/libhpcs.c index c660971..8677e87 100644 --- a/libhpcs.c +++ b/libhpcs.c @@ -176,7 +176,7 @@ enum HPCS_RetCode hpcs_read_mdata(const char* filename, struct HPCS_MeasuredData goto out; } - pret = read_signal(datafile, &mdata->data, &mdata->data_count, signal_step, signal_shift, mdata->sampling_rate, gentype); + pret = read_signal(datafile, &mdata->data, &mdata->data_count, signal_step, signal_shift, gentype); if (pret != PARSE_OK) { PR_DEBUG("Cannot parse data in the file\n"); ret = HPCS_E_PARSE_ERROR; @@ -184,6 +184,10 @@ enum HPCS_RetCode hpcs_read_mdata(const char* filename, struct HPCS_MeasuredData else ret = HPCS_OK; + pret = read_timing(datafile, mdata->data, &mdata->sampling_rate, mdata->data_count); + if (pret != PARSE_OK) + ret = HPCS_E_PARSE_ERROR; + out: fclose(datafile); return ret; @@ -428,39 +432,6 @@ static bool gentype_is_readable(const enum HPCS_GenType gentype) } } -static void guess_sampling_rate(const enum HPCS_ChemStationVer version, struct HPCS_MeasuredData *mdata) -{ - switch (version) { - case CHEMSTAT_UNTAGGED: - switch (mdata->file_type) { - case HPCS_TYPE_CE_DAD: - mdata->sampling_rate *= 10; - break; - default: - mdata->sampling_rate = CE_WORK_PARAM_SAMPRATE; - } - break; - case CHEMSTAT_B0626: - case CHEMSTAT_B0643: - case CHEMSTAT_B0644: - switch (mdata->file_type) { - case HPCS_TYPE_CE_DAD: - case HPCS_TYPE_CE_CCD: - mdata->sampling_rate /= 100; - break; - default: - if (version == CHEMSTAT_B0644) - mdata->sampling_rate /= 100; - else - mdata->sampling_rate = CE_WORK_PARAM_SAMPRATE; - break; - } - break; - default: - break; - } -} - static uint8_t month_to_number(const char* month) { if (strcmp(MON_JAN_STR, month) == 0) @@ -810,12 +781,6 @@ static enum HPCS_ParseCode read_file_header(FILE* datafile, enum HPCS_ChemStatio return pret; } - pret = read_sampling_rate(datafile, &mdata->sampling_rate, old_format); - if (pret != PARSE_OK) { - PR_DEBUGF("%s%d\n", "Cannot read sampling rate of the file, errno: ", pret); - return pret; - } - *cs_ver = detect_chemstation_version(mdata->cs_ver); if (pret != PARSE_OK) { PR_DEBUGF("%s%d\n", "Cannot detect ChemStation version, errno: ", pret); @@ -836,7 +801,9 @@ static enum HPCS_ParseCode read_file_header(FILE* datafile, enum HPCS_ChemStatio } } - guess_sampling_rate(*cs_ver, mdata); + /* Sampling rate information is unreliable unless the whole file is read */ + mdata->sampling_rate = -1.0; + return PARSE_OK; } @@ -940,13 +907,11 @@ out: } static enum HPCS_ParseCode read_signal(FILE* datafile, struct HPCS_TVPair** pairs, size_t* pairs_count, - const double signal_step, const double signal_shift, const double sampling_rate, const enum HPCS_GenType gentype) + const double signal_step, const double signal_shift, const enum HPCS_GenType gentype) { - const double time_step = 1 / (60 * sampling_rate); - size_t alloc_size = (size_t)((60 * sampling_rate) + 0.5); + size_t alloc_size = (size_t)((60 * 25)); bool read_file = true; double value = 0; - double time = 0; size_t segments_read = 0; size_t data_segments_read = 0; size_t next_marker_idx = 0; @@ -1002,7 +967,7 @@ static enum HPCS_ParseCode read_signal(FILE* datafile, struct HPCS_TVPair** pair /* Expand storage if there is more data than we can store */ if (alloc_size == data_segments_read) { struct HPCS_TVPair* nptr; - alloc_size += (size_t)((60 * sampling_rate) + 0.5); + alloc_size += (size_t)((60 * 25)); nptr = realloc(*pairs, sizeof(struct HPCS_TVPair) * alloc_size); if (nptr == NULL) { @@ -1045,10 +1010,8 @@ static enum HPCS_ParseCode read_signal(FILE* datafile, struct HPCS_TVPair** pair value += _v * signal_step + signal_shift; } - (*pairs)[data_segments_read].time = time; (*pairs)[data_segments_read].value = value; data_segments_read++; - time += time_step; break; default: PR_DEBUG("Invalid value from check_for_marker()\n"); @@ -1062,30 +1025,41 @@ static enum HPCS_ParseCode read_signal(FILE* datafile, struct HPCS_TVPair** pair return PARSE_OK; } -static enum HPCS_ParseCode read_sampling_rate(FILE* datafile, double* sampling_rate, const bool old_format) +static enum HPCS_ParseCode read_timing(FILE* datafile, struct HPCS_TVPair*const pairs, double *sampling_rate, const size_t data_count) { - char raw[2]; - uint16_t number; - size_t r; - - if (old_format) { - *sampling_rate = 0.0; /* This information cannot be read from the datafile */ - return PARSE_OK; - } + int32_t xmin; + int32_t xmax; + double xminf; + double xmaxf; + double time_step; + double t; + size_t idx; - fseek(datafile, DATA_OFFSET_SAMPLING_RATE, SEEK_SET); + fseek(datafile, DATA_OFFSET_XMIN, SEEK_SET); if (feof(datafile)) return PARSE_E_OUT_OF_RANGE; if (ferror(datafile)) return PARSE_E_CANT_READ; - r = fread(raw, SEGMENT_SIZE, 1, datafile); - if (r != 1) + if (fread(&xmin, LARGE_SEGMENT_SIZE, 1, datafile) < 1) return PARSE_E_CANT_READ; + if (fread(&xmax, LARGE_SEGMENT_SIZE, 1, datafile) < 1) + return PARSE_E_CANT_READ; + + be_to_cpu_val(xmin); + be_to_cpu_val(xmax); + + xminf = (double)xmin / 60000.0; + xmaxf = (double)xmax / 60000.0; - be_to_cpu(raw); - number = *(uint16_t*)(raw); - *sampling_rate = number / 10.0; + time_step = (xmaxf - xminf) / data_count; + *sampling_rate = 1.0 / (time_step * 60.0); + + t = xminf; + for (idx = 0; idx < data_count; idx++) { + pairs[idx].time = t; + t += time_step; + } return PARSE_OK; } diff --git a/libhpcs_p.h b/libhpcs_p.h index 00981ec..39a789d 100644 --- a/libhpcs_p.h +++ b/libhpcs_p.h @@ -83,6 +83,8 @@ const double CE_WORK_PARAM_SAMPRATE = 1.67; /* Offsets containing data of interest in .ch files */ const HPCS_offset DATA_OFFSET_GENTYPE = 0x000; +const HPCS_offset DATA_OFFSET_XMIN = 0x11A; +const HPCS_offset DATA_OFFSEt_XMAX = 0x11E; const HPCS_offset DATA_OFFSET_FILE_DESC = 0x15B; const HPCS_offset DATA_OFFSET_SAMPLE_INFO = 0x35A; const HPCS_offset DATA_OFFSET_OPERATOR_NAME = 0x758; @@ -175,7 +177,6 @@ static enum HPCS_ParseCode autodetect_file_type(FILE* datafile, enum HPCS_FileTy static enum HPCS_DataCheckCode check_for_marker(const char* segment, size_t* const next_marker_idx); static enum HPCS_ChemStationVer detect_chemstation_version(const char*const version_string); static bool gentype_is_readable(const enum HPCS_GenType gentype); -static void guess_sampling_rate(const enum HPCS_ChemStationVer version, struct HPCS_MeasuredData* mdata); static enum HPCS_ParseCode fetch_signal_step(FILE * datafile, double *step, double *shift, bool old_format); static bool file_type_description_is_readable(const char*const description); static enum HPCS_ParseCode next_native_line(HPCS_UFH fh, HPCS_NChar* line, int32_t length); @@ -191,9 +192,9 @@ static enum HPCS_ParseCode read_file_type_description(FILE* datafile, char** con static enum HPCS_ParseCode read_generic_type(FILE* datafile, enum HPCS_GenType* gentype); static enum HPCS_ParseCode read_method_info_file(HPCS_UFH fh, struct HPCS_MethodInfo* minfo); static enum HPCS_ParseCode read_signal(FILE* datafile, struct HPCS_TVPair** pairs, size_t* pairs_count, - const double sigal_step, const double signal_shift, const double sampling_rate, const enum HPCS_GenType gentype); -static enum HPCS_ParseCode read_sampling_rate(FILE* datafile, double* sampling_rate, const bool old_format); + const double sigal_step, const double signal_shift, const enum HPCS_GenType gentype); static enum HPCS_ParseCode read_string_at_offset(FILE* datafile, const HPCS_offset, char** const result, const bool read_as_wchar); +static enum HPCS_ParseCode read_timing(FILE* datafile, struct HPCS_TVPair*const pairs, double *sampling_rate, const size_t data_count); static void remove_trailing_newline(HPCS_NChar* s); static enum HPCS_ParseCode __read_string_at_offset_v1(FILE* datafile, const HPCS_offset offset, char** const result); static enum HPCS_ParseCode __read_string_at_offset_v2(FILE* datafile, const HPCS_offset offset, char** const result); diff --git a/test_tool.c b/test_tool.c index a4e8c78..7476205 100644 --- a/test_tool.c +++ b/test_tool.c @@ -25,11 +25,13 @@ static int read_data(const char* path) printf("Sample info: %s\n" "Operator name: %s\n" "Method name: %s\n" - "Y units: %s\n", + "Y units: %s\n" + "Sample rate: %lf\n", mdata->sample_info, mdata->operator_name, mdata->method_name, - mdata->y_units); + mdata->y_units, + mdata->sampling_rate); for (di = 0; di < mdata->data_count; di++) printf("Time: %.17lg, Value: %.17lg\n", mdata->data[di].time, mdata->data[di].value);