libecalc 8.19.0__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.
Files changed (399) hide show
  1. ecalc_cli/README.md +14 -0
  2. ecalc_cli/__init__.py +0 -0
  3. ecalc_cli/commands/__init__.py +0 -0
  4. ecalc_cli/commands/run.py +222 -0
  5. ecalc_cli/commands/selftest.py +38 -0
  6. ecalc_cli/commands/show.py +120 -0
  7. ecalc_cli/errors.py +4 -0
  8. ecalc_cli/io/__init__.py +0 -0
  9. ecalc_cli/io/cache.py +108 -0
  10. ecalc_cli/io/output.py +197 -0
  11. ecalc_cli/logger.py +103 -0
  12. ecalc_cli/main.py +88 -0
  13. ecalc_cli/types.py +19 -0
  14. ecalc_neqsim_wrapper/README.md +9 -0
  15. ecalc_neqsim_wrapper/__init__.py +18 -0
  16. ecalc_neqsim_wrapper/components.py +195 -0
  17. ecalc_neqsim_wrapper/exceptions.py +10 -0
  18. ecalc_neqsim_wrapper/java_service.py +27 -0
  19. ecalc_neqsim_wrapper/lib/NeqSim.jar +0 -0
  20. ecalc_neqsim_wrapper/lib/neqsim_version_info.md +30 -0
  21. ecalc_neqsim_wrapper/mappings.py +74 -0
  22. ecalc_neqsim_wrapper/thermo.py +435 -0
  23. libecalc/__init__.py +0 -0
  24. libecalc/application/__init__.py +0 -0
  25. libecalc/application/energy_calculator.py +193 -0
  26. libecalc/application/graph_result.py +63 -0
  27. libecalc/common/__init__.py +5 -0
  28. libecalc/common/component_info/__init__.py +0 -0
  29. libecalc/common/component_info/component_level.py +10 -0
  30. libecalc/common/component_info/compressor.py +6 -0
  31. libecalc/common/datetime/__init__.py +0 -0
  32. libecalc/common/datetime/utils.py +24 -0
  33. libecalc/common/decorators/__init__.py +0 -0
  34. libecalc/common/decorators/capturer.py +80 -0
  35. libecalc/common/decorators/feature_flags.py +82 -0
  36. libecalc/common/discriminator_fallback.py +25 -0
  37. libecalc/common/errors/__init__.py +0 -0
  38. libecalc/common/errors/exceptions.py +82 -0
  39. libecalc/common/graph.py +86 -0
  40. libecalc/common/list/__init__.py +0 -0
  41. libecalc/common/list/adjustment.py +17 -0
  42. libecalc/common/list/list_utils.py +126 -0
  43. libecalc/common/logger.py +17 -0
  44. libecalc/common/math/__init__.py +0 -0
  45. libecalc/common/math/math_utils.py +43 -0
  46. libecalc/common/math/numbers.py +92 -0
  47. libecalc/common/priorities.py +7 -0
  48. libecalc/common/priority_optimizer.py +71 -0
  49. libecalc/common/run_info.py +20 -0
  50. libecalc/common/stream_conditions.py +137 -0
  51. libecalc/common/string/__init__.py +0 -0
  52. libecalc/common/string/string_utils.py +42 -0
  53. libecalc/common/tabular_time_series.py +84 -0
  54. libecalc/common/temporal_model.py +58 -0
  55. libecalc/common/time_utils.py +281 -0
  56. libecalc/common/units.py +229 -0
  57. libecalc/common/utils/calculate_emission_intensity.py +82 -0
  58. libecalc/common/utils/rates.py +1159 -0
  59. libecalc/common/version.py +93 -0
  60. libecalc/core/__init__.py +0 -0
  61. libecalc/core/consumers/__init__.py +0 -0
  62. libecalc/core/consumers/base/__init__.py +1 -0
  63. libecalc/core/consumers/base/component.py +29 -0
  64. libecalc/core/consumers/compressor/__init__.py +1 -0
  65. libecalc/core/consumers/compressor/component.py +136 -0
  66. libecalc/core/consumers/consumer_system.py +244 -0
  67. libecalc/core/consumers/factory.py +53 -0
  68. libecalc/core/consumers/generator_set.py +109 -0
  69. libecalc/core/consumers/legacy_consumer/__init__.py +0 -0
  70. libecalc/core/consumers/legacy_consumer/component.py +401 -0
  71. libecalc/core/consumers/legacy_consumer/consumer_function/__init__.py +3 -0
  72. libecalc/core/consumers/legacy_consumer/consumer_function/compressor_consumer_function.py +173 -0
  73. libecalc/core/consumers/legacy_consumer/consumer_function/consumer_function.py +60 -0
  74. libecalc/core/consumers/legacy_consumer/consumer_function/consumer_tabular_energy_function.py +112 -0
  75. libecalc/core/consumers/legacy_consumer/consumer_function/direct_expression_consumer_function.py +116 -0
  76. libecalc/core/consumers/legacy_consumer/consumer_function/pump_consumer_function.py +120 -0
  77. libecalc/core/consumers/legacy_consumer/consumer_function/results.py +84 -0
  78. libecalc/core/consumers/legacy_consumer/consumer_function/types.py +6 -0
  79. libecalc/core/consumers/legacy_consumer/consumer_function/utils.py +90 -0
  80. libecalc/core/consumers/legacy_consumer/consumer_function_mapper/__init__.py +47 -0
  81. libecalc/core/consumers/legacy_consumer/consumer_function_mapper/compressor_consumer_function.py +18 -0
  82. libecalc/core/consumers/legacy_consumer/consumer_function_mapper/compressor_system_consumer_function.py +103 -0
  83. libecalc/core/consumers/legacy_consumer/consumer_function_mapper/direct_consumer_function.py +8 -0
  84. libecalc/core/consumers/legacy_consumer/consumer_function_mapper/pump_consumer_function.py +18 -0
  85. libecalc/core/consumers/legacy_consumer/consumer_function_mapper/pump_system_consumer_function.py +69 -0
  86. libecalc/core/consumers/legacy_consumer/consumer_function_mapper/tabulated.py +57 -0
  87. libecalc/core/consumers/legacy_consumer/result_mapper.py +221 -0
  88. libecalc/core/consumers/legacy_consumer/system/__init__.py +4 -0
  89. libecalc/core/consumers/legacy_consumer/system/consumer_function.py +447 -0
  90. libecalc/core/consumers/legacy_consumer/system/operational_setting.py +152 -0
  91. libecalc/core/consumers/legacy_consumer/system/results.py +147 -0
  92. libecalc/core/consumers/legacy_consumer/system/types.py +12 -0
  93. libecalc/core/consumers/legacy_consumer/system/utils.py +122 -0
  94. libecalc/core/consumers/pump/__init__.py +1 -0
  95. libecalc/core/consumers/pump/component.py +136 -0
  96. libecalc/core/models/__init__.py +5 -0
  97. libecalc/core/models/base.py +2 -0
  98. libecalc/core/models/chart/__init__.py +3 -0
  99. libecalc/core/models/chart/base.py +191 -0
  100. libecalc/core/models/chart/single_speed_chart.py +36 -0
  101. libecalc/core/models/chart/variable_speed_chart.py +435 -0
  102. libecalc/core/models/compressor/__init__.py +2 -0
  103. libecalc/core/models/compressor/base.py +193 -0
  104. libecalc/core/models/compressor/factory.py +134 -0
  105. libecalc/core/models/compressor/results.py +627 -0
  106. libecalc/core/models/compressor/sampled/__init__.py +1 -0
  107. libecalc/core/models/compressor/sampled/compressor_model_sampled.py +372 -0
  108. libecalc/core/models/compressor/sampled/compressor_model_sampled_1d.py +139 -0
  109. libecalc/core/models/compressor/sampled/compressor_model_sampled_2d.py +349 -0
  110. libecalc/core/models/compressor/sampled/compressor_model_sampled_3d.py +861 -0
  111. libecalc/core/models/compressor/sampled/constants.py +5 -0
  112. libecalc/core/models/compressor/sampled/convex_hull_common.py +494 -0
  113. libecalc/core/models/compressor/train/__init__.py +0 -0
  114. libecalc/core/models/compressor/train/base.py +230 -0
  115. libecalc/core/models/compressor/train/chart/__init__.py +2 -0
  116. libecalc/core/models/compressor/train/chart/chart_creator.py +240 -0
  117. libecalc/core/models/compressor/train/chart/generic_chart_data.py +56 -0
  118. libecalc/core/models/compressor/train/chart/single_speed_compressor_chart.py +86 -0
  119. libecalc/core/models/compressor/train/chart/types.py +51 -0
  120. libecalc/core/models/compressor/train/chart/variable_speed_compressor_chart.py +529 -0
  121. libecalc/core/models/compressor/train/fluid.py +283 -0
  122. libecalc/core/models/compressor/train/simplified_train.py +624 -0
  123. libecalc/core/models/compressor/train/single_speed_compressor_train_common_shaft.py +974 -0
  124. libecalc/core/models/compressor/train/stage.py +270 -0
  125. libecalc/core/models/compressor/train/types.py +32 -0
  126. libecalc/core/models/compressor/train/utils/__init__.py +0 -0
  127. libecalc/core/models/compressor/train/utils/common.py +148 -0
  128. libecalc/core/models/compressor/train/utils/enthalpy_calculations.py +265 -0
  129. libecalc/core/models/compressor/train/utils/numeric_methods.py +167 -0
  130. libecalc/core/models/compressor/train/utils/variable_speed_compressor_train_common_shaft.py +44 -0
  131. libecalc/core/models/compressor/train/variable_speed_compressor_train_common_shaft.py +780 -0
  132. libecalc/core/models/compressor/train/variable_speed_compressor_train_common_shaft_multiple_streams_and_pressures.py +1580 -0
  133. libecalc/core/models/compressor/utils.py +81 -0
  134. libecalc/core/models/fuel.py +91 -0
  135. libecalc/core/models/generator.py +39 -0
  136. libecalc/core/models/model_input_validation.py +212 -0
  137. libecalc/core/models/pump/__init__.py +2 -0
  138. libecalc/core/models/pump/factory.py +64 -0
  139. libecalc/core/models/pump/pump.py +355 -0
  140. libecalc/core/models/results/__init__.py +9 -0
  141. libecalc/core/models/results/base.py +76 -0
  142. libecalc/core/models/results/compressor.py +267 -0
  143. libecalc/core/models/results/generic.py +7 -0
  144. libecalc/core/models/results/pump.py +13 -0
  145. libecalc/core/models/results/turbine.py +23 -0
  146. libecalc/core/models/tabulated.py +103 -0
  147. libecalc/core/models/turbine.py +76 -0
  148. libecalc/core/result/__init__.py +11 -0
  149. libecalc/core/result/base.py +56 -0
  150. libecalc/core/result/emission.py +28 -0
  151. libecalc/core/result/results.py +179 -0
  152. libecalc/core/utils/__init__.py +0 -0
  153. libecalc/core/utils/array_type.py +25 -0
  154. libecalc/domain/__init__.py +0 -0
  155. libecalc/domain/stream_conditions.py +114 -0
  156. libecalc/domain/tabular/__init__.py +0 -0
  157. libecalc/domain/tabular/exceptions.py +20 -0
  158. libecalc/domain/tabular/tabular.py +38 -0
  159. libecalc/dto/__init__.py +58 -0
  160. libecalc/dto/base.py +88 -0
  161. libecalc/dto/component_graph.py +64 -0
  162. libecalc/dto/components.py +509 -0
  163. libecalc/dto/core_specs/__init__.py +0 -0
  164. libecalc/dto/core_specs/base/__init__.py +0 -0
  165. libecalc/dto/core_specs/base/operational_settings.py +12 -0
  166. libecalc/dto/core_specs/compressor/__init__.py +0 -0
  167. libecalc/dto/core_specs/compressor/operational_settings.py +30 -0
  168. libecalc/dto/core_specs/pump/__init__.py +0 -0
  169. libecalc/dto/core_specs/pump/operational_settings.py +30 -0
  170. libecalc/dto/core_specs/system/__init__.py +0 -0
  171. libecalc/dto/emission.py +17 -0
  172. libecalc/dto/models/__init__.py +78 -0
  173. libecalc/dto/models/base.py +25 -0
  174. libecalc/dto/models/chart.py +105 -0
  175. libecalc/dto/models/compressor/__init__.py +33 -0
  176. libecalc/dto/models/compressor/base.py +66 -0
  177. libecalc/dto/models/compressor/chart.py +21 -0
  178. libecalc/dto/models/compressor/fluid.py +66 -0
  179. libecalc/dto/models/compressor/sampled.py +47 -0
  180. libecalc/dto/models/compressor/stage.py +33 -0
  181. libecalc/dto/models/compressor/train.py +203 -0
  182. libecalc/dto/models/consumer_system.py +112 -0
  183. libecalc/dto/models/direct.py +28 -0
  184. libecalc/dto/models/generator_set.py +34 -0
  185. libecalc/dto/models/pump.py +35 -0
  186. libecalc/dto/models/sampled.py +10 -0
  187. libecalc/dto/models/tabulated.py +38 -0
  188. libecalc/dto/models/turbine.py +28 -0
  189. libecalc/dto/node_info.py +12 -0
  190. libecalc/dto/result_options.py +12 -0
  191. libecalc/dto/types.py +145 -0
  192. libecalc/dto/utils/__init__.py +0 -0
  193. libecalc/dto/utils/validators.py +56 -0
  194. libecalc/dto/variables.py +67 -0
  195. libecalc/examples/__init__.py +2 -0
  196. libecalc/examples/advanced/__init__.py +29 -0
  197. libecalc/examples/advanced/base_profile.csv +23 -0
  198. libecalc/examples/advanced/compressor_chart.csv +12 -0
  199. libecalc/examples/advanced/compressor_sampled.csv +5 -0
  200. libecalc/examples/advanced/genset.csv +8 -0
  201. libecalc/examples/advanced/model.yaml +212 -0
  202. libecalc/examples/advanced/pump_chart.csv +10 -0
  203. libecalc/examples/simple/__init__.py +46 -0
  204. libecalc/examples/simple/compressor_sampled.csv +17 -0
  205. libecalc/examples/simple/compressor_sampled_with_turbine.csv +7 -0
  206. libecalc/examples/simple/genset.csv +8 -0
  207. libecalc/examples/simple/model.yaml +100 -0
  208. libecalc/examples/simple/model_duplicate_emissions_in_fuel.yaml +42 -0
  209. libecalc/examples/simple/model_duplicate_names.yaml +38 -0
  210. libecalc/examples/simple/model_multiple_energy_models_one_consumer.yaml +44 -0
  211. libecalc/examples/simple/model_temporal.yaml +117 -0
  212. libecalc/examples/simple/production_data.csv +13 -0
  213. libecalc/examples/simple/pump_chart.csv +7 -0
  214. libecalc/examples/simple/pump_sampled.csv +9 -0
  215. libecalc/expression/__init__.py +1 -0
  216. libecalc/expression/expression.py +202 -0
  217. libecalc/expression/expression_evaluator.py +408 -0
  218. libecalc/fixtures/.gitignore +1 -0
  219. libecalc/fixtures/__init__.py +18 -0
  220. libecalc/fixtures/case_types.py +18 -0
  221. libecalc/fixtures/case_utils.py +32 -0
  222. libecalc/fixtures/cases/__init__.py +0 -0
  223. libecalc/fixtures/cases/all_energy_usage_models/__init__.py +79 -0
  224. libecalc/fixtures/cases/all_energy_usage_models/all_models_dto.py +1170 -0
  225. libecalc/fixtures/cases/all_energy_usage_models/conftest.py +260 -0
  226. libecalc/fixtures/cases/all_energy_usage_models/data/Archive.zip +0 -0
  227. libecalc/fixtures/cases/all_energy_usage_models/data/all_energy_usage_models.yaml +625 -0
  228. libecalc/fixtures/cases/all_energy_usage_models/data/einput/compressor_sampled_1d.csv +7 -0
  229. libecalc/fixtures/cases/all_energy_usage_models/data/einput/genset.csv +10 -0
  230. libecalc/fixtures/cases/all_energy_usage_models/data/einput/predefined_compressor_chart_curves.csv +37 -0
  231. libecalc/fixtures/cases/all_energy_usage_models/data/einput/pump_tabular.csv +11 -0
  232. libecalc/fixtures/cases/all_energy_usage_models/data/einput/pumpchart.csv +8 -0
  233. libecalc/fixtures/cases/all_energy_usage_models/data/einput/pumpchart_variable_speed.csv +19 -0
  234. libecalc/fixtures/cases/all_energy_usage_models/data/einput/tabular.csv +6 -0
  235. libecalc/fixtures/cases/all_energy_usage_models/data/sim/base_profile.csv +5 -0
  236. libecalc/fixtures/cases/all_energy_usage_models/data/sim/flare.csv +5 -0
  237. libecalc/fixtures/cases/consumer_system_v2/__init__.py +27 -0
  238. libecalc/fixtures/cases/consumer_system_v2/consumer_system_v2_dto.py +660 -0
  239. libecalc/fixtures/cases/consumer_system_v2/data/compressor1.csv +5 -0
  240. libecalc/fixtures/cases/consumer_system_v2/data/compressor_sampled_1d.csv +7 -0
  241. libecalc/fixtures/cases/consumer_system_v2/data/consumer_system_v2.yaml +286 -0
  242. libecalc/fixtures/cases/consumer_system_v2/data/genset.csv +4 -0
  243. libecalc/fixtures/cases/consumer_system_v2/data/pumpchart.csv +7 -0
  244. libecalc/fixtures/cases/consumer_system_v2_multiple_streams/data/compressor1.csv +5 -0
  245. libecalc/fixtures/cases/consumer_system_v2_multiple_streams/data/compressor_sampled_1d.csv +7 -0
  246. libecalc/fixtures/cases/consumer_system_v2_multiple_streams/data/consumer_system_v2.yaml +193 -0
  247. libecalc/fixtures/cases/consumer_system_v2_multiple_streams/data/einput/predefined_compressor_chart_curves.csv +37 -0
  248. libecalc/fixtures/cases/consumer_system_v2_multiple_streams/data/genset.csv +4 -0
  249. libecalc/fixtures/cases/consumer_with_time_slots_models.py +296 -0
  250. libecalc/fixtures/cases/input_file_examples/__init__.py +0 -0
  251. libecalc/fixtures/cases/input_file_examples/einput/tabular_missing_header_fuel.csv +6 -0
  252. libecalc/fixtures/cases/input_file_examples/sim/base_profile_missing_header_oil_prod.csv +5 -0
  253. libecalc/fixtures/cases/ltp_export/__init__.py +35 -0
  254. libecalc/fixtures/cases/ltp_export/data/.gitignore +1 -0
  255. libecalc/fixtures/cases/ltp_export/data/einput/gascompression.csv +1286 -0
  256. libecalc/fixtures/cases/ltp_export/data/einput/gascompression_zero_power.csv +1286 -0
  257. libecalc/fixtures/cases/ltp_export/data/einput/genset_17MW.csv +26 -0
  258. libecalc/fixtures/cases/ltp_export/data/einput/onshore_power.csv +5 -0
  259. libecalc/fixtures/cases/ltp_export/data/einput/pumpchart_water_inj.csv +12 -0
  260. libecalc/fixtures/cases/ltp_export/data/ltp_export.yaml +575 -0
  261. libecalc/fixtures/cases/ltp_export/data/sim/cable_loss.csv +11 -0
  262. libecalc/fixtures/cases/ltp_export/data/sim/flare_diesel_cold_venting_fugitives.csv +25 -0
  263. libecalc/fixtures/cases/ltp_export/data/sim/max_usage_from_shore.csv +12 -0
  264. libecalc/fixtures/cases/ltp_export/data/sim/mobile_installations_host_field.csv +14 -0
  265. libecalc/fixtures/cases/ltp_export/data/sim/mobile_installations_satellite_A.csv +14 -0
  266. libecalc/fixtures/cases/ltp_export/data/sim/mobile_installations_satellite_B.csv +14 -0
  267. libecalc/fixtures/cases/ltp_export/data/sim/prod_inj_forecast.csv +25 -0
  268. libecalc/fixtures/cases/ltp_export/data/sim/steamgen.csv +25 -0
  269. libecalc/fixtures/cases/ltp_export/installation_setup.py +514 -0
  270. libecalc/fixtures/cases/ltp_export/loading_storage_ltp_yaml.py +64 -0
  271. libecalc/fixtures/cases/ltp_export/ltp_power_from_shore_yaml.py +101 -0
  272. libecalc/fixtures/cases/ltp_export/utilities.py +38 -0
  273. libecalc/fixtures/cases/minimal/__init__.py +2 -0
  274. libecalc/fixtures/cases/minimal/minimal_dto.py +68 -0
  275. libecalc/fixtures/cases/minimal/minimal_yaml.py +39 -0
  276. libecalc/fixtures/cases/venting_emitters/__init__.py +1 -0
  277. libecalc/fixtures/cases/venting_emitters/venting_emitter_yaml.py +183 -0
  278. libecalc/fixtures/compressor_process_simulations/compressor_process_simulations.py +619 -0
  279. libecalc/fixtures/conftest.py +123 -0
  280. libecalc/infrastructure/__init__.py +0 -0
  281. libecalc/infrastructure/file_io.py +526 -0
  282. libecalc/infrastructure/file_utils.py +182 -0
  283. libecalc/presentation/__init__.py +0 -0
  284. libecalc/presentation/exporter/__init__.py +0 -0
  285. libecalc/presentation/exporter/aggregators.py +89 -0
  286. libecalc/presentation/exporter/appliers.py +104 -0
  287. libecalc/presentation/exporter/configs/__init__.py +0 -0
  288. libecalc/presentation/exporter/configs/configs.py +734 -0
  289. libecalc/presentation/exporter/dto/__init__.py +0 -0
  290. libecalc/presentation/exporter/dto/dtos.py +113 -0
  291. libecalc/presentation/exporter/exporter.py +34 -0
  292. libecalc/presentation/exporter/filters.py +38 -0
  293. libecalc/presentation/exporter/formatters/__init__.py +0 -0
  294. libecalc/presentation/exporter/formatters/formatter.py +57 -0
  295. libecalc/presentation/exporter/generators.py +36 -0
  296. libecalc/presentation/exporter/handlers/__init__.py +0 -0
  297. libecalc/presentation/exporter/handlers/handler.py +82 -0
  298. libecalc/presentation/exporter/queries.py +726 -0
  299. libecalc/presentation/flow_diagram/EcalcModelMapper.py +578 -0
  300. libecalc/presentation/flow_diagram/__init__.py +0 -0
  301. libecalc/presentation/flow_diagram/fde_models.py +79 -0
  302. libecalc/presentation/json_result/__init__.py +0 -0
  303. libecalc/presentation/json_result/aggregators.py +54 -0
  304. libecalc/presentation/json_result/mapper.py +1448 -0
  305. libecalc/presentation/json_result/result/__init__.py +17 -0
  306. libecalc/presentation/json_result/result/base.py +13 -0
  307. libecalc/presentation/json_result/result/emission.py +75 -0
  308. libecalc/presentation/json_result/result/results.py +308 -0
  309. libecalc/presentation/json_result/result/tabular_time_series.py +119 -0
  310. libecalc/presentation/simple_result/__init__.py +5 -0
  311. libecalc/presentation/simple_result/simple.py +370 -0
  312. libecalc/presentation/yaml/__init__.py +0 -0
  313. libecalc/presentation/yaml/energy_model_validation.py +17 -0
  314. libecalc/presentation/yaml/file_context.py +52 -0
  315. libecalc/presentation/yaml/ltp_validation.py +33 -0
  316. libecalc/presentation/yaml/mappers/__init__.py +0 -0
  317. libecalc/presentation/yaml/mappers/component_mapper.py +324 -0
  318. libecalc/presentation/yaml/mappers/consumer_function_mapper.py +351 -0
  319. libecalc/presentation/yaml/mappers/create_references.py +158 -0
  320. libecalc/presentation/yaml/mappers/facility_input.py +203 -0
  321. libecalc/presentation/yaml/mappers/fluid_mapper.py +147 -0
  322. libecalc/presentation/yaml/mappers/fuel_and_emission_mapper.py +37 -0
  323. libecalc/presentation/yaml/mappers/model.py +669 -0
  324. libecalc/presentation/yaml/mappers/utils.py +305 -0
  325. libecalc/presentation/yaml/mappers/variables_mapper/__init__.py +1 -0
  326. libecalc/presentation/yaml/mappers/variables_mapper/time_series.py +8 -0
  327. libecalc/presentation/yaml/mappers/variables_mapper/time_series_collection.py +161 -0
  328. libecalc/presentation/yaml/mappers/variables_mapper/time_series_collection_mapper.py +109 -0
  329. libecalc/presentation/yaml/mappers/variables_mapper/timeseries_utils.py +160 -0
  330. libecalc/presentation/yaml/mappers/variables_mapper/variables_mapper.py +141 -0
  331. libecalc/presentation/yaml/model.py +93 -0
  332. libecalc/presentation/yaml/parse_input.py +23 -0
  333. libecalc/presentation/yaml/validation_errors.py +323 -0
  334. libecalc/presentation/yaml/yaml_entities.py +59 -0
  335. libecalc/presentation/yaml/yaml_keywords.py +192 -0
  336. libecalc/presentation/yaml/yaml_models/__init__.py +0 -0
  337. libecalc/presentation/yaml/yaml_models/exceptions.py +20 -0
  338. libecalc/presentation/yaml/yaml_models/pyyaml_yaml_model.py +469 -0
  339. libecalc/presentation/yaml/yaml_models/ruamel_yaml_model.py +156 -0
  340. libecalc/presentation/yaml/yaml_models/yaml_model.py +260 -0
  341. libecalc/presentation/yaml/yaml_types/__init__.py +9 -0
  342. libecalc/presentation/yaml/yaml_types/components/__init__.py +0 -0
  343. libecalc/presentation/yaml/yaml_types/components/legacy/__init__.py +0 -0
  344. libecalc/presentation/yaml/yaml_types/components/legacy/energy_usage_model/__init__.py +47 -0
  345. libecalc/presentation/yaml/yaml_types/components/legacy/energy_usage_model/common.py +27 -0
  346. libecalc/presentation/yaml/yaml_types/components/legacy/energy_usage_model/yaml_energy_usage_model_compressor.py +42 -0
  347. libecalc/presentation/yaml/yaml_types/components/legacy/energy_usage_model/yaml_energy_usage_model_compressor_train_multiple_streams.py +51 -0
  348. libecalc/presentation/yaml/yaml_types/components/legacy/energy_usage_model/yaml_energy_usage_model_consumer_system.py +138 -0
  349. libecalc/presentation/yaml/yaml_types/components/legacy/energy_usage_model/yaml_energy_usage_model_direct.py +40 -0
  350. libecalc/presentation/yaml/yaml_types/components/legacy/energy_usage_model/yaml_energy_usage_model_pump.py +47 -0
  351. libecalc/presentation/yaml/yaml_types/components/legacy/energy_usage_model/yaml_energy_usage_model_tabulated.py +46 -0
  352. libecalc/presentation/yaml/yaml_types/components/legacy/yaml_electricity_consumer.py +48 -0
  353. libecalc/presentation/yaml/yaml_types/components/legacy/yaml_fuel_consumer.py +54 -0
  354. libecalc/presentation/yaml/yaml_types/components/system/__init__.py +0 -0
  355. libecalc/presentation/yaml/yaml_types/components/system/yaml_consumer_system.py +122 -0
  356. libecalc/presentation/yaml/yaml_types/components/system/yaml_system_component_conditions.py +55 -0
  357. libecalc/presentation/yaml/yaml_types/components/train/yaml_train.py +69 -0
  358. libecalc/presentation/yaml/yaml_types/components/yaml_asset.py +75 -0
  359. libecalc/presentation/yaml/yaml_types/components/yaml_base.py +25 -0
  360. libecalc/presentation/yaml/yaml_types/components/yaml_category_field.py +11 -0
  361. libecalc/presentation/yaml/yaml_types/components/yaml_compressor.py +62 -0
  362. libecalc/presentation/yaml/yaml_types/components/yaml_expression_type.py +49 -0
  363. libecalc/presentation/yaml/yaml_types/components/yaml_generator_set.py +80 -0
  364. libecalc/presentation/yaml/yaml_types/components/yaml_installation.py +93 -0
  365. libecalc/presentation/yaml/yaml_types/components/yaml_pump.py +59 -0
  366. libecalc/presentation/yaml/yaml_types/emitters/__init__.py +0 -0
  367. libecalc/presentation/yaml/yaml_types/emitters/yaml_venting_emitter.py +297 -0
  368. libecalc/presentation/yaml/yaml_types/facility_model/__init__.py +0 -0
  369. libecalc/presentation/yaml/yaml_types/facility_model/yaml_facility_model.py +120 -0
  370. libecalc/presentation/yaml/yaml_types/fuel_type/__init__.py +0 -0
  371. libecalc/presentation/yaml/yaml_types/fuel_type/yaml_emission.py +22 -0
  372. libecalc/presentation/yaml/yaml_types/fuel_type/yaml_fuel_type.py +34 -0
  373. libecalc/presentation/yaml/yaml_types/models/__init__.py +27 -0
  374. libecalc/presentation/yaml/yaml_types/models/model_reference.py +1 -0
  375. libecalc/presentation/yaml/yaml_types/models/model_reference_validation.py +236 -0
  376. libecalc/presentation/yaml/yaml_types/models/yaml_compressor_chart.py +135 -0
  377. libecalc/presentation/yaml/yaml_types/models/yaml_compressor_stages.py +98 -0
  378. libecalc/presentation/yaml/yaml_types/models/yaml_compressor_trains.py +177 -0
  379. libecalc/presentation/yaml/yaml_types/models/yaml_compressor_with_turbine.py +37 -0
  380. libecalc/presentation/yaml/yaml_types/models/yaml_enums.py +29 -0
  381. libecalc/presentation/yaml/yaml_types/models/yaml_fluid.py +85 -0
  382. libecalc/presentation/yaml/yaml_types/models/yaml_turbine.py +59 -0
  383. libecalc/presentation/yaml/yaml_types/time_series/__init__.py +0 -0
  384. libecalc/presentation/yaml/yaml_types/time_series/yaml_time_series.py +74 -0
  385. libecalc/presentation/yaml/yaml_types/yaml_data_or_file.py +36 -0
  386. libecalc/presentation/yaml/yaml_types/yaml_default_datetime.py +20 -0
  387. libecalc/presentation/yaml/yaml_types/yaml_stream.py +46 -0
  388. libecalc/presentation/yaml/yaml_types/yaml_stream_conditions.py +101 -0
  389. libecalc/presentation/yaml/yaml_types/yaml_temporal_model.py +46 -0
  390. libecalc/presentation/yaml/yaml_types/yaml_variable.py +30 -0
  391. libecalc/presentation/yaml/yaml_validation_context.py +31 -0
  392. libecalc/presentation/yaml/yaml_validators/__init__.py +0 -0
  393. libecalc/presentation/yaml/yaml_validators/file_validators.py +22 -0
  394. libecalc/version.py +13 -0
  395. libecalc-8.19.0.dist-info/LICENSE +165 -0
  396. libecalc-8.19.0.dist-info/METADATA +165 -0
  397. libecalc-8.19.0.dist-info/RECORD +399 -0
  398. libecalc-8.19.0.dist-info/WHEEL +4 -0
  399. libecalc-8.19.0.dist-info/entry_points.txt +3 -0
