enum HPCS_RetCode ret;
enum HPCS_GenType gentype;
enum HPCS_ChemStationVer cs_ver;
+ double signal_step;
+ double signal_shift;
if (mdata == NULL)
return HPCS_E_NULLPTR;
}
}
- switch (mdata->file_type) {
- case HPCS_TYPE_CE_ANALOG:
- pret = read_signal(datafile, &mdata->data, &mdata->data_count, CE_WORK_PARAM_OLD_STEP, mdata->sampling_rate, gentype);
- break;
- case HPCS_TYPE_CE_CCD:
- pret = read_signal(datafile, &mdata->data, &mdata->data_count, CE_CCD_STEP, mdata->sampling_rate, gentype);
- break;
- case HPCS_TYPE_CE_CURRENT:
- pret = read_signal(datafile, &mdata->data, &mdata->data_count, guess_current_step(cs_ver, gentype), mdata->sampling_rate, gentype);
- break;
- case HPCS_TYPE_CE_DAD:
- pret = read_signal(datafile, &mdata->data, &mdata->data_count, CE_DAD_STEP, mdata->sampling_rate, gentype);
- break;
- case HPCS_TYPE_CE_POWER:
- case HPCS_TYPE_CE_VOLTAGE:
- pret = read_signal(datafile, &mdata->data, &mdata->data_count, guess_elec_sigstep(cs_ver, mdata->file_type), mdata->sampling_rate, gentype);
- break;
- case HPCS_TYPE_CE_PRESSURE:
- pret = read_signal(datafile, &mdata->data, &mdata->data_count, CE_WORK_PARAM_STEP, mdata->sampling_rate, gentype);
- break;
- case HPCS_TYPE_CE_TEMPERATURE:
- pret = read_signal(datafile, &mdata->data, &mdata->data_count, CE_WORK_PARAM_OLD_STEP * 10.0, mdata->sampling_rate, gentype);
- break;
- case HPCS_TYPE_UNKNOWN:
- ret = HPCS_E_UNKNOWN_TYPE;
- goto out;
+ pret = fetch_signal_step(datafile, &signal_step, &signal_shift, OLD_FORMAT(gentype));
+ if (pret != PARSE_OK) {
+ PR_DEBUG("Cannot read signal step and shift\n");
+ ret = HPCS_E_PARSE_ERROR;
+ goto out;
}
+ pret = read_signal(datafile, &mdata->data, &mdata->data_count, signal_step, signal_shift, mdata->sampling_rate, gentype);
if (pret != PARSE_OK) {
PR_DEBUG("Cannot parse data in the file\n");
ret = HPCS_E_PARSE_ERROR;
return CHEMSTAT_UNKNOWN;
}
+static enum HPCS_ParseCode fetch_signal_step(FILE *datafile, double *step, double *shift, bool old_format)
+{
+ int32_t version;
+ double _step;
+ double _shift;
+ HPCS_offset veroff;
+ HPCS_offset shiftoff;
+ HPCS_offset stepoff;
+
+ if (old_format) {
+ veroff = DATA_OFFSET_SIGSTEP_VERSION_OLD;
+ shiftoff = DATA_OFFSET_SIGSTEP_SHIFT_OLD;
+ stepoff = DATA_OFFSET_SIGSTEP_STEP_OLD;
+ } else {
+ veroff = DATA_OFFSET_SIGSTEP_VERSION;
+ shiftoff = DATA_OFFSET_SIGSTEP_SHIFT;
+ stepoff = DATA_OFFSET_SIGSTEP_STEP;
+ }
+
+ fseek(datafile, veroff, SEEK_SET);
+ if (feof(datafile))
+ return PARSE_E_OUT_OF_RANGE;
+ if (ferror(datafile))
+ return PARSE_E_CANT_READ;
+ if (fread(&version, LARGE_SEGMENT_SIZE, 1, datafile) < 1)
+ return PARSE_E_CANT_READ;
+
+ be_to_cpu_val(version);
+ switch (version) {
+ case 1:
+ *step = SIGSTEP_V1;
+ *shift = 0.0;
+ return PARSE_OK;
+ case 2:
+ *step = SIGSTEP_V2;
+ *shift = 0.0;
+ return PARSE_OK;
+ default:
+ break;
+ }
+
+ fseek(datafile, shiftoff, SEEK_SET);
+ if (feof(datafile))
+ return PARSE_E_OUT_OF_RANGE;
+ if (ferror(datafile))
+ return PARSE_E_CANT_READ;
+ if (fread(&_shift, DOUBLE_SEGMENT_SIZE, 1, datafile) < 1)
+ return PARSE_E_CANT_READ;
+
+ fseek(datafile, stepoff, SEEK_SET);
+ if (feof(datafile))
+ return PARSE_E_OUT_OF_RANGE;
+ if (ferror(datafile))
+ return PARSE_E_CANT_READ;
+ if (fread(&_step, DOUBLE_SEGMENT_SIZE, 1, datafile) < 1)
+ return PARSE_E_CANT_READ;
+
+ be_to_cpu_val(_shift);
+ be_to_cpu_val(_step);
+ *shift = _shift;
+ *step = _step;
+
+ return PARSE_OK;
+}
static bool file_type_description_is_readable(const char*const description)
{
}
}
-static HPCS_step guess_current_step(const enum HPCS_ChemStationVer version, const enum HPCS_GenType gentype)
-{
- if (version == CHEMSTAT_B0625 || OLD_FORMAT(gentype))
- return CE_WORK_PARAM_OLD_STEP * 10.0;
-
- return CE_CURRENT_STEP;
-}
-
-static HPCS_step guess_elec_sigstep(const enum HPCS_ChemStationVer version, const enum HPCS_FileType file_type)
-{
- if (version != CHEMSTAT_B0625) {
- switch (file_type) {
- case HPCS_TYPE_CE_POWER:
- return CE_ENERGY_STEP;
- default:
- return CE_WORK_PARAM_OLD_STEP;
- }
- }
-
- return CE_WORK_PARAM_STEP;
-}
-
static void guess_sampling_rate(const enum HPCS_ChemStationVer version, struct HPCS_MeasuredData *mdata)
{
switch (version) {
}
static enum HPCS_ParseCode read_signal(FILE* datafile, struct HPCS_TVPair** pairs, size_t* pairs_count,
- const HPCS_step step, const double sampling_rate, const enum HPCS_GenType gentype)
+ const double signal_step, const double signal_shift, const double sampling_rate, const enum HPCS_GenType gentype)
{
const double time_step = 1 / (60 * sampling_rate);
size_t alloc_size = (size_t)((60 * sampling_rate) + 0.5);
be_to_cpu(lraw);
_v = *(int32_t*)lraw;
- value = _v * step;
+ value = _v * signal_step + signal_shift;
} else {
int16_t _v;
be_to_cpu(raw);
_v = *(int16_t*)raw;
- value += _v * step;
+ value += _v * signal_step + signal_shift;
}
(*pairs)[data_segments_read].time = time;
};
typedef size_t HPCS_offset;
-typedef double HPCS_step;
typedef size_t HPCS_segsize;
const char FILE_TYPE_ID_ADC_A[] = "ADC CHANNEL A";
const char MON_NOV_STR[] = "Nov";
const char MON_DEC_STR[] = "Dec";
-/* Precision of measured values. */
-const HPCS_step CE_CURRENT_STEP = 0.01;
-const HPCS_step CE_CCD_STEP = 0.0000596046450027643;
-const HPCS_step CE_DAD_STEP = 0.000476837158203;
-const HPCS_step CE_ENERGY_STEP = 0.00000459365687208207;
-const HPCS_step CE_WORK_PARAM_STEP = 0.001;
-const HPCS_step CE_WORK_PARAM_OLD_STEP = 0.000083333333;
-
/* Hardcoded sampling rates */
const double CE_WORK_PARAM_SAMPRATE = 1.67;
const HPCS_offset DATA_OFFSET_CS_VER = 0xE11;
const HPCS_offset DATA_OFFSET_CS_REV = 0xEDA;
const HPCS_offset DATA_OFFSET_SAMPLING_RATE = 0x101C;
+const HPCS_offset DATA_OFFSET_SIGSTEP_VERSION = 0x1026;
+const HPCS_offset DATA_OFFSET_SIGSTEP_SHIFT = 0x1274;
+const HPCS_offset DATA_OFFSET_SIGSTEP_STEP = 0x127C;
const HPCS_offset DATA_OFFSET_Y_UNITS = 0x104C;
const HPCS_offset DATA_OFFSET_DEVSIG_INFO = 0x1075;
const HPCS_offset DATA_OFFSET_DATA_START = 0x1800;
const HPCS_offset DATA_OFFSET_OPERATOR_NAME_OLD = 0x095;
const HPCS_offset DATA_OFFSET_DATE_OLD = 0x0B3;
const HPCS_offset DATA_OFFSET_METHOD_NAME_OLD = 0x0E5;
+const HPCS_offset DATA_OFFSET_SIGSTEP_VERSION_OLD = 0x21E;
+const HPCS_offset DATA_OFFSET_SIGSTEP_SHIFT_OLD = 0x27C;
+const HPCS_offset DATA_OFFSET_SIGSTEP_STEP_OLD = 0x284;
const HPCS_offset DATA_OFFSET_Y_UNITS_OLD = 0x245;
const HPCS_offset DATA_OFFSET_DEVSIG_INFO_OLD = 0x255;
const HPCS_offset DATA_OFFSET_DATA_START_OLD = 0x400;
const HPCS_segsize SMALL_SEGMENT_SIZE = 1;
const HPCS_segsize SEGMENT_SIZE = 2;
const HPCS_segsize LARGE_SEGMENT_SIZE = 4;
+const HPCS_segsize DOUBLE_SEGMENT_SIZE = 8;
+
+const double SIGSTEP_V1 = 0.1;
+const double SIGSTEP_V2 = 0.00240841663372301;
const char HPCS_OK_STR[] = "OK.";
const char HPCS_E_NULLPTR_STR[] = "Null pointer to measured data struct.";
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 HPCS_step guess_current_step(const enum HPCS_ChemStationVer version, const enum HPCS_GenType gentype);
-static HPCS_step guess_elec_sigstep(const enum HPCS_ChemStationVer version, const enum HPCS_FileType file_type);
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);
static HPCS_UFH open_data_file(const char* filename);
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 HPCS_step step, const double sampling_rate, const enum HPCS_GenType gentype);
+ 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);
static enum HPCS_ParseCode read_string_at_offset(FILE* datafile, const HPCS_offset, char** const result, const bool read_as_wchar);
static void remove_trailing_newline(HPCS_NChar* s);
#ifdef _HPCS_LITTLE_ENDIAN
#define be_to_cpu(bytes) reverse_endianness((char*)bytes, sizeof(bytes));
+#define be_to_cpu_val(v) do { char *b = (char *)&v; const size_t sz = sizeof(v); reverse_endianness(b, sz); } while (0)
void reverse_endianness(char* bytes, size_t sz) {
size_t i;
#elif defined _HPCS_BIG_ENDIAN
#define be_to_cpu(bytes)
+#define be_to_cpu_val(v)
#else
#error "Endiannes has not been determined."
#endif