WSL/SLF GitLab Repository

Commit 8d46d04d authored by Thomas Egger's avatar Thomas Egger
Browse files

Performance boost: Redesign of class MeteoData. The individual public double...

Performance boost: Redesign of class MeteoData. The individual public double members like tss, ta, rh have been removed and instead of the rather complicated internal representation with the help of std::map and pointers, the MeteoData object now holds all its important information in one double vector (meteo data) and one string vector (parameter names). Thus the overloaded copy constructor could be slashed radically. This leads to huge performance gains, especially when dealing with huge vectors of MeteoData (which are needed for filtering, resampling, etc).

Furthermore the access to the meteo parameters has been simpleified by overloading the operator(), replacing the old .param(size_t index) and .param(string paramname) functions:

MeteoData md;
double ta = md(MeteoData::TA);

OR

double ta = md("TA");

These changes were propagated into all of MeteoIO.
parent aac3021a
......@@ -201,15 +201,17 @@ void A3DIO::convertUnits(MeteoData& meteo)
meteo.standardizeNodata(plugin_nodata);
//converts C to Kelvin, converts RH to [0,1]
if(meteo.ta!=IOUtils::nodata) {
meteo.ta=C_TO_K(meteo.ta);
}
if(meteo.tsg!=IOUtils::nodata) {
meteo.tsg=C_TO_K(meteo.tsg);
}
if(meteo.rh!=IOUtils::nodata) {
meteo.rh /= 100.;
}
double& ta = meteo(MeteoData::TA);
if (ta != IOUtils::nodata)
ta = C_TO_K(ta);
double& tsg = meteo(MeteoData::TSG);
if (tsg != IOUtils::nodata)
tsg = C_TO_K(tsg);
double& rh = meteo(MeteoData::RH);
if (rh != IOUtils::nodata)
rh /= 100.;
}
void A3DIO::read1DStation(std::string& file_1d, StationData& sd)
......@@ -617,30 +619,30 @@ void A3DIO::read2DMeteoData(const std::string& filename, const std::string& para
tmpmd.date = tmp_date;
if (parameter == "nswc") {
if (!IOUtils::convertString(tmpmd.hnw, tmpvec[ii], std::dec)) {
if (!IOUtils::convertString(tmpmd(MeteoData::HNW), tmpvec[ii], std::dec)) {
cleanup();
throw ConversionFailedException("For hnw value in " + filename + " for date " + tmpmd.date.toString(Date::FULL), AT);
}
} else if (parameter == "rh") {
if (!IOUtils::convertString(tmpmd.rh, tmpvec[ii], std::dec)) {
if (!IOUtils::convertString(tmpmd(MeteoData::RH), tmpvec[ii], std::dec)) {
cleanup();
throw ConversionFailedException("For rh value in " + filename + " for date " + tmpmd.date.toString(Date::FULL), AT);
}
} else if (parameter == "ta") {
if (!IOUtils::convertString(tmpmd.ta, tmpvec[ii], std::dec)) {
if (!IOUtils::convertString(tmpmd(MeteoData::TA), tmpvec[ii], std::dec)) {
cleanup();
throw ConversionFailedException("For ta value in " + filename + " for date " + tmpmd.date.toString(Date::FULL), AT);
}
} else if (parameter == "vw") {
if (!IOUtils::convertString(tmpmd.vw, tmpvec[ii], std::dec)) {
if (!IOUtils::convertString(tmpmd(MeteoData::VW), tmpvec[ii], std::dec)) {
cleanup();
throw ConversionFailedException("For vw value in " + filename + " for date " + tmpmd.date.toString(Date::FULL), AT);
}
} else if (parameter == "dw") {
if (!IOUtils::convertString(tmpmd.dw, tmpvec[ii], std::dec)) {
if (!IOUtils::convertString(tmpmd(MeteoData::DW), tmpvec[ii], std::dec)) {
cleanup();
throw ConversionFailedException("For dw value in " + filename + " for date " + tmpmd.date.toString(Date::FULL), AT);
}
......@@ -807,30 +809,30 @@ int A3DIO::create1DFile(const std::vector< std::vector<MeteoData> >& data)
file.fill('0');
file << setw(4) << yyyy << " " << setw(2) << mm << " " << setw(2) << dd << " " << setw(2) << hh << " ";
file.fill(' ');
if(data[ii][j].ta == IOUtils::nodata)
if(data[ii][j](MeteoData::TA) == IOUtils::nodata)
file << setw(6) << setprecision(0) << IOUtils::nodata << " ";
else
file << setw(6) << setprecision(2) << K_TO_C(data[ii][j].ta) << " ";
if(data[ii][j].iswr == IOUtils::nodata)
file << setw(6) << setprecision(2) << K_TO_C(data[ii][j](MeteoData::TA)) << " ";
if(data[ii][j](MeteoData::ISWR) == IOUtils::nodata)
file << setw(6) << setprecision(0) << IOUtils::nodata << " ";
else
file << setw(6) << setprecision(2) << data[ii][j].iswr << " ";
if(data[ii][j].vw == IOUtils::nodata)
file << setw(6) << setprecision(2) << data[ii][j](MeteoData::ISWR) << " ";
if(data[ii][j](MeteoData::VW) == IOUtils::nodata)
file << setw(6) << setprecision(0) << IOUtils::nodata << " ";
else
file << setw(6) << setprecision(2) << data[ii][j].vw << " ";
if(data[ii][j].rh == IOUtils::nodata)
file << setw(6) << setprecision(2) << data[ii][j](MeteoData::VW) << " ";
if(data[ii][j](MeteoData::RH) == IOUtils::nodata)
file << setw(6) << setprecision(0) << IOUtils::nodata << " ";
else
file << setw(6) << setprecision(2) << data[ii][j].rh * 100. << " ";
if(data[ii][j].ilwr == IOUtils::nodata)
file << setw(6) << setprecision(2) << data[ii][j](MeteoData::RH) * 100. << " ";
if(data[ii][j](MeteoData::ILWR) == IOUtils::nodata)
file << setw(6) << setprecision(0) << IOUtils::nodata << " ";
else
file << setw(6) << setprecision(2) << data[ii][j].ilwr << " ";
if(data[ii][j].hnw == IOUtils::nodata)
file << setw(6) << setprecision(2) << data[ii][j](MeteoData::ILWR) << " ";
if(data[ii][j](MeteoData::HNW) == IOUtils::nodata)
file << setw(6) << setprecision(0) << IOUtils::nodata << "\n";
else
file << setw(6) << setprecision(2) << data[ii][j].hnw << "\n";
file << setw(6) << setprecision(2) << data[ii][j](MeteoData::HNW) << "\n";
}
file.close();
}
......@@ -917,7 +919,7 @@ int A3DIO::write2DmeteoFile(const std::vector< std::vector<MeteoData> >& data,
file << setw(4) << year << " " << setw(2) << month << " " << setw(2) << day << " " << setw(2) << hour;
file.fill(' ');
for(size_t j=0; j<sta_nr; j++) {
double value = data[j][ii].param(parindex);
double value = data[j][ii](parindex);
if(value==IOUtils::nodata) {
file << " " << setw(7) << setprecision(0) << IOUtils::nodata;
} else {
......
......@@ -77,19 +77,6 @@ Date::Date(const time_t& in_time, const bool& in_dst) {
dst = false;
setDate(in_time, in_dst);
}
//HACK: is it needed? Why paroc_base instead of POPC??
/**
* @brief Copy constructor.
* @param in_date Date object to copy
*/
#ifdef _POPC_
Date::Date(const Date& in_date) : paroc_base()
#else
Date::Date(const Date& in_date)
#endif
{
setDate(in_date);
}
/**
* @brief Date constructor by elements.
......
......@@ -94,7 +94,6 @@ class Date {
Date(const double& julian_in, const double& in_timezone, const bool& in_dst=false);
Date(const int& year, const int& month, const int& day, const int& hour, const int& minute, const double& in_timezone, const bool& in_dst=false);
Date(const time_t&, const bool& in_dst=false);
Date(const Date& in_date);
void setFromSys();
void setTimeZone(const double& in_timezone, const bool& in_dst=false);
......
......@@ -194,7 +194,7 @@ bool FilterAlgorithms::getWindowData(const std::string& filtername, const std::v
//Push all relevant data elements into the vector vecWindow
//cout << "Start: " << startposition << " End: " << endposition << endl;
for (unsigned int ii=startposition+1; (ii--) > endposition; ){
const double& tmp = vecM[ii].param(paramindex);
const double& tmp = vecM[ii](paramindex);
if (tmp != IOUtils::nodata) {
vecWindow.push_back(tmp);
if (vecDate != NULL) (*vecDate).push_back(vecM[ii].date);
......@@ -266,19 +266,19 @@ void FilterAlgorithms::ExpSmoothingProcess(const std::vector<MeteoData>& vecM, c
if (windowposition == "left"){
vecTmpWindow.erase(vecTmpWindow.begin()+posfind+1, vecTmpWindow.end()); //delete all after posfind
vecWindowM[ii].param(paramindex) = ExpSmoothingAlgorithm(vecTmpWindow, paramindex, alpha);
//cout << "ExpSmoothing: " << vecWindowM[ii].param(paramindex) << endl;
vecWindowM[ii](paramindex) = ExpSmoothingAlgorithm(vecTmpWindow, paramindex, alpha);
//cout << "ExpSmoothing: " << vecWindowM[ii](paramindex) << endl;
} else if (windowposition == "right"){
vecTmpWindow.erase(vecTmpWindow.begin(), vecTmpWindow.begin()+posfind); //delete all before posfind
std::reverse(vecTmpWindow.begin(), vecTmpWindow.end()); //reverse the vector, posfind most significant
vecWindowM[ii].param(paramindex) = ExpSmoothingAlgorithm(vecTmpWindow, paramindex, alpha);
//cout << "ExpSmoothing: " << vecWindowM[ii].param(paramindex) << endl;
vecWindowM[ii](paramindex) = ExpSmoothingAlgorithm(vecTmpWindow, paramindex, alpha);
//cout << "ExpSmoothing: " << vecWindowM[ii](paramindex) << endl;
} else { //centered window - regroup according to time difference with posfind
for (unsigned int jj=0; jj<vecTmpWindow.size(); jj++)
vecTmpWindow[jj].date=Date(abs(vecWindowM[ii].date.getJulianDate() - vecTmpWindow[jj].date.getJulianDate()));
std::sort(vecTmpWindow.begin(), vecTmpWindow.end(), compareMeteoData);
vecWindowM[ii].param(paramindex) = ExpSmoothingAlgorithm(vecTmpWindow, paramindex, alpha);
//cout << "ExpSmoothing: " << vecWindowM[ii].param(paramindex) << endl;
vecWindowM[ii](paramindex) = ExpSmoothingAlgorithm(vecTmpWindow, paramindex, alpha);
//cout << "ExpSmoothing: " << vecWindowM[ii](paramindex) << endl;
}
}
}
......@@ -321,19 +321,19 @@ void FilterAlgorithms::WMASmoothingProcess(const std::vector<MeteoData>& vecM, c
if (windowposition == "left"){
vecTmpWindow.erase(vecTmpWindow.begin()+posfind+1, vecTmpWindow.end()); //delete all after posfind
vecWindowM[ii].param(paramindex) = WMASmoothingAlgorithm(vecTmpWindow, paramindex);
//cout << "WMASmoothing: " << vecWindowM[ii].param(paramindex) << endl;
vecWindowM[ii](paramindex) = WMASmoothingAlgorithm(vecTmpWindow, paramindex);
//cout << "WMASmoothing: " << vecWindowM[ii](paramindex) << endl;
} else if (windowposition == "right"){
vecTmpWindow.erase(vecTmpWindow.begin(), vecTmpWindow.begin()+posfind); //delete all before posfind
std::reverse(vecTmpWindow.begin(), vecTmpWindow.end()); //reverse the vector, posfind most significant
vecWindowM[ii].param(paramindex) = WMASmoothingAlgorithm(vecTmpWindow, paramindex);
//cout << "WMASmoothing: " << vecWindowM[ii].param(paramindex) << endl;
vecWindowM[ii](paramindex) = WMASmoothingAlgorithm(vecTmpWindow, paramindex);
//cout << "WMASmoothing: " << vecWindowM[ii](paramindex) << endl;
} else { //centered window - regroup according to time difference with posfind
for (unsigned int jj=0; jj<vecTmpWindow.size(); jj++)
vecTmpWindow[jj].date=Date(abs(vecWindowM[ii].date.getJulianDate() - vecTmpWindow[jj].date.getJulianDate()));
std::sort(vecTmpWindow.begin(), vecTmpWindow.end(), compareMeteoData);
vecWindowM[ii].param(paramindex) = WMASmoothingAlgorithm(vecTmpWindow, paramindex);
//cout << "WMASmoothing: " << vecWindowM[ii].param(paramindex) << endl;
vecWindowM[ii](paramindex) = WMASmoothingAlgorithm(vecTmpWindow, paramindex);
//cout << "WMASmoothing: " << vecWindowM[ii](paramindex) << endl;
}
}
}
......@@ -459,7 +459,7 @@ double FilterAlgorithms::ExpSmoothingAlgorithm(const std::vector<MeteoData>& vec
bool initCompleted = false;
double expavg = IOUtils::nodata;
for (unsigned int ii=0; ii<vecMeteo.size(); ii++){
const double& currentval = vecMeteo[ii].param(paramindex);
const double& currentval = vecMeteo[ii](paramindex);
if (currentval != IOUtils::nodata){
if (!initCompleted){
expavg = currentval;
......@@ -492,7 +492,7 @@ double FilterAlgorithms::WMASmoothingAlgorithm(const std::vector<MeteoData>& vec
unsigned int counter = 0;
for (unsigned int ii=0; ii<vecMeteo.size(); ii++){
const double& currentval = vecMeteo[ii].param(paramindex);
const double& currentval = vecMeteo[ii](paramindex);
if (currentval != IOUtils::nodata){
if (wma == IOUtils::nodata) wma = 0.0; //initialize wma here, otherwise it could be nodata
......@@ -528,7 +528,7 @@ void FilterAlgorithms::RateFilter(const std::vector<MeteoData>& /*vecM*/, const
int last_good=-1;
for(unsigned int ii=0; ii<vecWindowM.size(); ii++) {
if(vecWindowM[ii].param(paramindex)!=IOUtils::nodata) {
if(vecWindowM[ii](paramindex)!=IOUtils::nodata) {
last_good=ii;
break;
}
......@@ -538,9 +538,9 @@ void FilterAlgorithms::RateFilter(const std::vector<MeteoData>& /*vecM*/, const
const unsigned int start=last_good+1;
for(unsigned int ii=start; ii<vecWindowM.size(); ii++) {
double& value = vecWindowM[ii].param(paramindex);
double& value = vecWindowM[ii](paramindex);
const double curr_time = vecWindowM[ii].date.getJulianDate();
const double prev_value = vecWindowM[last_good].param(paramindex);
const double prev_value = vecWindowM[last_good](paramindex);
const double prev_time = vecWindowM[last_good].date.getJulianDate();
if(value==IOUtils::nodata) {
......@@ -579,7 +579,7 @@ void FilterAlgorithms::MinMaxFilter(const std::vector<MeteoData>& /*vecM*/, cons
//Run actual MinMax filter over all relevant meteo data
for(unsigned int ii=0; ii<vecWindowM.size(); ii++){
double& value = vecWindowM[ii].param(paramindex);
double& value = vecWindowM[ii](paramindex);
if (value == IOUtils::nodata) continue;
......@@ -617,7 +617,7 @@ void FilterAlgorithms::MinValueFilter(const std::vector<MeteoData>& /*vecM*/, co
//Run actual MinValue filter over all relevant meteo data
for(unsigned int ii=0; ii<vecWindowM.size(); ii++){
double& value = vecWindowM[ii].param(paramindex);
double& value = vecWindowM[ii](paramindex);
if (value == IOUtils::nodata) continue;
......@@ -649,7 +649,7 @@ void FilterAlgorithms::MaxValueFilter(const std::vector<MeteoData>& /*vecM*/, co
//Run actual MaxValue filter over all relevant meteo data
for(unsigned int ii=0; ii<vecWindowM.size(); ii++){
double& value = vecWindowM[ii].param(paramindex);
double& value = vecWindowM[ii](paramindex);
if (value == IOUtils::nodata) continue;
......@@ -680,7 +680,7 @@ void FilterAlgorithms::MedianAbsoluteDeviationFilter(const std::vector<MeteoData
//NOTE Problem: if a bunch of identical values ~median are part of the data set, mad will be 0
//and therefore we will reject all values that are != median
for (unsigned int ii=0; ii<vecWindowM.size(); ii++){
double& value = vecWindowM[ii].param(paramindex);
double& value = vecWindowM[ii](paramindex);
if (value == IOUtils::nodata) //No need to run filter for nodata points
continue;
......@@ -726,7 +726,7 @@ void FilterAlgorithms::StandardDeviationFilter(const std::vector<MeteoData>& vec
const MeteoData::Parameters& paramindex, std::vector<MeteoData>& vecWindowM)
{
for (unsigned int ii=0; ii<vecWindowM.size(); ii++){
double& value = vecWindowM[ii].param(paramindex);
double& value = vecWindowM[ii](paramindex);
if (value == IOUtils::nodata) //No need to run filter for nodata points
continue;
......@@ -772,7 +772,7 @@ void FilterAlgorithms::Tukey53HFilter(const std::vector<MeteoData>& vecM, const
const double k = 3.;
for (unsigned int ii=4; ii<vecWindowM.size()-4; ii++) {
double& value = vecWindowM[ii].param(paramindex);
double& value = vecWindowM[ii](paramindex);
if (value == IOUtils::nodata) //No need to run filter for nodata points
continue;
......@@ -792,7 +792,7 @@ void FilterAlgorithms::Tukey53HFilter(const std::vector<MeteoData>& vecM, const
std::vector<double> u;
for(int k=-2; k<=2; k++) {
const int index = ii + k + j + i;
const double value = vecWindowM[index].param(paramindex);
const double value = vecWindowM[index](paramindex);
if(value!=IOUtils::nodata)
u.push_back( value );
}
......@@ -861,7 +861,7 @@ void FilterAlgorithms::AccumulateProcess(const std::vector<MeteoData>& vecM, con
double sum = 0.0;
bool exist=false;
while((vecM[pos].date + deltatime) > vecM[startpos].date){
const double& val = vecM[pos].param(paramindex);
const double& val = vecM[pos](paramindex);
if (val != IOUtils::nodata) {
sum += val;
......@@ -872,10 +872,10 @@ void FilterAlgorithms::AccumulateProcess(const std::vector<MeteoData>& vecM, con
else break;
}
if(exist==true)
vecWindowM[ii].param(paramindex) = sum;
vecWindowM[ii](paramindex) = sum;
else
vecWindowM[ii].param(paramindex) = IOUtils::nodata;
//cout << "sum: " << vecWindowM[ii].param(paramindex) << endl;
vecWindowM[ii](paramindex) = IOUtils::nodata;
//cout << "sum: " << vecWindowM[ii](paramindex) << endl;
} else {
throw IOException("Could not find an element to start accumulation", AT);
}
......@@ -925,7 +925,7 @@ void FilterAlgorithms::MedianAvgProcess(const std::vector<MeteoData>& vecM, cons
double median = IOUtils::nodata;
try {
median = Interpol1D::getMedian(vecWindow);
vecWindowM[ii].param(paramindex) = median;
vecWindowM[ii](paramindex) = median;
} catch(const exception&){
continue; //the median calculation did not work out, filter is not applied, value unchanged
}
......@@ -973,7 +973,7 @@ void FilterAlgorithms::MeanAvgProcess(const std::vector<MeteoData>& vecM, const
double mean = IOUtils::nodata;
try {
mean = Interpol1D::arithmeticMean(vecWindow);
vecWindowM[ii].param(paramindex) = mean;
vecWindowM[ii](paramindex) = mean;
} catch(const exception&){
continue; //the mean calculation did not work out, filter is not applied, value unchanged
}
......@@ -1052,8 +1052,8 @@ void FilterAlgorithms::WindAvgProcess(const std::vector<MeteoData>& vecM, const
meandirection = fmod( atan2(ve,vn) * 180. / M_PI + 360. , 360.); // turn into degrees [0;360)
}
vecWindowM[ii].param(MeteoData::VW) = meanspeed;
vecWindowM[ii].param(MeteoData::DW) = meandirection;
vecWindowM[ii](MeteoData::VW) = meanspeed;
vecWindowM[ii](MeteoData::DW) = meandirection;
}
}
......
......@@ -123,7 +123,7 @@ size_t InterpolationAlgorithm::getData(const MeteoData::Parameters& param,
vecMeta.clear();
for (size_t ii=0; ii<vecMeteo.size(); ii++){
const double& val = vecMeteo[ii].param(param);
const double& val = vecMeteo[ii](param);
if (val != IOUtils::nodata){
vecData.push_back(val);
vecMeta.push_back(vecMeteo[ii].meta);
......@@ -419,9 +419,9 @@ void RHAlgorithm::initialize(const MeteoData::Parameters& in_param) {
nrOfMeasurments = 0;
for (size_t ii=0; ii<vecMeteo.size(); ii++){
if ((vecMeteo[ii].rh != IOUtils::nodata) && (vecMeteo[ii].ta != IOUtils::nodata)){
vecDataTA.push_back(vecMeteo[ii].ta);
vecDataRH.push_back(vecMeteo[ii].rh);
if ((vecMeteo[ii](MeteoData::RH) != IOUtils::nodata) && (vecMeteo[ii](MeteoData::TA) != IOUtils::nodata)){
vecDataTA.push_back(vecMeteo[ii](MeteoData::TA));
vecDataRH.push_back(vecMeteo[ii](MeteoData::RH));
vecMeta.push_back(vecMeteo[ii].meta);
nrOfMeasurments++;
}
......@@ -486,8 +486,8 @@ void ILWRAlgorithm::initialize(const MeteoData::Parameters& in_param) {
nrOfMeasurments = 0;
for (size_t ii=0; ii<vecMeteo.size(); ii++){
if ((vecMeteo[ii].ilwr != IOUtils::nodata) && (vecMeteo[ii].ta != IOUtils::nodata)){
vecDataEA.push_back( Atmosphere::blkBody_Emissivity( vecMeteo[ii].ilwr, vecMeteo[ii].ta) );
if ((vecMeteo[ii](MeteoData::ILWR) != IOUtils::nodata) && (vecMeteo[ii](MeteoData::TA) != IOUtils::nodata)){
vecDataEA.push_back( Atmosphere::blkBody_Emissivity( vecMeteo[ii](MeteoData::ILWR), vecMeteo[ii](MeteoData::TA)) );
vecMeta.push_back(vecMeteo[ii].meta);
nrOfMeasurments++;
}
......@@ -571,9 +571,9 @@ void SimpleWindInterpolationAlgorithm::initialize(const MeteoData::Parameters& i
nrOfMeasurments = 0;
for (size_t ii=0; ii<vecMeteo.size(); ii++){
if ((vecMeteo[ii].vw != IOUtils::nodata) && (vecMeteo[ii].dw != IOUtils::nodata)){
vecDataVW.push_back(vecMeteo[ii].vw);
vecDataDW.push_back(vecMeteo[ii].dw);
if ((vecMeteo[ii](MeteoData::VW) != IOUtils::nodata) && (vecMeteo[ii](MeteoData::DW) != IOUtils::nodata)){
vecDataVW.push_back(vecMeteo[ii](MeteoData::VW));
vecDataDW.push_back(vecMeteo[ii](MeteoData::DW));
vecMeta.push_back(vecMeteo[ii].meta);
nrOfMeasurments++;
}
......
......@@ -26,6 +26,7 @@ namespace mio {
************************************************************/
const size_t MeteoData::nrOfParameters = MeteoData::lastparam - MeteoData::firstparam + 1;
map<size_t, string> MeteoData::static_meteoparamname;
std::vector<std::string> MeteoData::s_default_paramname;
const bool MeteoData::__init = MeteoData::initStaticData();
bool MeteoData::initStaticData()
......@@ -45,6 +46,20 @@ bool MeteoData::initStaticData()
static_meteoparamname[RSWR] = "RSWR";
static_meteoparamname[P] = "P";
s_default_paramname.push_back("TA");
s_default_paramname.push_back("RH");
s_default_paramname.push_back("VW");
s_default_paramname.push_back("DW");
s_default_paramname.push_back("VW_MAX");
s_default_paramname.push_back("ISWR");
s_default_paramname.push_back("RSWR");
s_default_paramname.push_back("ILWR");
s_default_paramname.push_back("HS");
s_default_paramname.push_back("HNW");
s_default_paramname.push_back("TSG");
s_default_paramname.push_back("TSS");
s_default_paramname.push_back("P");
return true;
}
......@@ -56,85 +71,38 @@ const std::string& MeteoData::getParameterName(const size_t& parindex)
return MeteoData::static_meteoparamname[parindex];
}
/************************************************************
* non-static section *
************************************************************/
const std::string& MeteoData::getNameForParameter(const size_t& parindex) const
{
std::map<size_t, std::string>::const_iterator it;
it = meteoparamname.find(parindex);
#ifndef NOSAFECHECKS
if (it == meteoparamname.end())
if (parindex >= nrOfAllParameters)
throw IndexOutOfBoundsException("Trying to get name for parameter that does not exist", AT);
#endif
return it->second;
return param_name[parindex];
}
void MeteoData::associateMemberVariables()
bool MeteoData::param_exists(const std::string& i_paramname) const
{
//The following mapping needs to be done for every instance of MeteoData
meteoparam[TA] = &ta;
meteoparam[ISWR] = &iswr;
meteoparam[VW] = &vw;
meteoparam[DW] = &dw;
meteoparam[VW_MAX] = &vw_max;
meteoparam[RH] = &rh;
meteoparam[ILWR] = &ilwr;
meteoparam[HNW] = &hnw;
meteoparam[TSG] = &tsg;
meteoparam[TSS] = &tss;
meteoparam[HS] = &hs;
meteoparam[RSWR] = &rswr;
meteoparam[P] = &p;
}
size_t current_size = param_name.size();
for (size_t ii = 0; ii<current_size; ii++) {
if (param_name[ii] == i_paramname)
return true;
}
void MeteoData::initParameterMap()
{//NOTE: any performace improvement here would make a big difference...
//Associate unsigned int value and a string representation of a meteo parameter
meteoparamname[TA] = "TA";
meteoparamname[ISWR] = "ISWR";
meteoparamname[VW] = "VW";
meteoparamname[DW] = "DW";
meteoparamname[VW_MAX] = "VW_MAX";
meteoparamname[RH] = "RH";
meteoparamname[ILWR] = "ILWR";
meteoparamname[HNW] = "HNW";
meteoparamname[TSG] = "TSG";
meteoparamname[TSS] = "TSS";
meteoparamname[HS] = "HS";
meteoparamname[RSWR] = "RSWR";
meteoparamname[P] = "P";
//The following mapping needs to be done for every instance of MeteoData
associateMemberVariables();
nrOfAllParameters = meteoparam.size();
//Go through all parameters in <int,string> map and store them into <string,double*> map
map<size_t, string>::const_iterator tmpit;
for (tmpit = meteoparamname.begin(); tmpit != meteoparamname.end(); tmpit++)
mapParameterByName[tmpit->second] = meteoparam[tmpit->first];
//Check for inconsistency between enum Parameters and the two maps meteoparam and meteoparamname
if ((meteoparam.size() != meteoparamname.size()) || (meteoparam.size() != getNrOfParameters()))
throw IOException("Inconsistency within class MeteoData: Check function initParameterMap()", AT);
return false;
}
void MeteoData::addParameter(const std::string& i_paramname)
{
//Check whether name is taken
std::map<std::string, double*>::const_iterator it;
it = mapParameterByName.find(i_paramname);
if (it != mapParameterByName.end())
throw IndexOutOfBoundsException("Trying to add a meteo parameter that already exists: " + i_paramname, AT);
//Add parameter to extraparameters map
extraparameters[i_paramname] = IOUtils::nodata;
meteoparamname[getNrOfParameters()] = i_paramname;
meteoparam[getNrOfParameters()] = &extraparameters[i_paramname];
mapParameterByName[i_paramname] = &extraparameters[i_paramname];
//check if name is already taken
if (param_exists(i_paramname))
return; //do nothing
//add parameter
param_name.push_back(i_paramname);
data.push_back(IOUtils::nodata);
//Increase nrOfAllParameters
nrOfAllParameters++;
......@@ -145,65 +113,16 @@ size_t MeteoData::getNrOfParameters() const
return nrOfAllParameters;
}
MeteoData::MeteoData() : date(0.0, 0.), resampled(false)
MeteoData::MeteoData() : date(0.0, 0.), resampled(false), nrOfAllParameters(MeteoData::nrOfParameters)
{
initParameterMap(); //must be first statement
initAllParameters();
param_name = s_default_paramname;
data = vector<double>(nrOfAllParameters, IOUtils::nodata);
}
MeteoData::MeteoData(const Date& date_in) : date(date_in), resampled(false)
MeteoData::MeteoData(const Date& date_in) : date(date_in), resampled(false), nrOfAllParameters(MeteoData::nrOfParameters)
{
initParameterMap(); //must be first statement
initAllParameters();
}
#ifdef _POPC_
MeteoData::MeteoData(const MeteoData& md) : paroc_base()
#else
MeteoData::MeteoData(const MeteoData& md)
#endif
{
*this = md; //reverts to the operator= implementation
}
MeteoData& MeteoData::operator=(const MeteoData& rhs)
{
//NOTE: any performace improvement here would make a big difference...
if (this == &rhs) //Test self assignment
return *this;
date = rhs.date;
meta = rhs.meta;
resampled = rhs.resampled;
extraparameters = rhs.extraparameters;
meteoparamname = rhs.meteoparamname;
associateMemberVariables(); //sets the pointers for the standard parameters in the meteoparam map
std::map<size_t, double*>::const_iterator tmpit;
for (size_t ii=0; ii<=MeteoData::lastparam; ii++) {
//go through meteoparameters and copy them by value
double* val = meteoparam[ii];
tmpit = rhs.meteoparam.find(ii);
*val = *(tmpit->second); //copy by value
mapParameterByName[meteoparamname[ii]] = val; //copy pointer into mapParameterByName
}
for (size_t ii=MeteoData::lastparam+1; ii<rhs.getNrOfParameters(); ii++) {
//for the extraparameters other measures are necessary