rtc-tools 2.5.1rc1__py3-none-any.whl → 2.5.2a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rtc-tools might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rtc-tools
3
- Version: 2.5.1rc1
3
+ Version: 2.5.2a2
4
4
  Summary: Toolbox for control and optimization of water systems.
5
5
  Home-page: https://oss.deltares.nl/web/rtc-tools/home
6
6
  Author: Deltares
@@ -27,8 +27,8 @@ Classifier: Operating System :: MacOS
27
27
  Requires-Python: >=3.5
28
28
  License-File: COPYING.LESSER
29
29
  Requires-Dist: casadi (==3.5.*)
30
- Requires-Dist: numpy (>=1.16.0)
31
- Requires-Dist: scipy (>=1.0.0)
30
+ Requires-Dist: numpy (<1.23,>=1.16.0)
31
+ Requires-Dist: scipy (<1.11,>=1.0.0)
32
32
  Requires-Dist: pymoca (==0.9.*)
33
33
  Requires-Dist: rtc-tools-channel-flow (>=1.1.0)
34
34
  Provides-Extra: all
@@ -1,5 +1,5 @@
1
1
  rtctools/__init__.py,sha256=GzuYmrfvai2LnOnLGZUweYWn4SJQH9txwzwVO-ykvN4,106
2
- rtctools/_version.py,sha256=YkGn2tyAZqKSTb3t_ABQJYEE21LoH2A56D5O1RPOGJY,500
2
+ rtctools/_version.py,sha256=0K1yImT9X9wdqhZb9KmjXsI77YhAB2XLta4BABO1ADg,499
3
3
  rtctools/rtctoolsapp.py,sha256=tK8hLfozegtH9kY5bmAox8lCE427uhxBWEp5pBqhiSA,4193
4
4
  rtctools/util.py,sha256=SkYvRJPZVuWXlWk3NMO9Xdx_Vy7vhO_qPMN0nJ96Vdc,7371
5
5
  rtctools/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -10,7 +10,7 @@ rtctools/_internal/debug_check_helpers.py,sha256=YDPNB2yVY2Lkztoz8GabG0TX3-2CS0D
10
10
  rtctools/data/__init__.py,sha256=k4WorSsD-Y8l2meIYHPaSOdGEgonribLkyoMASAhe90,157
11
11
  rtctools/data/csv.py,sha256=1pEYJ2Y0pxNFONH0iwacAbkKb3959lyqA_-jQ0O4CPo,4947
12
12
  rtctools/data/netcdf.py,sha256=QpAzAowSdmbJRkuPLCFbhoyGpecxZENhJi9Tjc7YDOY,18692
13
- rtctools/data/pi.py,sha256=o_9whVJofk7F8yvzz9rZdRqyer8FSXZ0TePX5GHa7OQ,42336
13
+ rtctools/data/pi.py,sha256=m7KGieJ6d5j7jQhsc_XVFhEeyMH7j8PvKAcVJ2xpkI4,42363
14
14
  rtctools/data/rtc.py,sha256=2cPDTuU0T4GiueG8ESHUPObtkDY9jahEBQ48Bc-CCeg,8853
15
15
  rtctools/data/storage.py,sha256=A2U1OuBzzTYADCN_BhLf9mmIQN4BZ_GNG_DdN_JoGoo,13011
16
16
  rtctools/data/interpolation/__init__.py,sha256=GBubCIT5mFoSTV-lOk7cpwvZekNMEe5bvqSQJ9HE34M,73
@@ -18,21 +18,21 @@ rtctools/data/interpolation/bspline.py,sha256=xg1PqXlbpBZ5dPE5ngvdnJ7utSZyx8BgMq
18
18
  rtctools/data/interpolation/bspline1d.py,sha256=xLlxKrYNr-DADQ6UILGqgiJCAN-Db40USJa-XOmauFg,6002
19
19
  rtctools/data/interpolation/bspline2d.py,sha256=RJO9XbjrNFNgkYjS88l-c4miu9xW1yroACpQ9v0u7bg,1607