ecalc_cli/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # eCalc CLI
2
+
3
+ eCalc CLI is provided as a part of the libeCalc package as an example UI for how to use libeCalc, AND for a more
4
+ convenient way to use libeCalc without needing to have knowledge about programming.
5
+
6
+ eCalc CLI is implemented with Typer, that provides helpful interactive help on how to use it.
7
+
8
+ Start with
9
+
10
+ ```shell
11
+ ecalc --help
12
+ ```
13
+
14
+ and go on from there.
ecalc_cli/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,222 @@
1
+ from datetime import datetime
2
+ from pathlib import Path
3
+
4
+ import libecalc.common.time_utils
5
+ import libecalc.version
6
+ import typer
7
+ from libecalc.application.energy_calculator import EnergyCalculator
8
+ from libecalc.application.graph_result import GraphResult
9
+ from libecalc.common.math.numbers import Numbers
10
+ from libecalc.common.run_info import RunInfo
11
+ from libecalc.infrastructure.file_utils import OutputFormat, get_result_output
12
+ from libecalc.presentation.json_result.mapper import get_asset_result
13
+ from libecalc.presentation.yaml.model import YamlModel
14
+
15
+ from ecalc_cli.errors import EcalcCLIError
16
+ from ecalc_cli.io.cache import Cache
17
+ from ecalc_cli.io.output import (
18
+ write_flow_diagram,
19
+ write_json,
20
+ write_ltp_export,
21
+ write_output,
22
+ write_stp_export,
23
+ )
24
+ from ecalc_cli.logger import logger
25
+ from ecalc_cli.types import DateFormat, Frequency
26
+
27
+
28
+ def run(
29
+ model_file: Path = typer.Argument(
30
+ ...,
31
+ help="The Model YAML-file specifying time series inputs,"
32
+ " facility inputs and the relationship between energy consumers.",
33
+ ),
34
+ output_frequency: Frequency = typer.Option(
35
+ libecalc.common.time_utils.Frequency.NONE.name,
36
+ "--output-frequency",
37
+ "-f",
38
+ "--outputfrequency",
39
+ help="Frequency of output. Options are DAY, MONTH, YEAR. If not specified, it will give"
40
+ " time steps equal to the union of all input given with INFLUENCE_TIME_VECTOR set to True."
41
+ " Down-sampling the result may lead to loss of data, and rates such as MW may not add up to cumulative values",
42
+ ),
43
+ csv: bool = typer.Option(
44
+ True,
45
+ "--csv",
46
+ "-c",
47
+ help="Toggle output of csv data.",
48
+ ),
49
+ json: bool = typer.Option(
50
+ False,
51
+ "--json",
52
+ help="Toggle output of json output.",
53
+ ),
54
+ output_folder: Path = typer.Option(
55
+ None,
56
+ "--output-folder",
57
+ "-o",
58
+ "--outputfolder",
59
+ help="Outputfolder. Defaults to output/ relative to the yml setup file",
60
+ show_default=False,
61
+ ),
62
+ name_prefix: str = typer.Option(
63
+ None,
64
+ "--name-prefix",
65
+ "-n",
66
+ "--nameprefix",
67
+ help="Name prefix for output data. Defaults to name of setup file.",
68
+ ),
69
+ ltp_export: bool = typer.Option(
70
+ False,
71
+ "--ltp-export",
72
+ help="In addition to standard output, a specific Long Term Prognosis (LTP) file "
73
+ "will be provided for simple export of LTP relevant data (Tabular Separated Values).",
74
+ ),
75
+ stp_export: bool = typer.Option(
76
+ False,
77
+ "--stp-export",
78
+ help="In addition to standard output, a specific Short Term Prognosis (STP) file "
79
+ "will be provided for simple export of STP relevant data (Tabular Separated Values).",
80
+ ),
81
+ flow_diagram: bool = typer.Option(
82
+ False,
83
+ "--flow-diagram",
84
+ help="Output the input model formatted to be displayed in a custom flow diagram format in JSON",
85
+ ),
86
+ detailed_output: bool = typer.Option(
87
+ False,
88
+ "--detailed-output",
89
+ "--detailedoutput",
90
+ help="Output detailed output."
91
+ " When False you will get basic results such as energy usage, power, time vector.",
92
+ ),
93
+ date_format_option: DateFormat = typer.Option(
94
+ DateFormat.ISO_8601.value,
95
+ "--date-format-option",
96
+ help='Date format option. 0: "YYYY-MM-DD HH:MM:SS" (Accepted variant of ISO8601), 1: "YYYYMMDD HH:MM:SS" (ISO8601), 2: "DD.MM.YYYY HH:MM:SS". Default 0 (ISO 8601)',
97
+ ),
98
+ ):
99
+ """CLI command to run a ecalc model."""
100
+ if output_folder is None:
101
+ output_folder = model_file.parent / "output"
102
+
103
+ if name_prefix is None:
104
+ name_prefix = model_file.stem
105
+
106
+ output_frequency = libecalc.common.time_utils.Frequency[output_frequency.name]
107
+
108
+ run_info = RunInfo(version=libecalc.version.current_version(), start=datetime.now())
109
+ logger.info(f"eCalc™ simulation starting. Running {run_info}")
110
+ validate_arguments(model_file=model_file, output_folder=output_folder)
111
+
112
+ model = YamlModel(path=model_file, output_frequency=output_frequency)
113
+
114
+ if (flow_diagram or ltp_export) and (model.start is None or model.end is None):
115
+ logger.warning(
116
+ "When using Flow Diagram or Long Term Prognosis export, START and END should be specified in YAML to make sure you get the intended period as output. See documentation for more information."
117
+ )
118
+
119
+ if flow_diagram:
120
+ write_flow_diagram(
121
+ model_dto=model.dto,
122
+ result_options=model.result_options,
123
+ output_folder=output_folder,
124
+ name_prefix=name_prefix,
125
+ )
126
+
127
+ energy_calculator = EnergyCalculator(graph=model.graph)
128
+ precision = 6
129
+ consumer_results = energy_calculator.evaluate_energy_usage(model.variables)
130
+ emission_results = energy_calculator.evaluate_emissions(
131
+ variables_map=model.variables,
132
+ consumer_results=consumer_results,
133
+ )
134
+ results_core = GraphResult(
135
+ graph=model.graph,
136
+ consumer_results=consumer_results,
137
+ variables_map=model.variables,
138
+ emission_results=emission_results,
139
+ )
140
+
141
+ run_info.end = datetime.now()
142
+
143
+ cache = Cache(user_specified_output_path=output_folder)
144
+ cache.write_run_info(run_info)
145
+ cache.write_results(
146
+ results=results_core,
147
+ component_dto=model.dto,
148
+ )
149
+
150
+ output_prefix: Path = output_folder / name_prefix
151
+
152
+ results_dto = get_asset_result(results_core)
153
+
154
+ if output_frequency != Frequency.NONE:
155
+ # Note: LTP can't use this resampled-result yet, because of differences in methodology.
156
+ results_resampled = Numbers.format_results_to_precision(
157
+ results_dto.resample(output_frequency), precision=precision
158
+ )
159
+ else:
160
+ results_resampled = results_dto.model_copy()
161
+
162
+ if csv:
163
+ csv_data = get_result_output(
164
+ results=results_resampled,
165
+ output_format=OutputFormat.CSV,
166
+ simple_output=not detailed_output,
167
+ date_format_option=int(date_format_option.value),
168
+ )
169
+ write_output(output=csv_data, output_file=output_prefix.with_suffix(".csv"))
170
+
171
+ if json:
172
+ write_json(
173
+ results=results_resampled,
174
+ output_folder=output_folder,
175
+ name_prefix=name_prefix,
176
+ run_info=run_info,
177
+ date_format_option=int(date_format_option.value),
178
+ simple_output=not detailed_output,
179
+ )
180
+
181
+ if ltp_export:
182
+ write_ltp_export(
183
+ results=results_core,
184
+ output_folder=output_folder,
185
+ frequency=output_frequency, # Keep until alternative export option is in place (e.g. stp-export)
186
+ name_prefix=name_prefix,
187
+ )
188
+
189
+ if stp_export:
190
+ write_stp_export(
191
+ results=results_core,
192
+ output_folder=output_folder,
193
+ frequency=output_frequency, # Keep until alternative export option is in place (e.g. stp-export)
194
+ name_prefix=name_prefix,
195
+ )
196
+
197
+ logger.info(f"eCalc™ simulation successful. Duration: {run_info.end - run_info.start}")
198
+
199
+
200
+ def validate_arguments(model_file: Path, output_folder: Path):
201
+ """Helper function used to validate the CLI run command arguments.
202
+
203
+ Args:
204
+ model_file:
205
+ output_folder:
206
+
207
+ Returns:
208
+
209
+ Raises:
210
+ EcalcCLIError: If one of the arguments are invalid
211
+
212
+ """
213
+ if not model_file.is_file():
214
+ raise EcalcCLIError(f"Setup file: {model_file.absolute()}: no such file")
215
+
216
+ if not output_folder.parent.is_dir():
217
+ raise EcalcCLIError(
218
+ f"Output path {output_folder} not valid. Please specify an existing path or the name of a new folder in an existing path"
219
+ )
220
+
221
+ if not output_folder.is_dir():
222
+ output_folder.mkdir()
@@ -0,0 +1,38 @@
1
+ import libecalc.version
2
+ from ecalc_neqsim_wrapper import start_server
3
+
4
+ from ecalc_cli.logger import logger
5
+
6
+
7
+ def selftest_java() -> bool:
8
+ """Check java installation.
9
+
10
+ Returns:
11
+ bool: True if Java is installed correctly, False otherwise.
12
+
13
+ """
14
+ try:
15
+ start_server()
16
+ logger.debug("SUCCESS: Java seems to be correctly installed!")
17
+ return True
18
+ except Exception:
19
+ logger.error(
20
+ "Java does not seem to be installed. eCalc will currently not work since NeqSim depends on Java. Please install. See instructions in documentation."
21
+ )
22
+ return False
23
+
24
+
25
+ def selftest():
26
+ """Did eCalc install successfully? Go through a number of checkpoints and let user know what is ok and what is not."""
27
+ logger.info(f"eCalc™ Version {libecalc.version.current_version()}")
28
+ logger.info("Starting selftest ...")
29
+
30
+ # 1. Check that Java is installed (required for NeqSim and fluid simulation), and Neqsim can be used
31
+ java_installed = selftest_java()
32
+
33
+ # TODO: 3. Run the simple test fixture, see that it works (1. from code 2. from yaml)
34
+
35
+ if java_installed:
36
+ logger.info("eCalc™ selftest done successfully.")
37
+ else:
38
+ logger.error("eCalc™ selftest done with errors. See descriptions above.")
@@ -0,0 +1,120 @@
1
+ from pathlib import Path
2
+
3
+ import libecalc.common.time_utils
4
+ import libecalc.version
5
+ import typer
6
+ from libecalc.infrastructure.file_utils import (
7
+ OutputFormat,
8
+ get_component_output,
9
+ get_result_output,
10
+ )
11
+ from libecalc.presentation.yaml.yaml_entities import ResourceStream
12
+ from libecalc.presentation.yaml.yaml_models.pyyaml_yaml_model import PyYamlYamlModel
13
+
14
+ from ecalc_cli.io.cache import Cache
15
+ from ecalc_cli.io.output import write_output
16
+ from ecalc_cli.logger import logger
17
+ from ecalc_cli.types import DateFormat, Frequency
18
+
19
+ app = typer.Typer()
20
+
21
+
22
+ @app.command("yaml")
23
+ def show_yaml(
24
+ model_file: Path = typer.Argument(
25
+ ...,
26
+ help="YAML file specifying time series inputs, facility inputs and the relationship between energy consumers.",
27
+ ),
28
+ output_file: Path = typer.Option(
29
+ None,
30
+ "--file",
31
+ help="Write the data to a file with the specified name.",
32
+ ),
33
+ ):
34
+ """Show yaml model. This will show the yaml after processing !include."""
35
+ model_filepath = model_file
36
+ with open(model_filepath) as model_file:
37
+ read_model = PyYamlYamlModel.dump_and_load_yaml(
38
+ ResourceStream(name=model_file.name, stream=model_file), base_dir=model_filepath.parent
39
+ )
40
+ write_output(read_model, output_file)
41
+
42
+
43
+ @app.command("results")
44
+ def show_results(
45
+ component_name: str = typer.Option(
46
+ None,
47
+ "-n",
48
+ "--name",
49
+ help="Filter the results to only show the component with this name",
50
+ ),
51
+ output_format: OutputFormat = typer.Option(
52
+ OutputFormat.JSON.value,
53
+ "--output-format",
54
+ help="Show the data in this format.",
55
+ ),
56
+ output_file: Path = typer.Option(
57
+ None,
58
+ "--file",
59
+ help="Write the data to a file with the specified name.",
60
+ ),
61
+ output_folder: Path = typer.Option(
62
+ Path.cwd(),
63
+ "--output-folder",
64
+ help="Output folder. Defaults to current working directory",
65
+ show_default=False,
66
+ ),
67
+ detailed_output: bool = typer.Option(
68
+ False,
69
+ "--detailed-output",
70
+ help="Output detailed output." " When False you will get basic energy usage and emissions results",
71
+ ),
72
+ date_format_option: DateFormat = typer.Option(
73
+ DateFormat.ISO_8601.value,
74
+ "--date-format-option",
75
+ help='Date format option. 0: "YYYY-MM-DD HH:MM:SS" (Accepted variant of ISO8601), 1: "YYYYMMDD HH:MM:SS" (ISO8601), 2: "DD.MM.YYYY HH:MM:SS". Default 0 (ISO 8601)',
76
+ ),
77
+ output_frequency: Frequency = typer.Option(
78
+ libecalc.common.time_utils.Frequency.NONE.name,
79
+ "--output-frequency",
80
+ "-f",
81
+ help="Frequency of output. Options are DAY, MONTH, YEAR. If not specified, it will give"
82
+ " time steps equal to the union of all input given with INFLUENCE_TIME_VECTOR set to True."
83
+ " Down-sampling the result may lead to loss of data, and rates such as MW may not add up to cumulative values",
84
+ ),
85
+ ):
86
+ """Show results. You need to run eCalc™ before this will be available."""
87
+ cache = Cache(user_specified_output_path=output_folder)
88
+ results = cache.load_results()
89
+ run_info = cache.load_run_info()
90
+
91
+ if run_info.version != libecalc.version.current_version():
92
+ logger.warning(
93
+ f"Your version of eCalc™ '{libecalc.version.current_version()}' is different to the one used to create the results '{run_info.version}'."
94
+ )
95
+
96
+ if output_frequency != Frequency.NONE:
97
+ results_resampled = results.resample(libecalc.common.time_utils.Frequency[output_frequency.name])
98
+ else:
99
+ results_resampled = results.model_copy()
100
+
101
+ component_name = component_name
102
+
103
+ if component_name is None:
104
+ # Default to full result if no specified component.
105
+ text = get_result_output(
106
+ results_resampled,
107
+ output_format=output_format,
108
+ simple_output=not detailed_output,
109
+ date_format_option=int(date_format_option.value),
110
+ )
111
+ else:
112
+ text = get_component_output(
113
+ results_resampled,
114
+ component_name,
115
+ output_format=output_format,
116
+ simple_output=not detailed_output,
117
+ date_format_option=int(date_format_option.value),
118
+ )
119
+
120
+ write_output(text, output_file)
ecalc_cli/errors.py ADDED
@@ -0,0 +1,4 @@
1
+ class EcalcCLIError(Exception):
2
+ """Placeholder for user-facing exception handling. TODO: Add sanitation."""
3
+
4
+ pass
File without changes
ecalc_cli/io/cache.py ADDED
@@ -0,0 +1,108 @@
1
+ from dataclasses import dataclass, field
2
+ from pathlib import Path
3
+
4
+ from libecalc import dto
5
+ from libecalc.application.graph_result import EnergyCalculatorResult, GraphResult
6
+ from libecalc.common.run_info import RunInfo
7
+ from libecalc.dto.base import EcalcBaseModel
8
+ from libecalc.presentation.json_result.mapper import get_asset_result
9
+ from libecalc.presentation.json_result.result import EcalcModelResult
10
+
11
+ from ecalc_cli.logger import logger
12
+
13
+
14
+ class CacheData(EcalcBaseModel):
15
+ """Data model for content in cache."""
16
+
17
+ component_dto: dto.Asset
18
+ results: EnergyCalculatorResult
19
+
20
+
21
+ @dataclass
22
+ class Cache:
23
+ """Data class for CLI cache, storing model, results and run info."""
24
+
25
+ user_specified_output_path: Path
26
+ cache_path: Path = field(init=False)
27
+ results_path: Path = field(init=False)
28
+ run_info_path: Path = field(init=False)
29
+
30
+ def __post_init__(self):
31
+ self.cache_path = self.user_specified_output_path / ".ecalc"
32
+ self.cache_path.mkdir(mode=0o770, exist_ok=True)
33
+ self.results_path = self.cache_path / "results.json"
34
+ self.run_info_path = self.cache_path / "run_info.json"
35
+
36
+ def write_results(self, results: GraphResult, component_dto: dto.Asset):
37
+ """Write results to cache.
38
+
39
+ Args:
40
+ results: Model results
41
+ component_dto: Model used
42
+
43
+ Returns:
44
+
45
+ """
46
+ logger.info(f"Writing results to cache '{self.cache_path}'.")
47
+ self.results_path.touch(mode=0o660, exist_ok=True)
48
+ cache_data = CacheData(
49
+ results=results.get_results(),
50
+ component_dto=component_dto,
51
+ )
52
+ self.results_path.write_text(cache_data.model_dump_json())
53
+
54
+ def write_run_info(self, run_info: RunInfo):
55
+ """Write meta information about the run to the cache.
56
+
57
+ Args:
58
+ run_info: A data model containing meta data of a eCalc run
59
+
60
+ Returns:
61
+
62
+ """
63
+ logger.info(f"Writing run info to cache '{self.cache_path}'.")
64
+ self.run_info_path.touch(mode=0o660, exist_ok=True)
65
+ self.run_info_path.write_text(run_info.model_dump_json())
66
+
67
+ def load_run_info(self) -> RunInfo:
68
+ """Load metadata about run from cache.
69
+
70
+ Returns:
71
+ Cached metadata about a eCalc run
72
+
73
+ Raises:
74
+ ValueError: If the run info filepath is not set.
75
+
76
+ """
77
+ if not self.run_info_path.is_file():
78
+ msg = "Could not find run info in this directory. Run the model again to generate results."
79
+ logger.error(msg)
80
+ raise ValueError(msg)
81
+
82
+ return RunInfo.model_validate_json(self.run_info_path.read_text())
83
+
84
+ def load_results(self) -> EcalcModelResult:
85
+ """Load cached results from an ecalc run.
86
+
87
+ Returns:
88
+ Ecalc run results for a model
89
+
90
+ Raises:
91
+ ValueError: If the results path is not set
92
+
93
+ """
94
+ if not self.results_path.is_file():
95
+ msg = "Could not find results in this directory, make sure you run 'ecalc show' from the output directory of 'ecalc run' (or specify --outputfolder). Run the model again if no output directory exists."
96
+ raise ValueError(msg)
97
+ cached_text = self.results_path.read_text()
98
+ cache_data = CacheData.model_validate_json(cached_text)
99
+ graph = cache_data.component_dto.get_graph()
100
+
101
+ return get_asset_result(
102
+ GraphResult(
103
+ graph=graph,
104
+ emission_results=cache_data.results.emission_results,
105
+ consumer_results=cache_data.results.consumer_results,
106
+ variables_map=cache_data.results.variables_map,
107
+ )
108
+ )