WSL/SLF GitLab Repository

Commit 28da250f authored by Mathias Bavay's avatar Mathias Bavay
Browse files

The Config class now has a method getValues() to retrieve in a vector of type...

The Config class now has a method getValues() to retrieve in a vector of type T all values whose keys match a given pattern. This makes it possible to retrieve in one call all the Input::STATIONx values even in the case of discontinuous numbering (issue 341) as well as easily get the number of stations declared in io.ini (issue 220). This number of stations is not guaranteed to work (since some plugins don't list the input stations in io.ini) but should guide memory allocation in user code anyway.

A reference has been fixed in Suntrajectory, redundant errort checking has been removed from GeneratorAlgorithms.
parent 526dc163
......@@ -256,6 +256,24 @@ class Config {
}
}
template <typename T> void getValues(const std::string& keystart, const std::string& section, std::vector<T>& vecT) const
{
vecT.clear();
std::vector< std::string > vecKeys;
const std::string new_section( IOUtils::strToUpper(section) );
const size_t nr_keys = findKeys(vecKeys, keystart, new_section);
for(size_t ii=0; ii<nr_keys; ++ii) {
const std::string full_key = new_section + "::" + vecKeys[ii];
T tmp;
try {
IOUtils::getValueForKey<T>(properties, full_key, tmp, IOUtils::dothrow);
} catch(const std::exception& e){
throw UnknownValueException("[E] Error in "+sourcename+" reading key "+full_key, AT);
}
vecT.push_back(tmp);
}
}
/**
* @brief Function that searches for a given string within the keys of section (default: GENERAL)
......
......@@ -110,6 +110,10 @@ bool SinGenerator::generate(const size_t& param, MeteoData& md)
} else if(type=='d') {
const double julian = md.date.getJulian();
t = (julian - Optim::intPart(julian) - phase) + .25; //watch out: julian day starts at noon!
} else {
std::stringstream ss;
ss << "Invalid period \"" << type << "\" specified for the " << algo << " generator";
throw InvalidArgumentException(ss.str(), AT);
}
const double w = 2.*M_PI;
......
......@@ -91,7 +91,7 @@ class SunTrajectory {
/**
* @class SunMeeus
* @brief Calculate the Sun's position based on the Meeus algorithm.
* See J. Meeus, <i>"Astronomical Algorithms"</i>, 1998, 2nd ed, ISBN 0-943396-61-1.
* See J. Meeus, <i>"Astronomical Algorithms"</i>, 1998, 2nd ed, Willmann-Bell, Inc., Richmond, VA, USA, ISBN 0-943396-61-1.
* A useful reference is also NOAA's spreadsheet at http://www.esrl.noaa.gov/gmd/grad/solcalc/calcdetails.html or
* http://energyworksus.com/solar_installation_position.html for comparing positional data. The technical report
* I. Reda, A. Andreas, <i>"Solar Position Algorithm for Solar Radiation Applications"</i>, 2008, NREL/TP-560-34302
......
......@@ -144,24 +144,8 @@ void BormaIO::readMeteoData(const Date& dateStart, const Date& dateEnd,
void BormaIO::readStationNames()
{
vecStationName.clear();
size_t counter = 1;
string stationname;
do {
stringstream ss;
stationname.clear();
ss << "STATION" << counter;
cfg.getValue(ss.str(), "Input", stationname, IOUtils::nothrow);
if (!stationname.empty()){
vecStationName.push_back(stationname);
}
counter++;
} while (!stationname.empty());
nr_stations = counter - 1;
cfg.getValues("STATION", "INPUT", vecStationName);
nr_stations = vecStationName.size();
}
void BormaIO::getFiles(const std::string& stationname, const Date& start_date, const Date& end_date,
......
......@@ -385,26 +385,7 @@ void ImisIO::parseStationID(const std::string& stationID, std::string& stat_abk,
void ImisIO::readStationIDs(std::vector<std::string>& vecStationID)
{
vecStationID.clear();
size_t current_stationnr = 1;
string current_station;
do {
current_station.clear();
stringstream ss;
ss << "STATION" << current_stationnr;
cfg.getValue(ss.str(), "Input", current_station, IOUtils::nothrow);
if (!current_station.empty()) {
cerr << "\tRead stationname " << ss.str() << ": '" << current_station << "'\n";
if (!isdigit(current_station[0])) {
vecStationID.push_back(current_station);
} else {
cerr << "\t ==> discarded as neither IMIS, nor ENET, nor ANETZ station!\n";
}
}
current_stationnr++;
} while (!current_station.empty());
cfg.getValues("STATION", "INPUT", vecStationID);
if(vecStationID.empty()) {
cerr << "\tNo stations specified for IMISIO... is this what you want?\n";
......
......@@ -152,32 +152,18 @@ void SMETIO::parseInputOutputSection()
cfg.getValue("METEO", "Input", in_meteo, IOUtils::nothrow);
if (in_meteo == "SMET") { //keep it synchronized with IOHandler.cc for plugin mapping!!
cfg.getValue("METEOPATH", "Input", inpath);
size_t counter = 1;
string filename;
do {
stringstream ss;
filename.clear();
ss << "STATION" << counter;
cfg.getValue(ss.str(), "Input", filename, IOUtils::nothrow);
if (!filename.empty()){
if(IOUtils::getExtension(filename)=="") filename += dflt_extension; //default extension
ostringstream file_and_path;
file_and_path << inpath << "/" << filename;
if (!IOUtils::validFileName(file_and_path.str())) //Check whether filename is valid
throw InvalidFileNameException(file_and_path.str(), AT);
vecFiles.push_back(file_and_path.str());
}
counter++;
} while (!filename.empty());
nr_stations = counter - 1;
for (size_t ii=0; ii<vecFiles.size(); ii++){
vec_smet_reader.push_back(smet::SMETReader(vecFiles[ii]));
std::vector<std::string> vecFilenames;
cfg.getValues("STATION", "INPUT", vecFilenames);
for (size_t ii=0; ii<vecFilenames.size(); ii++) {
const string filename = vecFilenames[ii];
const string extension = IOUtils::getExtension(filename);
const std::string file_and_path = (extension!="")? inpath+"/"+filename : inpath+"/"+filename+dflt_extension;
if (!IOUtils::validFileName(file_and_path)) //Check whether filename is valid
throw InvalidFileNameException(file_and_path, AT);
vecFiles.push_back(file_and_path);
vec_smet_reader.push_back(smet::SMETReader(file_and_path));
}
}
......
......@@ -121,7 +121,7 @@ const std::string SNIO::dflt_extension = ".inp";
SNIO::SNIO(const std::string& configfile)
: cfg(configfile),
vecAllStations(), vecIndex(), fin(), fout(),
vecAllStations(), vecFilenames(), vecIndex(), fin(), fout(),
coordin(), coordinparam(), coordout(), coordoutparam(),
in_tz(0.), out_tz(0.), nr_meteoData(min_nr_meteoData),
number_meas_temperatures(0), number_of_solutes (0), vw_drift(false), rho_hn(false),
......@@ -142,7 +142,7 @@ SNIO::SNIO(const std::string& configfile)
SNIO::SNIO(const Config& cfgreader)
: cfg(cfgreader),
vecAllStations(), vecIndex(), fin(), fout(),
vecAllStations(), vecFilenames(), vecIndex(), fin(), fout(),
coordin(), coordinparam(), coordout(), coordoutparam(),
in_tz(0.), out_tz(0.), nr_meteoData(min_nr_meteoData),
number_meas_temperatures(0), number_of_solutes (0), vw_drift(false), rho_hn(false),
......@@ -307,7 +307,7 @@ std::string SNIO::getStationID(const std::string& filename)
//Now get the 2nd column looking something like <{STATIONNAME}Data>
station_id = tmpvec[1].substr(1, tmpvec[1].length()-1); //leaving away the
size_t pos = station_id.find("Data");
const size_t pos = station_id.find("Data");
if (pos != string::npos) {
station_id = station_id.substr(0, pos);
} else {
......@@ -322,46 +322,6 @@ std::string SNIO::getStationID(const std::string& filename)
return station_id;
}
void SNIO::readMetaData()
{
/**
* Parse through the io.ini file and read the desired file names STATION#
*/
vecAllStations.clear();
string metafile, inpath;
cfg.getValue("METAFILE", "Input", metafile, IOUtils::nothrow);
cfg.getValue("METEOPATH", "Input", inpath);
size_t current_stationnr = 1;
string current_station;
do { //Look for STATION1, STATION2, etc
current_station.clear();
stringstream ss;
ss << "STATION" << current_stationnr;
cfg.getValue(ss.str(), "Input", current_station, IOUtils::nothrow);
if ((current_stationnr == 1) && (current_station.empty()))
throw InvalidFormatException("Missing key \"STATION1\" in config: Please specify a SNOWPACK formatted meteo data file", AT);
if (!current_station.empty()){
if(IOUtils::getExtension(current_station)=="") current_station += dflt_extension; //default extension
string station_id = getStationID(inpath+ "/" +current_station);
StationData sd(Coords(), station_id);
if (!metafile.empty()) { //a metafile has been provided, so get metadata
if (readStationMetaData(inpath+ "/" +metafile, station_id, sd) == false) {
stringstream msg;
msg << "No metadata found for station " << station_id << " in " << metafile;
throw NoAvailableDataException(msg.str(), AT);
}
}
vecAllStations.push_back(sd);
}
current_stationnr++;
} while (!current_station.empty());
}
void SNIO::parseMetaDataLine(const std::vector<std::string>& vecLine, StationData& sd)
{
if (vecLine.size() != 6)
......@@ -379,6 +339,41 @@ void SNIO::parseMetaDataLine(const std::vector<std::string>& vecLine, StationDat
sd.setStationData(stationcoord, vecLine[0], vecLine[1]);
}
void SNIO::readMetaData()
{
/**
* Parse through the io.ini file and read the desired file names STATION#
*/
vecAllStations.clear();
vecFilenames.clear();
string metafile, inpath;
cfg.getValue("METAFILE", "Input", metafile, IOUtils::nothrow);
cfg.getValue("METEOPATH", "Input", inpath);
cfg.getValues("STATION", "INPUT", vecFilenames);
vecAllStations.resize(vecFilenames.size());
for (size_t ii=0; ii<vecFilenames.size(); ii++) {
const string filename = vecFilenames[ii];
const string extension = IOUtils::getExtension(filename);
const std::string file_and_path = (extension!="")? inpath+"/"+filename : inpath+"/"+filename+dflt_extension;
const string station_id = getStationID(file_and_path);
if (!IOUtils::validFileName(file_and_path)) //Check whether filename is valid
throw InvalidFileNameException(file_and_path, AT);
StationData sd(Coords(), station_id);
if (!metafile.empty()) { //a metafile has been provided, so get metadata
if (readStationMetaData(inpath+ "/" +metafile, station_id, sd) == false) {
stringstream msg;
msg << "No metadata found for station " << station_id << " in " << metafile;
throw NoAvailableDataException(msg.str(), AT);
}
}
vecAllStations[ii] = sd;
vecFilenames[ii] = file_and_path; //replace short name with usable file name
}
}
void SNIO::readMeteoData(const Date& dateStart, const Date& dateEnd,
std::vector< std::vector<MeteoData> >& vecMeteo, const size_t&)
......@@ -393,7 +388,7 @@ void SNIO::readMeteoData(const Date& dateStart, const Date& dateEnd,
string inpath;
cfg.getValue("METEOPATH", "Input", inpath);
if (vecAllStations.empty())
if (vecAllStations.empty() || vecFilenames.empty())
readMetaData();
vecMeteo.clear();
......@@ -402,36 +397,31 @@ void SNIO::readMeteoData(const Date& dateStart, const Date& dateEnd,
vecIndex.resize(vecAllStations.size());
for (size_t ii=0; ii<vecAllStations.size(); ii++){
string filename, line;
ostringstream ss, file_with_path;
ss << ii+1;
cfg.getValue("STATION"+ss.str(), "Input", filename);
if(IOUtils::getExtension(filename)=="") filename += dflt_extension; //default extension
file_with_path << inpath << "/" << filename;
const std::string file_with_path = vecFilenames[ii];
if ( !IOUtils::validFileName(file_with_path.str()) )
throw InvalidFileNameException(file_with_path.str(), AT);
if ( !IOUtils::fileExists(file_with_path.str()) )
throw FileNotFoundException(file_with_path.str(), AT);
if ( !IOUtils::validFileName(file_with_path) )
throw InvalidFileNameException(file_with_path, AT);
if ( !IOUtils::fileExists(file_with_path) )
throw FileNotFoundException(file_with_path, AT);
fin.clear();
fin.open (file_with_path.str().c_str(), std::ifstream::in);
fin.open (file_with_path.c_str(), std::ifstream::in);
if (fin.fail())
throw FileAccessException(file_with_path.str(), AT);
throw FileAccessException(file_with_path, AT);
if (fin.eof())
throw InvalidFileNameException(file_with_path.str() + ": Empty file", AT);
throw InvalidFileNameException(file_with_path + ": Empty file", AT);
const char eoln = IOUtils::getEoln(fin); //get the end of line character for the file
try {
string line;
getline(fin, line, eoln); //read complete line meta information, ignore it
if (line.length()>=3){
if (line.substr(0,3) != "MTO") //if its not meta information rewind to the beginning
fin.seekg (0, ios::beg);
} else {
throw InvalidFormatException(file_with_path.str() + ": first line in invalid format", AT);
throw InvalidFormatException(file_with_path + ": first line in invalid format", AT);
}
size_t linenr = 0;
......@@ -450,7 +440,7 @@ void SNIO::readMeteoData(const Date& dateStart, const Date& dateEnd,
MeteoData md;
md.meta = vecAllStations[ii];
if (parseMeteoLine(tmpvec, file_with_path.str(), linenr, dateStart, dateEnd, md)){//the date is within the requested range -> we keep the data
if (parseMeteoLine(tmpvec, file_with_path, linenr, dateStart, dateEnd, md)){//the date is within the requested range -> we keep the data
convertUnits(md);
vecMeteo[ii].push_back(md);
......@@ -464,12 +454,12 @@ void SNIO::readMeteoData(const Date& dateStart, const Date& dateEnd,
if (tmpvec.at(0) == "END") {
break; //reached end of MeteoData
} else {
throw InvalidFormatException(file_pos(file_with_path.str(), linenr) + " premature end of line", AT);
throw InvalidFormatException(file_pos(file_with_path, linenr) + " premature end of line", AT);
}
} else if (ncols == 0){
//Ignore empty lines
} else {
throw InvalidFormatException(file_pos(file_with_path.str(), linenr) + " premature end of line", AT);
throw InvalidFormatException(file_pos(file_with_path, linenr) + " premature end of line", AT);
}
}
......
......@@ -81,6 +81,7 @@ class SNIO : public IOInterface {
const Config cfg;
std::vector<StationData> vecAllStations;
std::vector<std::string> vecFilenames;
std::vector< IOUtils::FileIndexer > vecIndex;
std::ifstream fin; //Input file streams
std::ofstream fout;//Output file streams
......
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