c4dynamics 2.3.2__tar.gz → 2.3.5__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 (117) hide show
  1. {c4dynamics-2.3.2/c4dynamics.egg-info → c4dynamics-2.3.5}/PKG-INFO +70 -39
  2. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/README.md +50 -24
  3. c4dynamics-2.3.5/c4dynamics/__init__.py +326 -0
  4. c4dynamics-2.3.5/c4dynamics/datasets/__init__.py +109 -0
  5. c4dynamics-2.3.5/c4dynamics/datasets/_manager.py +649 -0
  6. c4dynamics-2.3.5/c4dynamics/datasets/_registry.py +84 -0
  7. c4dynamics-2.3.5/c4dynamics/detectors/__init__.py +26 -0
  8. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/detectors/yolo3_opencv.py +383 -291
  9. c4dynamics-2.3.5/c4dynamics/envs/__init__.py +11 -0
  10. c4dynamics-2.3.5/c4dynamics/envs/mountain_car.py +903 -0
  11. c4dynamics-2.3.5/c4dynamics/eqm/__init__.py +33 -0
  12. c4dynamics-2.3.5/c4dynamics/eqm/derivs.py +192 -0
  13. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/eqm/integrate.py +188 -181
  14. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/filters/__init__.py +76 -75
  15. c4dynamics-2.3.5/c4dynamics/filters/ekf.py +300 -0
  16. c4dynamics-2.3.5/c4dynamics/filters/kalman.py +733 -0
  17. c4dynamics-2.3.5/c4dynamics/filters/lowpass.py +131 -0
  18. c4dynamics-2.3.5/c4dynamics/rotmat/__init__.py +33 -0
  19. c4dynamics-2.3.5/c4dynamics/rotmat/animate.py +467 -0
  20. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/rotmat/rotmat.py +109 -107
  21. c4dynamics-2.3.5/c4dynamics/sensors/__init__.py +64 -0
  22. c4dynamics-2.3.5/c4dynamics/sensors/lineofsight.py +74 -0
  23. c4dynamics-2.3.5/c4dynamics/sensors/radar.py +762 -0
  24. c4dynamics-2.3.5/c4dynamics/sensors/seeker.py +1034 -0
  25. c4dynamics-2.3.5/c4dynamics/states/__init__.py +29 -0
  26. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/states/lib/__init__.py +13 -19
  27. c4dynamics-2.3.5/c4dynamics/states/lib/datapoint.py +625 -0
  28. c4dynamics-2.3.5/c4dynamics/states/lib/pixelpoint.py +621 -0
  29. c4dynamics-2.3.5/c4dynamics/states/lib/rigidbody.py +649 -0
  30. c4dynamics-2.3.5/c4dynamics/states/state.py +1557 -0
  31. c4dynamics-2.3.5/c4dynamics/utils/__init__.py +28 -0
  32. c4dynamics-2.3.5/c4dynamics/utils/_struct.py +10 -0
  33. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/utils/const.py +25 -27
  34. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/utils/cprint.py +37 -29
  35. c4dynamics-2.3.5/c4dynamics/utils/gen_gif.py +142 -0
  36. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/utils/idx2keys.py +2 -1
  37. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics/utils/images_loader.py +12 -11
  38. c4dynamics-2.3.5/c4dynamics/utils/math.py +163 -0
  39. c4dynamics-2.3.5/c4dynamics/utils/plottools.py +95 -0
  40. c4dynamics-2.3.5/c4dynamics/utils/plottracks.py +369 -0
  41. c4dynamics-2.3.5/c4dynamics/utils/printpts.py +36 -0
  42. c4dynamics-2.3.5/c4dynamics/utils/slides_gen.py +66 -0
  43. c4dynamics-2.3.5/c4dynamics/utils/tictoc.py +170 -0
  44. c4dynamics-2.3.5/c4dynamics/utils/video_gen.py +337 -0
  45. c4dynamics-2.3.5/c4dynamics/utils/vidgen.py +173 -0
  46. {c4dynamics-2.3.2 → c4dynamics-2.3.5/c4dynamics.egg-info}/PKG-INFO +70 -39
  47. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics.egg-info/SOURCES.txt +1 -1
  48. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics.egg-info/requires.txt +8 -4
  49. c4dynamics-2.3.5/pyproject.toml +76 -0
  50. c4dynamics-2.3.5/setup.cfg +22 -0
  51. c4dynamics-2.3.5/setup.py +67 -0
  52. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_animate.py +28 -31
  53. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_const.py +7 -3
  54. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_cprint.py +4 -2
  55. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_datapoint.py +15 -12
  56. c4dynamics-2.3.5/tests/test_datasets.py +130 -0
  57. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_derivs.py +7 -4
  58. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_ekf.py +14 -24
  59. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_gen_gif.py +23 -24
  60. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_integrate.py +46 -16
  61. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_kalman.py +42 -41
  62. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_lowpass.py +6 -4
  63. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_math.py +4 -4
  64. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_pixelpoint.py +11 -11
  65. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_plotdefaults.py +8 -7
  66. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_radar.py +18 -10
  67. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_rigidbody.py +22 -10
  68. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_rotmat.py +7 -6
  69. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_seeker.py +12 -7
  70. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_state.py +72 -21
  71. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_state_assignment.py +2 -2
  72. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_state_assignment_strict.py +18 -12
  73. c4dynamics-2.3.5/tests/test_tictoc.py +43 -0
  74. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/tests/test_yolov3_opencv.py +37 -19
  75. c4dynamics-2.3.2/CLASSIFIERS.txt +0 -6
  76. c4dynamics-2.3.2/c4dynamics/__init__.py +0 -315
  77. c4dynamics-2.3.2/c4dynamics/datasets/__init__.py +0 -97
  78. c4dynamics-2.3.2/c4dynamics/datasets/_manager.py +0 -613
  79. c4dynamics-2.3.2/c4dynamics/datasets/_registry.py +0 -83
  80. c4dynamics-2.3.2/c4dynamics/detectors/__init__.py +0 -26
  81. c4dynamics-2.3.2/c4dynamics/envs/__init__.py +0 -13
  82. c4dynamics-2.3.2/c4dynamics/envs/mountain_car.py +0 -477
  83. c4dynamics-2.3.2/c4dynamics/eqm/__init__.py +0 -36
  84. c4dynamics-2.3.2/c4dynamics/eqm/derivs.py +0 -194
  85. c4dynamics-2.3.2/c4dynamics/filters/ekf.py +0 -302
  86. c4dynamics-2.3.2/c4dynamics/filters/kalman.py +0 -709
  87. c4dynamics-2.3.2/c4dynamics/filters/lowpass.py +0 -123
  88. c4dynamics-2.3.2/c4dynamics/rotmat/__init__.py +0 -36
  89. c4dynamics-2.3.2/c4dynamics/rotmat/animate.py +0 -460
  90. c4dynamics-2.3.2/c4dynamics/sensors/__init__.py +0 -65
  91. c4dynamics-2.3.2/c4dynamics/sensors/lineofsight.py +0 -78
  92. c4dynamics-2.3.2/c4dynamics/sensors/radar.py +0 -721
  93. c4dynamics-2.3.2/c4dynamics/sensors/seeker.py +0 -1006
  94. c4dynamics-2.3.2/c4dynamics/states/__init__.py +0 -33
  95. c4dynamics-2.3.2/c4dynamics/states/lib/datapoint.py +0 -639
  96. c4dynamics-2.3.2/c4dynamics/states/lib/pixelpoint.py +0 -758
  97. c4dynamics-2.3.2/c4dynamics/states/lib/rigidbody.py +0 -647
  98. c4dynamics-2.3.2/c4dynamics/states/state.py +0 -1533
  99. c4dynamics-2.3.2/c4dynamics/utils/__init__.py +0 -27
  100. c4dynamics-2.3.2/c4dynamics/utils/_struct.py +0 -10
  101. c4dynamics-2.3.2/c4dynamics/utils/gen_gif.py +0 -130
  102. c4dynamics-2.3.2/c4dynamics/utils/math.py +0 -124
  103. c4dynamics-2.3.2/c4dynamics/utils/plottools.py +0 -123
  104. c4dynamics-2.3.2/c4dynamics/utils/plottracks.py +0 -307
  105. c4dynamics-2.3.2/c4dynamics/utils/printpts.py +0 -39
  106. c4dynamics-2.3.2/c4dynamics/utils/slides_gen.py +0 -67
  107. c4dynamics-2.3.2/c4dynamics/utils/tictoc.py +0 -174
  108. c4dynamics-2.3.2/c4dynamics/utils/video_gen.py +0 -302
  109. c4dynamics-2.3.2/c4dynamics/utils/vidgen.py +0 -185
  110. c4dynamics-2.3.2/pyproject.toml +0 -39
  111. c4dynamics-2.3.2/setup.cfg +0 -4
  112. c4dynamics-2.3.2/setup.py +0 -60
  113. c4dynamics-2.3.2/tests/test_datasets.py +0 -124
  114. c4dynamics-2.3.2/tests/test_tictoc.py +0 -43
  115. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/LICENSE +0 -0
  116. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics.egg-info/dependency_links.txt +0 -0
  117. {c4dynamics-2.3.2 → c4dynamics-2.3.5}/c4dynamics.egg-info/top_level.txt +0 -0
