WSL/SLF GitLab Repository

DataGenerator.cc 7.31 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/***********************************************************************************/
/*  Copyright 2009 WSL Institute for Snow and Avalanche Research    SLF-DAVOS      */
/***********************************************************************************/
/* This file is part of MeteoIO.
    MeteoIO is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MeteoIO is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with MeteoIO.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <meteoio/DataGenerator.h>

using namespace std;

namespace mio {

/**
*
*/ //explain how to use the generators for the end user

29
30
DataGenerator::DataGenerator(const Config& cfg)
              : mapAlgorithms(), generators_defined(false)
31
{
32
	setAlgorithms(cfg);
33
34
}

35
36
DataGenerator::~DataGenerator()
{ //we have to deallocate the memory allocated by "new GeneratorAlgorithm()"
37
	std::map< std::string, std::vector<GeneratorAlgorithm*> >::iterator it;
38
	for(it=mapAlgorithms.begin(); it!=mapAlgorithms.end(); ++it) {
39
		std::vector<GeneratorAlgorithm*> &vec = it->second;
40
		for(size_t ii=0; ii<vec.size(); ii++)
41
42
43
44
			delete vec[ii];
	}
}

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
DataGenerator& DataGenerator::operator=(const DataGenerator& source)
{
	if(this != &source) {
		mapAlgorithms = source.mapAlgorithms;
		generators_defined = source.generators_defined;
	}
	return *this;
}

/**
 * @brief generate data to fill missing data points.
 * This relies on data generators defined by the user for each meteo parameters.
 * This loops over the defined generators and stops as soon as all missing points
 * have been successfully replaced.
 * @param vecMeteo vector containing one point for each station
 */
void DataGenerator::fillMissing(METEO_SET& vecMeteo) const
{
	if(!generators_defined) return; //no generators defined by the end user

65
	std::map< std::string, std::vector<GeneratorAlgorithm*> >::const_iterator it;
66
	for(it=mapAlgorithms.begin(); it!=mapAlgorithms.end(); ++it) {
67
68
69
		const std::vector<GeneratorAlgorithm*> vecGenerators = it->second;
		for(size_t station=0; station<vecMeteo.size(); station++) { //process this parameter on all stations
			const size_t param = vecMeteo[station].getParameterIndex(it->first);
70
			if(param==IOUtils::npos) continue;
71
72
73

			size_t jj=0;
			while (jj<vecGenerators.size() && vecGenerators[jj]->generate(param, vecMeteo[station]) != true) jj++;
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
		}
	}
}

/**
 * @brief generate data to fill missing data points.
 * This relies on data generators defined by the user for each meteo parameters.
 * This loops over the defined generators and stops as soon as all missing points
 * have been successfully replaced.
 * @param vecVecMeteo vector containing a timeserie for each station
 */
void DataGenerator::fillMissing(std::vector<METEO_SET>& vecVecMeteo) const
{
	if(!generators_defined) return; //no generators defined by the end user

89
	std::map< std::string, std::vector<GeneratorAlgorithm*> >::const_iterator it;
90
	for(it=mapAlgorithms.begin(); it!=mapAlgorithms.end(); ++it) {
91
		const std::vector<GeneratorAlgorithm*> vecGenerators = it->second;
92

93
94
		for(size_t station=0; station<vecVecMeteo.size(); station++) { //process this parameter on all stations
			const size_t param = vecVecMeteo[station][0].getParameterIndex(it->first);
95
			if(param==IOUtils::npos) continue;
96

97
98
			size_t jj=0;
			while (jj<vecGenerators.size() && vecGenerators[jj]->generate(param, vecVecMeteo[station]) != true) jj++;
99
100
101
102
103
104
105
106
107
		}
	}
}

/** @brief build the generators for each meteo parameter
 * By reading the Config object build up a list of user configured algorithms
 * for each MeteoData::Parameters parameter (i.e. each member variable of MeteoData like ta, p, hnw, ...)
 * Concept of this constructor: loop over all MeteoData::Parameters and then look
 * for configuration of interpolation algorithms within the Config object.
108
 * @param cfg configuration object to use for getting the algorithms configuration
109
 */
