Commit 0d12fd6f authored by Achim Morschhauser's avatar Achim Morschhauser
Browse files

Save/write calibration

parent 495ec6b4
......@@ -17,6 +17,9 @@ class Obs_Calibration_Vector {
private:
/** File for ADC calibration constants */
std::string file_ADC="";
/** The offset */
double offset[3];
/** The scale value */
......@@ -82,10 +85,17 @@ public:
/** 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);
};
......
......@@ -140,9 +140,11 @@ int Obs_Calibration_Vector::get_adc_calibrate(std::string config,
cal = it->second;
scale = cal.scale;
offset = cal.offset;
} else {
return(-1);
}
return(-1);
return(0);
}
......@@ -159,7 +161,13 @@ int Obs_Calibration_Vector::add_adc_calibrate(std::string config,
cal.offset = offset;
cal.scale = scale;
map_ADC[config]=cal;
// Check if already exists
if (map_ADC.count(config)>0) {
map_ADC[config]=cal;
} else {
std::cerr << "Calibration for " << config << " overwritten.";
}
return(0);
......@@ -173,13 +181,67 @@ int Obs_Calibration_Vector::add_adc_calibrate(std::string config,
int Obs_Calibration_Vector::save_adc_calibrate(std::string filename) {
/* PROBLEM: Save the comments in ADC file when new configurations are
* stored.
* 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_buf(filename);
std::ofstream file_out;
std::string line, config, comment;
size_t pos_c;
struct adc_cal cal;
// 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 (file_buf,line) ) {
// Parse from line
if (parse_adc_calibration(line,config,cal,comment) < 0){
file_out << line << std::endl;
} else {
// Configuration exists and is overwritten
if (map_ADC_cpy.count(config)>0) {
file_out << "#" << line << std::endl;
cal=map_ADC_cpy[config];
file_out << config << "," << cal.offset << "," <<
cal.scale << ";" << comment << std::endl;
// Configuration doesn't exist
} else {
file_out << line << 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));
}
/****************************************************************************
*
......@@ -191,10 +253,8 @@ int Obs_Calibration_Vector::add_adc_calibrate(std::string config,
std::ifstream file;
std::string line;
std::string config; // configuration string used as key
struct adc_cal cal; // calibration constants used as value
size_t pos_c;
std::string config; // configuration string used as key
struct adc_cal cal; // calibration constants used as value
// Open file
file.open(filename,std::ios::out);
......@@ -202,22 +262,10 @@ int Obs_Calibration_Vector::add_adc_calibrate(std::string config,
// Read from file
if (file.is_open()) {
while ( getline (file,line) ) {
// Find comment token ("#")
pos_c = line.find('#');
line=line.substr(0,pos_c);
if (line.size()==0) continue;
// Find configuration string
pos_c=line.find(',');
config=line.substr(0,pos_c);
// Find calibration string
line=line.substr(pos_c+1);
pos_c=line.find(',');
cal.offset = line.substr(0,pos_c);
cal.scale = line.substr(pos_c+1);
// Parse from line
parse_adc_calibration(line,config,cal);
// Save key-value pair
map_ADC[config]=cal;
std::cout << "Read ADC: " << config << " " << cal.offset <<
" " << cal.scale << std::endl;
}
file.close();
} else {
......@@ -228,3 +276,54 @@ int Obs_Calibration_Vector::add_adc_calibrate(std::string config,
return 0;
}
int Obs_Calibration_Vector::read_adc_calibrate() {
if (file_ADC.empty()) return(-1);
return(read_adc_calibrate(file_ADC));
}
/****************************************************************************
*
* Parse an ADC calibration line
*
***************************************************************************/
int Obs_Calibration_Vector::parse_adc_calibration(std::string line,
std::string& config, struct adc_cal& cal, std::string& comment) {
size_t pos_c;
// Find comment token ("#")
pos_c=line.find('#');
comment=line.substr(pos_c);
// Proceed with uncommented part
line=line.substr(0,pos_c);
if (line.size()==0) return(-1);
// Find configuration string
pos_c=line.find(',');
config=line.substr(0,pos_c);
// Find calibration string
line=line.substr(pos_c+1);
pos_c=line.find(',');
cal.offset = line.substr(0,pos_c);
line=line.substr(pos_c+1);
pos_c=line.find(';');
cal.scale = line.substr(0,pos_c);
std::cout << "Read ADC: " << config << " " << cal.offset <<
" " << cal.scale << std::endl;
return(0);
}
int Obs_Calibration_Vector::parse_adc_calibration(std::string line,
std::string& config, struct adc_cal& cal) {
std::string comment;
return(parse_adc_calibration(line,config,cal,comment));
}
\ No newline at end of file
......@@ -1047,7 +1047,7 @@ int driver_obs_obsdaq::init() {
int driver_obs_obsdaq::init_run(double freq){
// The receive buffer
//std::string recv;
std::string str_recv;
char recv[20]="";
// A command to send
char cmd[20];
......@@ -1105,28 +1105,28 @@ int driver_obs_obsdaq::init_run(double freq){
sprintf(cmd,"$%1dRS",i);
send(cmd);
receive(recv,sizeof(recv),5);
str_recv = std::string(recv);
//checked_send(cmd,"02",2,1,&recv,1);
std::cout << "REC CONFIG: " << recv << std::endl;
// Get the last four bytes ("ccdd") and add channel number
config= sn + "/" + recv[2,4] + "/" + std::to_string(i);
config= sn + "/" + str_recv.substr(7,4) + "/" + std::to_string(i);
fprintf(stderr,"----- CONFIG: %s\n",config.c_str());
// Check if calibration for the given config
// was pre-determined
if (driver_obs::cal->get_adc_calibrate
(config, adc_offset, adc_scale)<0){
(config, adc_offset, adc_scale)<0){
// Automatic Calibration
auto_calibrate(i,1);
// Save calibration constants
driver_obs::cal->save_adc_calibrate();
} else {
// Set the pre-determined calibration constant
sprintf(cmd,"$%1dWO%s",i,adc_offset.c_str());
send(cmd); waitanswer(5);
checked_send(cmd,adc_offset.c_str(),6,4);
sprintf(cmd,"$%1dWF%s",i,adc_scale.c_str());
send(cmd); waitanswer(5);
checked_send(cmd,adc_offset.c_str(),6,4);
}
//printf("============ GOT: %06X %06X\n",adc_offset,adc_scale);
......
# config (serialnumber/ccdd/channel),scale,offset
# Tatuoca
OD-550C0001/0203/1,3AEC9C,00028E
OD-550C0001/0203/2,3AEC9C,00028E
OD-550C0001/0203/3,3AEC9C,00028E
OD-56A17021/0223/0,3AEC9C,00028E;
OD-56A17021/0223/1,3AEC9C,00028E;
OD-56A17021/0223/2,3AEC9C,00028E;
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