Commit 05b2fac0 authored by Achim Morschhauser's avatar Achim Morschhauser
Browse files

Calibration routines updated

- Manual calibration added
- Calibration functions cleaned and updated
parent 097d880b
......@@ -15,36 +15,35 @@ class Obs_Calibration_Vector {
private:
/** File for ADC calibration constants */
std::string file_ADC="";
/** File for ADC calibration constants */
std::string file_ADC = "";
/** The offset */
std::vector<double> offset;
/** The scale value */
std::vector<double> scale;
int N=0;
int N = 0;
/** Non-zero calibration constants */
char do_cal=0;
/** ADC calibration constant */
struct adc_cal {
std::string scale="";
std::string offset="";
std::string comment="";
bool operator==(const adc_cal& a) const {
return (scale == a.scale && offset == a.offset);
}
};
/** Map containing the ADC calibration key-value pairs */
std::unordered_map<std::string, struct adc_cal> map_ADC;
char do_cal = 0;
/** ADC calibration constant */
struct adc_cal {
std::string scale = "";
std::string offset = "";
std::string comment = "";
bool operator==(const adc_cal &a) const {
return (scale == a.scale && offset == a.offset);
}
};
/** Map containing the ADC calibration key-value pairs */
std::unordered_map<std::string, struct adc_cal> map_ADC;
/** ADC Offsets */
std::vector<int> adc_offset;
/** ADC scale values */
......@@ -59,11 +58,11 @@ private:
public:
/** Constructor with single values */
Obs_Calibration_Vector(int N, double offset=0, double scale=1);
Obs_Calibration_Vector(int N, double offset = 0, double scale = 1);
/** Constructor with vector values */
Obs_Calibration_Vector(std::vector<double>& offset,
std::vector<double>& scale);
Obs_Calibration_Vector(std::vector<double> &offset,
std::vector<double> &scale);
//
// Public Methods
......@@ -72,35 +71,34 @@ public:
public:
/** Calibrate data */
int calibrate(data_obs* sdata);
int calibrate(data_obs *sdata);
/** Get the calibration constants for the ADC */
int get_adc_calibrate(std::string config, std::string &offset,
std::string &scale);
std::string &scale);
/** Add a calibration constant for the ADC */
int add_adc_calibrate(std::string config, std::string offset,
std::string scale, std::string comment);
/** Save the calibration constants to file */
int save_adc_calibrate(std::string filename);
int save_adc_calibrate();
/** Read the calibration constants from file */
int read_adc_calibrate(std::string filename);
int read_adc_calibrate();
/** Parse an ADC calibration line */
int parse_adc_calibration(std::string line,
std::string& config, struct adc_cal& cal);
int parse_adc_calibration(std::string line,
std::string& config, struct adc_cal& cal, std::string& comment);
/** Set the internal ADC calibration file */
int set_adc_calibrate(std::string filename);
/** Get the internal ADC calibration file */
std::string get_adc_calibrate();
std::string scale, std::string comment);
/** Save the calibration constants to file */
int save_adc_calibrate(std::string filename);
int save_adc_calibrate();
/** Read the calibration constants from file */
int read_adc_calibrate(std::string filename);
int read_adc_calibrate();
/** Parse an ADC calibration line */
int parse_adc_calibration(std::string line, std::string &config,
struct adc_cal &cal);
int parse_adc_calibration(std::string line, std::string &config,
struct adc_cal &cal, std::string &comment);
/** Set the internal ADC calibration file */
int set_adc_calibrate(std::string filename);
/** Get the internal ADC calibration file */
std::string get_adc_calibrate();
};
......
......@@ -111,10 +111,10 @@ int stop();
//int set_manual_calibrate(float scale, float offset);
/** Automatically calibrate the ObsDAQ */
int auto_calibrate(int channel, int repeat);
int auto_calibrate(int repeat, double freq);
/** Manually calibrate the ObsDAQ */
int full_calibrate(int channel, int repeat);
int manual_calibrate(int repeat, double freq);
//
// Protected Methods
......@@ -176,8 +176,21 @@ int init();
/** Prepare continuous data acquisition **/
int init_run(double freq);
/** Automatically calibrate the ObsDAQ with given config*/
int auto_calibrate(int channel, int repeat, std::string config);
/** General calibration routine for all three channels*/
int calibrate(int repeat, std::string mode, double &fullscale);
int calibrate_channel(int channel, int repeat, std::string mode, std::string config);
/** Set calibration on the ObsDAQ*/
int set_calibration(int channel, std::string &adc_offset,
std::string &adc_scale);
double read_cal(int channel, char mode, int N, double val);
/** Choose the sampling frequency **/
int set_freq(double freq);
int write_message(std::string msg);
std::string ask_message(std::string msg);
std::string ask_message(std::string msg, std::vector<std::string>);
};
......
......@@ -154,97 +154,102 @@ int Obs_Calibration_Vector::add_adc_calibrate(std::string config,
* Save the calibration constants to file
*
***************************************************************************/
int Obs_Calibration_Vector::save_adc_calibrate(std::string filename) {
/* PROBLEM: Save the comments in ADC file when new configurations are
* stored. Cannot simply append, as duplicates need to be treated.
* SOLUTION: Save whole file in string before writing. Then, rewrite
* file. Comment out duplicates instead of overwriting.
*/
std::ifstream file_in(filename);
std::stringstream buf_in;
std::ofstream file_out;
std::string line, config, comment;
time_t t = time(0); // Current time
char time_c[20]; // Current time as c-string
size_t pos_c;
struct adc_cal cal, cal_buf;
// Copy the file to stringstream
if (file_in) {
buf_in << file_in.rdbuf();
file_in.close();
}
// Copy the hash map
// The copy will be used to track what has been written to file
std::unordered_map<std::string, struct adc_cal> map_ADC_cpy(map_ADC);
// Open file as new blank file
file_out.open(filename, std::ios::out | std::ios::trunc);
// Read from buffered file
while (getline(buf_in, line)) {
// Parse from line
// Comment line
if (parse_adc_calibration(line, config, cal_buf, comment) < 0) {
file_out << line << std::endl;
} else {
// Configuration exists
if (map_ADC_cpy.count(config) > 0) {
cal = map_ADC_cpy[config];
map_ADC_cpy.erase(config);
// Existing config is the same
if (cal == cal_buf) {
file_out << line << std::endl;
// Existing config is different
} else {
file_out << "# " << asctime(gmtime(&t)) << " UTC\n";
file_out << "#" << line << std::endl;
file_out << config << "," << cal.offset << "," << cal.scale
<< ";" << comment << std::endl;
}
// Configuration doesn't exist
} else {
file_out << line << std::endl;
}
}
}
// Write all remaining configurations
for (auto &i : map_ADC_cpy) {
strftime(time_c, sizeof(time_c), "%F %T", gmtime(&t));
file_out << "\n# " << i.second.comment << " " << time_c << " UTC\n";
file_out << i.first << "," << i.second.scale << "," << i.second.offset
<< ";" << std::endl;
}
file_out.close();
return (0);
}
int Obs_Calibration_Vector::save_adc_calibrate() {
if (file_ADC.empty())
return (-1);
return (save_adc_calibrate(file_ADC));
}
int Obs_Calibration_Vector::save_adc_calibrate(std::string filename) {
/* PROBLEM: Save the comments in ADC file when new configurations are
* stored. Cannot simply append, as duplicates need to be treated.
* SOLUTION: Save whole file in string before writing. Then, rewrite
* file. Comment out duplicates instead of overwriting.
*/
std::ifstream file_in(filename);
std::stringstream buf_in;
std::ofstream file_out;
std::string line, config, comment;
time_t t=time(0); // Current time
char time_c[20]; // Current time as c-string
size_t pos_c;
struct adc_cal cal, cal_buf;
// Transform time to string
strftime(time_c, sizeof(time_c), "%F %T", gmtime(&t));
// Copy the file to stringstream
if (file_in) {
buf_in << file_in.rdbuf();
file_in.close();
}
// Copy the hash map
// The copy will be used to track what has been written to file
std::unordered_map<std::string, struct adc_cal> map_ADC_cpy(map_ADC);
// Open file as new blank file
file_out.open(filename,std::ios::out | std::ios::trunc);
// Read from buffered file
while ( getline (buf_in,line) ) {
// Parse from line
if (parse_adc_calibration(line,config,cal_buf,comment) < 0){
// Comment line
file_out << line << std::endl;
} else {
// Configuration exists in file and new calibration map
if (map_ADC_cpy.count(config)>0) {
cal=map_ADC_cpy[config];
map_ADC_cpy.erase(config);
// Existing config is the same
if (cal==cal_buf){
file_out << line << std::endl;
// Existing config is different
} else {
file_out << "#" << line << std::endl;
file_out << "# " << cal.comment << " " << time_c
<< " UTC\n";
file_out << config << "," << cal.scale << "," << cal.offset
<< ";" << std::endl;
}
// Configuration only exists in file
} else {
file_out << line << std::endl;
}
}
}
// Write all remaining configurations
for (auto& i : map_ADC_cpy){
file_out << "\n# " << i.second.comment << " " << time_c << " UTC\n";
file_out << i.first << "," << i.second.scale << ","
<< i.second.offset << ";" << std::endl;
}
file_out.close();
return(0);
}
int Obs_Calibration_Vector::save_adc_calibrate() {
if (file_ADC.empty()) return(-1);
return(save_adc_calibrate(file_ADC));
}
/****************************************************************************
*
* Read the calibration constants to file
......
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment