pcsf 0.1.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 (97) hide show
  1. pcsf-0.1.0/LICENSE +28 -0
  2. pcsf-0.1.0/PKG-INFO +354 -0
  3. pcsf-0.1.0/README.md +290 -0
  4. pcsf-0.1.0/pyproject.toml +133 -0
  5. pcsf-0.1.0/setup.cfg +4 -0
  6. pcsf-0.1.0/src/pcsf/__init__.py +100 -0
  7. pcsf-0.1.0/src/pcsf/_logging.py +73 -0
  8. pcsf-0.1.0/src/pcsf/_version.py +19 -0
  9. pcsf-0.1.0/src/pcsf/adapters/__init__.py +41 -0
  10. pcsf-0.1.0/src/pcsf/adapters/_common.py +91 -0
  11. pcsf-0.1.0/src/pcsf/adapters/emc.py +296 -0
  12. pcsf-0.1.0/src/pcsf/adapters/mare2dem.py +207 -0
  13. pcsf-0.1.0/src/pcsf/adapters/modem.py +344 -0
  14. pcsf-0.1.0/src/pcsf/adapters/occam2d.py +246 -0
  15. pcsf-0.1.0/src/pcsf/algorithms/__init__.py +65 -0
  16. pcsf-0.1.0/src/pcsf/algorithms/comparison.py +145 -0
  17. pcsf-0.1.0/src/pcsf/algorithms/locate.py +219 -0
  18. pcsf-0.1.0/src/pcsf/algorithms/projection.py +90 -0
  19. pcsf-0.1.0/src/pcsf/algorithms/registration.py +211 -0
  20. pcsf-0.1.0/src/pcsf/algorithms/regrid.py +146 -0
  21. pcsf-0.1.0/src/pcsf/algorithms/sampling.py +345 -0
  22. pcsf-0.1.0/src/pcsf/algorithms/uncertainty.py +384 -0
  23. pcsf-0.1.0/src/pcsf/api/__init__.py +375 -0
  24. pcsf-0.1.0/src/pcsf/api/property.py +413 -0
  25. pcsf-0.1.0/src/pcsf/api/registry.py +421 -0
  26. pcsf-0.1.0/src/pcsf/api/types.py +45 -0
  27. pcsf-0.1.0/src/pcsf/cli/__init__.py +5 -0
  28. pcsf-0.1.0/src/pcsf/cli/__main__.py +8 -0
  29. pcsf-0.1.0/src/pcsf/cli/main.py +183 -0
  30. pcsf-0.1.0/src/pcsf/compat/__init__.py +20 -0
  31. pcsf-0.1.0/src/pcsf/compat/h5py.py +71 -0
  32. pcsf-0.1.0/src/pcsf/compat/numpy.py +32 -0
  33. pcsf-0.1.0/src/pcsf/compat/optional.py +101 -0
  34. pcsf-0.1.0/src/pcsf/compat/python.py +47 -0
  35. pcsf-0.1.0/src/pcsf/core/__init__.py +89 -0
  36. pcsf-0.1.0/src/pcsf/core/conformance.py +311 -0
  37. pcsf-0.1.0/src/pcsf/core/encodings.py +216 -0
  38. pcsf-0.1.0/src/pcsf/core/hdf5.py +639 -0
  39. pcsf-0.1.0/src/pcsf/core/provenance.py +170 -0
  40. pcsf-0.1.0/src/pcsf/core/record.py +301 -0
  41. pcsf-0.1.0/src/pcsf/core/schema.py +939 -0
  42. pcsf-0.1.0/src/pcsf/core/text.py +1320 -0
  43. pcsf-0.1.0/src/pcsf/core/versioning.py +113 -0
  44. pcsf-0.1.0/src/pcsf/datasets/__init__.py +58 -0
  45. pcsf-0.1.0/src/pcsf/datasets/mare2dem_tiny/tiny.1.resistivity +8 -0
  46. pcsf-0.1.0/src/pcsf/datasets/mare2dem_tiny/tiny.ele.txt +4 -0
  47. pcsf-0.1.0/src/pcsf/datasets/mare2dem_tiny/tiny.logfile +10 -0
  48. pcsf-0.1.0/src/pcsf/datasets/mare2dem_tiny/tiny.node.txt +6 -0
  49. pcsf-0.1.0/src/pcsf/datasets/mare2dem_tiny/tiny.poly +19 -0
  50. pcsf-0.1.0/src/pcsf/datasets/modem_tiny/tiny.dat +12 -0
  51. pcsf-0.1.0/src/pcsf/datasets/modem_tiny/tiny_NLCG.log +5 -0
  52. pcsf-0.1.0/src/pcsf/datasets/modem_tiny/tiny_NLCG_002.rho +19 -0
  53. pcsf-0.1.0/src/pcsf/datasets/occam2d_tiny/ITER01.iter +11 -0
  54. pcsf-0.1.0/src/pcsf/datasets/occam2d_tiny/ITER02.iter +11 -0
  55. pcsf-0.1.0/src/pcsf/datasets/occam2d_tiny/LogFile.logfile +10 -0
  56. pcsf-0.1.0/src/pcsf/datasets/occam2d_tiny/Occam2DMesh +21 -0
  57. pcsf-0.1.0/src/pcsf/datasets/occam2d_tiny/Occam2DModel +11 -0
  58. pcsf-0.1.0/src/pcsf/datasets/occam2d_tiny/OccamDataFile.dat +13 -0
  59. pcsf-0.1.0/src/pcsf/decorators.py +263 -0
  60. pcsf-0.1.0/src/pcsf/exceptions.py +181 -0
  61. pcsf-0.1.0/src/pcsf/native/__init__.py +21 -0
  62. pcsf-0.1.0/src/pcsf/native/_tokens.py +85 -0
  63. pcsf-0.1.0/src/pcsf/native/mare2dem.py +411 -0
  64. pcsf-0.1.0/src/pcsf/native/modem.py +419 -0
  65. pcsf-0.1.0/src/pcsf/native/occam2d.py +643 -0
  66. pcsf-0.1.0/src/pcsf/plugins/__init__.py +138 -0
  67. pcsf-0.1.0/src/pcsf/py.typed +0 -0
  68. pcsf-0.1.0/src/pcsf/schemas/__init__.py +99 -0
  69. pcsf-0.1.0/src/pcsf/schemas/inversion-record.schema.json +83 -0
  70. pcsf-0.1.0/src/pcsf/schemas/model-provenance.schema.json +28 -0
  71. pcsf-0.1.0/src/pcsf/studio/__init__.py +201 -0
  72. pcsf-0.1.0/src/pcsf/studio/__main__.py +8 -0
  73. pcsf-0.1.0/src/pcsf/studio/convert.py +282 -0
  74. pcsf-0.1.0/src/pcsf/studio/convert_page.py +664 -0
  75. pcsf-0.1.0/src/pcsf/studio/figures.py +622 -0
  76. pcsf-0.1.0/src/pcsf/studio/resources/pcsf-studio.png +0 -0
  77. pcsf-0.1.0/src/pcsf/studio/resources/pcsf-studio.svg +44 -0
  78. pcsf-0.1.0/src/pcsf/studio/sources.py +265 -0
  79. pcsf-0.1.0/src/pcsf/studio/style.py +473 -0
  80. pcsf-0.1.0/src/pcsf/studio/summary.py +444 -0
  81. pcsf-0.1.0/src/pcsf/studio/window.py +2179 -0
  82. pcsf-0.1.0/src/pcsf/utils/__init__.py +19 -0
  83. pcsf-0.1.0/src/pcsf/utils/arrays.py +116 -0
  84. pcsf-0.1.0/src/pcsf/utils/geo.py +101 -0
  85. pcsf-0.1.0/src/pcsf/utils/hashing.py +91 -0
  86. pcsf-0.1.0/src/pcsf/utils/io.py +154 -0
  87. pcsf-0.1.0/src/pcsf/utils/text.py +42 -0
  88. pcsf-0.1.0/src/pcsf.egg-info/PKG-INFO +354 -0
  89. pcsf-0.1.0/src/pcsf.egg-info/SOURCES.txt +95 -0
  90. pcsf-0.1.0/src/pcsf.egg-info/dependency_links.txt +1 -0
  91. pcsf-0.1.0/src/pcsf.egg-info/entry_points.txt +5 -0
  92. pcsf-0.1.0/src/pcsf.egg-info/requires.txt +42 -0
  93. pcsf-0.1.0/src/pcsf.egg-info/top_level.txt +1 -0
  94. pcsf-0.1.0/tests/test_collection.py +43 -0
  95. pcsf-0.1.0/tests/test_conformance_suite.py +29 -0
  96. pcsf-0.1.0/tests/test_pycsamt_interop.py +89 -0
  97. pcsf-0.1.0/tests/test_schemas.py +85 -0
pcsf-0.1.0/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Kouao Laurent Kouadio and the PCSF contributors.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pcsf-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,354 @@
1
+ Metadata-Version: 2.4
2
+ Name: pcsf
3
+ Version: 0.1.0
4
+ Summary: Portable Common Subsurface Format: exchange format, tools and algorithms for electromagnetic inversion models
5
+ Author-email: Kouao Laurent Kouadio <etanoyau@gmail.com>
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/earthai-tech/pcsf
8
+ Project-URL: Documentation, https://pcsf.readthedocs.io
9
+ Project-URL: Source, https://github.com/earthai-tech/pcsf
10
+ Project-URL: Issues, https://github.com/earthai-tech/pcsf/issues
11
+ Project-URL: Changelog, https://github.com/earthai-tech/pcsf/blob/master/CHANGELOG.md
12
+ Keywords: magnetotellurics,electromagnetic,inversion,resistivity,geophysics,file format,HDF5,interoperability,Occam2D,ModEM,MARE2DEM
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: BSD License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Topic :: Scientific/Engineering :: Physics
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.9
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy>=1.22
31
+ Requires-Dist: h5py>=3.8
32
+ Provides-Extra: algorithms
33
+ Requires-Dist: scipy>=1.8; extra == "algorithms"
34
+ Requires-Dist: matplotlib>=3.5; extra == "algorithms"
35
+ Provides-Extra: emc
36
+ Requires-Dist: netCDF4>=1.6; extra == "emc"
37
+ Provides-Extra: mare2dem
38
+ Requires-Dist: triangle>=20220202; extra == "mare2dem"
39
+ Provides-Extra: schema
40
+ Requires-Dist: jsonschema>=4.17; extra == "schema"
41
+ Provides-Extra: geo
42
+ Requires-Dist: pyproj>=3.3; extra == "geo"
43
+ Provides-Extra: studio
44
+ Requires-Dist: PySide6>=6.5; extra == "studio"
45
+ Requires-Dist: matplotlib>=3.5; extra == "studio"
46
+ Provides-Extra: all
47
+ Requires-Dist: pcsf[algorithms,emc,geo,mare2dem,schema,studio]; extra == "all"
48
+ Provides-Extra: dev
49
+ Requires-Dist: pcsf[algorithms,emc,geo,mare2dem,schema]; extra == "dev"
50
+ Requires-Dist: pytest>=7; extra == "dev"
51
+ Requires-Dist: pytest-cov>=4; extra == "dev"
52
+ Requires-Dist: ruff>=0.4; extra == "dev"
53
+ Requires-Dist: mypy>=1.5; extra == "dev"
54
+ Requires-Dist: pre-commit>=3; extra == "dev"
55
+ Provides-Extra: docs
56
+ Requires-Dist: sphinx>=7; extra == "docs"
57
+ Requires-Dist: pydata-sphinx-theme>=0.15; extra == "docs"
58
+ Requires-Dist: numpydoc>=1.6; extra == "docs"
59
+ Requires-Dist: myst-parser>=2; extra == "docs"
60
+ Requires-Dist: sphinx-copybutton>=0.5; extra == "docs"
61
+ Requires-Dist: sphinx-design>=0.5; extra == "docs"
62
+ Requires-Dist: matplotlib>=3.5; extra == "docs"
63
+ Dynamic: license-file
64
+
65
+ <div align="center">
66
+ <picture>
67
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/earthai-tech/pcsf/da378cfae1cd31c3e593839fa54a87916967aad6/docs/_static/logo/pcsf-logo-dark.svg">
68
+ <img src="https://raw.githubusercontent.com/earthai-tech/pcsf/da378cfae1cd31c3e593839fa54a87916967aad6/docs/_static/logo/pcsf-logo.svg" alt="PCSF: Portable Common Subsurface Format" width="560"/>
69
+ </picture>
70
+ <br/>
71
+ <em>One exchange format for electromagnetic inversion models &mdash; read, check, compare and convert, whatever code produced them.</em>
72
+ <br/><br/>
73
+ <a href="https://pypi.org/project/pcsf/"><img alt="PyPI" src="https://img.shields.io/pypi/v/pcsf?color=orange&label=PyPI"/></a>
74
+ <a href="https://github.com/earthai-tech/pcsf/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/earthai-tech/pcsf?label=release&color=blueviolet"/></a>
75
+ <a href="https://github.com/earthai-tech/pcsf/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/earthai-tech/pcsf/actions/workflows/ci.yml/badge.svg"/></a>
76
+ <a href="https://pcsf.readthedocs.io/en/latest/"><img alt="Documentation" src="https://readthedocs.org/projects/pcsf/badge/?version=latest"/></a>
77
+ <a href="https://codecov.io/github/earthai-tech/pcsf"><img alt="Coverage" src="https://codecov.io/github/earthai-tech/pcsf/graph/badge.svg?token=75F2FYN2MW"/></a>
78
+ <a href="https://opensource.org/licenses/BSD-3-Clause"><img alt="License: BSD-3-Clause" src="https://img.shields.io/badge/license-BSD--3--Clause-blue"/></a>
79
+ <br/>
80
+ <img alt="Python" src="https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue?logo=python&logoColor=white"/>
81
+ <img alt="Format version" src="https://img.shields.io/badge/PCSF%20format-0.1.0-2f5fd0"/>
82
+ <img alt="Encodings" src="https://img.shields.io/badge/encodings-HDF5%20%7C%20text-5b8af5"/>
83
+ <img alt="Platform" src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey"/>
84
+ <a href="https://github.com/astral-sh/ruff"><img alt="Code style: ruff" src="https://img.shields.io/badge/code%20style-ruff-D7FF64?logo=ruff&logoColor=black"/></a>
85
+ <br/>
86
+ <a href="https://pypi.org/project/pcsf/"><img alt="Downloads" src="https://img.shields.io/pypi/dm/pcsf?label=downloads&color=brightgreen"/></a>
87
+ <a href="https://github.com/earthai-tech/pcsf/commits/master"><img alt="Last commit" src="https://img.shields.io/github/last-commit/earthai-tech/pcsf"/></a>
88
+ <a href="https://github.com/earthai-tech/pcsf/issues"><img alt="Issues" src="https://img.shields.io/github/issues/earthai-tech/pcsf"/></a>
89
+ <a href="https://github.com/earthai-tech/pcsf/pulls"><img alt="PRs welcome" src="https://img.shields.io/badge/PRs-welcome-brightgreen"/></a>
90
+ <a href="https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/CODE_OF_CONDUCT.md"><img alt="Contributor Covenant" src="https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg"/></a>
91
+ <br/><br/>
92
+
93
+ **[Documentation](https://pcsf.readthedocs.io)** Β·
94
+ [Specification](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/spec/pcsf-0.1.md) Β·
95
+ [Quick start](#quick-start) Β·
96
+ [PCSF Studio](#pcsf-studio) Β·
97
+ [Changelog](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/CHANGELOG.md)
98
+
99
+ </div>
100
+
101
+ ---
102
+
103
+ ## 🧭 Why PCSF?
104
+
105
+ Every inversion code writes its own format, with its own logarithm
106
+ base, axis order, coordinate frame, depth datum and discretization.
107
+ A reader who does not know these conventions misreads the model, and
108
+ the errors are as large as the geological contrasts the model is meant
109
+ to show. **PCSF states the conventions in the file**, so a model can
110
+ be read, checked and compared without knowing the code that made it.
111
+
112
+ | | What the file holds |
113
+ |---|---|
114
+ | 🎚️ **Canonical resistivity** | linear Ω·m, with the solver's own values and their encoding kept unchanged (`log10`, `ln`, `linear`, `log10_conductivity`, `conductivity`, or a plugin encoding) |
115
+ | 🧱 **Native geometry** | 2D section (`grid2d`), 3D grid (`grid3d`), triangular mesh (`mesh_unstructured`) or set of profiles (`multiline`) β€” never resampled |
116
+ | πŸ—ΊοΈ **Spatial reference** | station table, topography, coordinate reference system |
117
+ | πŸ“‹ **Inversion record** | data, errors, solver, regularization, misfit, convergence and depth of investigation, with a completeness check |
118
+ | βœ… **Conformance** | rules C1–C10, checked by every reader and by `pcsf validate` |
119
+
120
+ One model, two encodings that convert into each other **bit for bit**:
121
+ **PCSF** (HDF5, binary, compressed) and **PCSM** (plain text, comments
122
+ allowed, optionally `.pcsm.gz`).
123
+
124
+ ## πŸš€ Installation
125
+
126
+ ```bash
127
+ pip install pcsf # core: NumPy + h5py only
128
+ pip install "pcsf[all]" # + algorithms, EMC, MARE2DEM, CRS, schemas, Studio
129
+ ```
130
+
131
+ Requires **Python 3.9+**.
132
+
133
+ <details>
134
+ <summary><b>Optional extras &amp; source install</b></summary>
135
+
136
+ | Extra | Installs | For |
137
+ |---|---|---|
138
+ | `algorithms` | SciPy, Matplotlib | sampling, registration, comparison of models |
139
+ | `emc` | netCDF4 | EarthScope / IRIS Earth Model Collaboration archives |
140
+ | `mare2dem` | triangle | triangulation of MARE2DEM meshes |
141
+ | `geo` | pyproj | coordinate reference systems |
142
+ | `schema` | jsonschema | validation of the metadata against the JSON Schemas |
143
+ | `studio` | PySide6, Matplotlib | PCSF Studio, the graphical application |
144
+ | `all` | all of the above | |
145
+
146
+ From the repository:
147
+
148
+ ```bash
149
+ git clone https://github.com/earthai-tech/pcsf.git
150
+ cd pcsf
151
+ pip install -e ".[all,dev]"
152
+ pytest
153
+ ```
154
+
155
+ </details>
156
+
157
+ <a id="quick-start"></a>
158
+
159
+ ## ⚑ Quick start
160
+
161
+ ```python
162
+ import pcsf
163
+
164
+ model = pcsf.read("model.pcsf") # .pcsf, .pcsm or .pcsm.gz, detected from content
165
+ print(pcsf.info(model))
166
+ pcsf.validate(model).raise_if_failed() # conformance rules C1-C10
167
+ pcsf.write(model, "model.pcsm.gz") # lossless text copy
168
+ ```
169
+
170
+ <details>
171
+ <summary><b>Convert solver output (Occam2D, ModEM, MARE2DEM, EMC)</b></summary>
172
+
173
+ No inversion package is needed: the native files are parsed by pcsf
174
+ itself.
175
+
176
+ ```python
177
+ from pcsf.adapters import (
178
+ emc_to_pcsf, mare2dem_to_pcsf, modem_to_pcsf, occam2d_to_pcsf,
179
+ )
180
+
181
+ m = occam2d_to_pcsf("occam_run/") # run folder
182
+ m = modem_to_pcsf("run/m_NLCG_100.rho", data="run/d.dat")
183
+ m = mare2dem_to_pcsf("demo.6.resistivity", log="demo.logfile")
184
+ m = emc_to_pcsf("WUS-MT-2021.nc")
185
+ pcsf.write(m, "model.pcsf")
186
+ ```
187
+
188
+ | Solver | Adapter | Geometry kind |
189
+ |---|---|---|
190
+ | Occam2D | `occam2d_to_pcsf` | `grid2d` |
191
+ | ModEM | `modem_to_pcsf` | `grid3d` |
192
+ | MARE2DEM | `mare2dem_to_pcsf` | `mesh_unstructured` |
193
+ | EMC netCDF | `emc_to_pcsf` (and back: `pcsf_to_emc`) | `grid3d` (geographic) |
194
+
195
+ Other codes plug in through the `pcsf.adapters` entry point (see
196
+ [CONTRIBUTING.md](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/CONTRIBUTING.md)).
197
+
198
+ </details>
199
+
200
+ <details>
201
+ <summary><b>Sample and compare two models</b></summary>
202
+
203
+ ```python
204
+ from pcsf.algorithms import compare_log10, sample_log10
205
+
206
+ # log10(rho) of each model at the same points of its frame
207
+ a = sample_log10(model_a, points)
208
+ b = sample_log10(model_b, points)
209
+ result = compare_log10(a, b) # difference, RMS, bias, correlation
210
+ print(result)
211
+ ```
212
+
213
+ The sampling is multilinear on grids and exact on meshes; the weights,
214
+ the frame registration and the propagation of uncertainty are exposed
215
+ in `pcsf.algorithms`.
216
+
217
+ </details>
218
+
219
+ <details>
220
+ <summary><b>Command line</b></summary>
221
+
222
+ ```bash
223
+ pcsf info model.pcsf # summary of a file
224
+ pcsf validate *.pcsf # conformance rules C1-C10
225
+ pcsf convert model.pcsf model.pcsm # PCSF <-> PCSM <-> PCSM gzip
226
+ pcsf compare a.pcsf b.pcsf # difference of two models
227
+ pcsf studio model.pcsf # open PCSF Studio
228
+ pcsf version
229
+ ```
230
+
231
+ </details>
232
+
233
+ <a id="pcsf-studio"></a>
234
+
235
+ ## πŸ–₯️ PCSF Studio
236
+
237
+ A viewer, inspector and converter for PCSF models and solver runs.
238
+
239
+ <p align="center">
240
+ <img src="https://raw.githubusercontent.com/earthai-tech/pcsf/da378cfae1cd31c3e593839fa54a87916967aad6/docs/_static/studio-light.png" alt="PCSF Studio showing a ModEM model" width="780"/>
241
+ </p>
242
+
243
+ - πŸ”Ž **Open** `.pcsf` / `.pcsm` files, Occam2D, ModEM and MARE2DEM runs,
244
+ and EMC netCDF files β€” or drop them on the window.
245
+ - πŸ—ΊοΈ **Draw** sections, depth slices, meshes and lines, with topography
246
+ and stations.
247
+ - πŸ“‹ **Inspect** stations, metadata, the inversion record and the
248
+ conformance rules; the statistics panel collapses to the right to
249
+ give the plot more room.
250
+ - πŸ” **Convert** any number of solver runs to `.pcsf`, `.pcsm` or
251
+ `.pcsm.gz` on the Convert page.
252
+ - πŸ“€ **Export** figures (PNG, SVG, PDF) and CSV tables; light and dark
253
+ themes.
254
+
255
+ **Download** β€” installers that need no Python:
256
+
257
+ | Platform | Download | Install |
258
+ |---|---|---|
259
+ | Windows 10/11 (64-bit) | [**pcsf-studio-setup.exe**](https://github.com/earthai-tech/pcsf/releases/latest/download/pcsf-studio-setup.exe) | Run the installer. SmartScreen warns on unsigned builds: **More info β†’ Run anyway**. |
260
+ | Linux (x86-64) | [**pcsf-studio-x86_64.AppImage**](https://github.com/earthai-tech/pcsf/releases/latest/download/pcsf-studio-x86_64.AppImage) | `chmod +x pcsf-studio-x86_64.AppImage && ./pcsf-studio-x86_64.AppImage` |
261
+ | Linux (x86-64) | [**pcsf-studio-linux.sh**](https://github.com/earthai-tech/pcsf/releases/latest/download/pcsf-studio-linux.sh) | `sh pcsf-studio-linux.sh` (installs in `~/.local`, no root) |
262
+
263
+ Checksums (`SHA256SUMS`) and older versions are on the
264
+ [releases page](https://github.com/earthai-tech/pcsf/releases). With
265
+ Python:
266
+
267
+ ```bash
268
+ pip install "pcsf[studio]"
269
+ pcsf-studio model.pcsf # or: pcsf studio, python -m pcsf.studio
270
+ ```
271
+
272
+ <details>
273
+ <summary><b>Building the installers, and embedding</b></summary>
274
+
275
+ The installers are built by [installers/build.py](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/installers/README.md).
276
+ `pcsf-studio --self-test` checks an installation without a window.
277
+
278
+ The widget that shows one model, `pcsf.studio.ModelView`, can be
279
+ embedded in other Qt applications; pyCSAMT's desktop app uses it.
280
+
281
+ </details>
282
+
283
+ <details>
284
+ <summary><b>Screenshots: dark theme and Convert page</b></summary>
285
+
286
+ <p align="center">
287
+ <img src="https://raw.githubusercontent.com/earthai-tech/pcsf/da378cfae1cd31c3e593839fa54a87916967aad6/docs/_static/studio-dark.png" alt="PCSF Studio, dark theme" width="780"/>
288
+ <br/><br/>
289
+ <img src="https://raw.githubusercontent.com/earthai-tech/pcsf/da378cfae1cd31c3e593839fa54a87916967aad6/docs/_static/studio-convert.png" alt="The Convert page of PCSF Studio" width="780"/>
290
+ </p>
291
+
292
+ </details>
293
+
294
+ ## 🧩 Project
295
+
296
+ <details>
297
+ <summary><b>Repository layout</b></summary>
298
+
299
+ | Path | Content |
300
+ |---|---|
301
+ | `spec/` | versioned specification and PCSM grammar (EBNF); JSON Schemas in `src/pcsf/schemas/` |
302
+ | `conformance/` | reference files and expected values for independent implementations |
303
+ | `src/pcsf/api/` | **stable public API**: facade, base classes, types, registry |
304
+ | `src/pcsf/core/` | data model, encodings, versioning, HDF5 and text I/O, records, conformance |
305
+ | `src/pcsf/algorithms/` | sampling, point location, comparison, uncertainty, projection, registration |
306
+ | `src/pcsf/native/`, `adapters/` | solver parsers and converters (Occam2D, ModEM, MARE2DEM, EMC) |
307
+ | `src/pcsf/plugins/` | entry-point discovery (`pcsf.encodings`, `pcsf.adapters`, `pcsf.formats`) |
308
+ | `src/pcsf/cli/`, `studio/` | command-line tool, graphical application |
309
+ | `installers/` | Windows `.exe`, Linux `.AppImage` / `.sh` builds |
310
+ | `paper/` | reproduction of the paper |
311
+
312
+ Everything under `pcsf.api` (and re-exported by `pcsf`) follows
313
+ semantic versioning; other modules are internal.
314
+
315
+ </details>
316
+
317
+ <details>
318
+ <summary><b>Status and roadmap</b></summary>
319
+
320
+ Version 0.1.0, format version 0.1.0.
321
+
322
+ | Phase | Content | Status |
323
+ |---|---|---|
324
+ | 1 | core data model and algorithms | βœ… |
325
+ | 2 | solver parsers and adapters, conformance suite, JSON Schemas | βœ… |
326
+ | 3 | pyCSAMT uses pcsf as its format core | βœ… |
327
+ | 4 | PCSF Studio and its installers | βœ… |
328
+ | 5 | reproduction of the paper ([paper/](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/paper/README.md)) | βœ… |
329
+ | β€” | first release (0.1.0) on PyPI, with the Studio installers | βœ… |
330
+
331
+ See [CHANGELOG.md](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/CHANGELOG.md).
332
+
333
+ </details>
334
+
335
+ <details>
336
+ <summary><b>Contributing</b></summary>
337
+
338
+ Issues and pull requests are welcome; see
339
+ [CONTRIBUTING.md](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/CONTRIBUTING.md) and the
340
+ [code of conduct](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/CODE_OF_CONDUCT.md). New solvers, encodings and
341
+ companion formats can be added as plugins without changing pcsf.
342
+
343
+ </details>
344
+
345
+ ## πŸ“– Citing
346
+
347
+ If you use pcsf, please cite it as given in
348
+ [CITATION.cff](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/CITATION.cff) (GitHub's *Cite this repository* button
349
+ gives APA and BibTeX). The format and its algorithms are described in a
350
+ manuscript in preparation for *Geophysics*.
351
+
352
+ ## βš–οΈ Licence
353
+
354
+ BSD 3-Clause. See [LICENSE](https://github.com/earthai-tech/pcsf/blob/da378cfae1cd31c3e593839fa54a87916967aad6/LICENSE).