Documentation for OpenFLUID 2.2.1
DistributionBindings.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2021-2026, INRAE
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 
33 /**
34  @file DistributionBindings.hpp
35 
36  @author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
37  @author Armel THÖNI <armel.thoni@inrae.fr>
38  */
39 
40 
41 #ifndef __OPENFLUID_TOOLS_DISTRIBUTIONBINDINGS_HPP__
42 #define __OPENFLUID_TOOLS_DISTRIBUTIONBINDINGS_HPP__
43 
44 
46 #include <openfluid/dllexport.hpp>
55 #include <openfluid/config.hpp>
56 
57 
58 namespace openfluid { namespace tools {
59 
60 
61 inline std::vector<openfluid::tools::ClassIDVar>
62 stringArrayToClassIDVarList(const std::vector<std::string>& StringArray, bool RemoveFirst=false)
63 {
64  std::vector<openfluid::tools::ClassIDVar> CSVTriplets;
65  int Begin = RemoveFirst ? 1 : 0;
66  for (std::size_t i=Begin;i<StringArray.size();i++)
67  {
68  const std::string& Column = StringArray[i];
69  // parse and create CSVTriplet
70  std::size_t HashPosition = Column.find(openfluid::config::CHAR_SEPARATOR_UNIT);
71  std::size_t ColonPosition = Column.find(openfluid::config::CHAR_SEPARATOR_VAR);
72 
73  if(HashPosition == std::string::npos || ColonPosition == std::string::npos)
74  {
75  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION, "wrong format for multicolumn csv file");
76  }
77 
78  openfluid::tools::ClassIDVar CurrentCSVTriplet;
79 
80  CurrentCSVTriplet.UnitsClass = Column.substr(0,HashPosition);
81  CurrentCSVTriplet.UnitsIDsStr = Column.substr(HashPosition+1, ColonPosition-HashPosition-1);
82  CurrentCSVTriplet.VariableName = Column.substr(ColonPosition+1);
83 
84  CSVTriplets.push_back(CurrentCSVTriplet);
85  }
86  return CSVTriplets;
87 };
88 
89 
90 // =====================================================================
91 // =====================================================================
92 
93 
94 inline std::vector<openfluid::tools::ClassIDVar> stringSelectionToClassIDVarList(const std::string& SelectionStr,
95  bool RemoveFirst=false)
96 {
97  std::vector<std::string> Columns = openfluid::tools::split(SelectionStr, ";");
98  //TODO Extract and make split char consistent between ops
99 
100  return stringArrayToClassIDVarList(Columns, RemoveFirst);
101 };
102 
103 
104 template<typename DataType=double>
106 {
107  public:
108 
110 
112 
114 
115  ReaderNextValue(): Reader(nullptr), isAvailable(false)
116  { }
117 };
118 
119 
120 // =====================================================================
121 // =====================================================================
122 
123 
124 template<typename DataType=double>
126 {
127  public:
128 
129  typedef std::list<ReaderNextValue<DataType>> ReadersNextValues_t;
130 
131 
132  protected:
133 
135 
136 
137  public:
138 
140 
142  {
143 
144  // delete readers
145 
147  {
148  if (RNV.Reader)
149  {
150  delete RNV.Reader;
151  }
152  }
153  }
154 
156  {
158  {
159  bool DataFound = true;
161 
162  if ((RNV.isAvailable && RNV.NextValue.first < DT) ||
163  RNV.isAvailable == false)
164  {
165  RNV.isAvailable = false;
166 
167  while (DataFound && !RNV.isAvailable)
168  {
169  DataFound = RNV.Reader->getNextValue(CI);
170  if (DataFound && CI.first >= DT)
171  {
172  RNV.isAvailable = true;
173  RNV.NextValue = CI;
174  }
175  }
176  }
177  }
178  }
179 
181  {
182  openfluid::core::DateTime DTPlusOne(DT);
183  DTPlusOne.addSeconds(1);
184  advanceToTime(DTPlusOne);
185 
187 
188  bool AvailableFound = false;
189 
191  {
192 
193  if (!AvailableFound && RNV.isAvailable)
194  {
195  NDT = RNV.NextValue.first;
196  AvailableFound = true;
197  }
198  }
199 
200  if (!AvailableFound)
201  {
202  return false;
203  }
204 
206  {
207  if (RNV.isAvailable && RNV.NextValue.first < NDT)
208  {
209  NDT = RNV.NextValue.first;
210  }
211  }
212 
213  NextDT = NDT;
214 
215  return true;
216  }
217 
218 };
219 
220 
221 // =====================================================================
222 // =====================================================================
223 
224 
225 template<typename DataType=double, typename TV=openfluid::core::DoubleValue>
227 {
228  public:
229 
230  typedef std::map<openfluid::core::UnitID_t,ReaderNextValue<DataType>*> UnitIDReader_t;
231 
232 
233  protected:
234 
236 
237  public:
238 
240  {
241  DistributionTables::SourceIDFile_t::const_iterator itb = DistriTables.SourcesTable.begin();
242  DistributionTables::SourceIDFile_t::const_iterator ite = DistriTables.SourcesTable.end();
243 
244  for (DistributionTables::SourceIDFile_t::const_iterator it = itb; it != ite; ++it)
245  {
247  RNV.Reader = new ProgressiveChronFileReader<DataType>((*it).second);
248  this->m_ReadersNextValues.push_back(RNV);
249 
250  DistributionTables::UnitIDSourceID_t::const_iterator itub = DistriTables.UnitsTable.begin();
251  DistributionTables::UnitIDSourceID_t::const_iterator itue = DistriTables.UnitsTable.end();
252 
253  for (DistributionTables::UnitIDSourceID_t::const_iterator itu = itub; itu != itue; ++itu)
254  {
255  if ((*itu).second == (*it).first)
256  {
257  m_UnitIDReaders[(*itu).first] = &this->m_ReadersNextValues.back();
258  }
259  }
260  }
261  }
262 
264  const openfluid::core::DateTime& DT,
265  TV& Value)
266  {
267  // if a value is available for DT : passes the value to caller, and returns true
268  // else returns false
269  typename UnitIDReader_t::iterator it = m_UnitIDReaders.find(UnitID);
270  if (it != m_UnitIDReaders.end() && (*it).second->isAvailable && (*it).second->NextValue.first == DT)
271  {
272  // Previous method for double, avoiding any precision issue from conversions:
273  // Value.set((*it).second->NextValue.second);
274  // Requires a dedicated function override at template level
275  openfluid::core::StringValue CurrentValueSV = openfluid::core::StringValue((*it).second->NextValue.second);
276  if (Value.getType() == openfluid::core::Value::STRING)
277  {
278  Value = CurrentValueSV;
279  return true;
280  }
281  else
282  {
283  return CurrentValueSV.convert(Value);
284  }
285  }
286  return false;
287  }
288 
290  {
291  for (auto& IDReader : m_UnitIDReaders)
292  {
293  std::cout << IDReader.first << " -> " << IDReader.second->Reader->getFileName() << std::endl;
294  }
295  }
296 };
297 
298 
299 // =====================================================================
300 // =====================================================================
301 
302 
303 class OPENFLUID_API DistributionBindings : public SimpleDistributionBindings<double, openfluid::core::DoubleValue>
304 {
305  public:
307  }
308 };
309 
310 
311 // =====================================================================
312 // =====================================================================
313 
314 
316 {
317  public:
318 
319  typedef std::map<std::vector<std::string>, unsigned int> TripletLocation_t;
320 
321  private:
322 
323  TripletLocation_t m_ColBySelectionTriplets;
324 
325  inline static const std::string s_MissingValueString = "NA"; // TODO set as parameter transmitted by calling object
326 
327 
328  public:
329 
330  MulticolDistributionBindings(const std::string& DataFile,
331  const std::string& DateFormat = "%Y%m%dT%H%M%S",
332  const std::string& ColSeparators = ";");
333 
334 
335  /**
336  Apply to Value the wanted value from distribution table for given variable at given time
337  @return the status as int: 1 for success, 0 for expected NA, -1 for failed conversion from string to double
338  @throw openfluid::base::FrameworkException when wrong number of columns
339  */
340  int getValue(const openfluid::core::UnitsClass_t& UnitsClass,
341  const openfluid::core::UnitID_t& UnitID,
342  const openfluid::core::VariableName_t& VariableName,
343  const openfluid::core::DateTime& DT,
345 
347  {
348  return m_ColBySelectionTriplets;
349  }
350 };
351 
352 
353 } }
354 
355 
356 #endif /* __OPENFLUID_TOOLS_DISTRIBUTIONBINDINGS_HPP__ */
Definition: FrameworkException.hpp:51
Class for management of date and time information.
Definition: DateTime.hpp:88
void addSeconds(const RawTime_t &Seconds)
Definition: DoubleValue.hpp:81
Definition: StringValue.hpp:83
bool convert(Value &Val) const override
@ STRING
Definition: Value.hpp:66
Definition: DistributionBindings.hpp:304
DistributionBindings(const DistributionTables &DistriTables)
Definition: DistributionBindings.hpp:306
Definition: DistributionTables.hpp:55
UnitIDSourceID_t UnitsTable
Definition: DistributionTables.hpp:64
SourceIDFile_t SourcesTable
Definition: DistributionTables.hpp:62
Definition: DistributionBindings.hpp:126
void advanceToTime(const openfluid::core::DateTime &DT)
Definition: DistributionBindings.hpp:155
ReadersNextValues_t m_ReadersNextValues
Definition: DistributionBindings.hpp:134
~GenericDistributionBindings()
Definition: DistributionBindings.hpp:141
bool advanceToNextTimeAfter(const openfluid::core::DateTime &DT, openfluid::core::DateTime &NextDT)
Definition: DistributionBindings.hpp:180
std::list< ReaderNextValue< DataType > > ReadersNextValues_t
Definition: DistributionBindings.hpp:129
Definition: DistributionBindings.hpp:316
MulticolDistributionBindings(const std::string &DataFile, const std::string &DateFormat="%Y%m%dT%H%M%S", const std::string &ColSeparators=";")
TripletLocation_t getColBySelectionTriplet()
Definition: DistributionBindings.hpp:346
int getValue(const openfluid::core::UnitsClass_t &UnitsClass, const openfluid::core::UnitID_t &UnitID, const openfluid::core::VariableName_t &VariableName, const openfluid::core::DateTime &DT, openfluid::core::DoubleValue &Value)
std::map< std::vector< std::string >, unsigned int > TripletLocation_t
Definition: DistributionBindings.hpp:319
Definition: ProgressiveChronFileReader.hpp:56
Definition: DistributionBindings.hpp:106
ChronItem_t< DataType > NextValue
Definition: DistributionBindings.hpp:111
bool isAvailable
Definition: DistributionBindings.hpp:113
ReaderNextValue()
Definition: DistributionBindings.hpp:115
ProgressiveChronFileReader< DataType > * Reader
Definition: DistributionBindings.hpp:109
Definition: DistributionBindings.hpp:227
UnitIDReader_t m_UnitIDReaders
Definition: DistributionBindings.hpp:235
SimpleDistributionBindings(const DistributionTables &DistriTables)
Definition: DistributionBindings.hpp:239
bool getValue(const openfluid::core::UnitID_t &UnitID, const openfluid::core::DateTime &DT, TV &Value)
Definition: DistributionBindings.hpp:263
void displayBindings()
Definition: DistributionBindings.hpp:289
std::map< openfluid::core::UnitID_t, ReaderNextValue< DataType > * > UnitIDReader_t
Definition: DistributionBindings.hpp:230
#define OPENFLUID_API
Definition: dllexport.hpp:86
unsigned int UnitID_t
Definition: TypeDefs.hpp:70
std::string VariableName_t
Definition: TypeDefs.hpp:131
std::string UnitsClass_t
Definition: TypeDefs.hpp:98
std::vector< openfluid::tools::ClassIDVar > stringArrayToClassIDVarList(const std::vector< std::string > &StringArray, bool RemoveFirst=false)
Definition: DistributionBindings.hpp:62
std::vector< openfluid::tools::ClassIDVar > stringSelectionToClassIDVarList(const std::string &SelectionStr, bool RemoveFirst=false)
Definition: DistributionBindings.hpp:94
std::vector< std::string > OPENFLUID_API split(const std::string &Str, const char Sep, bool KeepEmpty=false)
std::pair< openfluid::core::DateTime, DataType > ChronItem_t
Definition: ChronologicalSerie.hpp:55
Definition: ApplicationException.hpp:47
Definition: VarHelpers.hpp:98
std::string UnitsIDsStr
Definition: VarHelpers.hpp:100
openfluid::core::VariableName_t VariableName
Definition: VarHelpers.hpp:60
openfluid::core::UnitsClass_t UnitsClass
Definition: VarHelpers.hpp:58