20
20
  rtctools/optimization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- rtctools/optimization/collocated_integrated_optimization_problem.py,sha256=r04BEwFGcanANTgbAWCkaoqOOnci8hGBVsn3ls-rx2I,116362
21
+ rtctools/optimization/collocated_integrated_optimization_problem.py,sha256=G2goCNLx8qARaR0JawJum0Fr4jxtiQAAQAXxaqS4m00,116465
22
22
  rtctools/optimization/control_tree_mixin.py,sha256=mYHJUaskdeChCrqSTIPpFXwBU1JcwlwLtUTjwvR7CQ8,9030
23
- rtctools/optimization/csv_lookup_table_mixin.py,sha256=GJXXTXHGcM_GOeRNhfOiqF7EILeve4Jnu_gc_FcBQio,16296
23
+ rtctools/optimization/csv_lookup_table_mixin.py,sha256=mEZdl1ca69K9ptJdKxCGIle4MrAwBTB4AJiVYQctyZg,16651
24
24
  rtctools/optimization/csv_mixin.py,sha256=FvMcuLlKu-YJo2NNudwMUUYKNb6HN4cevndWjlo5nis,11624
25
- rtctools/optimization/goal_programming_mixin.py,sha256=EIvgmL-BiJhij2ajE6erswtRD447A26d5Yh4MeoAEGY,31601
25
+ rtctools/optimization/goal_programming_mixin.py,sha256=itns49Wq8MSUQWG4XhmlTG4OFkrV_0KeU53Y2vXUXOQ,31616
26
26
  rtctools/optimization/goal_programming_mixin_base.py,sha256=MOXNAlDBOvsPgWMY-D2DUQX2HcOGfFw-bvOmZSiwepk,39951
27
27
  rtctools/optimization/homotopy_mixin.py,sha256=cgRPL-Ag9kd4iJQMbgKrRok-BUaRQwVJSCiAw_-1eck,6782
28
28
  rtctools/optimization/initial_state_estimation_mixin.py,sha256=CasRmqWVtyEpc4DwWcvpEcHBX7y0jsFERg5MSVb2FUo,3126
29
- rtctools/optimization/io_mixin.py,sha256=QkA9TxbMjlGn79WxuMLQyE9yIS-jBSJFLjSn9lkuqdI,11781
29
+ rtctools/optimization/io_mixin.py,sha256=ZvltLXl1UON_GzlPVfkuvZvM2DUsz71B4HPVDoOSMgg,11817
30
30
  rtctools/optimization/linearization_mixin.py,sha256=ZG7553zowwSgl9Roe2yc24cp0DlqKkb2cmImGnaVGt0,1019
31
31
  rtctools/optimization/linearized_order_goal_programming_mixin.py,sha256=Aws3b0rnL-t8Bp_KOI9TbqqcuLb5ofSKKQMYjtUtLS0,8736
32
32
  rtctools/optimization/min_abs_goal_programming_mixin.py,sha256=kom9pV7Th5N31Adoc9RZRlQTcfqIzwui0PDe5AQnYuU,13293
33
33
  rtctools/optimization/modelica_mixin.py,sha256=f8bdeQB5jvlAggfwU4G7WSaT-ityy8D8Ckhi1mpJekA,16202
34
34
  rtctools/optimization/netcdf_mixin.py,sha256=fqhQSiSARQ4l6lwqp6ZDQ-SuIAeMPkQ69NcFnvk97C4,7259
35
- rtctools/optimization/optimization_problem.py,sha256=TsGZIC5yJFXQbiPXxlRWqhRoBVO7RWGRrMm5LdUFuTo,41817
35
+ rtctools/optimization/optimization_problem.py,sha256=p0Tq2gj9sX9tOmMz9n3igXvrI822-lHeu1Tl31n3tg8,43078
36
36
  rtctools/optimization/pi_mixin.py,sha256=0sp0y_GT0BB5Mrv6WSDNIgNUz63mbfVxNPW3LDU7zw4,10785
37
37
  rtctools/optimization/single_pass_goal_programming_mixin.py,sha256=LxLquZYAnhR5wV39S3cgL3jKKQi4C3n6i0K55DETSdc,25126
