16 #include <TBufferJSON.h>
25 namespace experimental {
29 const std::vector<real_t>& old_x_values,
30 std::vector<real_t>& new_x_values)
const {
31 new_x_values.resize(old_x_values.size());
32 for (
size_t i = 0; i < old_x_values.size(); i++) {
39 const std::vector<real_t>& old_y_values,
40 std::vector<real_t>& new_y_values)
const {
41 new_y_values.resize(old_y_values.size());
42 for (
size_t i = 0; i < old_y_values.size(); i++) {
49 const std::vector<real_t>& old_y_error_low,
50 std::vector<real_t>& new_y_error_low)
const {
51 new_y_error_low.resize(old_y_error_low.size());
52 for (
size_t i = 0; i < old_y_error_low.size(); i++) {
60 const std::vector<real_t>& old_y_error_high,
61 std::vector<real_t>& new_y_error_high)
const {
62 new_y_error_high.resize(old_y_error_high.size());
63 for (
size_t i = 0; i < old_y_error_high.size(); i++) {
98 : ycollector(ycollector), xcollector(xcollector) {}
103 : y_reducer_collector(y_reducer_collector), xcollector(xcollector) {}
107 : ycollector(other.ycollector),
108 xcollector(other.xcollector),
109 x_values(other.x_values),
110 y_values(other.y_values),
111 y_error_low(other.y_error_low),
112 y_error_high(other.y_error_high) {
120 if (
this == &other) {
137 if (y_reducer_collector) {
138 delete y_reducer_collector;
147 "The time series objects that should be merged do not "
148 "contain the same entries. Operation aborted.");
149 return std::numeric_limits<real_t>::infinity();
151 for (
auto& p : ts1.
data_) {
152 if (ts2.
data_.find(p.first) == ts2.
data_.end()) {
154 "The time series objects that should be merged do not "
155 "contain the same entries. Operation aborted");
156 return std::numeric_limits<real_t>::infinity();
160 for (
auto& pair : ts1.
data_) {
161 auto& key = pair.first;
163 auto& xref = ts1.
data_.at(key).x_values;
164 auto& xcurrent = ts2.
data_.at(key).x_values;
165 if (xref.size() != xcurrent.size()) {
167 "The time series objects for entry (", key,
168 ") have different x_values. Operation aborted.");
169 return std::numeric_limits<real_t>::infinity();
171 for (uint64_t j = 0; j < xref.size(); ++j) {
172 if (std::abs(xref[j] - xcurrent[j]) > 1e-5) {
174 "The time series objects for entry (", key,
175 ") have different x_values. Operation aborted.");
176 return std::numeric_limits<real_t>::infinity();
183 for (
auto& pair : ts1.
data_) {
184 auto& key = pair.first;
185 auto& yref = ts1.
data_.at(key).y_values;
186 auto& ycurrent = ts2.
data_.at(key).y_values;
199 TimeSeries* merged,
const std::vector<TimeSeries>& time_series,
200 const std::function<
void(
const std::vector<real_t>&,
real_t*,
real_t*,
204 "Parameter 'merged' is a nullptr. Operation aborted.");
209 if (merged->
data_.size() != 0) {
211 "Parameter 'merged' is not empty. Operation aborted.");
215 if (time_series.size() == 0) {
217 "The given time series vector is empty. Operation aborted.");
219 }
else if (time_series.size() == 1) {
220 *merged = time_series[0];
225 auto& ref = time_series[0];
226 for (uint64_t i = 1; i < time_series.size(); ++i) {
227 auto& current = time_series[i];
228 if (ref.data_.size() != current.data_.size()) {
230 "The time series objects that should be merged do not "
231 "contain the same entries. Operation aborted.");
234 for (
auto& p : ref.data_) {
235 if (current.data_.find(p.first) == current.data_.end()) {
237 "The time series objects that should be merged do not "
238 "contain the same entries. Operation aborted");
244 for (
auto& pair : ref.data_) {
245 auto& key = pair.first;
247 auto& xref = ref.data_.at(key).x_values;
248 for (uint64_t i = 1; i < time_series.size(); ++i) {
249 auto& xcurrent = time_series[i].data_.at(key).x_values;
250 if (xref.size() != xcurrent.size()) {
251 Log::Warning(
"TimeSeries::Merge",
"The time series objects for entry (",
252 key,
") have different x_values. Operation aborted.");
255 for (uint64_t j = 0; j < xref.size(); ++j) {
256 if (std::abs(xref[j] - xcurrent[j]) > 1e-5) {
258 "The time series objects for entry (", key,
259 ") have different x_values. Operation aborted.");
269 auto& mdata = merged->
data_[key];
270 mdata.x_values.resize(xref.size());
271 mdata.y_values.resize(xref.size());
272 mdata.y_error_low.resize(xref.size());
273 mdata.y_error_high.resize(xref.size());
275 #pragma omp parallel for
276 for (uint64_t i = 0; i < xref.size(); ++i) {
277 mdata.x_values[i] = xref[i];
278 std::vector<real_t> all_y_values(time_series.size());
279 for (uint64_t j = 0; j < time_series.size(); ++j) {
280 all_y_values[j] = time_series[j].data_.at(key).y_values[i];
281 merger(all_y_values, &mdata.y_values[i], &mdata.y_error_low[i],
282 &mdata.y_error_high[i]);
296 : data_(std::move(other.data_)) {}
300 data_ = std::move(other.data_);
314 auto it =
data_.find(
id);
315 if (it !=
data_.end()) {
316 Log::Warning(
"TimeSeries::Add",
"TimeSeries with id (",
id,
317 ") exists already. Operation aborted.");
319 data_.emplace(
id,
Data(ycollector, xcollector));
326 auto it =
data_.find(
id);
327 if (it !=
data_.end()) {
328 Log::Warning(
"TimeSeries::Add",
"TimeSeries with id (",
id,
329 ") exists already. Operation aborted.");
331 data_.emplace(
id,
Data(y_reducer_collector, xcollector));
336 const std::string& transformed_id,
339 auto previous_data =
data_.find(old_id);
340 if (previous_data ==
data_.end()) {
341 Log::Warning(
"TimeSeries::AddTransformed",
"TimeSeries with id (", old_id,
342 ") does not exist. Operation aborted.");
346 auto transformed_data =
data_.find(transformed_id);
347 if (transformed_data !=
data_.end()) {
348 Log::Warning(
"TimeSeries::AddTransformed",
"TimeSeries with id (",
349 transformed_id,
") exists already. Operation aborted.");
357 const auto& previous = previous_data->second;
364 data_.emplace(transformed_id, data);
369 if (!
data_.empty()) {
371 auto* scheduler = sim->GetScheduler();
372 auto* param = sim->GetParam();
375 std::vector<std::pair<Reducer<real_t>*,
const std::string>> reducers;
376 for (
auto& entry :
data_) {
377 auto& result_data = entry.second;
378 if (result_data.y_reducer_collector ==
nullptr) {
381 result_data.y_reducer_collector->Reset();
383 std::make_pair(result_data.y_reducer_collector, entry.first));
384 if (result_data.xcollector ==
nullptr) {
385 result_data.x_values.push_back(scheduler->GetSimulatedSteps() *
386 param->simulation_time_step);
388 result_data.x_values.push_back(result_data.xcollector(sim));
393 auto execute_reducers =
L2F([&](
Agent* agent) {
394 for (
auto& el : reducers) {
398 sim->GetResourceManager()->ForEachAgentParallel(execute_reducers);
399 for (
auto& el : reducers) {
400 data_[el.second].y_values.push_back(el.first->GetResult());
405 for (
auto& entry :
data_) {
406 auto& result_data = entry.second;
407 if (result_data.ycollector ==
nullptr) {
410 result_data.y_values.push_back(result_data.ycollector(sim));
411 if (result_data.xcollector ==
nullptr) {
412 result_data.x_values.push_back(scheduler->GetSimulatedSteps() *
413 param->simulation_time_step);
415 result_data.x_values.push_back(result_data.xcollector(sim));
426 "Adding a TimeSeries to itself is not supported. Operation aborted.");
429 for (
auto& p : ts.
data_) {
431 auto id =
Concat(p.first,
"-", suffix);
433 Log::Warning(
"TimeSeries::Add",
"TimeSeries with id (",
id,
434 ") exists already. Consider changing the suffix parameter "
435 "to make it unique. Operation aborted.");
439 data_.emplace(
id, p.second);
445 const std::vector<real_t>& y_values) {
447 Log::Warning(
"TimeSeries::Add",
"TimeSeries with id (",
id,
448 ") exists already. Consider changing the suffix parameter to "
449 "make it unique. Operation aborted.");
456 data_.emplace(
id, data);
461 const std::vector<real_t>& y_values,
462 const std::vector<real_t>& y_error_low,
463 const std::vector<real_t>& y_error_high) {
465 Log::Warning(
"TimeSeries::Add",
"TimeSeries with id (",
id,
466 ") exists already. Consider changing the suffix parameter to "
467 "make it unique. Operation aborted.");
476 data_.emplace(
id, data);
481 const std::vector<real_t>& y_values,
482 const std::vector<real_t>& y_error) {
484 Log::Warning(
"TimeSeries::Add",
"TimeSeries with id (",
id,
485 ") exists already. Consider changing the suffix parameter to "
486 "make it unique. Operation aborted.");
494 data_.emplace(
id, data);
507 return data_.at(
id).x_values;
512 return data_.at(
id).y_values;
517 const std::string&
id)
const {
518 return data_.at(
id).y_error_low;
523 const std::string&
id)
const {
524 return data_.at(
id).y_error_high;
529 for (
auto& p :
data_) {
530 std::cout << p.first << std::endl;
541 TBufferJSON::ExportToFile(full_filepath.c_str(),
this, Class());