@@ -1,35 +1,40 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: c4dynamics
3
- Version: 2.3.2
3
+ Version: 2.3.5
4
4
  Summary: Python framework for state-space modeling and algorithm development
5
- Author: c4dynamics
6
5
  Author-email: Ziv Meri <zivmeri@gmail.com>
7
6
  License-Expression: MIT
8
- Keywords: python,state-space,dynamics,physics,algorithms,computer vision,navigation,guidance,slam,vslam,image processing,signal processing,control
9
- Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: Intended Audience :: Developers
7
+ Project-URL: Homepage, https://github.com/c4dynamics/c4dynamics/discussions
8
+ Project-URL: Documentation, https://c4dynamics.github.io/c4dynamics/
9
+ Project-URL: Source, https://github.com/c4dynamics/c4dynamics
10
+ Project-URL: Issues, https://github.com/c4dynamics/c4dynamics/issues
11
+ Keywords: python,state-space,dynamics,physics,algorithms,control,navigation,guidance,slam,vslam,computer-vision,image-processing,signal-processing
11
12
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Operating System :: Unix
13
- Classifier: Operating System :: MacOS :: MacOS X
14
- Classifier: Operating System :: Microsoft :: Windows
15
- Requires-Python: >=3.8,<3.13
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Operating System :: OS Independent
19
+ Requires-Python: <3.13,>=3.8
16
20
  Description-Content-Type: text/markdown