38
38
  rtctools/optimization/timeseries.py,sha256=W2xYBZRZxKgOQ0aW_le5NDbXOBbokCeK-mjSUUa_EVs,1753
@@ -41,9 +41,9 @@ rtctools/simulation/csv_mixin.py,sha256=SIggsf7lfml3iWyhFSzCSCdxLt86ElluJQYxPYUk
41
41
  rtctools/simulation/io_mixin.py,sha256=DizXxYg3MhOqyYXdHVlF9rLTfOo_aXc59Jh_hzGcgkc,6163
42
42
  rtctools/simulation/pi_mixin.py,sha256=6uvqJZweP7wvEbiPmHMnOldG7_kvtqrdFVme0LVOVCo,9048
43
43
  rtctools/simulation/simulation_problem.py,sha256=FOP0JysrEccjbDevwN-qsD4IXtVZHV6BGP3Tmn9RhNM,35345
44
- rtc_tools-2.5.1rc1.dist-info/COPYING.LESSER,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
45
- rtc_tools-2.5.1rc1.dist-info/METADATA,sha256=flvIFJsthGRXkpUsqmZChkhF246kUaH0X5bsM5qf9Ao,1443
46
- rtc_tools-2.5.1rc1.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
47
- rtc_tools-2.5.1rc1.dist-info/entry_points.txt,sha256=-x622IB_l1duw2M6t6syfQ4yzOiQTp0IZxKGcYRgWgk,151
48
- rtc_tools-2.5.1rc1.dist-info/top_level.txt,sha256=pnBrb58PFPd1kp1dqa-JHU7R55h3alDNJIJnF3Jf9Dw,9
49
- rtc_tools-2.5.1rc1.dist-info/RECORD,,
44
+ rtc_tools-2.5.2a2.dist-info/COPYING.LESSER,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
45
+ rtc_tools-2.5.2a2.dist-info/METADATA,sha256=Fj09TM-bI_B0APYwcNWSEygJfnT4iB4IstUXpf62bQw,1454
46
+ rtc_tools-2.5.2a2.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
47
+ rtc_tools-2.5.2a2.dist-info/entry_points.txt,sha256=-x622IB_l1duw2M6t6syfQ4yzOiQTp0IZxKGcYRgWgk,151
48
+ rtc_tools-2.5.2a2.dist-info/top_level.txt,sha256=pnBrb58PFPd1kp1dqa-JHU7R55h3alDNJIJnF3Jf9Dw,9
49
+ rtc_tools-2.5.2a2.dist-info/RECORD,,
rtctools/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2022-12-08T16:06:43+0000",
11
+ "date": "2023-03-21T15:45:07+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "3f949d10da42fb1aa8b9888f742771dd50947494",
15
- "version": "2.5.1rc1"
14
+ "full-revisionid": "51c2d6cf97df52e8a6790dc74aa9ec0866fc5a5c",
15
+ "version": "2.5.2a2"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
rtctools/data/pi.py CHANGED
@@ -732,14 +732,6 @@ class Timeseries:
732
732
  if self.__binary:
733
733
  f = io.open(self.binary_path, 'wb')
734
734
 
735
- if self.timezone is not None:
736
- timezone = self.__xml_root.find('pi:timeZone', ns)
737
- if timezone is None:
738
- timezone = ET.Element('{%s}' % (ns['pi'], ) + 'timeZone')
739
- # timeZone has to be the first element according to the schema
740
- self.__xml_root.insert(0, timezone)
741
- timezone.text = str(self.timezone)
742
-
743
735
  if self.make_new_file:
744
736
  # Force reinitialization in case write() is called more than once
745
737
  self.__reset_xml_tree()
@@ -753,6 +745,14 @@ class Timeseries:
753
745
  ensemble_member=ensemble_member, miss_val=-999, unit=unit)
754
746
 
755
747
  for ensemble_member in range(len(self.__values)):
748
+ if self.timezone is not None:
749
+ timezone = self.__xml_root.find('pi:timeZone', ns)
750
+ if timezone is None:
751
+ timezone = ET.Element('{%s}' % (ns['pi'],) + 'timeZone')
752
+ # timeZone has to be the first element according to the schema
753
+ self.__xml_root.insert(0, timezone)
754
+ timezone.text = str(self.timezone)
755
+
756
756
  for series in self.__xml_root.findall('pi:series', ns):
757
757
  header = series.find('pi:header', ns)
758
758
 
@@ -227,7 +227,7 @@ class CollocatedIntegratedOptimizationProblem(OptimizationProblem, metaclass=ABC
227
227
 
228
228
  if self.integrated_states:
229
229
  warnings.warn("Integrated states are deprecated and support will be removed in a future version.",
230
- FutureWarning)
230
+ FutureWarning, stacklevel=1)
231
231
 
232
232
  # Variables that are integrated states are not yet allowed to have size > 1
233
233
  for variable in self.integrated_states:
@@ -442,7 +442,8 @@ class CollocatedIntegratedOptimizationProblem(OptimizationProblem, metaclass=ABC
442
442
  # Establish integrator theta
443
443
  theta = self.theta
444
444
  if theta < 1:
445
- warnings.warn("Explicit collocation is deprecated and will be removed in a future version.", FutureWarning)
445
+ warnings.warn("Explicit collocation is deprecated and will be removed in a future version.",
446
+ FutureWarning, stacklevel=1)
446
447
 
447
448
  # Set CasADi function options
448
449
  options = self.solver_options()
@@ -1326,7 +1327,8 @@ class CollocatedIntegratedOptimizationProblem(OptimizationProblem, metaclass=ABC
1326
1327
  ca.repmat(np.nan, len(self.path_variables)),
1327
1328
  ca.repmat(np.nan, len(self.__extra_constant_inputs))),
1328
1329
  ca.repmat(np.nan, len(self.extra_variables))])
1329
- delayed_feedback_history[i, :] = history_delayed_feedback_res
1330
+ delayed_feedback_history[i, :] = [
1331
+ float(val) for val in history_delayed_feedback_res]
1330
1332
 
1331
1333
  initial_delayed_feedback = delayed_feedback_function.call(
1332
1334
  self.__func_initial_inputs[ensemble_member], False, True)
@@ -293,6 +293,11 @@ class CSVLookupTableMixin(OptimizationProblem):
293
293
  curve_name, *curvefit_options))
294
294
  return tuple(curvefit_options)
295
295
 
296
+ def check_lookup_table(lookup_table):
297
+ if lookup_table in self.__lookup_tables:
298
+ raise Exception(
299
+ "Cannot add lookup table {},"
300
+ "since there is already one with this name.".format(lookup_table))
296
301
  # Read CSV files
297
302
  logger.info(
298
303
  "CSVLookupTableMixin: Generating Splines from lookup table data.")
@@ -365,6 +370,7 @@ class CSVLookupTableMixin(OptimizationProblem):
365
370
  symbols = [ca.SX.sym(inputs[0])]
366
371
  if not valid_cache:
367
372
  function = ca.Function('f', symbols, [BSpline1D(*tck)(symbols[0])])
373
+ check_lookup_table(output)
368
374
  self.__lookup_tables[output] = LookupTable(symbols, function, tck)
369
375
 
370
376
  elif len(csvinput.dtype.names) == 3:
@@ -400,6 +406,7 @@ class CSVLookupTableMixin(OptimizationProblem):
400
406
  symbols = [ca.SX.sym(inputs[0]), ca.SX.sym(inputs[1])]
401
407
  if not valid_cache:
402
408
  function = ca.Function('f', symbols, [BSpline2D(*tck)(symbols[0], symbols[1])])
409
+ check_lookup_table(output)
403
410
  self.__lookup_tables[output] = LookupTable(symbols, function, tck)
404
411
 
405
412
  else:
@@ -563,7 +563,7 @@ class GoalProgrammingMixin(_GoalProgrammingMixinBase):
563
563
  self.pre()
564
564
 
565
565
  # Group goals into subproblems
