PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/ensemble/ClassEnsembleForecast.cxx

https://gitlab.com/ineris/GPEC
C++ | 977 lines | 745 code | 179 blank | 53 comment | 147 complexity | 7a5e0115f17060cf5458bb85d63e8631 MD5 | raw file
Possible License(s): GPL-3.0
  1. // Copyright (C) 2013-2015 INERIS
  2. // Author(s) : Edouard Debry
  3. //
  4. // This file is part of GPEC.
  5. //
  6. // GPEC is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // GPEC is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with GPEC. If not, see <http://www.gnu.org/licenses/>.
  18. #ifndef GPEC_FILE_CLASS_ENSEMBLE_FORECAST_CXX
  19. #include "ClassEnsembleForecast.hxx"
  20. namespace GPEC
  21. {
  22. // Simulation index reverse at computation time.
  23. template<class C>
  24. inline void ClassEnsembleForecast<C>::compute_container_index_reverse()
  25. {
  26. int Nt = target_.GetNt();
  27. container_index_reverse_.Reallocate(Nt);
  28. for (int t = this->t_begin_; t < this->t_end_; t++)
  29. {
  30. // We could allocate only up to t_end, but this would break
  31. // ComputeWeight method for BCLC which runs on all time steps,
  32. // not only those before t.
  33. container_index_reverse_(t).Reallocate(Nt);
  34. if (this->container_index_(t).GetSize() == 0)
  35. continue;
  36. container_index_reverse_(t)(t) = this->container_index_(t);
  37. for (int h = 0; h < Nt; h++)
  38. {
  39. container_index_reverse_(t)(h).Reallocate(this->container_index_(t).GetSize());
  40. if (this->container_index_(h).GetSize() == this->Ncontainer_)
  41. container_index_reverse_(t)(h).Fill();
  42. else
  43. {
  44. int i(0), j(0);
  45. while (i < this->container_index_(h).GetSize() && j < this->container_index_(t).GetSize())
  46. if (this->container_index_(h)(i) > this->container_index_(t)(j))
  47. break;
  48. else if (this->container_index_(h)(i) < this->container_index_(t)(j))
  49. i++;
  50. else
  51. container_index_reverse_(t)(h)(j++) = i++;
  52. container_index_reverse_(t)(h).Resize(j);
  53. }
  54. }
  55. }
  56. }
  57. // Load target.
  58. template<class C>
  59. inline void ClassEnsembleForecast<C>::load_target(const int t_begin, const int t_end,
  60. const Vector1I &location_index,
  61. Vector2I &target_index,
  62. Vector2T &target_data) const
  63. {
  64. #ifdef GPEC_WITH_TIME
  65. clock_t c = clock();
  66. #endif
  67. int Nl = location_index.GetSize();
  68. int Nt = target_.GetNt();
  69. target_index.Reallocate(Nt);
  70. target_data.Reallocate(Nt);
  71. int n = target_time_step_.GetSize();
  72. for (int i = 0; i < n; i++)
  73. {
  74. int t = target_time_step_(i);
  75. target_index(t) = location_index;
  76. target_data(t).Reallocate(Nl);
  77. }
  78. if (this->in_memory_)
  79. {
  80. int location_offset = this->location_offset_rank_(this->rank_);
  81. for (int i = 0; i < n; i++)
  82. {
  83. int t = target_time_step_(i);
  84. if (target_index_(t).GetSize() > 0)
  85. {
  86. int i(0), j(0), l(0);
  87. while (l < target_index_(t).GetSize() && i < Nl)
  88. if (target_index_(t)(l) > location_index(i))
  89. i++;
  90. else if (target_index_(t)(l) < location_index(i))
  91. l++;
  92. else
  93. {
  94. target_index(t)(j) = location_index(i);
  95. target_data(t)(j++) = target_data_(t)(l);
  96. i++;
  97. l++;
  98. }
  99. target_index(t).Resize(j);
  100. target_data(t).Resize(j);
  101. }
  102. else
  103. for (int l = 0; l < Nl; l++)
  104. target_data(t)(l) = target_data_(t)(location_index(l) - location_offset);
  105. }
  106. }
  107. else
  108. if (C::Type() == CONTAINER_SIM_TYPE)
  109. {
  110. Vector<real_io_container> data(n);
  111. ifstream fin(target_file_.c_str(), ifstream::binary);
  112. for (int l = 0; l < Nl; l++)
  113. {
  114. fin.seekg(n * location_index(l) * sizeof(real_io_container), ios_base::beg);
  115. fin.read(reinterpret_cast<char*>(data.GetData()), n * sizeof(real_io_container));
  116. for (int i = 0; i < n; i++)
  117. target_data(target_time_step_(i))(l) = real_container(data(i));
  118. }
  119. fin.close();
  120. }
  121. else
  122. {
  123. Vector1I loc_index;
  124. Vector1T data;
  125. int Nl;
  126. int Nl_container = target_.Nl_;
  127. ifstream fin(target_file_.c_str(), ifstream::binary);
  128. for (int t = 0; t < Nt; t++)
  129. {
  130. fin.seekg(sizeof(int), ios_base::cur);
  131. fin.read(reinterpret_cast<char*>(&Nl), sizeof(int));
  132. if (Nl > 0)
  133. {
  134. fin.seekg(sizeof(int), ios_base::cur);
  135. if (Nl < Nl_container)
  136. {
  137. loc_index.Reallocate(Nl);
  138. fin.read(reinterpret_cast<char*>(loc_index.GetData()), Nl * sizeof(int));
  139. }
  140. data.Reallocate(Nl);
  141. fin.read(reinterpret_cast<char*>(data.GetData()), Nl * sizeof(real_io_container));
  142. if (Nl < Nl_container)
  143. {
  144. int l(0), loc(0);
  145. while (l < Nl && loc < location_index.GetSize())
  146. if (loc_index(l) > location_index(loc))
  147. loc++;
  148. else if (loc_index(l) < location_index(loc))
  149. l++;
  150. else
  151. {
  152. target_index(t)(loc) = loc_index(l);
  153. target_data(t)(loc) = real_container(data(l));
  154. l++;
  155. loc++;
  156. }
  157. target_index(t).Resize(loc);
  158. target_data(t).Resize(loc);
  159. }
  160. else
  161. for (int l = 0; l < location_index.GetSize(); l++)
  162. target_data(t)(l) = data(location_index(l));
  163. }
  164. else
  165. {
  166. fin.seekg(sizeof(int), ios_base::cur);
  167. fin.read(reinterpret_cast<char*>(&Nl), sizeof(int));
  168. if (Nl > 0)
  169. {
  170. fin.seekg(sizeof(int), ios_base::cur);
  171. if (Nl < Nl_container)
  172. fin.seekg(Nl * sizeof(int), ios_base::cur);
  173. fin.seekg(Nl * sizeof(real_io_container), ios_base::cur);
  174. }
  175. }
  176. fin.close();
  177. }
  178. }
  179. for (int t = 0; t < Nt; t++)
  180. if (t < t_begin || t >= t_end)
  181. {
  182. target_index(t).Clear();
  183. target_data(t).Clear();
  184. }
  185. #ifdef GPEC_WITH_TIME
  186. load_target_time += clock() - c;
  187. #endif
  188. }
  189. // Constructors.
  190. template<class C>
  191. ClassEnsembleForecast<C>::ClassEnsembleForecast(const string &name)
  192. : ClassEnsembleBase<C>(name), target_file_("")
  193. {
  194. #ifdef GPEC_WITH_LOGGER
  195. *(ClassGPEC::log_ptr_) << Bmagenta() << Fblack() << Info() << Reset()
  196. << "Instantiate forecast ensemble \"" << name
  197. << "\" (you will need one target : SetTarget() ...)." << endl;
  198. #endif
  199. #ifdef GPEC_WITH_TIME
  200. load_target_time = 0;
  201. compute_weight_time = 0;
  202. #endif
  203. return;
  204. }
  205. // Init.
  206. template<class C>
  207. void ClassEnsembleForecast<C>::Init(const string &species, int date_reference_int, const bool operational)
  208. {
  209. #ifdef GPEC_WITH_LOGGER
  210. *(ClassGPEC::log_ptr_) << Byellow() << Fblack() << Info() << Reset()
  211. << "Master initialization for forecast ensemble \"" << this->name_
  212. << "\" with species \"" << species << "\"." << Reset().Str() << endl;
  213. *(ClassGPEC::log_ptr_) << Fyellow() << Info(2) << Reset()
  214. << "Operational ? " << (operational ? "YES" : "NO") << endl;
  215. #endif
  216. // Read configuration.
  217. Ops::Ops ops(this->configuration_file_);
  218. string prefix = "ensemble." + this->name_ + ".init.";
  219. ops.SetPrefix(prefix);
  220. string frequency = ops.Get<string>("frequency", "", "hourly");
  221. string target_name = ops.Get<string>("target.name");
  222. string target_type = ops.Get<string>("target.type", "", "");
  223. int date_begin_int = ops.Get<int>("date.begin");
  224. int date_end_int = ops.Get<int>("date.end_excluded");
  225. vector<string> model_list = ops.GetEntryList("model");
  226. vector<string> model_name;
  227. vector<int> forecast_day;
  228. vector<string> method;
  229. for (int s = 0; s < int(model_list.size()); s++)
  230. {
  231. ops.SetPrefix(prefix + "model." + model_list[s] + ".");
  232. model_name.push_back(ops.Get<string>("name", "", model_list[s]));
  233. forecast_day.push_back(ops.Get<int>("forecast_day", "", 0));
  234. method.push_back(ops.Get<string>("method", "", "bilinear"));
  235. }
  236. ops.Close();
  237. if (date_reference_int == 0)
  238. date_reference_int = convert<int>(get_current_time("%Y%m%d"));
  239. #ifdef GPEC_WITH_LOGGER
  240. *(ClassGPEC::log_ptr_) << Fyellow() << Info(2) << Reset()
  241. << "Reference date is " << date_reference_int << endl;
  242. #endif
  243. Date date_begin;
  244. try
  245. {
  246. date_begin = get_date_from_int(date_begin_int);
  247. }
  248. catch (...)
  249. {
  250. date_begin.SetDate(date_reference_int);
  251. date_begin.AddDays(date_begin_int);
  252. date_begin_int = get_int_from_date(date_begin);
  253. }
  254. Date date_end;
  255. try
  256. {
  257. date_end = get_date_from_int(date_end_int);
  258. }
  259. catch (...)
  260. {
  261. date_end.SetDate(date_reference_int);
  262. date_end.AddDays(date_end_int);
  263. date_end_int = get_int_from_date(date_end);
  264. }
  265. #ifdef GPEC_WITH_LOGGER
  266. *(this->log_ptr_) << Fcyan() << Info(1) << Reset()
  267. << "Ensemble beginning date is \"" << date_begin_int
  268. << "\" and ending (excluded) date is \"" << date_end_int << "\"." << endl;
  269. #endif
  270. if (target_type.empty())
  271. target_ = C(target_name, species);
  272. else
  273. target_ = C(target_type, target_name, species);
  274. target_.LoadE(date_begin_int, date_end_int);
  275. if (frequency == "peak")
  276. target_.template FilterTime<ClassFilterTimePeak<real_container> >();
  277. else if (frequency == "mean")
  278. target_.template FilterTime<ClassFilterTimeMean<real_container> >();
  279. ostringstream sout;
  280. sout << this->container_directory_ << "/" << species
  281. << "_D" << showpos << int(rint(target_.GetForecastDayMean()))
  282. << "_" << target_name << "_" << target_type
  283. << C::GetFileExtension();
  284. target_file_ = sout.str();
  285. target_.Export(target_file_);
  286. #ifdef GPEC_WITH_LOGGER
  287. *(this->log_ptr_) << Bcyan() << Fblack() << Info() << Reset()
  288. << "Target of ensemble \"" << this->name_
  289. << "\" is \"" << target_.GetName() << "/" << target_.GetType() << "\"." << endl;
  290. #endif
  291. for (int s = 0; s < int(model_name.size()); s++)
  292. {
  293. sim_type sim(model_name[s], species);
  294. // True means we will replace missing days as much as possible.
  295. sim.Load(date_begin_int, date_end_int, forecast_day[s], true, operational);
  296. if (frequency == "peak")
  297. sim.template FilterTime<ClassFilterTimePeak<real_container> >();
  298. else if (frequency == "mean")
  299. sim.template FilterTime<ClassFilterTimeMean<real_container> >();
  300. if (method[s] == "bilinear")
  301. AddSimulation<ClassMethodBilinear<real_container> >(sim);
  302. else if (method[s] == "max")
  303. AddSimulation<ClassMethodMax<real_container> >(sim);
  304. else if (method[s] == "min")
  305. AddSimulation<ClassMethodMin<real_container> >(sim);
  306. else if (method[s] == "upleft")
  307. AddSimulation<ClassMethodUpLeft<real_container> >(sim);
  308. else if (method[s] == "upright")
  309. AddSimulation<ClassMethodUpRight<real_container> >(sim);
  310. else if (method[s] == "downleft")
  311. AddSimulation<ClassMethodDownLeft<real_container> >(sim);
  312. else if (method[s] == "downright")
  313. AddSimulation<ClassMethodDownRight<real_container> >(sim);
  314. else if (method[s] == "nearest")
  315. AddSimulation<ClassMethodNearest<real_container> >(sim);
  316. else
  317. throw GPEC::Error("Unknown interpolation method \"" + method[s] + "\".");
  318. }
  319. }
  320. // Destructor.
  321. template<class C>
  322. ClassEnsembleForecast<C>::~ClassEnsembleForecast()
  323. {
  324. return;
  325. }
  326. // Add Target.
  327. template<class C>
  328. void ClassEnsembleForecast<C>::SetTarget(const string species,
  329. string target_file,
  330. string config_file)
  331. {
  332. // Read configuration or argument, if nothing in configuration.
  333. Ops::Ops ops(this->configuration_file_);
  334. target_file_ = ops.Get<string>("ensemble." + this->name_ + ".target", "", target_file);
  335. ops.Close();
  336. // If empty, then no way to go on.
  337. if (target_file_.empty())
  338. throw GPEC::Error("Empty target file.");
  339. // Put species name in generic target file name, if necessary.
  340. target_file_ = find_replace(target_file_, "&s", species);
  341. // Construct target.
  342. if (target_file_[0] != '/')
  343. target_file_ = this->container_directory_ + "/" + target_file_;
  344. check_file(target_file_);
  345. target_.LoadFile(target_file_, config_file);
  346. }
  347. template<class C>
  348. void ClassEnsembleForecast<C>::SetTarget(const C &target)
  349. {
  350. ostringstream sout;
  351. sout << this->container_directory_ << "/" << target.GetSpecies()
  352. << "_D" << showpos << int(rint(target.GetForecastDayMean()))
  353. << "_" << target.GetName() << "_" << target.GetType()
  354. << C::GetFileExtension();
  355. target_file_ = sout.str();
  356. target.Export(target_file_);
  357. target_.FullCopy(target);
  358. }
  359. // Add Simulations.
  360. template<class C>
  361. void ClassEnsembleForecast<C>::AddSimulation(Vector<int> &index)
  362. {
  363. ClassPolyContainer<C>::AddContainer(index, target_.species_);
  364. }
  365. template<class C> template<class M>
  366. void ClassEnsembleForecast<C>::AddSimulation(const ClassContainerSimulation<real, real_io> &simulation, string container_file)
  367. {
  368. M algorithm;
  369. if (container_file.empty())
  370. {
  371. ostringstream sout;
  372. sout << this->container_directory_ << "/" << simulation.GetSpecies()
  373. << "_D" << showpos << int(rint(simulation.GetForecastDayMean()))
  374. << "_" << simulation.GetName() << "_" << target_.type_
  375. << "_" << algorithm.Name() << C::GetFileExtension();
  376. // << "_" << algorithm.Name() << "_" << noshowpos << this->Ncontainer_ << C::GetFileExtension();
  377. container_file = sout.str();
  378. }
  379. ClassPolyContainer<C>::template AddSimulation<M>(simulation, target_.type_, container_file);
  380. }
  381. template<class C>
  382. void ClassEnsembleForecast<C>::AddSimulationConstant(const real constant_value, string container_file)
  383. {
  384. if (this->Ncontainer_ == 0)
  385. throw GPEC::Error("You need to provide at least one container before adding a constant one.");
  386. C container;
  387. container.LoadFile(this->container_file_[0]);
  388. for (int t = 0; t < container.Nt_; t++)
  389. {
  390. container.forecast_(t).Reallocate(1);
  391. container.forecast_(t)(0) = 0;
  392. container.data_(t).Reallocate(container.Nl_);
  393. container.data_(t).Fill(real_container(constant_value));
  394. container.location_index_(t).Clear();
  395. }
  396. container.name_ = "Constant" + to_str(constant_value);
  397. if (container_file.empty())
  398. {
  399. ostringstream sout;
  400. sout << this->container_directory_ << "/" << container.species_
  401. << "_D" << showpos << int(rint(container.GetForecastDayMean()))
  402. << "_" << container.name_ << "_" << container.type_
  403. << C::GetFileExtension();
  404. //<< "_" << noshowpos << this->Ncontainer_ << C::GetFileExtension();
  405. container_file = sout.str();
  406. }
  407. ClassPolyContainer<C>::AddContainer(container, container_file);
  408. }
  409. template<class C>
  410. void ClassEnsembleForecast<C>::AddSimulationRandom(const real value_min, const real value_max,
  411. string container_file, int seed)
  412. {
  413. if (this->Ncontainer_ == 0)
  414. throw GPEC::Error("You need to provide at least one container before adding a constant one.");
  415. srand48(seed);
  416. C container;
  417. container.LoadFile(this->container_file_[0]);
  418. real_container value_delta = value_max - value_min;
  419. for (int t = 0; t < container.Nt_; t++)
  420. {
  421. container.forecast_(t).Reallocate(1);
  422. container.forecast_(t)(0) = 0;
  423. container.data_(t).Reallocate(container.Nl_);
  424. for (int l = 0; l < container.Nl_; l++)
  425. container.data_(t)(l) = value_min + drand48() * value_delta;
  426. container.location_index_(t).Clear();
  427. }
  428. container.name_ = "Random" + to_str(seed);
  429. if (container_file.empty())
  430. {
  431. ostringstream sout;
  432. sout << this->container_directory_ << "/" << container.species_
  433. << "_D" << showpos << int(rint(container.GetForecastDayMean()))
  434. << "_" << container.name_ << "_" << container.type_
  435. << C::GetFileExtension();
  436. //<< "_" << noshowpos << this->Ncontainer_ << C::GetFileExtension();
  437. container_file = sout.str();
  438. }
  439. ClassPolyContainer<C>::AddContainer(container, container_file);
  440. }
  441. // Load ensemble.
  442. template<class C>
  443. void ClassEnsembleForecast<C>::Load(string config_file)
  444. {
  445. int Nt = target_.Nt_;
  446. if (Nt == 0 || target_file_ == "")
  447. throw GPEC::Error("Empty target in ensemble forecast \"" + this->name_ + "\", use SetTarget().");
  448. ClassPolyContainer<C>::Load(config_file);
  449. target_time_step_.Reallocate(Nt);
  450. int i(0);
  451. for (int t = 0; t < Nt; t++)
  452. if (target_.data_(t).GetSize() > 0)
  453. target_time_step_(i++) = t;
  454. target_time_step_.Resize(i);
  455. int Nl = target_.Nl_;
  456. this->set_location_per_rank(Nl);
  457. int location_offset(0);
  458. if (this->split_memory_)
  459. {
  460. Nl = this->Nlocation_rank_(this->rank_);
  461. location_offset = this->location_offset_rank_(this->rank_);
  462. }
  463. if (this->in_memory_)
  464. {
  465. int n = target_time_step_.GetSize();
  466. target_index_.Reallocate(Nt);
  467. target_data_.Reallocate(Nt);
  468. for (int i = 0; i < n; i++)
  469. {
  470. int t = target_time_step_(i);
  471. target_index_(t).Reallocate(Nl);
  472. target_data_(t).Reallocate(Nl);
  473. if (target_.location_index_(t).GetSize() > 0)
  474. {
  475. int i(location_offset), j(0), l(0), imax(Nl + location_offset);
  476. while (l < target_.location_index_(t).GetSize() && i < imax)
  477. if (target_.location_index_(t)(l) > i)
  478. i++;
  479. else if (target_.location_index_(t)(l) < i)
  480. l++;
  481. else
  482. {
  483. target_index_(t)(j) = i;
  484. target_data_(t)(j++) = target_.data_(t)(l);
  485. i++;
  486. l++;
  487. }
  488. target_index_(t).Resize(j);
  489. target_data_(t).Resize(j);
  490. }
  491. else
  492. for (int j = 0; j < Nl; j++)
  493. target_data_(t)(j) = target_.data_(t)(j + location_offset);
  494. }
  495. }
  496. target_.PartialClear();
  497. }
  498. // Clear ensemble.
  499. template<class C>
  500. void ClassEnsembleForecast<C>::Clear()
  501. {
  502. target_.Clear();
  503. target_file_ = "";
  504. target_time_step_.Clear();
  505. target_index_.Clear();
  506. target_data_.Clear();
  507. container_index_reverse_.Clear();
  508. ClassEnsembleBase<C>::Clear();
  509. }
  510. // Dump configuration.
  511. template<class C>
  512. string ClassEnsembleForecast<C>::DumpConfiguration(string config_file) const
  513. {
  514. string output = ClassPolyContainer<C>::DumpConfiguration();
  515. // Write lua configuration.
  516. Ops::Ops ops;
  517. int pos = target_file_.find_last_of('/');
  518. string basedir = target_file_.substr(0, pos);
  519. string basename = target_file_.substr(pos + 1);
  520. if (basedir == this->container_directory_)
  521. ops.Push(this->name_ + ".target", basename);
  522. else
  523. ops.Push(this->name_ + ".target", target_file_);
  524. output += ops.LuaDefinition();
  525. ops.Close();
  526. if (! config_file.empty())
  527. {
  528. ofstream fout(config_file.c_str());
  529. fout << output;
  530. fout.close();
  531. }
  532. return output;
  533. }
  534. // Get methods.
  535. template<class C>
  536. C* ClassEnsembleForecast<C>::GetTargetPtr()
  537. {
  538. return &target_;
  539. }
  540. template<class C>
  541. string ClassEnsembleForecast<C>::GetTargetFile() const
  542. {
  543. return target_file_;
  544. }
  545. // Compute weight.
  546. template <class C> template<class M>
  547. void ClassEnsembleForecast<C>::ComputeWeight(const int &t_begin, const int &t_end,
  548. const Vector2I &location_index,
  549. const Vector2T &location_factor)
  550. {
  551. if (! this->is_loaded_)
  552. throw GPEC::Error("Ensemble not loaded yet.");
  553. // Count algorithm error.
  554. int count_algorithm_error(0);
  555. // Clear weights.
  556. this->ClearWeight();
  557. this->t_begin_ = t_begin;
  558. this->t_end_ = t_end;
  559. #ifdef GPEC_WITH_LOGGER
  560. *(ClassGPEC::log_ptr_) << Byellow() << Fblack() << Info(2) << Reset()
  561. << "Compute weights for ensemble \"" << this->name_ << "\" with species \""
  562. << target_.species_ << "\" and target \"" << target_.name_ << "\", "
  563. << "between time indexes [" << this->t_begin_ << ", " << this->t_end_ << "[." << endl;
  564. #endif
  565. // Reallocate weights.
  566. int Nt = target_.GetNt();
  567. this->weight_.Reallocate(Nt);
  568. for (int t = this->t_begin_; t < this->t_end_; t++)
  569. this->weight_(t).Reallocate(location_index.GetSize());
  570. // Compute reverse index.
  571. compute_container_index_reverse();
  572. // Algorithm parameters.
  573. map<string, real_container> parameter = this->parameter_;
  574. M algorithm(parameter);
  575. algorithm.Init(target_, t_begin, t_end);
  576. this->algorithm_ = algorithm.GetName();
  577. // Each process rank has one part of weights.
  578. for (int j = 0; j < location_index.GetSize(); ++j)
  579. {
  580. #ifdef GPEC_WITH_LOGGER
  581. *(ClassGPEC::log_ptr_) << Frequency(2) << Bred() << Fwhite() << Info(3) << Reset() << Logger::Date()
  582. << "location " << j << "/" << location_index.GetSize() << endl;
  583. #endif
  584. Vector2I target_index;
  585. Vector2T target_data;
  586. load_target(0, t_end, location_index(j), target_index, target_data);
  587. Vector3T simulation_data;
  588. this->load_container(location_index(j), target_index, simulation_data);
  589. #ifdef GPEC_WITH_TIME
  590. clock_t c = clock();
  591. #endif
  592. Vector2T location_factor2(t_end);
  593. for (int t = 0; t < t_end; ++t)
  594. if (target_index(t).GetSize() > 0)
  595. {
  596. if (target_index(t).GetSize() == location_index(j).GetSize())
  597. location_factor2(t) = location_factor(j);
  598. else
  599. {
  600. location_factor2(t).Reallocate(target_index(t).GetSize());
  601. int i(0), k(0);
  602. while (i < target_index(t).GetSize())
  603. if (location_index(j)(k) == target_index(t)(i))
  604. location_factor2(t)(i++) = location_factor(j)(k++);
  605. else
  606. k++;
  607. }
  608. }
  609. for (int t = this->t_begin_; t < this->t_end_; ++t)
  610. if (this->container_index_(t).GetSize() > 0)
  611. if (! algorithm.ComputeWeight(t,
  612. target_,
  613. target_data,
  614. simulation_data,
  615. location_factor2,
  616. container_index_reverse_,
  617. this->weight_(t)(j)))
  618. count_algorithm_error++;
  619. #ifdef GPEC_WITH_TIME
  620. compute_weight_time += clock() - c;
  621. #endif
  622. }
  623. #ifdef GPEC_WITH_TIME
  624. #ifdef GPEC_WITH_LOGGER
  625. *(this->log_ptr_) << Fyellow() << User(0, "TIME") << Reset()
  626. << "load_container_time = " << real_container(load_container_time) / CLOCKS_PER_SEC << endl;
  627. *(this->log_ptr_) << Fyellow() << User(0, "TIME") << Reset()
  628. << "load_target_time = " << real_container(load_target_time) / CLOCKS_PER_SEC << endl;
  629. *(this->log_ptr_) << Fyellow() << User(0, "TIME") << Reset()
  630. << "compute_weight_time = " << real_container(compute_weight_time) / CLOCKS_PER_SEC << endl;
  631. #else
  632. cout << "load_container_time = " << real_container(load_container_time) / CLOCKS_PER_SEC << endl;
  633. cout << "load_target_time = " << real_container(load_target_time) / CLOCKS_PER_SEC << endl;
  634. cout << "compute_weight_time = " << real_container(compute_weight_time) / CLOCKS_PER_SEC << endl;
  635. #endif
  636. load_container_time = clock_t(0);
  637. load_target_time = clock_t(0);
  638. compute_weight_time = clock_t(0);
  639. #endif
  640. #ifdef GPEC_WITH_LOGGER
  641. if (count_algorithm_error > 0)
  642. {
  643. *(this->log_ptr_) << Bred() << Logger::Error() << Reset()
  644. << "count_algorithm_error = " << count_algorithm_error << endl;
  645. *(this->log_ptr_) << Fred() << User(0, "EXPLANATION") << Reset()
  646. << "Errors coming from the given algorithm are not fatal, they just mean "
  647. << "computed weights are not optimal or just inexistant. Most of the time, "
  648. << "it is a violated learning period." << endl;
  649. }
  650. #endif
  651. }
  652. template<class C> template<class M>
  653. void ClassEnsembleForecast<C>::ComputeWeightByTime(const int &t_begin, const int &t_end)
  654. {
  655. // Each rank computes part of time steps.
  656. int Nt_global = t_end - t_begin;
  657. int Nt_tmp = Nt_global / this->Nrank_;
  658. int Nt_local = Nt_tmp;
  659. int Nt_remaining = Nt_global % this->Nrank_;
  660. if (this->rank_ < Nt_remaining)
  661. Nt_local++;
  662. int t_begin_local(t_begin);
  663. for (int irank = 0; irank < this->rank_; irank++)
  664. {
  665. t_begin_local += Nt_tmp;
  666. if (this->rank_ < Nt_remaining)
  667. t_begin_local++;
  668. }
  669. int t_end_local = t_begin_local + Nt_local;
  670. // All locations used for all ranks.
  671. Vector2I location_index(1);
  672. location_index(0).Reallocate(target_.GetNlocation());
  673. location_index(0).Fill();
  674. Vector2T location_factor(1);
  675. location_factor(0).Reallocate(target_.GetNlocation());
  676. location_factor(0).Fill(real_container(1));
  677. #ifdef GPEC_WITH_LOGGER
  678. *(this->log_ptr_) << Bgreen() << Info() << Reset() << "Compute weights BY TIME from time step "
  679. << t_begin_local << " to " << t_end_local << " (excluded)." << endl;
  680. #endif
  681. ComputeWeight<M>(t_begin_local, t_end_local, location_index, location_factor);
  682. // Each rank receives its part of locations.
  683. this->weight_location_ = location_index;
  684. }
  685. template<class C> template<class M>
  686. void ClassEnsembleForecast<C>::ComputeWeightByLocation(const int &t_begin, const int &t_end)
  687. {
  688. // All ranks receives their part of locations to compute.
  689. this->set_location_per_rank(target_.Nl_);
  690. Vector2I location_index(this->location_rank_.GetSize());
  691. Vector2T location_factor(this->location_rank_.GetSize());
  692. for (int j = 0; j < this->location_rank_.GetSize(); j++)
  693. {
  694. location_index(j).PushBack(this->location_rank_(j));
  695. location_factor(j).PushBack(real_container(1));
  696. }
  697. #ifdef GPEC_WITH_LOGGER
  698. *(this->log_ptr_) << Bred() << Info() << Reset() << "Compute weights BY LOCATION from location "
  699. << this->location_offset_rank_(this->rank_) << " to "
  700. << this->Nlocation_rank_(this->rank_) + this->location_offset_rank_(this->rank_) - 1
  701. << "." << endl;
  702. #endif
  703. ComputeWeight<M>(t_begin, t_end, location_index, location_factor);
  704. this->weight_location_ = location_index;
  705. }
  706. template<class C> template<class M>
  707. void ClassEnsembleForecast<C>::ComputeWeightByCell(const string &type,
  708. const int &t_begin, const int &t_end)
  709. {
  710. real_container distance_cutoff = this->parameter_["distance_cutoff"];
  711. real_container distance_h = this->parameter_["distance_h"];
  712. real_container distance_beta = this->parameter_["distance_beta"];
  713. int location_min = int(this->parameter_["location_min"]);
  714. int location_max = int(this->parameter_["location_max"]);
  715. sim_type reference(type, target_.GetSpecies());
  716. this->set_location_per_rank(reference.GetNlocation());
  717. Vector2I location_index(this->location_rank_.GetSize());
  718. Vector2T location_factor(this->location_rank_.GetSize());
  719. for (int j = 0; j < this->location_rank_.GetSize(); j++)
  720. {
  721. int loc = this->location_rank_(j);
  722. real_container longitude = reference.GetLocationLongitude(loc);
  723. real_container latitude = reference.GetLocationLatitude(loc);
  724. int i(0);
  725. while (i < location_min && distance_cutoff < real_container(30))
  726. {
  727. location_index(j).Reallocate(target_.GetNlocation());
  728. location_factor(j).Reallocate(target_.GetNlocation());
  729. location_factor.Zero();
  730. for (int l = 0; l < target_.GetNlocation(); l++)
  731. {
  732. real_container lon = longitude - target_.GetLocationLongitude(l);
  733. real_container lat = latitude - target_.GetLocationLatitude(l);
  734. real_container distance = sqrt(lon * lon + lat * lat);
  735. if (distance < distance_cutoff)
  736. {
  737. real_container ratio = distance / distance_h;
  738. location_index(j)(i) = l;
  739. location_factor(j)(i++) = distance_beta * exp(-ratio) * (real_container(1) + ratio) + real_container(1);
  740. if (i == location_max)
  741. break;
  742. }
  743. }
  744. distance_cutoff *= real_container(2);
  745. }
  746. if (i < location_min)
  747. throw GPEC::Error("Unable to get enough locations for position " + to_str(loc) + " .");
  748. location_index(j).Resize(i);
  749. location_factor(j).Resize(i);
  750. }
  751. #ifdef GPEC_WITH_LOGGER
  752. *(this->log_ptr_) << Bmagenta() << Fblack() << Info() << Reset()
  753. << "Compute weights BY CELL." << endl;
  754. #endif
  755. ComputeWeight<M>(t_begin, t_end, location_index, location_factor);
  756. this->weight_location_.Reallocate(this->location_rank_.GetSize());
  757. for (int j = 0; j < this->location_rank_.GetSize(); j++)
  758. this->weight_location_(j).PushBack(this->location_rank_(j));
  759. }
  760. // Rank diagram.
  761. template<class C>
  762. void ClassEnsembleForecast<C>::RankDiagram(Vector1I &rank_diagram) const
  763. {
  764. rank_diagram.Reallocate(this->Ncontainer_ + 1);
  765. rank_diagram.Zero();
  766. int Nt = target_.GetNt();
  767. int Nlocation = target_.GetNlocation();
  768. for (int loc = 0; loc < Nlocation; loc++)
  769. {
  770. Vector1I target_location(1);
  771. target_location(0) = loc;
  772. Vector2I target_index;
  773. Vector2T target_data;
  774. load_target(0, Nt, target_location, target_index, target_data);
  775. Vector3T simulation_data;
  776. this->load_container(target_location, target_index, simulation_data);
  777. for (int t = 0; t < Nt; t++)
  778. if (target_index(t).GetSize() > 0)
  779. if (this->container_index_(t).GetSize() == this->Ncontainer_)
  780. {
  781. Sort(simulation_data(t)(0));
  782. if (target_data(t)(0) < simulation_data(t)(0)(0))
  783. rank_diagram(0)++;
  784. else if (target_data(t)(0) > simulation_data(t)(0)(this->Ncontainer_ - 1))
  785. rank_diagram(this->Ncontainer_)++;
  786. else
  787. for (int s = 1; s < this->Ncontainer_; s++)
  788. if (target_data(t)(0) > simulation_data(t)(0)(s))
  789. {
  790. rank_diagram(s)++;
  791. break;
  792. }
  793. }
  794. }
  795. }
  796. }
  797. #define GPEC_FILE_CLASS_ENSEMBLE_FORECAST_CXX
  798. #endif