17
21
  License-File: LICENSE
18
- Requires-Dist: imageio>=2.37.0
19
22
  Requires-Dist: matplotlib>=3.9.2
20
- Requires-Dist: natsort>=8.3.1
21
23
  Requires-Dist: numpy>=1.26.0
22
- Requires-Dist: opencv-python>=4.11.0.86
23
24
  Requires-Dist: pooch>=1.8.0
24
25
  Requires-Dist: scipy>=1.13.0
26
+ Provides-Extra: vision
27
+ Requires-Dist: imageio>=2.37.0; extra == "vision"
28
+ Requires-Dist: natsort>=8.3.1; extra == "vision"
29
+ Requires-Dist: opencv-python>=4.11.0.86; extra == "vision"
25
30
  Provides-Extra: dev
31
+ Requires-Dist: c4dynamics[vision]; extra == "dev"
32
+ Requires-Dist: coverage>=7.0.0; extra == "dev"
26
33
  Requires-Dist: nbsphinx>=0.9.3; extra == "dev"
27
- Requires-Dist: Sphinx>=8.1.3; extra == "dev"
34
+ Requires-Dist: sphinx>=8.1.3; extra == "dev"
28
35
  Requires-Dist: sphinx-book-theme>=1.1.4; extra == "dev"
29
36
  Requires-Dist: sphinx_design>=0.6.1; extra == "dev"
30
- Dynamic: author
31
37
  Dynamic: license-file
32
- Dynamic: requires-python
33
38
 
34
39
  <div align="center">
35
40
  <img src="https://github.com/C4dynamics/C4dynamics/blob/main/docs/source/_icon/c4dlogotext.svg">
@@ -37,6 +42,25 @@ Dynamic: requires-python
37
42
 
38
43
 
39
44
 