566
- subproblems = []
566
+ self.subproblems = []
567
567
  goals = self.goals()
568
568
  path_goals = self.path_goals()
569
569
 
@@ -580,7 +580,7 @@ class GoalProgrammingMixin(_GoalProgrammingMixinBase):
580
580
  priorities = {int(goal.priority) for goal in itertools.chain(goals, path_goals) if not goal.is_empty}
581
581
 
582
582
  for priority in sorted(priorities):
583
- subproblems.append((
583
+ self.subproblems.append((
584
584
  priority,
585
585
  [goal for goal in goals if int(goal.priority) == priority and not goal.is_empty],
586
586
  [goal for goal in path_goals if int(goal.priority) == priority and not goal.is_empty]))
@@ -605,7 +605,7 @@ class GoalProgrammingMixin(_GoalProgrammingMixinBase):
605
605
  self.__results_are_current = False
606
606
  self.__original_constant_input_keys = {}
607
607
  self.__original_parameter_keys = {}
608
- for i, (priority, goals, path_goals) in enumerate(subproblems):
608
+ for i, (priority, goals, path_goals) in enumerate(self.subproblems):
609
609
  logger.info("Solving goals at priority {}".format(priority))
610
610
 
611
611
  # Call the pre priority hook
@@ -310,5 +310,6 @@ class IOMixin(OptimizationProblem, metaclass=ABCMeta):
310
310
  Deprecated, use `io.reference_datetime` and `io.datetimes`, or override behavior using
311
311
  :py:meth:`OptimizationProblem.times` and/or :py:attr:`OptimizationProblem.initial_time`.
312
312
  """
313
- warnings.warn('get_forecast_index() is deprecated and will be removed in the future', FutureWarning)
313
+ warnings.warn('get_forecast_index() is deprecated and will be removed in the future',
314
+ FutureWarning, stacklevel=1)
314
315
  return bisect.bisect_left(self.io.datetimes, self.io.reference_datetime)
@@ -155,12 +155,34 @@ class OptimizationProblem(DataStoreAccessor, metaclass=ABCMeta):
155
155
 
156
156
  success, log_level = self.solver_success(self.__solver_stats, log_solver_failure_as_error)
157
157
 
158
+ return_status = self.__solver_stats['return_status']
159
+ if 'secondary_return_status' in self.__solver_stats:
160
+ return_status = "{}: {}".format(return_status, self.__solver_stats['secondary_return_status'])
161
+ wall_clock_time = "elapsed time not read"
162
+ if 't_wall_total' in self.__solver_stats:
163
+ wall_clock_time = "{} seconds".format(self.__solver_stats['t_wall_total'])
164
+ elif 't_wall_solver' in self.__solver_stats:
165
+ wall_clock_time = "{} seconds".format(self.__solver_stats['t_wall_solver'])
166
+
158
167
  if success:
159
- logger.log(log_level, "Solver succeeded with status {}".format(
160
- self.__solver_stats['return_status']))
168
+ logger.log(log_level, "Solver succeeded with status {} ({}).".format(
169
+ return_status, wall_clock_time))
161
170
  else:
162
- logger.log(log_level, "Solver failed with status {}".format(
163
- self.__solver_stats['return_status']))
171
+ try:
172
+ ii = [y[0] for y in self.loop_over_error].index(self.priority)
173
+ loop_error_indicator = self.loop_over_error[ii][1]
174
+ try:
175
+ loop_error = self.loop_over_error[ii][2]
176
+ if loop_error_indicator and loop_error in return_status:
177
+ log_level = logging.INFO
178
+ except IndexError:
179
+ if loop_error_indicator:
180
+ log_level = logging.INFO
181
+ logger.log(log_level, "Solver succeeded with status {} ({}).".format(
182
+ return_status, wall_clock_time))
183
+ except (AttributeError, ValueError):
184
+ logger.log(log_level, "Solver succeeded with status {} ({}).".format(
185
+ return_status, wall_clock_time))
164
186
 
165
187
  # Do any postprocessing
166
188
  if postprocessing: