fameio 3.2.0__tar.gz → 3.4.0__tar.gz

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 (62) hide show
  1. {fameio-3.2.0 → fameio-3.4.0}/CHANGELOG.md +21 -0
  2. {fameio-3.2.0 → fameio-3.4.0}/PKG-INFO +64 -40
  3. {fameio-3.2.0 → fameio-3.4.0}/README.md +63 -39
  4. {fameio-3.2.0 → fameio-3.4.0}/pyproject.toml +2 -1
  5. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/cli/convert_results.py +4 -6
  6. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/cli/make_config.py +3 -5
  7. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/cli/options.py +6 -4
  8. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/cli/parser.py +53 -29
  9. fameio-3.4.0/src/fameio/cli/reformat.py +58 -0
  10. fameio-3.4.0/src/fameio/input/__init__.py +19 -0
  11. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/loader/__init__.py +4 -6
  12. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/loader/controller.py +11 -16
  13. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/loader/loader.py +11 -9
  14. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/metadata.py +26 -29
  15. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/resolver.py +4 -6
  16. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/agent.py +18 -16
  17. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/attribute.py +85 -31
  18. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/contract.py +78 -38
  19. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/exception.py +3 -6
  20. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/fameiofactory.py +7 -12
  21. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/generalproperties.py +7 -8
  22. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/scenario.py +14 -18
  23. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/stringset.py +5 -6
  24. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/schema/agenttype.py +8 -10
  25. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/schema/attribute.py +30 -36
  26. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/schema/java_packages.py +6 -7
  27. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/schema/schema.py +9 -11
  28. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/validator.py +178 -41
  29. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/writer.py +20 -29
  30. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/logs.py +28 -19
  31. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/agent_type.py +14 -16
  32. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/conversion.py +9 -12
  33. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/csv_writer.py +33 -23
  34. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/data_transformer.py +11 -11
  35. fameio-3.4.0/src/fameio/output/execution_dao.py +170 -0
  36. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/input_dao.py +16 -19
  37. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/output_dao.py +7 -7
  38. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/reader.py +8 -10
  39. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/yaml_writer.py +2 -3
  40. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/scripts/__init__.py +15 -4
  41. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/scripts/convert_results.py +18 -17
  42. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/scripts/exception.py +1 -1
  43. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/scripts/make_config.py +3 -4
  44. fameio-3.4.0/src/fameio/scripts/reformat.py +71 -0
  45. fameio-3.4.0/src/fameio/scripts/reformat.py.license +3 -0
  46. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/series.py +78 -47
  47. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/time.py +56 -18
  48. fameio-3.4.0/src/fameio/tools.py +68 -0
  49. fameio-3.2.0/src/fameio/input/__init__.py +0 -19
  50. fameio-3.2.0/src/fameio/tools.py +0 -30
  51. {fameio-3.2.0 → fameio-3.4.0}/LICENSE.txt +0 -0
  52. {fameio-3.2.0 → fameio-3.4.0}/LICENSES/Apache-2.0.txt +0 -0
  53. {fameio-3.2.0 → fameio-3.4.0}/LICENSES/CC-BY-4.0.txt +0 -0
  54. {fameio-3.2.0 → fameio-3.4.0}/LICENSES/CC0-1.0.txt +0 -0
  55. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/__init__.py +0 -0
  56. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/cli/__init__.py +0 -0
  57. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/scenario/__init__.py +0 -0
  58. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/input/schema/__init__.py +0 -0
  59. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/output/__init__.py +0 -0
  60. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/scripts/__init__.py.license +0 -0
  61. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/scripts/convert_results.py.license +0 -0
  62. {fameio-3.2.0 → fameio-3.4.0}/src/fameio/scripts/make_config.py.license +0 -0
@@ -2,6 +2,27 @@
2
2
 
3
3
  SPDX-License-Identifier: CC0-1.0 -->
4
4
 
5
+ ## [3.4.0](https://gitlab.com/fame-framework/fame-io/-/tags/v3.4.0) - 2025-05-27
6
+ ### Changed
7
+ - Allow nesting of sender or receiver lists in contracts !228 (@dlr-cjs)
8
+
9
+ ### Added
10
+ - Add new keyword "Every" to Contracts that allow text qualification of Contract duration #249 (@dlr-cjs)
11
+ - Add helper method to return first time stamp of a given year #247 (@dlr-cjs)
12
+ - Add checks for Python 3.13 to CI #250 (@dlr-cjs)
13
+
14
+ ### Fixed
15
+ - Avoid causing a traceback by nested contract sender or receiver lists #228 (@dlr-cjs)
16
+
17
+ ## [3.3.0](https://gitlab.com/fame-framework/fame-io/-/tags/v3.3.0) - 2025-05-09
18
+ ### Changed
19
+ - Expose static methods to read, convert, and write time series #245 (@dlr-cjs)
20
+ - Improve docstrings of SchemaValidator !219 (@dlr-cjs)
21
+
22
+ ### Added
23
+ - Add command-line script to reformat time series #246 (@dlr-cjs)
24
+ - Read execution metadata from protobuf file #193 (@dlr-cjs)
25
+
5
26
  ## [3.2.0](https://gitlab.com/fame-framework/fame-io/-/tags/v3.2.0) - 2025-04-22
