nomogram 0.3.0__tar.gz → 0.5.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.
- nomogram-0.5.0/PKG-INFO +199 -0
- nomogram-0.5.0/README.md +165 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/pyproject.toml +5 -1
- {nomogram-0.3.0 → nomogram-0.5.0}/pyproject.toml.orig +10 -1
- nomogram-0.5.0/src/nomogram/__init__.py +72 -0
- nomogram-0.5.0/src/nomogram/_logo.py +228 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/catalog.py +1525 -169
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/comparison.py +177 -8
- nomogram-0.5.0/src/nomogram/data/NOTICE.md +40 -0
- nomogram-0.5.0/src/nomogram/data/catalog/atmosphere.toml +1590 -0
- nomogram-0.5.0/src/nomogram/data/catalog/core.toml +336 -0
- nomogram-0.5.0/src/nomogram/data/catalog/moist-air.toml +2396 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/data/catalog/radio.toml +1 -21
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/data/catalog/sea-water.toml +16 -14
- nomogram-0.5.0/src/nomogram/data/catalog/verifications.json +205 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/data/catalog/water-vapour.toml +232 -6
- nomogram-0.5.0/src/nomogram/data/semantics.json +1695 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/dimensions.py +126 -26
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/display.py +89 -6
- nomogram-0.5.0/src/nomogram/expression.py +725 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/inversion.py +222 -56
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/model.py +561 -41
- nomogram-0.5.0/src/nomogram/plot.py +955 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/relations.py +735 -54
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/search.py +158 -37
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/semantics.py +29 -9
- nomogram-0.3.0/PKG-INFO +0 -139
- nomogram-0.3.0/README.md +0 -105
- nomogram-0.3.0/src/nomogram/__init__.py +0 -17
- nomogram-0.3.0/src/nomogram/data/NOTICE.md +0 -28
- nomogram-0.3.0/src/nomogram/data/catalog/core.toml +0 -184
- nomogram-0.3.0/src/nomogram/data/catalog/moist-air.toml +0 -323
- nomogram-0.3.0/src/nomogram/data/catalog/verifications.json +0 -133
- nomogram-0.3.0/src/nomogram/data/semantics.json +0 -816
- nomogram-0.3.0/src/nomogram/expression.py +0 -384
- nomogram-0.3.0/src/nomogram/plot.py +0 -237
- {nomogram-0.3.0 → nomogram-0.5.0}/LICENSE +0 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/data/catalog/humidity.toml +0 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/py.typed +0 -0
- {nomogram-0.3.0 → nomogram-0.5.0}/src/nomogram/units.py +0 -0
nomogram-0.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nomogram
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Repository of scientific formulas: notations, units, validity domains
|
|
5
|
+
Keywords: scientific computing,formulas,units,dimensional analysis,physics,thermodynamics,geoscience,atmospheric science,meteorology,hydrology,psychrometrics
|
|
6
|
+
Author: miki4ia
|
|
7
|
+
Author-email: miki4ia <miki4ia@gmail.com>
|
|
8
|
+
License-Expression: BSD-3-Clause AND CC-BY-4.0 AND CC0-1.0
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
License-File: src/nomogram/data/NOTICE.md
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Hydrology
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Dist: numpy>=2.0
|
|
24
|
+
Requires-Dist: pint>=0.24.4
|
|
25
|
+
Requires-Dist: sympy>=1.13
|
|
26
|
+
Requires-Dist: matplotlib>=3.10.7 ; extra == 'viz'
|
|
27
|
+
Requires-Python: >=3.12
|
|
28
|
+
Project-URL: Homepage, https://github.com/miki4iaml/nomogram
|
|
29
|
+
Project-URL: Repository, https://github.com/miki4iaml/nomogram
|
|
30
|
+
Project-URL: Issues, https://github.com/miki4iaml/nomogram/issues
|
|
31
|
+
Project-URL: Changelog, https://github.com/miki4iaml/nomogram/blob/main/CHANGELOG.md
|
|
32
|
+
Provides-Extra: viz
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<picture>
|
|
37
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/miki4iaml/nomogram/v0.5.0/docs/images/banner-dark.svg">
|
|
38
|
+
<img alt="nomogram" src="https://raw.githubusercontent.com/miki4iaml/nomogram/v0.5.0/docs/images/banner-light.svg" width="480">
|
|
39
|
+
</picture>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
**English** | [Français](https://github.com/miki4iaml/nomogram/blob/v0.5.0/README.fr.md)
|
|
43
|
+
|
|
44
|
+
[](https://github.com/miki4iaml/nomogram/actions/workflows/ci.yml)
|
|
45
|
+
[](https://github.com/miki4iaml/nomogram/actions/workflows/github-code-scanning/codeql)
|
|
46
|
+
[](https://codecov.io/gh/miki4iaml/nomogram)
|
|
47
|
+
[](https://github.com/miki4iaml/nomogram/blob/v0.5.0/pyproject.toml)
|
|
48
|
+
[](https://github.com/miki4iaml/nomogram/blob/v0.5.0/LICENSE)
|
|
49
|
+
[](https://doi.org/10.5281/zenodo.23373134)
|
|
50
|
+
[](https://github.com/astral-sh/uv)
|
|
51
|
+
[](https://github.com/astral-sh/ruff)
|
|
52
|
+
[](https://mypy-lang.org/)
|
|
53
|
+
[](https://www.conventionalcommits.org/en/v1.0.0/)
|
|
54
|
+
|
|
55
|
+
**Formulas as data, not as code.**
|
|
56
|
+
|
|
57
|
+
nomogram does not hard-code functions: it catalogs formulas, each one
|
|
58
|
+
|
|
59
|
+
- **meaningful**: QUDT quantity kinds and units, links to CF and
|
|
60
|
+
Wikidata, its source, its validity domain when stated;
|
|
61
|
+
- **checked**: dimensions and units on loading, equivalences proved
|
|
62
|
+
symbolically, values cross-checked against references;
|
|
63
|
+
- **ready to use**: compute, compose, invert, plot, and compare with its
|
|
64
|
+
alternatives.
|
|
65
|
+
|
|
66
|
+
Built for trust, not for speed: to show that a calculation is right, and
|
|
67
|
+
where it comes from.
|
|
68
|
+
|
|
69
|
+
Pure Python, built on SymPy, numpy and pint; it works on an offline
|
|
70
|
+
workstation (no online engine).
|
|
71
|
+
|
|
72
|
+
> Early stage project (alpha).
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
pip install nomogram # core
|
|
78
|
+
pip install "nomogram[viz]" # with plots (matplotlib)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Installation from source
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
git clone https://github.com/miki4iaml/nomogram.git
|
|
85
|
+
cd nomogram
|
|
86
|
+
uv sync
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Python 3.12 or later. Plots need the `viz` extra (matplotlib):
|
|
90
|
+
`uv sync --extra viz`.
|
|
91
|
+
|
|
92
|
+
## Example
|
|
93
|
+
|
|
94
|
+
Every saturation vapour pressure formulation of the catalog against the
|
|
95
|
+
IAPWS reference, from 0 to 60 °C and within 1 %; curves stop where a formulation leaves its
|
|
96
|
+
stated validity domain, and the figure takes the option set of nomogram's
|
|
97
|
+
documentation ([script](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/examples/saturation_vapour_pressure.py)):
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
import numpy as np
|
|
101
|
+
import nomogram as nomo
|
|
102
|
+
from nomogram.units import Q_
|
|
103
|
+
|
|
104
|
+
catalog = nomo.catalog.catalog()
|
|
105
|
+
formulations = catalog.formulations_of("SaturationVapourPressureOverWater")
|
|
106
|
+
reference = catalog.formulations["iapws_sr1_86"]
|
|
107
|
+
temperatures = Q_(np.linspace(-60, 110, 341), "degC")
|
|
108
|
+
|
|
109
|
+
table = nomo.comparison.compare(
|
|
110
|
+
formulations, reference, {"ThermodynamicTemperature": temperatures}
|
|
111
|
+
)
|
|
112
|
+
with nomo.display.display_options(nomo.display.DisplayOptions.DOCUMENTATION):
|
|
113
|
+
nomo.plot.plot_deviations(table, xlim=(0, 60), ylim=(-1.0, 1.0)) # extra viz
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+

|
|
117
|
+
|
|
118
|
+
## Usage
|
|
119
|
+
|
|
120
|
+
The table holds the values and the relative deviations, by formulation;
|
|
121
|
+
values outside a formulation's validity domain are NaN unless asked
|
|
122
|
+
otherwise (`outside="ignore"`). Formulations also chain, for instance
|
|
123
|
+
the absolute humidity from any saturation vapour pressure formulation:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
ha = nomo.comparison.compose(
|
|
127
|
+
catalog.formulations["mass_concentration_ideal_gas"], {"e_s": reference}
|
|
128
|
+
)
|
|
129
|
+
ha.evaluate(RH=Q_(100, "percent"), T=Q_(20, "degC")).to("g/m^3") # 17.29
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`compare` gives each value to the input of its quantity kind. A
|
|
133
|
+
formulation with several inputs of one kind, such as a scheme
|
|
134
|
+
interpolating between two levels (the target pressure p and the
|
|
135
|
+
pressures p_1 and p_2 of the levels), compares once all but one of them
|
|
136
|
+
are fixed, which `compare` asks for: `partial` fixes inputs as `functools.partial` fixes arguments,
|
|
137
|
+
here the two levels, and leaves a function of p alone, evaluated,
|
|
138
|
+
compared and plotted like any formulation
|
|
139
|
+
([Humidity between two levels](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/vertical.md#humidity-between-two-levels)).
|
|
140
|
+
It also fixes what is known in advance, such as the levels of a sounding,
|
|
141
|
+
and names the curve in legends:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
levels = {"p_1": Q_(850, "hPa"), "p_2": Q_(500, "hPa"),
|
|
145
|
+
"T_1": Q_(278, "K"), "T_2": Q_(252, "K")}
|
|
146
|
+
in_ln_p = nomo.comparison.partial(
|
|
147
|
+
catalog.formulations["log_pressure_interpolation_temperature"],
|
|
148
|
+
label="T linear in ln p", **levels,
|
|
149
|
+
)
|
|
150
|
+
in_ln_p.evaluate(p=Q_(700, "hPa")).to("K") # 268.49
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Formulations are found by words, wildcards and fields, whatever their
|
|
154
|
+
notation ([Finding formulations](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/search.md)):
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
catalog.search(variable="rho*") # ρ in every notation
|
|
158
|
+
catalog.search(kind="VapourPressure", source="buck*")
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Each formulation keeps its units, validity domain, temperature scale and
|
|
162
|
+
references. The vocabulary is mapped in [docs/rosetta.md](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/rosetta.md);
|
|
163
|
+
[How nomogram earns trust](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/approach.md) explains what is checked and
|
|
164
|
+
how, and [Displaying formulas](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/display.md) shows formulas in notebooks,
|
|
165
|
+
Markdown and plots. [Sea water](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/sea-water.md) shows the salinity
|
|
166
|
+
scales and the vapour pressure of sea water, and what its 2 % lowering
|
|
167
|
+
changes at the sea surface. [The logo](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/logo.md) is a working
|
|
168
|
+
nomogram.
|
|
169
|
+
|
|
170
|
+
## Contributing
|
|
171
|
+
|
|
172
|
+
References to integrate, information or corrections about catalog
|
|
173
|
+
entries, new formulas and code are all welcome: see the
|
|
174
|
+
[ways to contribute](https://github.com/miki4iaml/nomogram/blob/v0.5.0/.github/CONTRIBUTING.md#ways-to-contribute) and
|
|
175
|
+
the [catalog guide](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/catalog.md).
|
|
176
|
+
|
|
177
|
+
## Data sources
|
|
178
|
+
|
|
179
|
+
nomogram's units come from QUDT, and so do its quantity kinds, except
|
|
180
|
+
those QUDT lacks, which nomogram defines as specializations of QUDT
|
|
181
|
+
kinds. nomogram links some kinds to CF standard names, which come, with
|
|
182
|
+
their canonical units, from the CF standard name table. The package
|
|
183
|
+
bundles a subset of each source:
|
|
184
|
+
|
|
185
|
+
- QUDT — Quantities, Units, Dimensions and Types, by QUDT.org
|
|
186
|
+
(<https://qudt.org>), release 3.5.2, licensed under
|
|
187
|
+
[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/);
|
|
188
|
+
- the [CF standard name table](https://cfconventions.org/Data/cf-standard-names/95/build/cf-standard-name-table.html),
|
|
189
|
+
version 95, [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/);
|
|
190
|
+
- the UCUM codes of the units, as QUDT gives them: © Regenstrief
|
|
191
|
+
Institute, Inc., [UCUM License](https://ucum.org/license).
|
|
192
|
+
|
|
193
|
+
What nomogram selects, changes and adds is listed in
|
|
194
|
+
[NOTICE.md](https://github.com/miki4iaml/nomogram/blob/v0.5.0/src/nomogram/data/NOTICE.md).
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
Code: [BSD-3-Clause](https://github.com/miki4iaml/nomogram/blob/v0.5.0/LICENSE). Bundled data: see
|
|
199
|
+
[Data sources](#data-sources).
|
nomogram-0.5.0/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/miki4iaml/nomogram/v0.5.0/docs/images/banner-dark.svg">
|
|
4
|
+
<img alt="nomogram" src="https://raw.githubusercontent.com/miki4iaml/nomogram/v0.5.0/docs/images/banner-light.svg" width="480">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
**English** | [Français](https://github.com/miki4iaml/nomogram/blob/v0.5.0/README.fr.md)
|
|
9
|
+
|
|
10
|
+
[](https://github.com/miki4iaml/nomogram/actions/workflows/ci.yml)
|
|
11
|
+
[](https://github.com/miki4iaml/nomogram/actions/workflows/github-code-scanning/codeql)
|
|
12
|
+
[](https://codecov.io/gh/miki4iaml/nomogram)
|
|
13
|
+
[](https://github.com/miki4iaml/nomogram/blob/v0.5.0/pyproject.toml)
|
|
14
|
+
[](https://github.com/miki4iaml/nomogram/blob/v0.5.0/LICENSE)
|
|
15
|
+
[](https://doi.org/10.5281/zenodo.23373134)
|
|
16
|
+
[](https://github.com/astral-sh/uv)
|
|
17
|
+
[](https://github.com/astral-sh/ruff)
|
|
18
|
+
[](https://mypy-lang.org/)
|
|
19
|
+
[](https://www.conventionalcommits.org/en/v1.0.0/)
|
|
20
|
+
|
|
21
|
+
**Formulas as data, not as code.**
|
|
22
|
+
|
|
23
|
+
nomogram does not hard-code functions: it catalogs formulas, each one
|
|
24
|
+
|
|
25
|
+
- **meaningful**: QUDT quantity kinds and units, links to CF and
|
|
26
|
+
Wikidata, its source, its validity domain when stated;
|
|
27
|
+
- **checked**: dimensions and units on loading, equivalences proved
|
|
28
|
+
symbolically, values cross-checked against references;
|
|
29
|
+
- **ready to use**: compute, compose, invert, plot, and compare with its
|
|
30
|
+
alternatives.
|
|
31
|
+
|
|
32
|
+
Built for trust, not for speed: to show that a calculation is right, and
|
|
33
|
+
where it comes from.
|
|
34
|
+
|
|
35
|
+
Pure Python, built on SymPy, numpy and pint; it works on an offline
|
|
36
|
+
workstation (no online engine).
|
|
37
|
+
|
|
38
|
+
> Early stage project (alpha).
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
pip install nomogram # core
|
|
44
|
+
pip install "nomogram[viz]" # with plots (matplotlib)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Installation from source
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
git clone https://github.com/miki4iaml/nomogram.git
|
|
51
|
+
cd nomogram
|
|
52
|
+
uv sync
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Python 3.12 or later. Plots need the `viz` extra (matplotlib):
|
|
56
|
+
`uv sync --extra viz`.
|
|
57
|
+
|
|
58
|
+
## Example
|
|
59
|
+
|
|
60
|
+
Every saturation vapour pressure formulation of the catalog against the
|
|
61
|
+
IAPWS reference, from 0 to 60 °C and within 1 %; curves stop where a formulation leaves its
|
|
62
|
+
stated validity domain, and the figure takes the option set of nomogram's
|
|
63
|
+
documentation ([script](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/examples/saturation_vapour_pressure.py)):
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
import numpy as np
|
|
67
|
+
import nomogram as nomo
|
|
68
|
+
from nomogram.units import Q_
|
|
69
|
+
|
|
70
|
+
catalog = nomo.catalog.catalog()
|
|
71
|
+
formulations = catalog.formulations_of("SaturationVapourPressureOverWater")
|
|
72
|
+
reference = catalog.formulations["iapws_sr1_86"]
|
|
73
|
+
temperatures = Q_(np.linspace(-60, 110, 341), "degC")
|
|
74
|
+
|
|
75
|
+
table = nomo.comparison.compare(
|
|
76
|
+
formulations, reference, {"ThermodynamicTemperature": temperatures}
|
|
77
|
+
)
|
|
78
|
+
with nomo.display.display_options(nomo.display.DisplayOptions.DOCUMENTATION):
|
|
79
|
+
nomo.plot.plot_deviations(table, xlim=(0, 60), ylim=(-1.0, 1.0)) # extra viz
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+

|
|
83
|
+
|
|
84
|
+
## Usage
|
|
85
|
+
|
|
86
|
+
The table holds the values and the relative deviations, by formulation;
|
|
87
|
+
values outside a formulation's validity domain are NaN unless asked
|
|
88
|
+
otherwise (`outside="ignore"`). Formulations also chain, for instance
|
|
89
|
+
the absolute humidity from any saturation vapour pressure formulation:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
ha = nomo.comparison.compose(
|
|
93
|
+
catalog.formulations["mass_concentration_ideal_gas"], {"e_s": reference}
|
|
94
|
+
)
|
|
95
|
+
ha.evaluate(RH=Q_(100, "percent"), T=Q_(20, "degC")).to("g/m^3") # 17.29
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`compare` gives each value to the input of its quantity kind. A
|
|
99
|
+
formulation with several inputs of one kind, such as a scheme
|
|
100
|
+
interpolating between two levels (the target pressure p and the
|
|
101
|
+
pressures p_1 and p_2 of the levels), compares once all but one of them
|
|
102
|
+
are fixed, which `compare` asks for: `partial` fixes inputs as `functools.partial` fixes arguments,
|
|
103
|
+
here the two levels, and leaves a function of p alone, evaluated,
|
|
104
|
+
compared and plotted like any formulation
|
|
105
|
+
([Humidity between two levels](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/vertical.md#humidity-between-two-levels)).
|
|
106
|
+
It also fixes what is known in advance, such as the levels of a sounding,
|
|
107
|
+
and names the curve in legends:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
levels = {"p_1": Q_(850, "hPa"), "p_2": Q_(500, "hPa"),
|
|
111
|
+
"T_1": Q_(278, "K"), "T_2": Q_(252, "K")}
|
|
112
|
+
in_ln_p = nomo.comparison.partial(
|
|
113
|
+
catalog.formulations["log_pressure_interpolation_temperature"],
|
|
114
|
+
label="T linear in ln p", **levels,
|
|
115
|
+
)
|
|
116
|
+
in_ln_p.evaluate(p=Q_(700, "hPa")).to("K") # 268.49
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Formulations are found by words, wildcards and fields, whatever their
|
|
120
|
+
notation ([Finding formulations](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/search.md)):
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
catalog.search(variable="rho*") # ρ in every notation
|
|
124
|
+
catalog.search(kind="VapourPressure", source="buck*")
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Each formulation keeps its units, validity domain, temperature scale and
|
|
128
|
+
references. The vocabulary is mapped in [docs/rosetta.md](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/rosetta.md);
|
|
129
|
+
[How nomogram earns trust](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/approach.md) explains what is checked and
|
|
130
|
+
how, and [Displaying formulas](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/display.md) shows formulas in notebooks,
|
|
131
|
+
Markdown and plots. [Sea water](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/sea-water.md) shows the salinity
|
|
132
|
+
scales and the vapour pressure of sea water, and what its 2 % lowering
|
|
133
|
+
changes at the sea surface. [The logo](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/logo.md) is a working
|
|
134
|
+
nomogram.
|
|
135
|
+
|
|
136
|
+
## Contributing
|
|
137
|
+
|
|
138
|
+
References to integrate, information or corrections about catalog
|
|
139
|
+
entries, new formulas and code are all welcome: see the
|
|
140
|
+
[ways to contribute](https://github.com/miki4iaml/nomogram/blob/v0.5.0/.github/CONTRIBUTING.md#ways-to-contribute) and
|
|
141
|
+
the [catalog guide](https://github.com/miki4iaml/nomogram/blob/v0.5.0/docs/catalog.md).
|
|
142
|
+
|
|
143
|
+
## Data sources
|
|
144
|
+
|
|
145
|
+
nomogram's units come from QUDT, and so do its quantity kinds, except
|
|
146
|
+
those QUDT lacks, which nomogram defines as specializations of QUDT
|
|
147
|
+
kinds. nomogram links some kinds to CF standard names, which come, with
|
|
148
|
+
their canonical units, from the CF standard name table. The package
|
|
149
|
+
bundles a subset of each source:
|
|
150
|
+
|
|
151
|
+
- QUDT — Quantities, Units, Dimensions and Types, by QUDT.org
|
|
152
|
+
(<https://qudt.org>), release 3.5.2, licensed under
|
|
153
|
+
[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/);
|
|
154
|
+
- the [CF standard name table](https://cfconventions.org/Data/cf-standard-names/95/build/cf-standard-name-table.html),
|
|
155
|
+
version 95, [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/);
|
|
156
|
+
- the UCUM codes of the units, as QUDT gives them: © Regenstrief
|
|
157
|
+
Institute, Inc., [UCUM License](https://ucum.org/license).
|
|
158
|
+
|
|
159
|
+
What nomogram selects, changes and adds is listed in
|
|
160
|
+
[NOTICE.md](https://github.com/miki4iaml/nomogram/blob/v0.5.0/src/nomogram/data/NOTICE.md).
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
Code: [BSD-3-Clause](https://github.com/miki4iaml/nomogram/blob/v0.5.0/LICENSE). Bundled data: see
|
|
165
|
+
[Data sources](#data-sources).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nomogram"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.0"
|
|
4
4
|
description = "Repository of scientific formulas: notations, units, validity domains"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -120,6 +120,9 @@ fail_under = 80
|
|
|
120
120
|
show_missing = true
|
|
121
121
|
exclude_also = ['if __name__ == "__main__":']
|
|
122
122
|
|
|
123
|
+
[tool.ruff.format]
|
|
124
|
+
exclude = ["*.md"]
|
|
125
|
+
|
|
123
126
|
[tool.ruff.lint]
|
|
124
127
|
extend-select = [
|
|
125
128
|
"ARG",
|
|
@@ -138,6 +141,7 @@ extend-select = [
|
|
|
138
141
|
|
|
139
142
|
[tool.codespell]
|
|
140
143
|
skip = "*.fr.md,uv.lock"
|
|
144
|
+
ignore-words-list = "flate,alph,mesures"
|
|
141
145
|
|
|
142
146
|
[tool.repo-review.ignore]
|
|
143
147
|
PC110 = "ruff format runs as a local hook through uv run --frozen (single version source: uv.lock)"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nomogram"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.0"
|
|
4
4
|
description = "Repository of scientific formulas: notations, units, validity domains"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -102,6 +102,12 @@ fail_under = 80
|
|
|
102
102
|
show_missing = true
|
|
103
103
|
exclude_also = ['if __name__ == "__main__":']
|
|
104
104
|
|
|
105
|
+
[tool.ruff.format]
|
|
106
|
+
# ruff also formats the code blocks of Markdown files when run without
|
|
107
|
+
# arguments; the documents keep their own layout (aligned comments), and
|
|
108
|
+
# tests/test_examples.py reads the values their code comments state.
|
|
109
|
+
exclude = ["*.md"]
|
|
110
|
+
|
|
105
111
|
[tool.ruff.lint]
|
|
106
112
|
# On top of ruff's default selection, which Dependabot bumps surface in CI.
|
|
107
113
|
extend-select = ["ARG", "B", "C4", "PIE", "PT", "PTH", "RET", "T20"]
|
|
@@ -114,6 +120,9 @@ extend-select = ["ARG", "B", "C4", "PIE", "PT", "PTH", "RET", "T20"]
|
|
|
114
120
|
|
|
115
121
|
[tool.codespell]
|
|
116
122
|
skip = "*.fr.md,uv.lock"
|
|
123
|
+
# Format terms: the Flate filter of PDF, the ALPH chunk of WebP; the
|
|
124
|
+
# French name of the BIPM (Bureau International des Poids et Mesures).
|
|
125
|
+
ignore-words-list = "flate,alph,mesures"
|
|
117
126
|
|
|
118
127
|
[tool.repo-review.ignore]
|
|
119
128
|
PC110 = "ruff format runs as a local hook through uv run --frozen (single version source: uv.lock)"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Miki
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
3
|
+
|
|
4
|
+
"""nomogram: a repository of scientific formulas.
|
|
5
|
+
|
|
6
|
+
Submodules are imported on demand, so that ``import nomogram`` stays
|
|
7
|
+
light: :mod:`nomogram.units` (pint), :mod:`nomogram.expression`
|
|
8
|
+
(SymPy), :mod:`nomogram.semantics` (bundled QUDT and CF subsets),
|
|
9
|
+
:mod:`nomogram.model` and :mod:`nomogram.catalog` (formulations),
|
|
10
|
+
:mod:`nomogram.dimensions`, :mod:`nomogram.comparison`,
|
|
11
|
+
:mod:`nomogram.inversion`, :mod:`nomogram.relations`,
|
|
12
|
+
:mod:`nomogram.search`, :mod:`nomogram.display` and :mod:`nomogram.plot`.
|
|
13
|
+
|
|
14
|
+
Each is also an attribute of the package, imported the first time it is
|
|
15
|
+
used (PEP 562)::
|
|
16
|
+
|
|
17
|
+
import nomogram as nomo
|
|
18
|
+
|
|
19
|
+
formulations = nomo.catalog.catalog().formulations_of("VapourPressure")
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from importlib import import_module
|
|
23
|
+
from importlib.metadata import version
|
|
24
|
+
from typing import TYPE_CHECKING
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from nomogram import catalog as catalog
|
|
28
|
+
from nomogram import comparison as comparison
|
|
29
|
+
from nomogram import dimensions as dimensions
|
|
30
|
+
from nomogram import display as display
|
|
31
|
+
from nomogram import expression as expression
|
|
32
|
+
from nomogram import inversion as inversion
|
|
33
|
+
from nomogram import model as model
|
|
34
|
+
from nomogram import plot as plot
|
|
35
|
+
from nomogram import relations as relations
|
|
36
|
+
from nomogram import search as search
|
|
37
|
+
from nomogram import semantics as semantics
|
|
38
|
+
from nomogram import units as units
|
|
39
|
+
|
|
40
|
+
__all__ = [
|
|
41
|
+
"__version__",
|
|
42
|
+
"catalog",
|
|
43
|
+
"comparison",
|
|
44
|
+
"dimensions",
|
|
45
|
+
"display",
|
|
46
|
+
"expression",
|
|
47
|
+
"inversion",
|
|
48
|
+
"model",
|
|
49
|
+
"plot",
|
|
50
|
+
"relations",
|
|
51
|
+
"search",
|
|
52
|
+
"semantics",
|
|
53
|
+
"units",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
#: Submodules reachable as attributes of the package.
|
|
57
|
+
_SUBMODULES = frozenset(__all__) - {"__version__"}
|
|
58
|
+
|
|
59
|
+
__version__ = version("nomogram")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def __getattr__(name: str) -> object:
|
|
63
|
+
"""Import a submodule the first time it is used as an attribute."""
|
|
64
|
+
if name in _SUBMODULES:
|
|
65
|
+
return import_module(f"{__name__}.{name}")
|
|
66
|
+
msg = f"module {__name__!r} has no attribute {name!r}"
|
|
67
|
+
raise AttributeError(msg)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def __dir__() -> list[str]:
|
|
71
|
+
"""The names of the package, submodules included before their import."""
|
|
72
|
+
return sorted({*globals(), *_SUBMODULES})
|