45
+
46
+
47
+ <div align="center">
48
+ <strong> Published in the Journal of Open Source Software (JOSS)</strong><br>
49
+ <a href="https://doi.org/10.5281/zenodo.17931207">
50
+ <img src="https://zenodo.org/badge/DOI/10.5281/zenodo.17931207.svg">
51
+ </a>
52
+ <br>
53
+ <a href="https://doi.org/10.21105/joss.08776">
54
+ <img src="https://joss.theoj.org/papers/10.21105/joss.08776/status.svg">
55
+ </a>
56
+ </div>
57
+
58
+ <br>
59
+
60
+
61
+
62
+
63
+
40
64
  # Tsipor Dynamics
41
65
 
42
66
  ## Algorithms Engineering and Development
@@ -57,9 +81,24 @@ Tsipor (bird) Dynamics (c4dynamics) is the Python framework for state-space mode
57
81
  ![Pepy Total Downloads](https://img.shields.io/pepy/dt/c4dynamics?style=for-the-badge&color=blue%20&link=https%3A%2F%2Fpepy.tech%2Fprojects%2Fc4dynamics%3FtimeRange%3DthreeMonths%26category%3Dversion%26includeCIDownloads%3Dtrue%26granularity%3Ddaily%26viewType%3Dline%26versions%3D2.0.3%252C2.0.1%252C2.0.0)
58
82
 
59
83
 
84
+ ## About c4dynamics
60
85
 
86
+ **c4dynamics** is designed to
87
+ simplify the development of algorithms for dynamic systems,
88
+ using state space representations.
89
+ It offers engineers and researchers a systematic approach to model,
90
+ simulate, and control systems in fields like
91
+ ``robotics, aerospace,`` and ``navigation``.
61
92
 
62
- [Documentation](https://c4dynamics.github.io/c4dynamics/)
93
+ The framework introduces ``state objects,`` which are foundational
94
+ data structures that encapsulate state vectors and provide
95
+ the tools for managing data, simulating system behavior,
96
+ and analyzing results.
97
+
98
+ With integrated modules for sensors,
99
+ detectors, and filters,
100
+ c4dynamics accelerates algorithm development
101
+ while maintaining flexibility and scalability.
63
102
 
64
103
 
65
104
  ## Why c4dynamics?
@@ -78,24 +117,15 @@ Tsipor (bird) Dynamics (c4dynamics) is the Python framework for state-space mode
78
117
 
79
118
 
80
119
 
120
+ ## Documentation
81
121
 
82
- **c4dynamics** is designed to
83
- simplify the development of algorithms for dynamic systems,
84
- using state space representations.
85
- It offers engineers and researchers a systematic approach to model,
86
- simulate, and control systems in fields like
87
- ``robotics, aerospace,`` and ``navigation``.
88
-
89
- The framework introduces ``state objects,`` which are foundational
90
- data structures that encapsulate state vectors and provide
91
- the tools for managing data, simulating system behavior,
92
- and analyzing results.
93
-
94
- With integrated modules for sensors,
95
- detectors, and filters,
96
- c4dynamics accelerates algorithm development
97
- while maintaining flexibility and scalability.
122
+ 📘 **Full documentation:**
123
+ https://c4dynamics.github.io/c4dynamics/
98
124
 
125
+ - Installation and setup guides
126
+ - Core concepts and state-space modeling philosophy
127
+ - API reference and examples
128
+ - Tutorials for filtering, sensing, and simulation workflows
99
129
 
100
130
 
101
131
  ## Requirements
@@ -124,24 +154,25 @@ To run the latest GitHub version, download the repo and install required package
124
154
  >>> pip install -r requirements.txt
125
155
  ```
126
156
 
127
-
128
-
129
-
130
157
 
131
158
  ## Quickstart
132
159
 
133
160
  Import c4dynamics:
134
- ```
161
+ ```python
135
162
  >>> import c4dynamics as c4d
136
163
  ```
137
164
 
138
165
  Define state space object of two variables in the state space (y, vy) with initial conditions (change the state with your variables):
139
- ```
166
+ ```python
140
167
  >>> s = c4d.state(y = 1, vy = 0.5)
141
168
  ```
169
+ Store with time stamp `t = 0`:
170
+ ```python
171
+ >>> s.store(t = 0)
172
+ ```
142
173
 
143
174
  Multiply the state vector by a matrix and store:
144
- ```
175
+ ```python
145
176
  >>> F = [[1, 1],
146
177
  [0, 1]]
147
178
  >>> s.X += F @ s.X
@@ -149,7 +180,7 @@ Multiply the state vector by a matrix and store:
149
180
  ```
150
181
 
151
182
  Print the state variables, the state vector, and the stored data:
152
- ```
183
+ ```python
153
184
  >>> print(s)
154
185
  [ y vy ]
155
186
  >>> s.X
@@ -4,6 +4,25 @@
4
4
 
5
5
 
6
6
 
7
+
8
+
9
+ <div align="center">
10
+ <strong> Published in the Journal of Open Source Software (JOSS)</strong><br>
11
+ <a href="https://doi.org/10.5281/zenodo.17931207">
12
+ <img src="https://zenodo.org/badge/DOI/10.5281/zenodo.17931207.svg">
13
+ </a>
14
+ <br>
15
+ <a href="https://doi.org/10.21105/joss.08776">
16
+ <img src="https://joss.theoj.org/papers/10.21105/joss.08776/status.svg">
17
+ </a>
18
+ </div>
19
+
20
+ <br>
21
+
22
+
23
+
24
+
25
+
7
26
  # Tsipor Dynamics
8
27
 
9
28
  ## Algorithms Engineering and Development
@@ -24,9 +43,24 @@ Tsipor (bird) Dynamics (c4dynamics) is the Python framework for state-space mode
24
43
  ![Pepy Total Downloads](https://img.shields.io/pepy/dt/c4dynamics?style=for-the-badge&color=blue%20&link=https%3A%2F%2Fpepy.tech%2Fprojects%2Fc4dynamics%3FtimeRange%3DthreeMonths%26category%3Dversion%26includeCIDownloads%3Dtrue%26granularity%3Ddaily%26viewType%3Dline%26versions%3D2.0.3%252C2.0.1%252C2.0.0)
25
44
 
26
45
 
46
+ ## About c4dynamics
27
47
 
48
+ **c4dynamics** is designed to
49
+ simplify the development of algorithms for dynamic systems,
50
+ using state space representations.
51
+ It offers engineers and researchers a systematic approach to model,
52
+ simulate, and control systems in fields like
53
+ ``robotics, aerospace,`` and ``navigation``.
28
54
 
29
- [Documentation](https://c4dynamics.github.io/c4dynamics/)
55
+ The framework introduces ``state objects,`` which are foundational
56
+ data structures that encapsulate state vectors and provide
57
+ the tools for managing data, simulating system behavior,
58
+ and analyzing results.
59
+
60
+ With integrated modules for sensors,
61
+ detectors, and filters,
62
+ c4dynamics accelerates algorithm development
63
+ while maintaining flexibility and scalability.
30
64
 
31
65
 
32
66
  ## Why c4dynamics?
@@ -45,24 +79,15 @@ Tsipor (bird) Dynamics (c4dynamics) is the Python framework for state-space mode
45
79
 
46
80
 
47
81
 
82
+ ## Documentation
48
83
 
49
- **c4dynamics** is designed to
50
- simplify the development of algorithms for dynamic systems,
51
- using state space representations.
52
- It offers engineers and researchers a systematic approach to model,
53
- simulate, and control systems in fields like
54
- ``robotics, aerospace,`` and ``navigation``.
55
-
56
- The framework introduces ``state objects,`` which are foundational
57
- data structures that encapsulate state vectors and provide
58
- the tools for managing data, simulating system behavior,
59
- and analyzing results.
60
-
61
- With integrated modules for sensors,
62
- detectors, and filters,
63
- c4dynamics accelerates algorithm development
64
- while maintaining flexibility and scalability.
84
+ 📘 **Full documentation:**
85
+ https://c4dynamics.github.io/c4dynamics/
65
86
 
87
+ - Installation and setup guides
88
+ - Core concepts and state-space modeling philosophy
89
+ - API reference and examples
90
+ - Tutorials for filtering, sensing, and simulation workflows
66
91
 
67
92
 
68
93
  ## Requirements
@@ -91,24 +116,25 @@ To run the latest GitHub version, download the repo and install required package
91
116
  >>> pip install -r requirements.txt
92
117
  ```
93
118
 
94
-
95
-
96
-
97
119
 
98
120
  ## Quickstart
99
121
 
100
122
  Import c4dynamics:
101
- ```
123
+ ```python
102
124
  >>> import c4dynamics as c4d
103
125
  ```
104
126
 
105
127
  Define state space object of two variables in the state space (y, vy) with initial conditions (change the state with your variables):
106
- ```
128
+ ```python
107
129
  >>> s = c4d.state(y = 1, vy = 0.5)
108
130
  ```
131
+ Store with time stamp `t = 0`:
132
+ ```python
133
+ >>> s.store(t = 0)
134
+ ```
109
135
 
110
136
  Multiply the state vector by a matrix and store:
111
- ```
137
+ ```python
112
138
  >>> F = [[1, 1],
113
139
  [0, 1]]
114
140
  >>> s.X += F @ s.X
@@ -116,7 +142,7 @@ Multiply the state vector by a matrix and store:
116
142
  ```
117
143
 
118
144
  Print the state variables, the state vector, and the stored data:
119
- ```
145
+ ```python
120
146
  >>> print(s)
121
147
  [ y vy ]
122
148
  >>> s.X
@@ -0,0 +1,326 @@
1
+ """
2
+
3
+ C4DYNAMICS
4
+ ==========
5
+
6
+ c4dynamics provides
7
+ 1. State objects as fundamental data structure for dynamic systems.
8
+ 2. Internal systems and 3rd party integrated libraries.
9
+ 3. Fast algorithmic operations over objects and systems.
10
+
11
+
12
+ How to use the documentation
13
+ ----------------------------
14
+ Documentation is currently availble through examples,
15
+ readme pages, and inline comments.
16
+
17
+
18
+ Available subpackages
19
+ ---------------------
20
+ sensors
21
+ Models of EO and EM sensors.
22
+ detectors
23
+ Objects detection models.
24
+ filters
25
+ Kalman and lowpass filters.
26
+ eqm
27
+ Runge Kutta solvers for integrating the equations of motion.
28
+ rotmat
29
+ Rotation matrices and rotational operations.
30
+ """
31
+
32
+ import os
33
+ import sys
34
+ import doctest
35
+ import warnings
36
+ import subprocess
37
+ import numpy as np
38
+
39
+ #
40
+ # body objects
41
+ ##
42
+ from . import rotmat as rotmat
43
+ from .states.lib.pixelpoint import pixelpoint as pixelpoint
44
+ from .states.lib.datapoint import datapoint as datapoint
45
+ from .states.lib.datapoint import create as create
46
+ from .states.state import state as state
47
+
48
+ # rotmat is required to importing rigidbody:
49
+ from .states.lib.rigidbody import rigidbody as rigidbody # rotmat is required to import rigidbody.
50
+
51
+ #
52
+ # routines
53
+ ##
54
+ from . import eqm as eqm
55
+
56
+ #
57
+ # utils
58
+ ##
59
+ from .utils.const import * # noqa: F403
60
+ from .utils.math import * # noqa: F403
61
+ from .utils.gen_gif import gif as gif
62
+ from .utils.cprint import cprint as cprint
63
+ from .utils.plottools import plotdefaults as plotdefaults
64
+ from .utils.plottools import _figdef as _figdef
65
+ from .utils.plottools import _legdef as _legdef
66
+ from .utils import tictoc as tictoc
67
+ from .utils.tictoc import tic as tic
68
+ from .utils.tictoc import toc as toc
69
+ from .utils._struct import struct as struct
70
+ from .utils.idx2keys import idx2keys as idx2keys
71
+ from . import datasets as datasets
72
+
73
+ #
74
+ # sensors
75
+ ##
76
+ from . import sensors as sensors
77
+ from . import filters as filters
78
+ from . import detectors as detectors
79
+
80
+ #
81
+ # reinforcement learning
82
+ ##
83
+ from . import envs as envs # noqa: F401
84
+
85
+ #
86
+ # version
87
+ ##
88
+ __version__ = "2.3.5" # update also in pyproject.toml & setup.py
89
+
90
+
91
+ #
92
+ # some convinient mirroring
93
+ ##
94
+ j = os.path.join
95
+
96
+
97
+ """
98
+ WARNINGS
99
+ """
100
+
101
+
102
+ class c4warn(UserWarning):
103
+ pass
104
+
105
+
106
+ # customize the warning messages:
107
+ YELLOW = "\033[93m"
108
+ RESET = "\033[0m" # Reset color to default
109
+
110
+
111
+ # Override showwarning to globally apply custom formatting
112
+ def show_warning(message, category, filename, lineno, file=None, line=None):
113
+
114
+ if issubclass(category, c4warn):
115
+ # Apply formatting for c4warn warnings
116
+
117
+ # FIXME suppressing is absolutely not working.
118
+ message1 = str(message) + "\n"
119
+ message2 = "To suppress c4dynamics' warnings, run: import warnings," \
120
+ "import c4dynamics as c4d, warnings.simplefilter('ignore', c4d.c4warn)\n"
121
+
122
+ print(f"\n{YELLOW}{message1}{RESET}{message2} (File: {filename}, Line: {lineno})")
123
+ else:
124
+ # For other warnings, use the default behavior
125
+ print(f"{category.__name__}: {message} (File: {filename}, Line: {lineno})")
126
+
127
+
128
+ warnings.showwarning = show_warning
129
+
130
+ """
131
+ TESTING
132
+ """
133
+
134
+
135
+ class IgnoreOutputChecker(doctest.OutputChecker):
136
+ from typing import Union
137
+
138
+ IGNORE_OUTPUT = doctest.register_optionflag("IGNORE_OUTPUT") # 2048
139
+ NUMPY_FORMAT = doctest.register_optionflag("NUMPY_FORMAT") # 4096
140
+
141
+ def check_output(self, want, got, optionflags):
142
+
143
+ # If the IGNORE_OUTPUT flag is set, always return True
144
+ if optionflags & self.IGNORE_OUTPUT:
145
+ return True
146
+
147
+ # If NUMPY_FORMAT flag is set, compare NumPy arrays with formatting tolerance
148
+ if optionflags & self.NUMPY_FORMAT:
149
+
150
+ want = self._convert_to_array(want)
151
+ got = self._convert_to_array(got)
152
+
153
+ if want is not None and got is not None:
154
+
155
+ abs_tol = 1e-3
156
+ rel_tol = 1e-3
157
+
158
+ if False:
159
+
160
+ # Calculate element-wise absolute and relative differences
161
+ # if diff < abs (for small values) OR diff/want < rel (for large values)
162
+ np.abs(want - got) < abs_tol
163
+ np.abs((want - got) / np.where(want != 0, want, np.inf)) < rel_tol
164
+
165
+ return np.allclose(want, got, atol=abs_tol, rtol=rel_tol)
166
+
167
+ # Otherwise, fall back to the original behavior
168
+ return super().check_output(want, got, optionflags) # type: ignore
169
+
170
+ def _convert_to_array(self, text):
171
+
172
+ import re
173
+
174
+ """Attempt to convert text to a NumPy array for comparison."""
175
+ try:
176
+
177
+ if "," not in text:
178
+ text = re.sub(r"\s+", ",", text.strip())
179
+
180
+ # Remove 'np.type'
181
+ text = re.sub(r"np\.\w+", "", text)
182
+ # Remove 'array(' and strip leading/trailing whitespace characters
183
+ text = re.sub(r"(array\()", "", text).strip()
184
+ # Remove brackets and parantheses
185
+ text = re.sub(r"[\[\]\(\)]", "", text)
186
+ # remove ellipsis
187
+ text = re.sub(r"\.\.\.", "", text)
188
+ # Convert to NumPy array
189
+ return np.fromstring(text, sep=",")
190
+
191
+ except ValueError:
192
+ print(
193
+ "\n \033[31m DOCSTRING ERROR: Could not convert to an array \033[0m",
194
+ file=sys.stderr,
195
+ )
196
+ return None # Return None if conversion fails
197
+
198
+ # Filter out tests for the animate method by overriding the testmod.
199
+
200
+
201
+ def testmod_filtering(module, filter_functions=[], **kwargs):
202
+
203
+ tests = []
204
+
205
+ for test in doctest.DocTestFinder().find(module):
206
+ filtfunc = False
207
+ for func in filter_functions:
208
+ if func == test.name:
209
+ filtfunc = True
210
+ break
211
+ if filtfunc:
212
+ continue
213
+ tests.append(test)
214
+
215
+ runner = doctest.DocTestRunner(**kwargs)
216
+ for test in tests:
217
+ runner.run(test)
218
+ return runner.summarize()
219
+
220
+
221
+ def rundoctests(module, exclude_functions=[]):
222
+ import doctest
223
+ import contextlib
224
+ import os
225
+ from c4dynamics import IgnoreOutputChecker # , cprint
226
+
227
+ # from matplotlib import pyplot as plt
228
+ from pathlib import Path
229
+
230
+ tofile = False
231
+ # pltbe = plt.get_backend()
232
+ # plt.switch_backend("tkAgg")
233
+
234
+ # Register the custom OutputChecker
235
+ doctest.OutputChecker = IgnoreOutputChecker
236
+
237
+ optionflags = doctest.FAIL_FAST
238
+ np.set_printoptions(legacy="1.25")
239
+
240
+ if tofile:
241
+ with open(os.path.join("tests", "_out", "output.txt"), "w") as f:
242
+ with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f):
243
+ # result = doctest.testmod(optionflags = optionflags)
244
+ result = testmod_filtering(module, exclude_functions, optionflags=optionflags)
245
+ else:
246
+ # result = doctest.testmod(optionflags = optionflags)
247
+ result = testmod_filtering(module, exclude_functions, optionflags=optionflags)
248
+
249
+ if result.failed == 0:
250
+ cprint(Path(module.__file__).parts[-1] + ": all tests passed!", "g")
251
+ else:
252
+ print(f"{result.failed}")
253
+
254
+ # plt.switch_backend(pltbe)
255
+
256
+
257
+ """
258
+ ROOT FOLDER
259
+ """
260
+
261
+
262
+ # just find the package root folder:
263
+ def c4dir(dir, addpath=""):
264
+ # dirname and basename are supplamentary:
265
+ # c:\dropbox\c4dynamics\text.txt
266
+ # dirname: c:\dropbox\c4dynamics
267
+ # basename: text.txt
268
+
269
+ inc4d = os.path.basename(dir) == "c4dynamics"
270
+ hasc4d = any(f == "c4dynamics" for f in os.listdir(dir) if os.path.isdir(os.path.join(dir, f)))
271
+
272
+ if inc4d and hasc4d:
273
+ addpath += ""
274
+ return addpath
275
+
276
+ addpath += "..\\"
277
+ return c4dir(os.path.dirname(dir), addpath)
278
+
279
+
280
+ """
281
+ KEYWORDS
282
+ """
283
+ #
284
+ # TODO BUG FIXME HACK NOTE XXX
285
+ #
286
+ # TODO IMPROVMEMNT
287
+ #
288
+ # BUG LOGICAL FAILURE PROBABLY COMES WITH XXX
289
+ # Highlights the presence of a bug or an issue.
290
+ # FIXME NOT SEVERE BUT A BETTER IDEA IS TO DO SO
291
+ # Indicates that there is a problem or bug that needs to be fixed.
292
+ # HACK I KNOW ITS NOT BEST SOLUTION TREAT IF U HAVE SPARE TIME
293
+ # Suggests that a workaround or temporary solution has been
294
+ # implemented and should be revisited.
295
+ # NOTE MORE IMPORTANT THAN A CASUAL COMMENT
296
+ # Provides additional information or context about the code.
297
+ # XXX TREAT THIS BEFORE OTHERS
298
+ # Used to highlight something that is problematic, needs attention,
299
+ # or should be addressed later.
300
+
301
+
302
+ # FIXME
303
+ # dependencies: for time limits requirementx.txt currently
304
+ # install all. actually maybe 90% of the users use only numpy
305
+ # and pyplot so it's a good practice to offer another full-req.txt
306
+ # file and add an import check for those not necessary:
307
+
308
+
309
+ def ensure_package(package_name):
310
+ try:
311
+ __import__(package_name)
312
+ except ImportError:
313
+ # Check if the user is in a conda environment
314
+ in_conda_env = os.environ.get("CONDA_PREFIX") is not None
315
+ manager = "conda" if in_conda_env else "pip"
316
+
317
+ user_input = input(
318
+ f"{package_name} is required but not installed. "
319
+ f"Would you like to install it with {manager}? (y/n): "
320
+ )
321
+
322
+ if user_input.lower() == "y":
323
+ if manager == "conda":
324
+ subprocess.check_call(["conda", "install", package_name, "-y"])
325
+ else:
326
+ subprocess.check_call(["pip", "install", package_name])