WSL/SLF GitLab Repository

Commit b663cf6b authored by Mathias Bavay's avatar Mathias Bavay
Browse files

Handling some warnings for new version of clang in MathOptim.h (turning them...

Handling some warnings for new version of clang in MathOptim.h (turning them off for the bit manipulations). Laying the foundations for the append mode in SMET files (not usable yet).
parent 3d3de7f4
......@@ -53,7 +53,7 @@ ELSE()
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
SET(PROFILING "-pg -fprofile-arcs") #add ${PROFILING} to the CFLAGS when necessary
SET(EXTRA_WARNINGS "${EXTRA_WARNINGS} -Wunsafe-loop-optimizations -Wvector-operation-performance")
SET(EXTRA_WARNINGS "${EXTRA_WARNINGS} -Wunsafe-loop-optimizations -Wvector-operation-performance -Wwrite-strings")
IF(NOT ANDROID)
SET(EXTRA_WARNINGS "${EXTRA_WARNINGS} -ansi")
IF(WIN32) #for gcc on windows
......
......@@ -103,6 +103,10 @@ namespace Optim {
return u.x*(1.5f - xhalf*u.x*u.x);// Newton step, repeating increases accuracy
}
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdouble-promotion"
#endif
inline double invSqrt(const double x) {
const double xhalf = 0.5f*x;
......@@ -114,6 +118,10 @@ namespace Optim {
u.i = SQRT_MAGIC_D - (u.i >> 1); // gives initial guess y0
return u.x*(1.5f - xhalf*u.x*u.x);// Newton step, repeating increases accuracy
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning( pop ) //for Visual C++, restore previous warnings behavior
#endif
......
......@@ -263,12 +263,62 @@ size_t SMETCommon::readLineToVec(const std::string& line_in, std::vector<std::st
return vec_string.size();
}
////////////////////////////////////////////////////////////
//// SMETWriter class
SMETWriter::SMETWriter(const std::string& in_filename, const SMETType& in_type)
: other_header_keys(), ascii_precision(), ascii_width(), header(), mandatory_header_keys(),
filename(in_filename), nodata_string(), smet_type(in_type), nodata_value(-999.), nr_of_fields(0),
julian_field(0), timestamp_field(0), location_wgs84(0), location_epsg(0),
location_in_header(false), location_in_data_wgs84(false), location_in_data_epsg(false),
timestamp_present(false), julian_present(false), file_is_binary(false) {}
timestamp_present(false), julian_present(false), file_is_binary(false), append_mode(false) {}
//what the caller MUST provide:
// * the fields header (for checks)
// * the ascii width and precision
// * nodata_value provided through set_header_value() calls
//HACK: the multipliers and offsets are not handled yet...
//for now, we do the most basic append: all the data after the first insertion point is deleted
SMETWriter::SMETWriter(const std::string& in_filename, const std::string& in_fields, const double& in_nodata)
: other_header_keys(), ascii_precision(), ascii_width(), header(), mandatory_header_keys(),
filename(in_filename), nodata_string(), smet_type(ASCII), nodata_value(in_nodata), nr_of_fields(0),
julian_field(0), timestamp_field(0), location_wgs84(0), location_epsg(0),
location_in_header(false), location_in_data_wgs84(false), location_in_data_epsg(false),
timestamp_present(false), julian_present(false), file_is_binary(false), append_mode(true)
{
SMETReader reader(filename);
smet_type = (reader.isAscii)? ASCII : BINARY;
nodata_string = reader.get_header_value("nodata");
//nodata_value = reader.nodata_value; //we trust the value provided to the constructor
nr_of_fields = reader.nr_of_fields;
julian_field = reader.julian_field;
timestamp_field = reader.timestamp_field;
timestamp_present = reader.timestamp_present;
julian_present = reader.julian_present;
location_wgs84 = reader.location_wgs84;
location_epsg = reader.location_epsg;
location_in_header = reader.location_in_header(WGS84) || reader.location_in_header(EPSG);
location_in_data_wgs84 = reader.location_in_data(WGS84);
location_in_data_epsg = reader.location_in_data(EPSG);
//check that the fields match
std::vector<std::string> vecFields;
SMETCommon::readLineToVec(in_fields, vecFields);
if (nr_of_fields!=vecFields.size()) {
std::ostringstream ss;
ss << "Trying to write " << vecFields.size() << " fields in file '" << filename << "' that has " << nr_of_fields << " fields";
throw SMETException(ss.str(), AT);
}
for (size_t ii=0; ii<nr_of_fields; ii++) {
if (vecFields[ii] != reader.get_field_name(ii)) {
std::ostringstream ss;
ss << "Trying to write field '" << vecFields[ii] << "' at position " << ii << " in file '" << filename << "' when it should be '" << reader.get_field_name(ii);
throw SMETException(ss.str(), AT);
}
}
}
void SMETWriter::set_header_value(const std::string& key, const double& value)
{
......@@ -435,6 +485,10 @@ void SMETWriter::write(const std::vector<std::string>& vec_timestamp, const std:
if (!SMETCommon::validFileAndPath(filename)) throw SMETException("Invalid file name \""+filename+"\"", AT);
errno = 0;
/*if (append_mode) {
}*/
ofstream fout;
fout.open(filename.c_str(), ios::binary);
if (fout.fail()) {
......@@ -445,7 +499,7 @@ void SMETWriter::write(const std::vector<std::string>& vec_timestamp, const std:
write_header(fout); //Write the header info, always in ASCII format
if (nr_of_fields == 0){
if (nr_of_fields == 0) {
fout.close();
return;
}
......@@ -471,8 +525,8 @@ void SMETWriter::write(const std::vector<std::string>& vec_timestamp, const std:
std::vector<double> current_data(nr_of_fields-1);
check_formatting();
if (smet_type == ASCII){
for (size_t ii=0; ii<nr_of_lines; ii++){
if (smet_type == ASCII) {
for (size_t ii=0; ii<nr_of_lines; ii++) {
const size_t offset = ii*(nr_of_fields-1);
if (!data.empty())
copy(data.begin()+offset, data.begin()+offset+nr_of_data_fields, current_data.begin());
......@@ -680,6 +734,9 @@ void SMETWriter::set_precision(const std::vector<int>& vec_precision)
ascii_precision = vec_precision;
}
////////////////////////////////////////////////////////////
//// SMETReader class
const size_t SMETReader::streampos_every_n_lines = 2000; //save streampos every 2000 lines of data
SMETReader::SMETReader(const std::string& in_fname)
......
......@@ -87,6 +87,105 @@ class SMETCommon {
static bool initStaticData(); ///<initialize the static collections
};
/**
* @class SMETWriter
* @brief The SMETWriter class that enables to write a SMET formatted file.
* The user constructs a SMETWriter class and fills in the header values
* Finally the user may call write(...) and pass the data to be written
*
* @author Thomas Egger
* @date 2011-07-14
*/
class SMETWriter {
public:
/**
* @brief The constructor allows to set the filename, the type and whether the file should be gzipped
* @param[in] in_filename The filename of the SMET file to be written
* @param[in] in_type The type of the SMET file, i.e. smet::ASCII or smet::BINARY (default: ASCII)
*/
SMETWriter(const std::string& in_filename, const SMETType& in_type=ASCII);
/**
* @brief The constructor allows to append data to an existing file
* @param[in] in_filename The filename of the SMET file to be written
* @param[in] in_headers The fields that should be written in order to check that we write the
* same data at the same place.
* @param[in] in_nodata Value representing nodata
*/
SMETWriter(const std::string& in_filename, const std::string& in_fields, const double& in_nodata);
/**
* @brief Set a key, value pair in the SMET header (both strings)
* @param[in] key A string key to set in the header (overwritten if already present)
* @param[in] value A string value associated with the key
*/
void set_header_value(const std::string& key, const std::string& value);
/**
* @brief Set a double value for a string key in a SMET header
* @param[in] key A string key to set in the header (overwritten if already present)
* @param[in] value A double value to be converted into a string and stored in the header
*/
void set_header_value(const std::string& key, const double& value);
/**
* @brief Write a SMET file, providing ASCII ISO formatted timestamps and data
* @param[in] vec_timestamp A vector with one ASCII date/time combined string for each line
* @param[in] data All the data to be written sequentially into the columns, the data
* is aligned sequentially, not per line; Total size of the vector:
* Total size of the vector: vec_timestamp.size() * nr_of_fields
* (timestamp is not counted as field)
*/
void write(const std::vector<std::string>& vec_timestamp, const std::vector<double>& data);
/**
* @brief Write a SMET file, providing a vector of doubles
* @param[in] data All the data to be written sequentially into the columns, the data
* is aligned sequentially, not per line;
*/
void write(const std::vector<double>& data);
/**
* @brief Set precision for each field (except timestamp), otherwise a default
* precision of 3 is used for each column
* @param[in] vec_precision Set the precision for every column to be written
* (timestamp is not counted if present)
*/
void set_precision(const std::vector<int>& vec_precision);
/**
* @brief Set width for each field (except timestamp), otherwise a default
* width of 8 is used for each column
* @param[in] vec_width Set the width for every column to be written
* (timestamp is not counted if present)
*/
void set_width(const std::vector<int>& vec_width);
private:
void write_header(std::ofstream& fout); //only writes when all necessary header values are set
void write_data_line_ascii(const std::string& timestamp, const std::vector<double>& data, std::ofstream& fout);
void write_data_line_binary(const std::vector<double>& data, std::ofstream& fout);
bool check_fields(const std::string& key, const std::string& value);
void check_formatting();
bool valid_header_pair(const std::string& key, const std::string& value);
bool valid_header();
std::vector<std::string> other_header_keys; //this vector is used to preserve the sequence of header keys
std::vector<int> ascii_precision, ascii_width;
std::map< std::string, std::string > header;
std::set<std::string> mandatory_header_keys;
std::string filename;
std::string nodata_string;
SMETType smet_type;
double nodata_value;
size_t nr_of_fields, julian_field, timestamp_field;
char location_wgs84, location_epsg;
bool location_in_header, location_in_data_wgs84, location_in_data_epsg;
bool timestamp_present, julian_present;
bool file_is_binary, append_mode;
};
/**
* @class SMETReader
* @brief The SMETReader class enables to read a SMET formatted file.
......@@ -97,6 +196,8 @@ class SMETCommon {
*/
class SMETReader {
public:
friend class SMETWriter; //so the writer can call the reader for handling append mode
/**
* @brief A constructor that will immediately parse the header of the SMET file
* @param[in] in_fname The filename of the SMET file
......@@ -213,7 +314,7 @@ class SMETReader {
* @return a std::string representing the filename
*/
std::string get_filename() const;
private:
void read_data_ascii(std::ifstream& fin, std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data);
void read_data_binary(std::ifstream& fin, std::vector<double>& vec_data);
......@@ -245,96 +346,6 @@ class SMETReader {
bool timestamp_interval, julian_interval; //true if data shall only be read for a time interval
};
/**
* @class SMETWriter
* @brief The SMETWriter class that enables to write a SMET formatted file.
* The user constructs a SMETWriter class and fills in the header values
* Finally the user may call write(...) and pass the data to be written
*
* @author Thomas Egger
* @date 2011-07-14
*/
class SMETWriter {
public:
/**
* @brief The constructor allows to set the filename, the type and whether the file should be gzipped
* @param[in] in_fname The filename of the SMET file to be written
* @param[in] in_type The type of the SMET file, i.e. smet::ASCII or smet::BINARY (default: ASCII)
*/
SMETWriter(const std::string& in_fname, const SMETType& in_type=ASCII);
/**
* @brief Set a key, value pair in the SMET header (both strings)
* @param[in] key A string key to set in the header (overwritten if already present)
* @param[in] value A string value associated with the key
*/
void set_header_value(const std::string& key, const std::string& value);
/**
* @brief Set a double value for a string key in a SMET header
* @param[in] key A string key to set in the header (overwritten if already present)
* @param[in] value A double value to be converted into a string and stored in the header
*/
void set_header_value(const std::string& key, const double& value);
/**
* @brief Write a SMET file, providing ASCII ISO formatted timestamps and data
* @param[in] vec_timestamp A vector with one ASCII date/time combined string for each line
* @param[in] data All the data to be written sequentially into the columns, the data
* is aligned sequentially, not per line; Total size of the vector:
* Total size of the vector: vec_timestamp.size() * nr_of_fields
* (timestamp is not counted as field)
*/
void write(const std::vector<std::string>& vec_timestamp, const std::vector<double>& data);
/**
* @brief Write a SMET file, providing a vector of doubles
* @param[in] data All the data to be written sequentially into the columns, the data
* is aligned sequentially, not per line;
*/
void write(const std::vector<double>& data);
/**
* @brief Set precision for each field (except timestamp), otherwise a default
* precision of 3 is used for each column
* @param[in] vec_precision Set the precision for every column to be written
* (timestamp is not counted if present)
*/
void set_precision(const std::vector<int>& vec_precision);
/**
* @brief Set width for each field (except timestamp), otherwise a default
* width of 8 is used for each column
* @param[in] vec_width Set the width for every column to be written
* (timestamp is not counted if present)
*/
void set_width(const std::vector<int>& vec_width);
private:
void write_header(std::ofstream& fout); //only writes when all necessary header values are set
void write_data_line_ascii(const std::string& timestamp, const std::vector<double>& data, std::ofstream& fout);
void write_data_line_binary(const std::vector<double>& data, std::ofstream& fout);
bool check_fields(const std::string& key, const std::string& value);
void check_formatting();
bool valid_header_pair(const std::string& key, const std::string& value);
bool valid_header();
std::vector<std::string> other_header_keys; //this vector is used to preserve the sequence of header keys
std::vector<int> ascii_precision, ascii_width;
std::map< std::string, std::string > header;
std::set<std::string> mandatory_header_keys;
std::string filename;
std::string nodata_string;
SMETType smet_type;
double nodata_value;
size_t nr_of_fields, julian_field, timestamp_field;
char location_wgs84, location_epsg;
bool location_in_header, location_in_data_wgs84, location_in_data_epsg;
bool timestamp_present, julian_present;
bool file_is_binary;
};
}
#endif
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