6
27
  ### Changed
7
28
  - Suppress detailed Exception traceback in console #239 (@dlr_fn, @dlr-cjs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fameio
3
- Version: 3.2.0
3
+ Version: 3.4.0
4
4
  Summary: Tools for input preparation and output digestion of FAME models
5
5
  License: Apache-2.0
6
6
  Keywords: FAME,fameio,agent-based modelling,energy systems
@@ -47,8 +47,7 @@ SPDX-License-Identifier: Apache-2.0 -->
47
47
  *Tools for input preparation and output digestion of FAME models*
48
48
 
49
49
  FAME-Io compiles input for FAME models in protobuf format and extracts model outputs to human-readable files.
50
- Please visit the [FAME-Wiki](https://gitlab.com/fame-framework/wiki/-/wikis/home) to get an explanation of FAME and its
51
- components.
50
+ Please visit the [FAME-Wiki](https://gitlab.com/fame-framework/wiki/-/wikis/home) to get an explanation of FAME and its components.
52
51
 
53
52
  # Installation
54
53
 
@@ -56,30 +55,26 @@ We recommend installing `fameio` using PyPI:
56
55
 
57
56
  pip install fameio
58
57
 
59
- You may also use `pipx`. For detailed information please refer to the
60
- official `pipx` [documentation](https://github.com/pypa/pipx).
58
+ You may also use `pipx`. For detailed information please refer to the official `pipx` [documentation](https://github.com/pypa/pipx).
61
59
 
62
60
  pipx install fameio
63
61
 
64
- `fameio` is currently developed and tested for Python 3.8 or higher.
62
+ `fameio` is currently developed and tested for Python 3.9 or higher.
65
63
  See the `pyproject.toml` for a complete listing of dependencies.
66
64
 
67
65
  # Usage
68
66
 
69
- FAME-Io currently offers two main scripts `makeFameRunConfig` and `convertFameResults`.
70
- Both are automatically installed with the package.
67
+ FAME-Io currently offers two main scripts `makeFameRunConfig` and `convertFameResults`, plus a helper script `reformatTimeSeries`
68
+ All are automatically installed with the package.
71
69
  The first one creates a protobuf file for FAME applications using YAML definition files and CSV files.
72
- The latter one reads output files from FAME applications in protobuf format and converts them to CSV files.
70
+ The second one reads output files from FAME applications in protobuf format and converts them to CSV files.
71
+ The third script reformats time series CSV files to FAME format.
73
72
 
74
- You may use the [example data](https://gitlab.com/dlr-ve/esy/amiris/examples) provided for
75
- the [AMIRIS](https://gitlab.com/dlr-ve/esy/amiris/amiris) model which can be used to simulate electricity markets
76
- in [Germany](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Germany2019), [Austria](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Austria2019),
77
- and a simple [proof-of-concept model](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Simple).
73
+ You may use the [example data](https://gitlab.com/dlr-ve/esy/amiris/examples) provided for the [AMIRIS](https://gitlab.com/dlr-ve/esy/amiris/amiris) model which can be used to simulate electricity markets in [Germany](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Germany2019), [Austria](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Austria2019), and a simple [proof-of-concept model](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Simple).
78
74
 
79
75
  ## Make a FAME run configuration
80
76
 
81
- Digests configuration files in YAML format, combines them with CSV data files and creates a single input file for FAME
82
- applications in protobuf format.
77
+ Digests configuration files in YAML format, combines them with CSV data files and creates a single input file for FAME applications in protobuf format.
83
78
  Call structure:
84
79
 
85
80
  makeFameRunConfig -f <path/to/scenario.yaml>
@@ -512,7 +507,7 @@ Contracts:
512
507
  ReceiverId: 2
513
508
  ProductName: ProductOfAgent_1
514
509
  FirstDeliveryTime: -25
515
- DeliveryIntervalInSteps: 3600
510
+ Every: 3600
516
511
  Metadata:
517
512
  Some: "additional information can go here"
518
513
 
@@ -520,7 +515,7 @@ Contracts:
520
515
  ReceiverId: 1
521
516
  ProductName: ProductOfAgent_2
522
517
  FirstDeliveryTime: -22
523
- DeliveryIntervalInSteps: 3600
518
+ Every: 1 hour
524
519
  Attributes:
525
520
  ProductAppendix: value
526
521
  TimeOffset: 42
@@ -532,7 +527,8 @@ Contract Parameters:
532
527
  * `ReceiverId` unique ID of agent receiving the product
533
528
  * `ProductName` name of the product to be sent
534
529
  * `FirstDeliveryTime` first time of delivery in the format "seconds after the January 1st 2000, 00:00:00"
535
- * `DeliveryIntervalInSteps` delay time in between deliveries in seconds
530
+ * `Every` delay time in between deliveries; either an integer value in seconds, or a qualified time span in the format "<integer> <TimeUnit>(s)", where TimeUnit is one of "second", "minute", "hour", "day", "week", "month", "year" - with an options "s" at the end; mind that week, month, and year refer to fixed-length intervals of 168, 730, and 8760 hours.
531
+ * `DeliveryIntervalInSteps` deprecated; delay time in between deliveries in seconds (use instead of `Every`)
536
532
  * `Metadata` can be assigned to add further helpful information about a Contract
537
533
  * `Attributes` can be set to include additional information as `int`, `float`, `enum`, or `dict` data types
538
534
 
@@ -546,59 +542,72 @@ example:
546
542
  ```yaml
547
543
  Contracts:
548
544
  # effectively 3 similar contracts (0 -> 11), (0 -> 12), (0 -> 13)
549
- # with otherwise identical ProductName, FirstDeliveryTime & DeliveryIntervalInSteps
545
+ # with otherwise identical ProductName, FirstDeliveryTime, and Every
550
546
  - SenderId: 0
551
547
  ReceiverId: [ 11, 12, 13 ]
552
548
  ProductName: MyOtherProduct
553
549
  FirstDeliveryTime: 100
554
- DeliveryIntervalInSteps: 3600
550
+ Every: 1 hour
555
551
 
556
552
  # effectively 3 similar contracts (1 -> 10), (2 -> 10), (3 -> 10)
557
- # with otherwise identical ProductName, FirstDeliveryTime & DeliveryIntervalInSteps
553
+ # with otherwise identical ProductName, FirstDeliveryTime, and Every
558
554
  - SenderId: [ 1, 2, 3 ]
559
555
  ReceiverId: 10
560
556
  ProductName: MyProduct
561
557
  FirstDeliveryTime: 100
562
- DeliveryIntervalInSteps: 3600
558
+ Every: 1 hour
563
559
 
564
560
  # effectively 3 similar contracts (1 -> 11), (2 -> 12), (3 -> 13)
565
- # with otherwise identical ProductName, FirstDeliveryTime & DeliveryIntervalInSteps
561
+ # with otherwise identical ProductName, FirstDeliveryTime, and Every
566
562
  - SenderId: [ 1, 2, 3 ]
567
563
  ReceiverId: [ 11, 12, 13 ]
568
564
  ProductName: MyThirdProduct
569
565
  FirstDeliveryTime: 100
570
- DeliveryIntervalInSteps: 3600
566
+ Every: 1 hour
571
567
  ```
572
568
 
573
- Combined with YAML anchors complex contract chains can be easily reduced to a minimum of required configuration.
574
- The following example is equivalent to the previous one and allows a quick extension of contracts to a new couple of
575
- agents e.g. (4;14):
569
+ When combined with YAML anchors, the complexity of extensive contract chains can be reduced.
570
+ The following example is equivalent to the previous one, enabling contracts to be quickly extended to a new group of agents:
576
571
 
577
572
  ```yaml
578
573
  Groups:
579
- - &agentList1: [ 1,2,3 ]
580
- - &agentList2: [ 11,12,13 ]
574
+ - &agentList1: [ 1, 2, 3 ]
575
+ - &agentList2: [ 11, 12, 13 ]
581
576
 
582
577
  Contracts:
583
578
  - SenderId: 0
584
579
  ReceiverId: *agentList2
585
580
  ProductName: MyOtherProduct
586
581
  FirstDeliveryTime: 100
587
- DeliveryIntervalInSteps: 3600
582
+ Every: 1 hour
588
583
 
589
584
  - SenderId: *agentList1
590
585
  ReceiverId: 10
591
586
  ProductName: MyProduct
592
587
  FirstDeliveryTime: 100
593
- DeliveryIntervalInSteps: 3600
588
+ Every: 1 hour
594
589
 
595
590
  - SenderId: *agentList1
596
591
  ReceiverId: *agentList2
597
592
  ProductName: MyThirdProduct
598
593
  FirstDeliveryTime: 100
599
- DeliveryIntervalInSteps: 3600
594
+ Every: 1 hour
600
595
  ```
601
596
 
597
+ Lists can be nested in senders and receivers as follows:
598
+
599
+ ```
600
+ Groups:
601
+ - SenderId: 42
602
+ ReceiverId: [1, [2, 3], [4, [5]]]
603
+ ProductName: AnImportantProduct
604
+ FirstDeliveryTime: 101
605
+ Every: 30 minutes
606
+ ```
607
+
608
+ This feature should not be overused, as nested lists can become messy and difficult to read.
609
+ Special care should be taken when using it with an N-to-N mapping, as it will be difficult to check whether senders and receivers are matched correctly.
610
+
602
611
  #### StringSets
603
612
 
604
613
  This optional section defines values of type `string_set`.
@@ -644,10 +653,8 @@ TIME_SERIES inputs are not directly fed into the Scenario YAML file.
644
653
  Instead, TIME_SERIES reference a CSV file that can be stored some place else.
645
654
  These CSV files follow a specific structure:
646
655
 
647
- * They should contain exactly two columns - any other columns are ignored.
648
- A warning is raised if more than two non-empty columns are detected.
649
- * The first column must be a time stamp in form `YYYY-MM-DD_hh:mm:ss` or
650
- a [FAME-Timestamp](https://gitlab.com/fame-framework/wiki/-/wikis/architecture/decisions/TimeStamp) integer value.
656
+ * They should contain exactly two columns - any other columns are ignored. A warning is raised if more than two non-empty columns are detected.
657
+ * The first column must be a time stamp in form `YYYY-MM-DD_hh:mm:ss` or a [FAME-Timestamp](https://gitlab.com/fame-framework/wiki/-/wikis/architecture/decisions/TimeStamp) integer value.
651
658
  * The second column must be a numerical value (either integer or floating-point)
652
659
  * The separator of the two columns is a semicolon
653
660
  * The data must **not** have headers, except for comments marked with `#`
@@ -663,11 +670,10 @@ Exemplary content of a valid CSV file:
663
670
  2016-01-01_00:00:00;42 # optional comment on this particular data point
664
671
  2017-01-01_00:00:00;0.1
665
672
 
666
- Please refer also to the detailed article about `TimeStamps` in
667
- the [FAME-Wiki](https://gitlab.com/fame-framework/wiki/-/wikis/TimeStamp).
668
- For large CSV files (with more than 20,000 rows) we recommend using the integer representation of FAME-Timestamps in the
669
- first column (instead of text representation) to improve conversion speed.
673
+ Please refer also to the detailed article about `TimeStamps` in the [FAME-Wiki](https://gitlab.com/fame-framework/wiki/-/wikis/TimeStamp).
674
+ For large CSV files (with more than 20,000 rows) we recommend using the integer representation of FAME-Timestamps in the first column (instead of text representation) to improve conversion speed.
670
675
  A warning will be raised for very large files (exceeding 50,000 rows) that require time stamp conversion.
676
+ Use `reformatTimeSeries` to convert one or multiple timeseries CSV files into FAME format to improve conversion speed and avoid this warning.
671
677
 
672
678
  ### Split and join multiple YAML files
673
679
 
@@ -936,6 +942,24 @@ run_config = handle_args(my_arg_string, my_defaults)
936
942
  convert_results(run_config)
937
943
  ```
938
944
 
945
+ ## Reformat time series
946
+
947
+ Takes CSV time series files and reformats them into FAME time format.
948
+ This improves speed of run configuration creation but also reduces readability of the CSV files' content.
949
+ Thus, we recommend to apply this reformatting only for CSV time series files with more than 20,000 lines.
950
+
951
+ Call structure:
952
+
953
+ reformatTimeSeries -fp <file_or_file_pattern*.csv>
954
+
955
+ You may also specify any of the following arguments:
956
+
957
+ | Command | Action |
958
+ |-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
959
+ | `-l` or `--log` <option> | Sets the logging level. Default is `WARNING`. Options are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. |
960
+ | `-lf` or `--logfile` <file> | Sets the logging file. Default is `None`. If `None` is provided, all logs get only printed to the console. |
961
+ | `--replace` or `--no-replace` | If `--replace` is specified, existing csv files are replaced with the new content. Otherwise and by default, new files are created extending the original file name by "_reformatted". |
962
+
939
963
  ## Cite FAME-Io
940
964
 
941
965
  If you use FAME-Io for academic work, please cite as follows.
@@ -15,8 +15,7 @@ SPDX-License-Identifier: Apache-2.0 -->
15
15
  *Tools for input preparation and output digestion of FAME models*
16
16
 
17
17
  FAME-Io compiles input for FAME models in protobuf format and extracts model outputs to human-readable files.
18
- Please visit the [FAME-Wiki](https://gitlab.com/fame-framework/wiki/-/wikis/home) to get an explanation of FAME and its
19
- components.
18
+ Please visit the [FAME-Wiki](https://gitlab.com/fame-framework/wiki/-/wikis/home) to get an explanation of FAME and its components.
20
19
 
21
20
  # Installation
22
21
 
@@ -24,30 +23,26 @@ We recommend installing `fameio` using PyPI:
24
23
 
25
24
  pip install fameio
26
25
 
27
- You may also use `pipx`. For detailed information please refer to the
28
- official `pipx` [documentation](https://github.com/pypa/pipx).
26
+ You may also use `pipx`. For detailed information please refer to the official `pipx` [documentation](https://github.com/pypa/pipx).
29
27
 
30
28
  pipx install fameio
31
29
 
32
- `fameio` is currently developed and tested for Python 3.8 or higher.
30
+ `fameio` is currently developed and tested for Python 3.9 or higher.
33
31
  See the `pyproject.toml` for a complete listing of dependencies.
34
32
 
35
33
  # Usage
36
34
 
37
- FAME-Io currently offers two main scripts `makeFameRunConfig` and `convertFameResults`.
38
- Both are automatically installed with the package.
35
+ FAME-Io currently offers two main scripts `makeFameRunConfig` and `convertFameResults`, plus a helper script `reformatTimeSeries`
36
+ All are automatically installed with the package.
39
37
  The first one creates a protobuf file for FAME applications using YAML definition files and CSV files.
40
- The latter one reads output files from FAME applications in protobuf format and converts them to CSV files.
38
+ The second one reads output files from FAME applications in protobuf format and converts them to CSV files.
39
+ The third script reformats time series CSV files to FAME format.
41
40
 
42
- You may use the [example data](https://gitlab.com/dlr-ve/esy/amiris/examples) provided for
43
- the [AMIRIS](https://gitlab.com/dlr-ve/esy/amiris/amiris) model which can be used to simulate electricity markets
44
- in [Germany](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Germany2019), [Austria](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Austria2019),
45
- and a simple [proof-of-concept model](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Simple).
41
+ You may use the [example data](https://gitlab.com/dlr-ve/esy/amiris/examples) provided for the [AMIRIS](https://gitlab.com/dlr-ve/esy/amiris/amiris) model which can be used to simulate electricity markets in [Germany](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Germany2019), [Austria](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Austria2019), and a simple [proof-of-concept model](https://gitlab.com/dlr-ve/esy/amiris/examples/-/tree/main/Simple).
46
42
 
47
43
  ## Make a FAME run configuration
48
44
 
49
- Digests configuration files in YAML format, combines them with CSV data files and creates a single input file for FAME
50
- applications in protobuf format.
45
+ Digests configuration files in YAML format, combines them with CSV data files and creates a single input file for FAME applications in protobuf format.
51
46
  Call structure:
52
47
 
53
48
  makeFameRunConfig -f <path/to/scenario.yaml>
@@ -480,7 +475,7 @@ Contracts:
480
475
  ReceiverId: 2
481
476
  ProductName: ProductOfAgent_1
482
477
  FirstDeliveryTime: -25
483
- DeliveryIntervalInSteps: 3600
478
+ Every: 3600
484
479
  Metadata:
485
480
  Some: "additional information can go here"
486
481
 
@@ -488,7 +483,7 @@ Contracts:
488
483
  ReceiverId: 1
489
484
  ProductName: ProductOfAgent_2
490
485
  FirstDeliveryTime: -22
491
- DeliveryIntervalInSteps: 3600
486
+ Every: 1 hour
492
487
  Attributes:
493
488
  ProductAppendix: value
494
489
  TimeOffset: 42
@@ -500,7 +495,8 @@ Contract Parameters:
500
495
  * `ReceiverId` unique ID of agent receiving the product
501
496
  * `ProductName` name of the product to be sent
502
497
  * `FirstDeliveryTime` first time of delivery in the format "seconds after the January 1st 2000, 00:00:00"
503
- * `DeliveryIntervalInSteps` delay time in between deliveries in seconds
498
+ * `Every` delay time in between deliveries; either an integer value in seconds, or a qualified time span in the format "<integer> <TimeUnit>(s)", where TimeUnit is one of "second", "minute", "hour", "day", "week", "month", "year" - with an options "s" at the end; mind that week, month, and year refer to fixed-length intervals of 168, 730, and 8760 hours.
499
+ * `DeliveryIntervalInSteps` deprecated; delay time in between deliveries in seconds (use instead of `Every`)
504
500
  * `Metadata` can be assigned to add further helpful information about a Contract
505
501
  * `Attributes` can be set to include additional information as `int`, `float`, `enum`, or `dict` data types
506
502
 
@@ -514,59 +510,72 @@ example:
514
510
  ```yaml
515
511
  Contracts:
516
512
  # effectively 3 similar contracts (0 -> 11), (0 -> 12), (0 -> 13)
517
- # with otherwise identical ProductName, FirstDeliveryTime & DeliveryIntervalInSteps
513
+ # with otherwise identical ProductName, FirstDeliveryTime, and Every
518
514
  - SenderId: 0
519
515
  ReceiverId: [ 11, 12, 13 ]
520
516
  ProductName: MyOtherProduct
521
517
  FirstDeliveryTime: 100
522
- DeliveryIntervalInSteps: 3600
518
+ Every: 1 hour
523
519
 
524
520
  # effectively 3 similar contracts (1 -> 10), (2 -> 10), (3 -> 10)
525
- # with otherwise identical ProductName, FirstDeliveryTime & DeliveryIntervalInSteps
521
+ # with otherwise identical ProductName, FirstDeliveryTime, and Every
526
522
  - SenderId: [ 1, 2, 3 ]
527
523
  ReceiverId: 10
528
524
  ProductName: MyProduct
529
525
  FirstDeliveryTime: 100
530
- DeliveryIntervalInSteps: 3600
526
+ Every: 1 hour
531
527
 
532
528
  # effectively 3 similar contracts (1 -> 11), (2 -> 12), (3 -> 13)
533
- # with otherwise identical ProductName, FirstDeliveryTime & DeliveryIntervalInSteps
529
+ # with otherwise identical ProductName, FirstDeliveryTime, and Every
534
530
  - SenderId: [ 1, 2, 3 ]
535
531
  ReceiverId: [ 11, 12, 13 ]
536
532
  ProductName: MyThirdProduct
537
533
  FirstDeliveryTime: 100
538
- DeliveryIntervalInSteps: 3600
534
+ Every: 1 hour
539
535
  ```
540
536
 
541
- Combined with YAML anchors complex contract chains can be easily reduced to a minimum of required configuration.
542
- The following example is equivalent to the previous one and allows a quick extension of contracts to a new couple of
543
- agents e.g. (4;14):
537
+ When combined with YAML anchors, the complexity of extensive contract chains can be reduced.
538
+ The following example is equivalent to the previous one, enabling contracts to be quickly extended to a new group of agents:
544
539
 
545
540
  ```yaml
546
541
  Groups:
547
- - &agentList1: [ 1,2,3 ]
548
- - &agentList2: [ 11,12,13 ]
542
+ - &agentList1: [ 1, 2, 3 ]
543
+ - &agentList2: [ 11, 12, 13 ]
549
544
 
550
545
  Contracts:
551
546
  - SenderId: 0
552
547
  ReceiverId: *agentList2
553
548
  ProductName: MyOtherProduct
554
549
  FirstDeliveryTime: 100
555
- DeliveryIntervalInSteps: 3600
550
+ Every: 1 hour
556
551
 
557
552
  - SenderId: *agentList1
558
553
  ReceiverId: 10
559
554
  ProductName: MyProduct
560
555
  FirstDeliveryTime: 100
561
- DeliveryIntervalInSteps: 3600
556
+ Every: 1 hour
562
557
 
563
558
  - SenderId: *agentList1
564
559
  ReceiverId: *agentList2
565
560
  ProductName: MyThirdProduct
566
561
  FirstDeliveryTime: 100
567
- DeliveryIntervalInSteps: 3600
562
+ Every: 1 hour
568
563
  ```
569
564
 
565
+ Lists can be nested in senders and receivers as follows:
566
+
567
+ ```
568
+ Groups:
569
+ - SenderId: 42
570
+ ReceiverId: [1, [2, 3], [4, [5]]]
571
+ ProductName: AnImportantProduct
572
+ FirstDeliveryTime: 101
573
+ Every: 30 minutes
574
+ ```
575
+
576
+ This feature should not be overused, as nested lists can become messy and difficult to read.
577
+ Special care should be taken when using it with an N-to-N mapping, as it will be difficult to check whether senders and receivers are matched correctly.
578
+
570
579
  #### StringSets
571
580
 
572
581
  This optional section defines values of type `string_set`.
@@ -612,10 +621,8 @@ TIME_SERIES inputs are not directly fed into the Scenario YAML file.
612
621
  Instead, TIME_SERIES reference a CSV file that can be stored some place else.
613
622
  These CSV files follow a specific structure:
614
623
 
615
- * They should contain exactly two columns - any other columns are ignored.
616
- A warning is raised if more than two non-empty columns are detected.
617
- * The first column must be a time stamp in form `YYYY-MM-DD_hh:mm:ss` or
618
- a [FAME-Timestamp](https://gitlab.com/fame-framework/wiki/-/wikis/architecture/decisions/TimeStamp) integer value.
624
+ * They should contain exactly two columns - any other columns are ignored. A warning is raised if more than two non-empty columns are detected.
625
+ * The first column must be a time stamp in form `YYYY-MM-DD_hh:mm:ss` or a [FAME-Timestamp](https://gitlab.com/fame-framework/wiki/-/wikis/architecture/decisions/TimeStamp) integer value.
619
626
  * The second column must be a numerical value (either integer or floating-point)
620
627
  * The separator of the two columns is a semicolon
621
628
  * The data must **not** have headers, except for comments marked with `#`
@@ -631,11 +638,10 @@ Exemplary content of a valid CSV file:
631
638
  2016-01-01_00:00:00;42 # optional comment on this particular data point
632
639
  2017-01-01_00:00:00;0.1
633
640
 
634
- Please refer also to the detailed article about `TimeStamps` in
635
- the [FAME-Wiki](https://gitlab.com/fame-framework/wiki/-/wikis/TimeStamp).
636
- For large CSV files (with more than 20,000 rows) we recommend using the integer representation of FAME-Timestamps in the
637
- first column (instead of text representation) to improve conversion speed.
641
+ Please refer also to the detailed article about `TimeStamps` in the [FAME-Wiki](https://gitlab.com/fame-framework/wiki/-/wikis/TimeStamp).
642
+ For large CSV files (with more than 20,000 rows) we recommend using the integer representation of FAME-Timestamps in the first column (instead of text representation) to improve conversion speed.
638
643
  A warning will be raised for very large files (exceeding 50,000 rows) that require time stamp conversion.
644
+ Use `reformatTimeSeries` to convert one or multiple timeseries CSV files into FAME format to improve conversion speed and avoid this warning.
639
645
 
640
646
  ### Split and join multiple YAML files
641
647
 
@@ -904,6 +910,24 @@ run_config = handle_args(my_arg_string, my_defaults)
904
910
  convert_results(run_config)
905
911
  ```
906
912
 
913
+ ## Reformat time series
914
+
915
+ Takes CSV time series files and reformats them into FAME time format.
916
+ This improves speed of run configuration creation but also reduces readability of the CSV files' content.
917
+ Thus, we recommend to apply this reformatting only for CSV time series files with more than 20,000 lines.
918
+
919
+ Call structure:
920
+
921
+ reformatTimeSeries -fp <file_or_file_pattern*.csv>
922
+
923
+ You may also specify any of the following arguments:
924
+
925
+ | Command | Action |
926
+ |-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
927
+ | `-l` or `--log` <option> | Sets the logging level. Default is `WARNING`. Options are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. |
928
+ | `-lf` or `--logfile` <file> | Sets the logging file. Default is `None`. If `None` is provided, all logs get only printed to the console. |
929
+ | `--replace` or `--no-replace` | If `--replace` is specified, existing csv files are replaced with the new content. Otherwise and by default, new files are created extending the original file name by "_reformatted". |
930
+
907
931
  ## Cite FAME-Io
908
932
 
909
933
  If you use FAME-Io for academic work, please cite as follows.
@@ -7,7 +7,7 @@ build-backend = "poetry.core.masonry.api"
7
7
 
8
8
  [project]
9
9
  name = "fameio"
10
- version = "3.2.0"
10
+ version = "3.4.0"
11
11
  description = "Tools for input preparation and output digestion of FAME models"
12
12
  license = "Apache-2.0"
13
13
  readme = "README.md"
@@ -39,6 +39,7 @@ repository = "https://gitlab.com/fame-framework/fame-io"
39
39
  [project.scripts]
40
40
  makeFameRunConfig = "fameio.scripts:makeFameRunConfig"
41
41
  convertFameResults = "fameio.scripts:convertFameResults"
42
+ reformatTimeSeries = "fameio.scripts:reformatTimeSeries"
42
43
 
43
44
  [tool.poetry]
44
45
  classifiers = [
@@ -26,8 +26,8 @@ CLI_DEFAULTS = {
26
26
  Options.FILE: None,
27
27
  Options.LOG_LEVEL: "WARN",
28
28
  Options.LOG_FILE: None,
29
- Options.AGENT_LIST: None,
30
29
  Options.OUTPUT: None,
30
+ Options.AGENT_LIST: None,
31
31
  Options.SINGLE_AGENT_EXPORT: False,
32
32
  Options.MEMORY_SAVING: False,
33
33
  Options.RESOLVE_COMPLEX_FIELD: ResolveOptions.SPLIT,
@@ -41,8 +41,7 @@ _OUTFILE_PATH_HELP = "Provide path to folder to store output .csv files"
41
41
 
42
42
 
43
43
  def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) -> dict[Options, Any]:
44
- """
45
- Handles command line arguments and returns `run_config` for convert_results script
44
+ """Handles command line arguments and returns `run_config` for convert_results script.
46
45
 
47
46
  Args:
48
47
  args: list of (command line) arguments, e.g., ['-f', 'my_file']; arg values take precedence over defaults
@@ -57,8 +56,7 @@ def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) ->
57
56
 
58
57
 
59
58
  def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentParser:
60
- """
61
- Creates a parser with given defaults to handle `make_config` configuration arguments
59
+ """Creates a parser with given defaults to handle `make_config` configuration arguments.
62
60
 
63
61
  Returns:
64
62
  new parser using given defaults for its arguments; if a default is not specified, hard-coded defaults are used
@@ -82,5 +80,5 @@ def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentPar
82
80
 
83
81
 
84
82
  def _get_default(defaults: dict, option: Options) -> Any:
85
- """Returns default for given `option` or its cli default"""
83
+ """Returns default for given `option` or its cli default."""
86
84
  return defaults.get(option, CLI_DEFAULTS[option])
@@ -34,8 +34,7 @@ _ENCODING_HELP = (
34
34
 
35
35
 
36
36
  def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) -> dict[Options, Any]:
37
- """
38
- Converts given `arguments` and returns a configuration for the make_config script
37
+ """Converts given `args` and returns a configuration for the make_config script.
39
38
 
40
39
  Args:
41
40
  args: list of (command line) arguments, e.g., ['-f', 'my_file']; arg values take precedence over defaults
@@ -50,8 +49,7 @@ def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) ->
50
49
 
51
50
 
52
51
  def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentParser:
53
- """
54
- Creates a parser with given defaults to handle `make_config` configuration arguments
52
+ """Creates a parser with given defaults to handle `make_config` configuration arguments.
55
53
 
56
54
  Returns:
57
55
  new parser using given defaults for its arguments; if a default is not specified, hard-coded defaults are used
@@ -67,5 +65,5 @@ def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentPar
67
65
 
68
66
 
69
67
  def _get_default(defaults: dict, option: Options) -> Any:
70
- """Returns default for given `option` or, if missing, its cli default"""
68
+ """Returns default for given `option` or, if missing, its cli default."""
71
69
  return defaults.get(option, CLI_DEFAULTS[option])
@@ -6,7 +6,7 @@ from enum import Enum, auto
6
6
 
7
7
 
8
8
  class ParsableEnum(Enum):
9
- """Extend this to create an enum that can be parsed with argparse"""
9
+ """Extend this to create an enum that can be parsed with argparse."""
10
10
 
11
11
  @classmethod
12
12
  def instantiate(cls, name: str) -> Enum:
@@ -20,7 +20,7 @@ class ParsableEnum(Enum):
20
20
 
21
21
 
22
22
  class Options(Enum):
23
- """Specifies command line configuration options"""
23
+ """Specifies command line configuration options."""
24
24
 
25
25
  FILE = auto()
26
26
  LOG_LEVEL = auto()
@@ -34,10 +34,12 @@ class Options(Enum):
34
34
  TIME_MERGING = auto()
35
35
  INPUT_RECOVERY = auto()
36
36
  INPUT_ENCODING = auto()
37
+ FILE_PATTERN = auto()
38
+ REPLACE = auto()
37
39
 
38
40
 
39
41
  class TimeOptions(ParsableEnum, Enum):
40
- """Specifies options for conversion of time in output"""
42
+ """Specifies options for conversion of time in output."""
41
43
 
42
44
  INT = auto()
43
45
  UTC = auto()
@@ -45,7 +47,7 @@ class TimeOptions(ParsableEnum, Enum):
45
47
 
46
48
 
47
49
  class ResolveOptions(ParsableEnum, Enum):
48
- """Specifies options for resolving complex fields in output files"""
50
+ """Specifies options for resolving complex fields in output files."""
49
51
 
50
52
  IGNORE = auto()
51
53
  SPLIT = auto()