fips 0.1.0b3__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 (52) hide show
  1. fips-0.1.0b3/LICENSE +21 -0
  2. fips-0.1.0b3/PKG-INFO +185 -0
  3. fips-0.1.0b3/README.md +152 -0
  4. fips-0.1.0b3/pyproject.toml +130 -0
  5. fips-0.1.0b3/setup.cfg +4 -0
  6. fips-0.1.0b3/src/fips/__init__.py +35 -0
  7. fips-0.1.0b3/src/fips/aggregators.py +377 -0
  8. fips-0.1.0b3/src/fips/base.py +608 -0
  9. fips-0.1.0b3/src/fips/covariance.py +344 -0
  10. fips-0.1.0b3/src/fips/estimators.py +648 -0
  11. fips-0.1.0b3/src/fips/filters.py +95 -0
  12. fips-0.1.0b3/src/fips/indexes.py +222 -0
  13. fips-0.1.0b3/src/fips/kernels.py +113 -0
  14. fips-0.1.0b3/src/fips/matrix.py +358 -0
  15. fips-0.1.0b3/src/fips/metrics.py +97 -0
  16. fips-0.1.0b3/src/fips/operators.py +96 -0
  17. fips-0.1.0b3/src/fips/pipeline.py +225 -0
  18. fips-0.1.0b3/src/fips/problem.py +359 -0
  19. fips-0.1.0b3/src/fips/problems/__init__.py +6 -0
  20. fips-0.1.0b3/src/fips/problems/flux/__init__.py +25 -0
  21. fips-0.1.0b3/src/fips/problems/flux/pipeline.py +229 -0
  22. fips-0.1.0b3/src/fips/problems/flux/problem.py +129 -0
  23. fips-0.1.0b3/src/fips/problems/flux/transport/__init__.py +7 -0
  24. fips-0.1.0b3/src/fips/problems/flux/transport/stilt/__init__.py +19 -0
  25. fips-0.1.0b3/src/fips/problems/flux/transport/stilt/builder.py +235 -0
  26. fips-0.1.0b3/src/fips/problems/flux/transport/stilt/errors.py +157 -0
  27. fips-0.1.0b3/src/fips/problems/flux/visualization.py +458 -0
  28. fips-0.1.0b3/src/fips/py.typed +2 -0
  29. fips-0.1.0b3/src/fips/vector.py +250 -0
  30. fips-0.1.0b3/src/fips/visualization.py +249 -0
  31. fips-0.1.0b3/src/fips.egg-info/PKG-INFO +185 -0
  32. fips-0.1.0b3/src/fips.egg-info/SOURCES.txt +50 -0
  33. fips-0.1.0b3/src/fips.egg-info/dependency_links.txt +1 -0
  34. fips-0.1.0b3/src/fips.egg-info/requires.txt +12 -0
  35. fips-0.1.0b3/src/fips.egg-info/top_level.txt +1 -0
  36. fips-0.1.0b3/tests/test_aggregators.py +381 -0
  37. fips-0.1.0b3/tests/test_base.py +228 -0
  38. fips-0.1.0b3/tests/test_covariance.py +562 -0
  39. fips-0.1.0b3/tests/test_estimators.py +867 -0
  40. fips-0.1.0b3/tests/test_filters.py +44 -0
  41. fips-0.1.0b3/tests/test_flux_problem.py +322 -0
  42. fips-0.1.0b3/tests/test_indexes.py +151 -0
  43. fips-0.1.0b3/tests/test_kernels.py +42 -0
  44. fips-0.1.0b3/tests/test_matrices.py +515 -0
  45. fips-0.1.0b3/tests/test_metrics.py +79 -0
  46. fips-0.1.0b3/tests/test_operators.py +360 -0
  47. fips-0.1.0b3/tests/test_pkg.py +1 -0
  48. fips-0.1.0b3/tests/test_problem.py +593 -0
  49. fips-0.1.0b3/tests/test_sparse.py +344 -0
  50. fips-0.1.0b3/tests/test_stilt_builder.py +209 -0
  51. fips-0.1.0b3/tests/test_vectors.py +285 -0
  52. fips-0.1.0b3/tests/test_visualization.py +264 -0
fips-0.1.0b3/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 James Mineau
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
fips-0.1.0b3/PKG-INFO ADDED
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: fips
3
+ Version: 0.1.0b3
4
+ Summary: Flexible Inverse Problem Solver (FIPS)
5
+ Author-email: James Mineau <jameskmineau@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/jmineau/fips
8
+ Project-URL: Documentation, https://jmineau.github.io/fips/
9
+ Project-URL: Repository, https://github.com/jmineau/fips
10
+ Project-URL: Issues, https://github.com/jmineau/fips/issues
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: joblib>=1.4.0
22
+ Requires-Dist: numpy>=1.22.0
23
+ Requires-Dist: pandas>=2.0.0
24
+ Requires-Dist: scipy>=1.8.0
25
+ Requires-Dist: typing-extensions>=4.0.0
26
+ Requires-Dist: xarray>=2022.3.0
27
+ Provides-Extra: flux
28
+ Requires-Dist: cartopy>=0.24.0; extra == "flux"
29
+ Requires-Dist: h5py>=3.11.0; extra == "flux"
30
+ Requires-Dist: matplotlib>=3.6.0; extra == "flux"
31
+ Requires-Dist: pystilt>=0.1.0a1; extra == "flux"
32
+ Dynamic: license-file
33
+
34
+ <div align=center>
35
+ <picture>
36
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jmineau/fips/main/docs/_static/logo_dark.png">
37
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/jmineau/fips/main/docs/_static/logo.png">
38
+ <img alt="fips logo" src="https://raw.githubusercontent.com/jmineau/fips/main/docs/_static/logo.png" width="600">
39
+ </picture>
40
+ </div>
41
+
42
+ [![Tests](https://github.com/jmineau/fips/actions/workflows/tests.yml/badge.svg)](https://github.com/jmineau/fips/actions/workflows/tests.yml)
43
+ [![Documentation](https://github.com/jmineau/fips/actions/workflows/docs.yml/badge.svg)](https://github.com/jmineau/fips/actions/workflows/docs.yml)
44
+ [![Code Quality](https://github.com/jmineau/fips/actions/workflows/quality.yml/badge.svg)](https://github.com/jmineau/fips/actions/workflows/quality.yml)
45
+ [![codecov](https://codecov.io/gh/jmineau/fips/branch/main/graph/badge.svg)](https://codecov.io/gh/jmineau/fips)
46
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
47
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
48
+ [![Pyright](https://img.shields.io/badge/pyright-checked-brightgreen.svg)](https://github.com/microsoft/pyright)
49
+
50
+ > **⚠️ Beta Release**: FIPS is currently in beta (v0.1.0b1). The core API is stable and ready for testing, but may evolve based on user feedback. Please [report any issues or edge cases](https://github.com/jmineau/fips/issues) you encounter.
51
+
52
+ ## Bridging Physics and Data
53
+ Inverse problems in geophysics and atmospheric science are incredibly complex, often involving massive state spaces, deeply heterogeneous observational networks, and explicit matrix-algebra requirements. While many general-purpose optimization tools exist, they often force researchers to strip away critical spatiotemporal metadata or translate pre-computed physical models into rigid, abstract array structures.
54
+
55
+ **FIPS (Flexible Inverse Problem Solver)** is built from the ground up to solve linear, matrix-based inverse problems without losing the context of your data. It provides the structural flexibility to handle messy, real-world realities seamlessly:
56
+
57
+ - **Native N-Dimensional Alignment**: FIPS natively utilizes `pandas.MultiIndex` to smoothly align heterogeneous datasets across any dimension. Whether you are mixing temporal, spatial, spectral, or sensor-specific data, your coordinates are never dropped or misaligned.
58
+
59
+ - **Modular Block Architecture**: Avoid wrangling monolithic arrays. Construct massive, multi-source state spaces and observation networks piece-by-piece using specialized `Block` and `MatrixBlock` objects.
60
+
61
+ - **Speak Your Domain's Language**: Built explicitly around the standard `y = Hx + error` paradigm. Directly plug in your pre-computed forward operators ($H$), prior covariances ($S_0$), and model-data mismatches ($S_z$).
62
+
63
+ - **Analytical Speed & Sparse Support**: FIPS is built for scale. By leveraging optimized sparse data structures and direct linear algebra rather than expensive sampling algorithms, it computes exact analytical Maximum A Posteriori (MAP) estimates for massive state spaces in seconds.
64
+
65
+ ## Installation
66
+
67
+ ### From GitHub
68
+ ```bash
69
+ pip install git+https://github.com/jmineau/fips
70
+ ```
71
+
72
+ ### From Source
73
+
74
+ ```bash
75
+ git clone https://github.com/jmineau/fips.git
76
+ cd fips
77
+ pip install -e .
78
+ ```
79
+
80
+ ## Usage
81
+
82
+ ### Single-block — one observation source
83
+
84
+ ```python
85
+ import numpy as np
86
+ import pandas as pd
87
+ from fips import Block, CovarianceMatrix
88
+ from fips.problems.flux import FluxProblem
89
+
90
+ # State: gridded prior fluxes (time × lat × lon)
91
+ flux_idx = pd.MultiIndex.from_product(
92
+ [pd.date_range("2023-01", periods=3, freq="MS"), [37.0, 38.0], [-112.0, -111.0]],
93
+ names=["time", "lat", "lon"],
94
+ )
95
+ prior = pd.Series(np.ones(12) * 1.5, index=flux_idx, name="flux")
96
+
97
+ # Observations: tower concentration measurements
98
+ obs_idx = pd.MultiIndex.from_product(
99
+ [pd.date_range("2023-01", periods=8, freq="2W"), ["UOU"]],
100
+ names=["time", "site"],
101
+ )
102
+ obs = pd.Series(np.ones(8) * 400.0, index=obs_idx, name="concentration")
103
+
104
+ # Forward operator (Jacobian), flux error covariance, obs error covariance
105
+ H = pd.DataFrame(np.random.rand(8, 12), index=obs_idx, columns=flux_idx)
106
+ S_0 = pd.DataFrame(np.eye(12) * 0.5, index=flux_idx, columns=flux_idx)
107
+ S_z = pd.DataFrame(np.eye(8) * 0.1, index=obs_idx, columns=obs_idx)
108
+
109
+ problem = FluxProblem(
110
+ obs=obs, prior=prior,
111
+ forward_operator=H, prior_error=S_0, modeldata_mismatch=S_z,
112
+ ).solve()
113
+
114
+ print(problem.posterior_fluxes) # posterior pd.Series indexed by (time, lat, lon)
115
+ print(problem.estimator.reduced_chi2) # reduced chi-squared statistic
116
+ ```
117
+
118
+ ### Multi-block — combined station + satellite observations
119
+
120
+ ```python
121
+ import numpy as np
122
+ import pandas as pd
123
+ from fips import Block, Vector, Matrix, MatrixBlock, CovarianceMatrix, InverseProblem
124
+
125
+ # State: same gridded prior fluxes (from above)
126
+ N_f = 12
127
+
128
+ # Obs block 1: ground station in-situ concentrations
129
+ station_idx = pd.MultiIndex.from_product(
130
+ [pd.date_range("2023-01", periods=8, freq="2W"), ["UOU"]],
131
+ names=["time", "site"],
132
+ )
133
+ station_obs = Block(pd.Series(np.ones(8) * 400.0,
134
+ index=station_idx, name="station"))
135
+
136
+ # Obs block 2: satellite column-average concentrations
137
+ satellite_idx = pd.MultiIndex.from_product(
138
+ [pd.date_range("2023-01", periods=3, freq="MS"), [37.5], [-111.5]],
139
+ names=["time", "lat", "lon"],
140
+ )
141
+ satellite_obs = Block(pd.Series(np.ones(3) * 0.00400,
142
+ index=satellite_idx, name="satellite"))
143
+
144
+ # Combine obs blocks into a list
145
+ obs_blks = [station_obs, satellite_obs]
146
+
147
+ # Jacobian: one MatrixBlock per obs type, both mapping to the "flux" state block
148
+ H_blks = [
149
+ MatrixBlock(
150
+ pd.DataFrame(np.random.rand(8, N_f),
151
+ index=station_idx, columns=flux_idx),
152
+ row_block="station", col_block="flux",
153
+ ),
154
+ MatrixBlock(
155
+ pd.DataFrame(np.random.rand(3, N_f),
156
+ index=satellite_idx, columns=flux_idx),
157
+ row_block="satellite", col_block="flux",
158
+ ),]
159
+
160
+ # Prior error covariance: only flux errors, no cross-block covariances
161
+ S_0 = CovarianceMatrix(np.eye(N_f) * 0.5, index=flux_idx, columns=flux_idx)
162
+
163
+ # Model-data mismatch covariance: block-diagonal with separate error levels for stations vs. satellite
164
+ S_z_blks = [
165
+ CovarianceMatrix(np.eye(8) * 0.1, index=station_idx, columns=station_idx),
166
+ CovarianceMatrix(np.eye(3) * 0.2, index=satellite_idx, columns=satellite_idx),
167
+ ]
168
+
169
+ # Pass blocks to the InverseProblem and solve
170
+ problem = InverseProblem(
171
+ obs=obs_blks, prior=prior,
172
+ forward_operator=H_blks, prior_error=S_0, modeldata_mismatch=S_z_blks,
173
+ ).solve()
174
+
175
+ print(problem.posterior['flux']) # posterior pd.Series indexed by (time, lat, lon)
176
+ print(problem.estimator.reduced_chi2) # reduced chi-squared statistic
177
+ ```
178
+
179
+ ## Documentation
180
+
181
+ Full documentation is available at [https://jmineau.github.io/fips/](https://jmineau.github.io/fips/)
182
+
183
+ ## Contributing
184
+
185
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
fips-0.1.0b3/README.md ADDED
@@ -0,0 +1,152 @@
1
+ <div align=center>
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jmineau/fips/main/docs/_static/logo_dark.png">
4
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/jmineau/fips/main/docs/_static/logo.png">
5
+ <img alt="fips logo" src="https://raw.githubusercontent.com/jmineau/fips/main/docs/_static/logo.png" width="600">
6
+ </picture>
7
+ </div>
8
+
9
+ [![Tests](https://github.com/jmineau/fips/actions/workflows/tests.yml/badge.svg)](https://github.com/jmineau/fips/actions/workflows/tests.yml)
10
+ [![Documentation](https://github.com/jmineau/fips/actions/workflows/docs.yml/badge.svg)](https://github.com/jmineau/fips/actions/workflows/docs.yml)
11
+ [![Code Quality](https://github.com/jmineau/fips/actions/workflows/quality.yml/badge.svg)](https://github.com/jmineau/fips/actions/workflows/quality.yml)
12
+ [![codecov](https://codecov.io/gh/jmineau/fips/branch/main/graph/badge.svg)](https://codecov.io/gh/jmineau/fips)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
15
+ [![Pyright](https://img.shields.io/badge/pyright-checked-brightgreen.svg)](https://github.com/microsoft/pyright)
16
+
17
+ > **⚠️ Beta Release**: FIPS is currently in beta (v0.1.0b1). The core API is stable and ready for testing, but may evolve based on user feedback. Please [report any issues or edge cases](https://github.com/jmineau/fips/issues) you encounter.
18
+
19
+ ## Bridging Physics and Data
20
+ Inverse problems in geophysics and atmospheric science are incredibly complex, often involving massive state spaces, deeply heterogeneous observational networks, and explicit matrix-algebra requirements. While many general-purpose optimization tools exist, they often force researchers to strip away critical spatiotemporal metadata or translate pre-computed physical models into rigid, abstract array structures.
21
+
22
+ **FIPS (Flexible Inverse Problem Solver)** is built from the ground up to solve linear, matrix-based inverse problems without losing the context of your data. It provides the structural flexibility to handle messy, real-world realities seamlessly:
23
+
24
+ - **Native N-Dimensional Alignment**: FIPS natively utilizes `pandas.MultiIndex` to smoothly align heterogeneous datasets across any dimension. Whether you are mixing temporal, spatial, spectral, or sensor-specific data, your coordinates are never dropped or misaligned.
25
+
26
+ - **Modular Block Architecture**: Avoid wrangling monolithic arrays. Construct massive, multi-source state spaces and observation networks piece-by-piece using specialized `Block` and `MatrixBlock` objects.
27
+
28
+ - **Speak Your Domain's Language**: Built explicitly around the standard `y = Hx + error` paradigm. Directly plug in your pre-computed forward operators ($H$), prior covariances ($S_0$), and model-data mismatches ($S_z$).
29
+
30
+ - **Analytical Speed & Sparse Support**: FIPS is built for scale. By leveraging optimized sparse data structures and direct linear algebra rather than expensive sampling algorithms, it computes exact analytical Maximum A Posteriori (MAP) estimates for massive state spaces in seconds.
31
+
32
+ ## Installation
33
+
34
+ ### From GitHub
35
+ ```bash
36
+ pip install git+https://github.com/jmineau/fips
37
+ ```
38
+
39
+ ### From Source
40
+
41
+ ```bash
42
+ git clone https://github.com/jmineau/fips.git
43
+ cd fips
44
+ pip install -e .
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ### Single-block — one observation source
50
+
51
+ ```python
52
+ import numpy as np
53
+ import pandas as pd
54
+ from fips import Block, CovarianceMatrix
55
+ from fips.problems.flux import FluxProblem
56
+
57
+ # State: gridded prior fluxes (time × lat × lon)
58
+ flux_idx = pd.MultiIndex.from_product(
59
+ [pd.date_range("2023-01", periods=3, freq="MS"), [37.0, 38.0], [-112.0, -111.0]],
60
+ names=["time", "lat", "lon"],
61
+ )
62
+ prior = pd.Series(np.ones(12) * 1.5, index=flux_idx, name="flux")
63
+
64
+ # Observations: tower concentration measurements
65
+ obs_idx = pd.MultiIndex.from_product(
66
+ [pd.date_range("2023-01", periods=8, freq="2W"), ["UOU"]],
67
+ names=["time", "site"],
68
+ )
69
+ obs = pd.Series(np.ones(8) * 400.0, index=obs_idx, name="concentration")
70
+
71
+ # Forward operator (Jacobian), flux error covariance, obs error covariance
72
+ H = pd.DataFrame(np.random.rand(8, 12), index=obs_idx, columns=flux_idx)
73
+ S_0 = pd.DataFrame(np.eye(12) * 0.5, index=flux_idx, columns=flux_idx)
74
+ S_z = pd.DataFrame(np.eye(8) * 0.1, index=obs_idx, columns=obs_idx)
75
+
76
+ problem = FluxProblem(
77
+ obs=obs, prior=prior,
78
+ forward_operator=H, prior_error=S_0, modeldata_mismatch=S_z,
79
+ ).solve()
80
+
81
+ print(problem.posterior_fluxes) # posterior pd.Series indexed by (time, lat, lon)
82
+ print(problem.estimator.reduced_chi2) # reduced chi-squared statistic
83
+ ```
84
+
85
+ ### Multi-block — combined station + satellite observations
86
+
87
+ ```python
88
+ import numpy as np
89
+ import pandas as pd
90
+ from fips import Block, Vector, Matrix, MatrixBlock, CovarianceMatrix, InverseProblem
91
+
92
+ # State: same gridded prior fluxes (from above)
93
+ N_f = 12
94
+
95
+ # Obs block 1: ground station in-situ concentrations
96
+ station_idx = pd.MultiIndex.from_product(
97
+ [pd.date_range("2023-01", periods=8, freq="2W"), ["UOU"]],
98
+ names=["time", "site"],
99
+ )
100
+ station_obs = Block(pd.Series(np.ones(8) * 400.0,
101
+ index=station_idx, name="station"))
102
+
103
+ # Obs block 2: satellite column-average concentrations
104
+ satellite_idx = pd.MultiIndex.from_product(
105
+ [pd.date_range("2023-01", periods=3, freq="MS"), [37.5], [-111.5]],
106
+ names=["time", "lat", "lon"],
107
+ )
108
+ satellite_obs = Block(pd.Series(np.ones(3) * 0.00400,
109
+ index=satellite_idx, name="satellite"))
110
+
111
+ # Combine obs blocks into a list
112
+ obs_blks = [station_obs, satellite_obs]
113
+
114
+ # Jacobian: one MatrixBlock per obs type, both mapping to the "flux" state block
115
+ H_blks = [
116
+ MatrixBlock(
117
+ pd.DataFrame(np.random.rand(8, N_f),
118
+ index=station_idx, columns=flux_idx),
119
+ row_block="station", col_block="flux",
120
+ ),
121
+ MatrixBlock(
122
+ pd.DataFrame(np.random.rand(3, N_f),
123
+ index=satellite_idx, columns=flux_idx),
124
+ row_block="satellite", col_block="flux",
125
+ ),]
126
+
127
+ # Prior error covariance: only flux errors, no cross-block covariances
128
+ S_0 = CovarianceMatrix(np.eye(N_f) * 0.5, index=flux_idx, columns=flux_idx)
129
+
130
+ # Model-data mismatch covariance: block-diagonal with separate error levels for stations vs. satellite
131
+ S_z_blks = [
132
+ CovarianceMatrix(np.eye(8) * 0.1, index=station_idx, columns=station_idx),
133
+ CovarianceMatrix(np.eye(3) * 0.2, index=satellite_idx, columns=satellite_idx),
134
+ ]
135
+
136
+ # Pass blocks to the InverseProblem and solve
137
+ problem = InverseProblem(
138
+ obs=obs_blks, prior=prior,
139
+ forward_operator=H_blks, prior_error=S_0, modeldata_mismatch=S_z_blks,
140
+ ).solve()
141
+
142
+ print(problem.posterior['flux']) # posterior pd.Series indexed by (time, lat, lon)
143
+ print(problem.estimator.reduced_chi2) # reduced chi-squared statistic
144
+ ```
145
+
146
+ ## Documentation
147
+
148
+ Full documentation is available at [https://jmineau.github.io/fips/](https://jmineau.github.io/fips/)
149
+
150
+ ## Contributing
151
+
152
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
@@ -0,0 +1,130 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "fips"
7
+ version = "0.1.0b3"
8
+ description = "Flexible Inverse Problem Solver (FIPS)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "James Mineau", email = "jameskmineau@gmail.com"}
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ ]
24
+ dependencies = [
25
+ "joblib>=1.4.0",
26
+ "numpy>=1.22.0",
27
+ "pandas>=2.0.0", # need pandas 2.0 for upgraded Index object
28
+ "scipy>=1.8.0",
29
+ "typing-extensions>=4.0.0",
30
+ "xarray>=2022.3.0",
31
+ ]
32
+
33
+ [project.optional-dependencies]
34
+ flux = [
35
+ "cartopy>=0.24.0", # numpy 2.0 support
36
+ "h5py>=3.11.0", # numpy 2.0 support
37
+ "matplotlib>=3.6.0",
38
+ "pystilt>=0.1.0a1",
39
+ ]
40
+
41
+ [dependency-groups]
42
+ dev = [
43
+ "fips[flux]",
44
+ "docstr-coverage>=2.0.0",
45
+ "ipykernel>=7.2.0",
46
+ "myst-parser>=2.0.0",
47
+ "nbsphinx>=0.9.0",
48
+ "pre-commit>=3.0.0",
49
+ "pydata-sphinx-theme>=0.14.0",
50
+ "pyright[nodejs]>=1.1.0",
51
+ "pytest>=7.0.0",
52
+ "pytest-cov>=4.0.0",
53
+ "ruff>=0.1.0",
54
+ "sphinx>=7.0.0",
55
+ "sphinx-autodoc-typehints>=1.24.0",
56
+ ]
57
+
58
+ [project.urls]
59
+ Homepage = "https://github.com/jmineau/fips"
60
+ Documentation = "https://jmineau.github.io/fips/"
61
+ Repository = "https://github.com/jmineau/fips"
62
+ Issues = "https://github.com/jmineau/fips/issues"
63
+
64
+ [tool.coverage.run]
65
+ source = ["src/fips"]
66
+ omit = ["*/tests/*", "*/test_*.py"]
67
+
68
+ [tool.coverage.report]
69
+ # Regexes for lines to exclude from consideration
70
+ exclude_also = [
71
+ # Don't complain about missing debug-only code:
72
+ "def __repr__",
73
+ "if self\\.debug",
74
+
75
+ # Don't complain if tests don't hit defensive assertion code:
76
+ "raise AssertionError",
77
+ "raise NotImplementedError",
78
+
79
+ # Don't complain if non-runnable code isn't run:
80
+ "if 0:",
81
+ "if __name__ == .__main__.:",
82
+
83
+ # Don't complain about abstract methods, they aren't run:
84
+ "@(abc\\.)?abstractmethod",
85
+ ]
86
+
87
+ [tool.pyright]
88
+ include = ["src"]
89
+ exclude = ["**/__pycache__", "**/.venv"]
90
+
91
+ [tool.pytest.ini_options]
92
+ testpaths = ["tests"]
93
+ filterwarnings = [
94
+ "ignore:numpy.core.multiarray is deprecated:DeprecationWarning",
95
+ ]
96
+
97
+ [tool.ruff]
98
+ target-version = "py310"
99
+
100
+ [tool.ruff.lint.pydocstyle]
101
+ convention = "numpy"
102
+
103
+ [tool.ruff.format]
104
+ docstring-code-format = true
105
+
106
+ [tool.ruff.lint]
107
+ select = [
108
+ "E", # pycodestyle
109
+ "F", # Pyflakes
110
+ "UP", # pyupgrade
111
+ "B", # flake8-bugbear
112
+ "SIM", # flake8-simplify
113
+ "I", # isort
114
+ "D", # pydocstyle
115
+ ]
116
+ ignore = [
117
+ "E501", # line too long, handled by formatter
118
+ "D200", # One-line docstring should fit on one line with quotes
119
+ "D212", # Multi-line docstring summary should start at the first line
120
+ "D400", # First line should end with a period, question mark, or exclamation point
121
+ ]
122
+
123
+ [tool.ruff.lint.isort]
124
+ known-first-party = ["fips"]
125
+
126
+ [tool.setuptools.packages.find]
127
+ where = ["src"]
128
+
129
+ [tool.setuptools.package-data]
130
+ "fips" = ["py.typed"]
fips-0.1.0b3/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,35 @@
1
+ """
2
+ Flexible Inverse Problem Solver (FIPS).
3
+
4
+ A Pythonic framework for solving linear inverse problems using Bayesian estimation.
5
+ Provides data structures for state vectors, observations, forward operators, and
6
+ covariance matrices; estimators for computing posteriors; and interfaces for
7
+ serialization, visualization, and specialized applications like atmospheric
8
+ flux inversion.
9
+ """
10
+
11
+ import logging
12
+
13
+ from .covariance import CovarianceMatrix
14
+ from .estimators import Estimator, available_estimators
15
+ from .matrix import Matrix, MatrixBlock
16
+ from .operators import ForwardOperator, convolve
17
+ from .pipeline import InversionPipeline
18
+ from .problem import InverseProblem
19
+ from .vector import Block, Vector
20
+
21
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
22
+
23
+ __all__ = [
24
+ "Block",
25
+ "Vector",
26
+ "Matrix",
27
+ "MatrixBlock",
28
+ "Estimator",
29
+ "available_estimators",
30
+ "ForwardOperator",
31
+ "CovarianceMatrix",
32
+ "InversionPipeline",
33
+ "InverseProblem",
34
+ "convolve",
35
+ ]