]> Devoid-pointer.net GitWeb - libHPCS.git/commitdiff
Read timing data from the file instead of guessing from the sampling
authorMichal Malý <madcatxster@gmail.com>
Thu, 18 Aug 2016 22:08:40 +0000 (00:08 +0200)
committerMichal Malý <madcatxster@gmail.com>
Thu, 18 Aug 2016 22:08:40 +0000 (00:08 +0200)
rate

libhpcs.c
libhpcs_p.h
test_tool.c

index c660971e33b38fc9f612d0dd87a7eecbd132428a..8677e87b090d96157e8b3d8aa445bd5ca0bef4de 100644 (file)
--- 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;
 }
index 00981ec8b7e264505eaea5e475c10d52422ad8e1..39a789d27588eb575a8bb837fde6e1623f032c75 100644 (file)
@@ -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);
index a4e8c78a6df2efe095b74787a3128e76e381fe72..7476205dcce644e6c7719a1b66671eee7de8bcc0 100644 (file)
@@ -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);