110
void DataGenerator::setAlgorithms(const Config& cfg)
111
{
112
	set<string> set_of_used_parameters;
113
	getParameters(cfg, set_of_used_parameters);
114
115
116

	set<string>::const_iterator it;
	for (it = set_of_used_parameters.begin(); it != set_of_used_parameters.end(); ++it) {
117
		std::vector<std::string> tmpAlgorithms;
118
119
		const std::string parname = *it;
		const size_t nrOfAlgorithms = getAlgorithmsForParameter(cfg, parname, tmpAlgorithms);
120
121
122
123

		std::vector<GeneratorAlgorithm*> vecGenerators(nrOfAlgorithms);
		for(size_t jj=0; jj<nrOfAlgorithms; jj++) {
			std::vector<std::string> vecArgs;
124
			getArgumentsForAlgorithm(cfg, parname, tmpAlgorithms[jj], vecArgs);
125
126
127
128
			vecGenerators[jj] = GeneratorAlgorithmFactory::getAlgorithm( tmpAlgorithms[jj], vecArgs);
		}

		if(nrOfAlgorithms>0) {
129
			mapAlgorithms[parname] = vecGenerators;
130
131
132
133
134
			generators_defined = true;
		}
	}
}

135
void DataGenerator::getParameters(const Config& cfg, std::set<std::string>& set_parameters)
136
137
138
139
140
141
142
143
144
145
146
147
148
149
{
	std::vector<std::string> vec_keys;
	cfg.findKeys(vec_keys, std::string(), "Generators");

	for (size_t ii=0; ii<vec_keys.size(); ii++) {
		const size_t found = vec_keys[ii].find_first_of(":");
		if (found != std::string::npos){
			const string tmp = vec_keys[ii].substr(0,found);
			set_parameters.insert( IOUtils::strToUpper(tmp) );
		}
	}
}

size_t DataGenerator::getAlgorithmsForParameter(const Config& cfg, const std::string& parname, std::vector<std::string>& vecAlgorithms)
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
{
	// This function retrieves the user defined generator algorithms for
	// parameter 'parname' by querying the Config object
	vecAlgorithms.clear();

	std::vector<std::string> vecKeys;
	cfg.findKeys(vecKeys, parname+"::generators", "Generators");

	if (vecKeys.size() > 1)
		throw IOException("Multiple definitions of " + parname + "::generators in config file", AT);;

	if (vecKeys.empty())
		return 0;

	cfg.getValue(vecKeys.at(0), "Generators", vecAlgorithms, IOUtils::nothrow);

	return vecAlgorithms.size();
}

169
170
size_t DataGenerator::getArgumentsForAlgorithm(const Config& cfg,
                                               const std::string& parname,
171
                                               const std::string& algorithm,
172
                                               std::vector<std::string>& vecArgs)
173
174
175
176
177
178
179
{
	vecArgs.clear();
	cfg.getValue(parname+"::"+algorithm, "Generators", vecArgs, IOUtils::nothrow);

	return vecArgs.size();
}

180
const std::string DataGenerator::toString() const {
181
	std::ostringstream os;
182
	os << "<DataGenerator>\n";
183
	os << "Generators defined: " << generators_defined << "\n";
184
	os << "User list of generators:\n";
185
	std::map< std::string, std::vector<GeneratorAlgorithm*> >::const_iterator iter = mapAlgorithms.begin();
186
	for (; iter != mapAlgorithms.end(); ++iter) {
187
		os << setw(10) << iter->first << " :: ";
188
		for(size_t jj=0; jj<iter->second.size(); jj++) {
189
190
191
192
193
194
			os << iter->second[jj]->getAlgo() << " ";
		}
		os << "\n";
	}

	os << "</DataGenerator>\n";
195
	return os.str();
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
}


#ifdef _POPC_
#include "marshal_meteoio.h"
using namespace mio; //HACK for POPC
void DataGenerator::Serialize(POPBuffer &buf, bool pack)
{
	/*if (pack)
	{

	}
	else
	{

	}*/
}
#endif

} //namespace