earthsciencekit 0.2.0__py3-none-any.whl
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.
- earthsciencekit/__init__.py +6 -0
- earthsciencekit/_validation.py +62 -0
- earthsciencekit/atmosphere/__init__.py +57 -0
- earthsciencekit/atmosphere/core/__init__.py +5 -0
- earthsciencekit/atmosphere/core/base.py +10 -0
- earthsciencekit/atmosphere/systems/__init__.py +1 -0
- earthsciencekit/atmosphere/systems/dynamics.py +208 -0
- earthsciencekit/atmosphere/systems/hydrostatics.py +214 -0
- earthsciencekit/atmosphere/systems/moisture.py +162 -0
- earthsciencekit/atmosphere/systems/thermodynamics.py +222 -0
- earthsciencekit/atmosphere/tests/__init__.py +0 -0
- earthsciencekit/atmosphere/tests/test_models.py +741 -0
- earthsciencekit/atmosphere/tests/test_physics.py +81 -0
- earthsciencekit/atmosphere/visualizers/__init__.py +9 -0
- earthsciencekit/climate/__init__.py +63 -0
- earthsciencekit/climate/core/__init__.py +5 -0
- earthsciencekit/climate/core/base.py +10 -0
- earthsciencekit/climate/systems/__init__.py +1 -0
- earthsciencekit/climate/systems/carbon.py +76 -0
- earthsciencekit/climate/systems/forcing.py +124 -0
- earthsciencekit/climate/systems/radiation.py +214 -0
- earthsciencekit/climate/systems/response.py +402 -0
- earthsciencekit/climate/systems/sea_level.py +77 -0
- earthsciencekit/climate/tests/__init__.py +0 -0
- earthsciencekit/climate/tests/test_models.py +1015 -0
- earthsciencekit/climate/tests/test_physics.py +16 -0
- earthsciencekit/climate/visualizers/__init__.py +9 -0
- earthsciencekit/constants/__init__.py +23 -0
- earthsciencekit/geophysics/__init__.py +77 -0
- earthsciencekit/geophysics/core/__init__.py +5 -0
- earthsciencekit/geophysics/core/base.py +10 -0
- earthsciencekit/geophysics/systems/__init__.py +1 -0
- earthsciencekit/geophysics/systems/deformation.py +161 -0
- earthsciencekit/geophysics/systems/dynamo.py +159 -0
- earthsciencekit/geophysics/systems/figure.py +292 -0
- earthsciencekit/geophysics/systems/gravity.py +235 -0
- earthsciencekit/geophysics/systems/magnetism.py +354 -0
- earthsciencekit/geophysics/tests/__init__.py +0 -0
- earthsciencekit/geophysics/tests/test_models.py +898 -0
- earthsciencekit/geophysics/tests/test_physics.py +171 -0
- earthsciencekit/geophysics/visualizers/__init__.py +9 -0
- earthsciencekit/integrators/__init__.py +62 -0
- earthsciencekit/oceanography/__init__.py +61 -0
- earthsciencekit/oceanography/core/__init__.py +5 -0
- earthsciencekit/oceanography/core/base.py +10 -0
- earthsciencekit/oceanography/systems/__init__.py +1 -0
- earthsciencekit/oceanography/systems/circulation.py +388 -0
- earthsciencekit/oceanography/systems/hydrography.py +212 -0
- earthsciencekit/oceanography/systems/inertial.py +86 -0
- earthsciencekit/oceanography/systems/waves.py +281 -0
- earthsciencekit/oceanography/tests/__init__.py +0 -0
- earthsciencekit/oceanography/tests/test_models.py +916 -0
- earthsciencekit/oceanography/tests/test_physics.py +102 -0
- earthsciencekit/oceanography/visualizers/__init__.py +9 -0
- earthsciencekit/plate_tectonics/__init__.py +59 -0
- earthsciencekit/plate_tectonics/core/__init__.py +5 -0
- earthsciencekit/plate_tectonics/core/base.py +10 -0
- earthsciencekit/plate_tectonics/systems/__init__.py +1 -0
- earthsciencekit/plate_tectonics/systems/boundaries.py +201 -0
- earthsciencekit/plate_tectonics/systems/cooling.py +238 -0
- earthsciencekit/plate_tectonics/systems/isostasy.py +157 -0
- earthsciencekit/plate_tectonics/systems/kinematics.py +290 -0
- earthsciencekit/plate_tectonics/tests/__init__.py +0 -0
- earthsciencekit/plate_tectonics/tests/test_models.py +920 -0
- earthsciencekit/plate_tectonics/tests/test_physics.py +94 -0
- earthsciencekit/plate_tectonics/visualizers/__init__.py +9 -0
- earthsciencekit/py.typed +0 -0
- earthsciencekit/results.py +73 -0
- earthsciencekit/seismology/__init__.py +59 -0
- earthsciencekit/seismology/core/__init__.py +5 -0
- earthsciencekit/seismology/core/base.py +10 -0
- earthsciencekit/seismology/systems/__init__.py +1 -0
- earthsciencekit/seismology/systems/interfaces.py +102 -0
- earthsciencekit/seismology/systems/rays.py +221 -0
- earthsciencekit/seismology/systems/sources.py +249 -0
- earthsciencekit/seismology/systems/waves.py +268 -0
- earthsciencekit/seismology/tests/__init__.py +0 -0
- earthsciencekit/seismology/tests/test_models.py +852 -0
- earthsciencekit/seismology/tests/test_physics.py +100 -0
- earthsciencekit/seismology/visualizers/__init__.py +9 -0
- earthsciencekit/tests/__init__.py +0 -0
- earthsciencekit/tests/test_core.py +181 -0
- earthsciencekit/tests/test_relations.py +36 -0
- earthsciencekit/units/__init__.py +66 -0
- earthsciencekit/visualizers/__init__.py +45 -0
- earthsciencekit/volcanology/__init__.py +61 -0
- earthsciencekit/volcanology/core/__init__.py +5 -0
- earthsciencekit/volcanology/core/base.py +10 -0
- earthsciencekit/volcanology/systems/__init__.py +1 -0
- earthsciencekit/volcanology/systems/eruptions.py +161 -0
- earthsciencekit/volcanology/systems/geochemistry.py +226 -0
- earthsciencekit/volcanology/systems/geochronology.py +304 -0
- earthsciencekit/volcanology/systems/magma.py +190 -0
- earthsciencekit/volcanology/tests/__init__.py +0 -0
- earthsciencekit/volcanology/tests/test_models.py +485 -0
- earthsciencekit/volcanology/tests/test_physics.py +176 -0
- earthsciencekit/volcanology/visualizers/__init__.py +9 -0
- earthsciencekit-0.2.0.dist-info/METADATA +127 -0
- earthsciencekit-0.2.0.dist-info/RECORD +102 -0
- earthsciencekit-0.2.0.dist-info/WHEEL +5 -0
- earthsciencekit-0.2.0.dist-info/licenses/LICENSE +15 -0
- earthsciencekit-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""Physical identities, limits and dynamic checks for earthsciencekit.volcanology."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pytest
|
|
5
|
+
from scipy.integrate import quad
|
|
6
|
+
|
|
7
|
+
from earthsciencekit.constants import LAMBDA_U235, LAMBDA_U238, SECONDS_PER_YEAR, U238_U235
|
|
8
|
+
from earthsciencekit.volcanology.systems.eruptions import (
|
|
9
|
+
column_height,
|
|
10
|
+
plume_rise_height,
|
|
11
|
+
simulate_eruption_column,
|
|
12
|
+
volcanic_explosivity_index,
|
|
13
|
+
)
|
|
14
|
+
from earthsciencekit.volcanology.systems.geochemistry import (
|
|
15
|
+
delta_value,
|
|
16
|
+
equilibrium_crystallization_melt,
|
|
17
|
+
fractional_crystallization_melt,
|
|
18
|
+
isotope_temperature,
|
|
19
|
+
lattice_strain_partition,
|
|
20
|
+
rayleigh_fractionation,
|
|
21
|
+
)
|
|
22
|
+
from earthsciencekit.volcanology.systems.geochronology import (
|
|
23
|
+
concordia_ratios,
|
|
24
|
+
decay_constant,
|
|
25
|
+
isochron_fit,
|
|
26
|
+
lead_lead_age,
|
|
27
|
+
parent_fraction,
|
|
28
|
+
radiocarbon_age,
|
|
29
|
+
radiogenic_daughter,
|
|
30
|
+
radiogenic_lead_ratio,
|
|
31
|
+
radiometric_age,
|
|
32
|
+
)
|
|
33
|
+
from earthsciencekit.volcanology.systems.magma import (
|
|
34
|
+
arrhenius_viscosity,
|
|
35
|
+
dike_ascent_velocity,
|
|
36
|
+
mogi_displacement,
|
|
37
|
+
shaw_viscosity,
|
|
38
|
+
water_solubility,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
GA = 1e9 * SECONDS_PER_YEAR
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_decay_conserves_atoms_and_age_inverts_accumulation():
|
|
45
|
+
rate = decay_constant(1.25 * GA)
|
|
46
|
+
time = np.array([0.1, 1, 4.5]) * GA
|
|
47
|
+
remaining = parent_fraction(rate, time)
|
|
48
|
+
np.testing.assert_allclose(parent_fraction(rate, 1.25 * GA), 0.5)
|
|
49
|
+
np.testing.assert_allclose(remaining + radiogenic_daughter(remaining, rate, time), 1)
|
|
50
|
+
np.testing.assert_allclose(radiometric_age(radiogenic_daughter(2.0, rate, time) / 2.0, rate), time)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_radiocarbon_half_life_is_libby():
|
|
54
|
+
np.testing.assert_allclose(radiocarbon_age(0.5), 5568 * SECONDS_PER_YEAR, rtol=1e-4)
|
|
55
|
+
assert radiocarbon_age(1.2) < 0
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_lead_ratio_limits_and_inversion():
|
|
59
|
+
np.testing.assert_allclose(radiogenic_lead_ratio(1e-3 * SECONDS_PER_YEAR), LAMBDA_U235 / (U238_U235 * LAMBDA_U238), rtol=1e-9)
|
|
60
|
+
ages = np.array([0.5, 2.0, 4.55]) * GA
|
|
61
|
+
np.testing.assert_allclose(lead_lead_age(radiogenic_lead_ratio(ages)), ages, rtol=1e-10)
|
|
62
|
+
assert np.all(np.diff(radiogenic_lead_ratio(ages)) > 0)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_concordia_clocks_agree_and_discordia_is_a_chord():
|
|
66
|
+
time = np.array([0.3, 1.8]) * GA
|
|
67
|
+
points = concordia_ratios(time)
|
|
68
|
+
np.testing.assert_allclose(radiometric_age(points[:, 0], LAMBDA_U235), time)
|
|
69
|
+
np.testing.assert_allclose(radiometric_age(points[:, 1], LAMBDA_U238), time)
|
|
70
|
+
# A partly reset zircon lies on the straight chord between formation and lead loss.
|
|
71
|
+
mixed = 0.6 * points[1] + 0.4 * points[0]
|
|
72
|
+
chord, offset = points[1] - points[0], mixed - points[0]
|
|
73
|
+
np.testing.assert_allclose(chord[0] * offset[1] - chord[1] * offset[0], 0, atol=1e-14)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_isochron_recovers_age_and_initial_ratio():
|
|
77
|
+
rate = 1.42e-11 / SECONDS_PER_YEAR
|
|
78
|
+
parent = np.array([0.1, 0.8, 2.5, 6.0])
|
|
79
|
+
daughter = 0.7030 + parent * np.expm1(rate * 2.0 * GA)
|
|
80
|
+
np.testing.assert_allclose(isochron_fit(parent, daughter, rate), [2.0 * GA, 0.7030], rtol=1e-10)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@pytest.mark.parametrize(
|
|
84
|
+
"args",
|
|
85
|
+
[
|
|
86
|
+
[[1.0], [1.0], 1.0],
|
|
87
|
+
[[1, 2], [1, 2, 3], 1.0],
|
|
88
|
+
[[1, 2], [1, 2], [1.0, 2.0]],
|
|
89
|
+
[[1, 1], [1, 2], 1.0],
|
|
90
|
+
[[1, 2], [2, 1], 1.0],
|
|
91
|
+
],
|
|
92
|
+
)
|
|
93
|
+
def test_isochron_rejections(args):
|
|
94
|
+
with pytest.raises(ValueError):
|
|
95
|
+
isochron_fit(*args)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_rayleigh_limits_and_delta():
|
|
99
|
+
np.testing.assert_allclose(rayleigh_fractionation(0.002, 1, 0.99), 0.002)
|
|
100
|
+
np.testing.assert_allclose(rayleigh_fractionation(0.002, [0.1, 0.5], 1), 0.002)
|
|
101
|
+
shifted = delta_value(rayleigh_fractionation(0.002, 0.5, 1.01), 0.002)
|
|
102
|
+
np.testing.assert_allclose(shifted, 1000 * np.expm1(np.log(0.5) * 0.01))
|
|
103
|
+
assert shifted < 0
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_crystallization_mass_balance_and_shared_tangent():
|
|
107
|
+
partition, initial = 0.2, 100.0
|
|
108
|
+
melt = 0.3
|
|
109
|
+
removed, _ = quad(lambda f: partition * fractional_crystallization_melt(initial, f, partition), melt, 1)
|
|
110
|
+
np.testing.assert_allclose(removed + melt * fractional_crystallization_melt(initial, melt, partition), initial, rtol=1e-10)
|
|
111
|
+
np.testing.assert_allclose(equilibrium_crystallization_melt(initial, [1, 0], partition), [initial, initial / partition])
|
|
112
|
+
step = 1e-6
|
|
113
|
+
for function in (fractional_crystallization_melt, equilibrium_crystallization_melt):
|
|
114
|
+
slope = (function(initial, 1, partition) - function(initial, 1 - step, partition)) / step
|
|
115
|
+
np.testing.assert_allclose(slope, (partition - 1) * initial, rtol=1e-4)
|
|
116
|
+
assert fractional_crystallization_melt(initial, 0.05, partition) > equilibrium_crystallization_melt(initial, 0.05, partition)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def test_lattice_strain_peaks_at_optimal_radius():
|
|
120
|
+
radius = np.linspace(0.8e-10, 1.3e-10, 2001)
|
|
121
|
+
partition = lattice_strain_partition(radius, 1.05e-10, 4.0, 250e9, 1600)
|
|
122
|
+
np.testing.assert_allclose(radius[np.argmax(partition)], 1.05e-10, atol=1e-13)
|
|
123
|
+
np.testing.assert_allclose(partition.max(), 4.0)
|
|
124
|
+
# For the same misfit, an oversized ion strains the lattice more than an undersized one.
|
|
125
|
+
assert lattice_strain_partition(1.2e-10, 1.05e-10, 4.0, 250e9, 1600) < lattice_strain_partition(0.9e-10, 1.05e-10, 4.0, 250e9, 1600)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_isotope_temperature_reference_and_sense():
|
|
129
|
+
np.testing.assert_allclose(isotope_temperature(-1.0, -1.0), 289.65)
|
|
130
|
+
assert isotope_temperature(1.0, 0.0) < isotope_temperature(0.0, 0.0)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_viscosity_pivot_and_reference():
|
|
134
|
+
np.testing.assert_allclose(shaw_viscosity(1e4 / 1.5, [1.0, 2.5, 4.0]), 0.1 * np.exp(-6.4))
|
|
135
|
+
assert shaw_viscosity(1100, 4.0) > shaw_viscosity(1100, 2.5)
|
|
136
|
+
np.testing.assert_allclose(arrhenius_viscosity(1300, 50, 3e5, 1300), 50)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def test_solubility_dike_and_mogi_scaling():
|
|
140
|
+
np.testing.assert_allclose(water_solubility(4e8, 4e-6) / water_solubility(1e8, 4e-6), 2)
|
|
141
|
+
np.testing.assert_allclose(dike_ascent_velocity(4, 300, 100, 9.8) / dike_ascent_velocity(2, 300, 100, 9.8), 4)
|
|
142
|
+
depth, volume, nu = 3000.0, 2e6, 0.25
|
|
143
|
+
half = mogi_displacement(depth * np.sqrt(2 ** (2 / 3) - 1), depth, volume, nu)[1]
|
|
144
|
+
np.testing.assert_allclose(half, mogi_displacement(0, depth, volume, nu)[1] / 2)
|
|
145
|
+
uplift, _ = quad(lambda r: 2 * np.pi * r * mogi_displacement(r, depth, volume, nu)[1], 0, np.inf)
|
|
146
|
+
np.testing.assert_allclose(uplift, 2 * (1 - nu) * volume, rtol=1e-8)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def test_plume_scaling_and_vei_bins():
|
|
150
|
+
np.testing.assert_allclose(plume_rise_height(2e9, 0.01) / plume_rise_height(1e9, 0.01), 2**0.25)
|
|
151
|
+
np.testing.assert_allclose(column_height(16e12) / column_height(1e12), 2)
|
|
152
|
+
volume = [0, 9.9e3, 1e4, 9.9e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e15]
|
|
153
|
+
np.testing.assert_array_equal(volcanic_explosivity_index(volume), [0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 8])
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def test_eruption_column_follows_pure_plume_similarity():
|
|
157
|
+
alpha, buoyancy_flux, origin = 0.12, 1.0, 1.0
|
|
158
|
+
speed = 5 / (6 * alpha) * (0.9 * alpha * buoyancy_flux) ** (1 / 3)
|
|
159
|
+
radius, velocity = 1.2 * alpha * origin, speed * origin ** (-1 / 3)
|
|
160
|
+
time = np.linspace(0, 30, 61)
|
|
161
|
+
result = simulate_eruption_column(radius, velocity, buoyancy_flux / (radius**2 * velocity), 0, time, entrainment=alpha)
|
|
162
|
+
exact = (origin ** (4 / 3) + 4 / 3 * speed * time) ** 0.75
|
|
163
|
+
np.testing.assert_allclose(result.values[:, 0], exact - origin, rtol=1e-6, atol=1e-7)
|
|
164
|
+
np.testing.assert_allclose(result.values[:, 1], speed * exact ** (-1 / 3), rtol=1e-6)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def test_eruption_column_reaches_mtt_height_and_settles():
|
|
168
|
+
frequency = 0.02
|
|
169
|
+
time = np.linspace(5, 3005, 1001)
|
|
170
|
+
result = simulate_eruption_column(1, 1, 1, frequency, time)
|
|
171
|
+
top = result.values[:, 0].max()
|
|
172
|
+
np.testing.assert_allclose(top, plume_rise_height(1, frequency), rtol=0.01)
|
|
173
|
+
assert 0.7 < result.values[-1, 0] / top < 0.9
|
|
174
|
+
assert result.values[0, 0] == 0 and result.time[0] == 5
|
|
175
|
+
with pytest.raises(ValueError):
|
|
176
|
+
simulate_eruption_column(1, [1, 2], 1, frequency, time)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Plots for earthsciencekit.volcanology.
|
|
2
|
+
|
|
3
|
+
The dynamic models return a TimeSeries, whose ``plot`` and ``animate`` methods
|
|
4
|
+
call these package-wide helpers.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from earthsciencekit.visualizers import animate_series, plot_series
|
|
8
|
+
|
|
9
|
+
__all__ = ["plot_series", "animate_series"]
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: earthsciencekit
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Inspectable Earth-system models for learning and teaching.
|
|
5
|
+
Author-email: Charles Poli <cpoli374@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cpoli/earthsciencekit
|
|
8
|
+
Project-URL: Documentation, https://cpoli.github.io/earthsciencekit/
|
|
9
|
+
Project-URL: Issues, https://github.com/cpoli/earthsciencekit/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/cpoli/earthsciencekit/blob/main/CHANGELOG.md
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: numpy>=1.24
|
|
15
|
+
Requires-Dist: scipy>=1.10
|
|
16
|
+
Requires-Dist: matplotlib>=3.6
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
19
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
20
|
+
Provides-Extra: docs
|
|
21
|
+
Requires-Dist: sphinx-design>=0.6; extra == "docs"
|
|
22
|
+
Requires-Dist: sphinx-gallery>=0.19; extra == "docs"
|
|
23
|
+
Requires-Dist: sphinx-autodoc-typehints>=2; extra == "docs"
|
|
24
|
+
Requires-Dist: sphinx>=7; extra == "docs"
|
|
25
|
+
Requires-Dist: pydata-sphinx-theme>=0.15; extra == "docs"
|
|
26
|
+
Requires-Dist: sphinx-sitemap>=2.6; extra == "docs"
|
|
27
|
+
Requires-Dist: sphinxext-opengraph>=0.9; extra == "docs"
|
|
28
|
+
Requires-Dist: jupyterlite-sphinx>=0.17; extra == "docs"
|
|
29
|
+
Requires-Dist: jupyterlite-pyodide-kernel>=0.4; extra == "docs"
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: sphinx-design>=0.6; extra == "dev"
|
|
32
|
+
Requires-Dist: sphinx-sitemap>=2.6; extra == "dev"
|
|
33
|
+
Requires-Dist: sphinxext-opengraph>=0.9; extra == "dev"
|
|
34
|
+
Requires-Dist: sphinx-gallery>=0.19; extra == "dev"
|
|
35
|
+
Requires-Dist: sphinx-autodoc-typehints>=2; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
37
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
38
|
+
Requires-Dist: sphinx>=7; extra == "dev"
|
|
39
|
+
Requires-Dist: pydata-sphinx-theme>=0.15; extra == "dev"
|
|
40
|
+
Requires-Dist: jupyterlite-sphinx>=0.17; extra == "dev"
|
|
41
|
+
Requires-Dist: jupyterlite-pyodide-kernel>=0.4; extra == "dev"
|
|
42
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
43
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
44
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
45
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
|
|
48
|
+
# EarthScienceKit
|
|
49
|
+
|
|
50
|
+
Inspectable Earth-system computations for learning and teaching.
|
|
51
|
+
|
|
52
|
+
[](https://pypi.org/project/earthsciencekit/)
|
|
53
|
+
[](https://github.com/cpoli/earthsciencekit/actions/workflows/ci.yml)
|
|
54
|
+
[](https://cpoli.github.io/earthsciencekit/)
|
|
55
|
+
[](https://colab.research.google.com/github/cpoli/earthsciencekit/blob/main/notebooks/quickstart.ipynb)
|
|
56
|
+
[](https://cpoli.github.io/earthsciencekit/lite/lab/)
|
|
57
|
+
|
|
58
|
+
EarthScienceKit **0.2.0** follows the MathematicsKit family structure with seven
|
|
59
|
+
subpackages and 171 domain models: 162 algebraic equations and nine sampled
|
|
60
|
+
dynamic models. Every model documents its units, input bounds and applicability.
|
|
61
|
+
NumPy and SciPy supply mature numerical foundations.
|
|
62
|
+
|
|
63
|
+
| Subpackage | Models | Focus |
|
|
64
|
+
| --- | ---: | --- |
|
|
65
|
+
| `plate_tectonics` | 23 | Euler rotation, spreading, subduction, isostasy, flexure, convection, hotspots, cooling |
|
|
66
|
+
| `seismology` | 23 | Elastic, surface and head waves, rays, interfaces, magnitudes, pulses, rebound |
|
|
67
|
+
| `atmosphere` | 22 | Hydrostatics, dry thermodynamics, humidity, stratification, rotation, Rossby waves, barotropic vorticity |
|
|
68
|
+
| `climate` | 24 | Radiation, greenhouse layers, insolation, forcing, feedback, ice-albedo hysteresis, red noise, heat storage, carbon and sea level |
|
|
69
|
+
| `oceanography` | 24 | Tides, trochoidal and dispersive waves, density and TEOS-10 cabbeling, dynamic method, Ekman spiral, gyres, two-box overturning, abyssal mixing |
|
|
70
|
+
| `geophysics` | 31 | Gravity anomalies, normal gravity and flattening, satellite J2, Stokes's geoid, dipole and Gauss coefficients, paleomagnetic poles, reversal anomalies, Love numbers, GRACE water, Rikitake dynamo |
|
|
71
|
+
| `volcanology` | 24 | Decay and radiometric ages, radiocarbon, Pb-Pb, concordia and isochron dating, Rayleigh and crystal fractionation, lattice strain, isotope thermometry, magma viscosity and ascent, Mogi inflation, plume and column heights, VEI |
|
|
72
|
+
|
|
73
|
+
## Install and explore
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
python -m pip install earthsciencekit
|
|
77
|
+
# Or from a checkout:
|
|
78
|
+
python -m pip install -e '.[dev]'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import numpy as np
|
|
83
|
+
from earthsciencekit.climate import simulate_one_box
|
|
84
|
+
from earthsciencekit.units import convert
|
|
85
|
+
|
|
86
|
+
time = convert(np.linspace(0, 100, 201), "year", "s")
|
|
87
|
+
result = simulate_one_box(4, 1.2, 2e8, time)
|
|
88
|
+
print(result.summary())
|
|
89
|
+
figure, axes = result.plot()
|
|
90
|
+
animation = result.animate(interval=40)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
SI units apply unless an argument explicitly states otherwise. Latitude and
|
|
94
|
+
angles use radians. Algebraic functions accept scalars and broadcast arrays;
|
|
95
|
+
finite real quantities and physical bounds are validated. Unit conversions are
|
|
96
|
+
explicit. Sampled histories copy their arrays, retain labels and support plots
|
|
97
|
+
and animation export.
|
|
98
|
+
|
|
99
|
+
## Documentation and validation
|
|
100
|
+
|
|
101
|
+
The Sphinx site has Subpackages, History, Examples and API entry points,
|
|
102
|
+
MathematicsKit-style cards/hubs and cross-links. Seven history pages connect
|
|
103
|
+
at least fifteen dated breakthroughs each to the APIs; seven guides explain equations,
|
|
104
|
+
conventions and independent checks. One executed gallery script per breakthrough
|
|
105
|
+
provides figures and Python/notebook downloads.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
MPLBACKEND=Agg python -m pytest --cov=earthsciencekit --cov-report=term-missing
|
|
109
|
+
python -m ruff check .
|
|
110
|
+
python -m ruff format --check .
|
|
111
|
+
MPLBACKEND=Agg python -m sphinx -E -W --keep-going -b html docs/source docs/_build/html
|
|
112
|
+
python -m build
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Coverage enforces 100% of production statements, including validators and
|
|
116
|
+
visualization; test files alone are omitted. This metric does not establish
|
|
117
|
+
physical applicability. Tests include independent analytic solutions,
|
|
118
|
+
conservation balances, limiting cases and invalid-input contracts. Exact release
|
|
119
|
+
results are in VERIFICATION.md; model limits are in docs/source/limitations.rst.
|
|
120
|
+
The documentation is hosted at https://cpoli.github.io/earthsciencekit/, and
|
|
121
|
+
`notebooks/quickstart.ipynb` runs in Colab from the badge above.
|
|
122
|
+
|
|
123
|
+
## Contribute
|
|
124
|
+
|
|
125
|
+
See CONTRIBUTING.md. Educational models should have explicit equations, units,
|
|
126
|
+
assumptions, independent benchmarks and an executable example. The MIT license
|
|
127
|
+
is in LICENSE. Please cite this software using CITATION.cff.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
earthsciencekit/__init__.py,sha256=y2G9auUbEWFqKOBZxNz8sy6F2ZoRbnjxXkkECsqWkak,322
|
|
2
|
+
earthsciencekit/_validation.py,sha256=dLu-IwJ_jX6PI4B7I8RnEI9clSz9oRIP7mUzosdJ1Y0,2374
|
|
3
|
+
earthsciencekit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
earthsciencekit/results.py,sha256=kqIGYdbxfmtKg-n0d0nUsovSA1z4_d5m2aDjjlvfJvk,2743
|
|
5
|
+
earthsciencekit/atmosphere/__init__.py,sha256=BVCwepZFT1q4Ua6dAduki_NsvY-pZolqRwEVIBC6s-I,1499
|
|
6
|
+
earthsciencekit/atmosphere/core/__init__.py,sha256=mK4pzb9WHCqPsmBImhIk9Ms6UTH5AV8t7ShLh1Yfzh0,143
|
|
7
|
+
earthsciencekit/atmosphere/core/base.py,sha256=_HXVjmY_AXZT6EOOWf1RbObenPg840muOU4-8CngIaU,344
|
|
8
|
+
earthsciencekit/atmosphere/systems/__init__.py,sha256=B5-4uqLrp4ZHBVwTYX8KiGEpnc9TLhVyXO1r9mvwvnA,62
|
|
9
|
+
earthsciencekit/atmosphere/systems/dynamics.py,sha256=4W8VtaVE8TrrcO8ubeZDP3dQZlcdz9P77m_-xlzbUmc,7779
|
|
10
|
+
earthsciencekit/atmosphere/systems/hydrostatics.py,sha256=HzaaFOdKgYdeulQK0X_QVNTv2YoKzfsRtPsmeb4Iov8,7702
|
|
11
|
+
earthsciencekit/atmosphere/systems/moisture.py,sha256=bWMF9OF1H5MUT8isMFuO5FQzDSj7cVMJY8C5XgQMEDI,5497
|
|
12
|
+
earthsciencekit/atmosphere/systems/thermodynamics.py,sha256=ML0OE3udGjAEjvNHbvZmICR49jkZ9MuxqtmqtCBEyYs,8291
|
|
13
|
+
earthsciencekit/atmosphere/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
earthsciencekit/atmosphere/tests/test_models.py,sha256=DfAUqZ5YCLWuroL2NT8oyG1PKy3BGWsNMGDi9DicHRc,22334
|
|
15
|
+
earthsciencekit/atmosphere/tests/test_physics.py,sha256=Gr76JA6JUVwIfnpLwxMeUedoLOcGkpBBb2zuGBmW8zk,4188
|
|
16
|
+
earthsciencekit/atmosphere/visualizers/__init__.py,sha256=9VuKM6SRINAc5X3U5fNg1wTSxK-vkPhRII0dis95GbQ,272
|
|
17
|
+
earthsciencekit/climate/__init__.py,sha256=PiMQzgkKcTKhpjQk6Iz_SS5w3g1At8FRf2_aLFScLeM,1610
|
|
18
|
+
earthsciencekit/climate/core/__init__.py,sha256=KcFFGkscE2x7f3RzywgW8U9Wr9dtuSGfjNY3unrfhBs,137
|
|
19
|
+
earthsciencekit/climate/core/base.py,sha256=8ZvEmnfCm7Yqf74-q8pVPjiyg6ZaDXoADkzZ01lpZic,341
|
|
20
|
+
earthsciencekit/climate/systems/__init__.py,sha256=9cTds58wevD1vT-S0eYbWmIpZNNAiQTenVq1w0GYW8o,59
|
|
21
|
+
earthsciencekit/climate/systems/carbon.py,sha256=hUpr3Ym9ZPEBX_f7-lwFBffuzkEybmMrk80eaLQn6yY,2434
|
|
22
|
+
earthsciencekit/climate/systems/forcing.py,sha256=aXXfNrlRpL8tapTxO8y_SSRgmpSxv0U0s0cypUa2dT0,5235
|
|
23
|
+
earthsciencekit/climate/systems/radiation.py,sha256=ADfdhg4UweP0f-Sf5MO5eMn2ZSFkiGFbWzvWfJtC9jQ,8369
|
|
24
|
+
earthsciencekit/climate/systems/response.py,sha256=kPcuDHhTswf1CQCnAUISko8vLAWFp2a1t8tPALCWkPI,15462
|
|
25
|
+
earthsciencekit/climate/systems/sea_level.py,sha256=uSVpUx2s70QvBqhq6WyZtY1g26nyKPMUUniA_TNkFEY,2707
|
|
26
|
+
earthsciencekit/climate/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
earthsciencekit/climate/tests/test_models.py,sha256=H6BTiG1RpdXiByFlSUuEMWHgj_15S0Se1AMd5t8ibH0,32254
|
|
28
|
+
earthsciencekit/climate/tests/test_physics.py,sha256=7PfuMKmoy2euAXtOLe31ewSwXj14Rk-Wmwf7Cj1UGWU,686
|
|
29
|
+
earthsciencekit/climate/visualizers/__init__.py,sha256=jBvDuTeaeZuDgslnqn6E17W7v-sEBZh3A9wdWduUn24,269
|
|
30
|
+
earthsciencekit/constants/__init__.py,sha256=APOuRHb_PUOynz2oHLqhpLfcLa6feEGL2fyQ52Mvceg,1098
|
|
31
|
+
earthsciencekit/geophysics/__init__.py,sha256=J2cj4GMo9f_8Qz4sLpHFAAjjetxgJmUF1AmZ6VUHBcc,2019
|
|
32
|
+
earthsciencekit/geophysics/core/__init__.py,sha256=BTtWNgMANWqopaVh5_eTrjtusv42T97x6fNjY__P01s,143
|
|
33
|
+
earthsciencekit/geophysics/core/base.py,sha256=zxIF98U6plv7yOS0SzcXVlrA3pYHD_cH00zaIfon4RY,344
|
|
34
|
+
earthsciencekit/geophysics/systems/__init__.py,sha256=MdBxyEh8ClRlsbq4BCV5L-h5n5DxfeQqQIbK95E9KaQ,62
|
|
35
|
+
earthsciencekit/geophysics/systems/deformation.py,sha256=NnaJhQi9RTbCu4iNfavM5LtxLqwVgMU8KdzyHnSstjM,6160
|
|
36
|
+
earthsciencekit/geophysics/systems/dynamo.py,sha256=4a6-SZR1K5gzvVVNyIOhGTNz5JLG-WLx1I9fSkviB6I,5971
|
|
37
|
+
earthsciencekit/geophysics/systems/figure.py,sha256=6IdXNhPDjJdivr10Z_y4nZ9-oGT7_YS7s6GdLMgd1_g,11645
|
|
38
|
+
earthsciencekit/geophysics/systems/gravity.py,sha256=8O_Aw1vyOCTs2xJ-qYOt6yv3kU8U0wQc2vy7d9lXLhM,9554
|
|
39
|
+
earthsciencekit/geophysics/systems/magnetism.py,sha256=trf2gXLck4s115y2aQrxkUYcEyQ7pu1JFJbiVM-cXIo,14342
|
|
40
|
+
earthsciencekit/geophysics/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
+
earthsciencekit/geophysics/tests/test_models.py,sha256=v_ORQ2hj7F3gwQMFitpQTiVEsNxHFtUcU1vV2yZYU8U,30905
|
|
42
|
+
earthsciencekit/geophysics/tests/test_physics.py,sha256=mlQVx6lI4U9hYMubUBckfp1gBBklffzHjxC-dJN9pB4,8001
|
|
43
|
+
earthsciencekit/geophysics/visualizers/__init__.py,sha256=ZUJH2ISnOIjfouiE63p6G22x-2N_bpnn8h-H7ZI7-_c,272
|
|
44
|
+
earthsciencekit/integrators/__init__.py,sha256=nA-QTqn5lTqYfFsapWCn-cB-A1dvEb_60TdWR3B8XnA,2873
|
|
45
|
+
earthsciencekit/oceanography/__init__.py,sha256=HTBuih1BJAgDkX3E29LFLn2hwHtbLR-xFrhq4_52xuM,1592
|
|
46
|
+
earthsciencekit/oceanography/core/__init__.py,sha256=pelU5srHpHkmMOdS5_ZYu7YzeGEQD2VnfayY7ABuofI,147
|
|
47
|
+
earthsciencekit/oceanography/core/base.py,sha256=4FiQ5im8ZmqA05aI52kpXAXRJTqkvaWl_R9eKyuRHvM,346
|
|
48
|
+
earthsciencekit/oceanography/systems/__init__.py,sha256=r7VwPe9BxWWavWbYpCYTcM6N6n5TkU1aCzuA7ijboVE,64
|
|
49
|
+
earthsciencekit/oceanography/systems/circulation.py,sha256=-q4JYcK1K0FEc94bC7URgR5ALufbcq-XkGigbiQjb8U,16231
|
|
50
|
+
earthsciencekit/oceanography/systems/hydrography.py,sha256=Fj9AuNWM_IoUYhhyEaRWpX9hRwCp7IoySKqZNhvaIjs,8841
|
|
51
|
+
earthsciencekit/oceanography/systems/inertial.py,sha256=c9c9S--H317yFU7S0mY54gg_ckx0zB1j5pqL77ybs9I,2740
|
|
52
|
+
earthsciencekit/oceanography/systems/waves.py,sha256=Y8c114vlSvsc2UXBLGsQ33VHmhmiG8jL7rIPYWF4TJE,9759
|
|
53
|
+
earthsciencekit/oceanography/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
|
+
earthsciencekit/oceanography/tests/test_models.py,sha256=hZzMi8j4juSME6jaMlw2xazfhdNpDeW8T3kpmPcBtmk,27949
|
|
55
|
+
earthsciencekit/oceanography/tests/test_physics.py,sha256=-KxhtUqS3jmSGjmoiNIO_SNXnw5eUIvrS49LKvxVsuo,5063
|
|
56
|
+
earthsciencekit/oceanography/visualizers/__init__.py,sha256=VN1EpxrXMqE9sliwE--Qn7jbdrnIdXMWI5dao8Sz9tM,274
|
|
57
|
+
earthsciencekit/plate_tectonics/__init__.py,sha256=yz_y2ZOVlHAB2kbChwbcIl8WLNIGAZBLhPIe_HajDBU,1431
|
|
58
|
+
earthsciencekit/plate_tectonics/core/__init__.py,sha256=VS7FHryENkFrsUgSvIKGBj90-5hoSY9KT6KM-pNlMzY,153
|
|
59
|
+
earthsciencekit/plate_tectonics/core/base.py,sha256=EHz27jYu7Hh9kskimhPzVdsSF7n3Ihz12U862PpuWmA,349
|
|
60
|
+
earthsciencekit/plate_tectonics/systems/__init__.py,sha256=LSg9fJWTthOSyJGAjGi0ab2vtLIeaSwdx7eHx4U1Fu0,67
|
|
61
|
+
earthsciencekit/plate_tectonics/systems/boundaries.py,sha256=rffmLFzqeDV0kHBN_Nh-LHxclzcUPbFVJx-O3l1rSuk,6582
|
|
62
|
+
earthsciencekit/plate_tectonics/systems/cooling.py,sha256=j4dB-97feBru6mP-vFT2PYox5bq-_fBndgbjoLAex8I,10820
|
|
63
|
+
earthsciencekit/plate_tectonics/systems/isostasy.py,sha256=V9ScQ2bhUBhJUPGdwq-heQrONzknup0DH7UqL3D36-I,5981
|
|
64
|
+
earthsciencekit/plate_tectonics/systems/kinematics.py,sha256=yyiZabixEz50deQokc4MBh8e3Zu7eeOdxAwoiTNhkc4,9907
|
|
65
|
+
earthsciencekit/plate_tectonics/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
|
+
earthsciencekit/plate_tectonics/tests/test_models.py,sha256=T1-awDQJQXRnrmlaXJBh8OO19vpmR1qwInlyKvty5gk,27360
|
|
67
|
+
earthsciencekit/plate_tectonics/tests/test_physics.py,sha256=IWl_nfEsVB8e2Fdyh6yWgs3RITxKhWvxypnLU1m-l7E,4590
|
|
68
|
+
earthsciencekit/plate_tectonics/visualizers/__init__.py,sha256=F0wPPWUUKEMYlkKO2vKbrLQjG9rFBquI7mYMO_TSCF4,277
|
|
69
|
+
earthsciencekit/seismology/__init__.py,sha256=4RXyuOtgyxuy1i11OMiu8lAT066IoDWfRxVK89g2UWU,1421
|
|
70
|
+
earthsciencekit/seismology/core/__init__.py,sha256=rG0A0GCwpXfay8TMJdZb_o6Wxdb5jRIGv-SksJfy5Sc,143
|
|
71
|
+
earthsciencekit/seismology/core/base.py,sha256=dMMSmIQ8GDm1qj-9x9vRu6GW1Kq-iGZEao1Ze4Hquy4,344
|
|
72
|
+
earthsciencekit/seismology/systems/__init__.py,sha256=aKYKTPRHjeQr90U8v8PQhQ4my7zki8uMjr_Zqh30qao,62
|
|
73
|
+
earthsciencekit/seismology/systems/interfaces.py,sha256=5mOEmnISb-xxI90oDoLUCiHS_j_lEM0N-BbDW0EjID0,3274
|
|
74
|
+
earthsciencekit/seismology/systems/rays.py,sha256=GmfPkg2PWkVF-gUn5AWvvzhaHV6xn1xFBJaxxLLfF_k,8034
|
|
75
|
+
earthsciencekit/seismology/systems/sources.py,sha256=CvY2RP0rsRTZ0UOVscLmDG4z2vz28b4gtKWzoTforDE,8103
|
|
76
|
+
earthsciencekit/seismology/systems/waves.py,sha256=u7ISl8sLtebHzP2ZhIgYxZ8VNei7-YXrLR6j0zgoVb0,10289
|
|
77
|
+
earthsciencekit/seismology/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
78
|
+
earthsciencekit/seismology/tests/test_models.py,sha256=z5NYAgtQoFIqRska_iPeqi1y8wnS5YPy-tyY5G6Ndtw,24992
|
|
79
|
+
earthsciencekit/seismology/tests/test_physics.py,sha256=JJQNUTiIcd8QVgOwWy2symTJvac2iqe83weMnnJAGz0,4499
|
|
80
|
+
earthsciencekit/seismology/visualizers/__init__.py,sha256=S96Dzpe2DU_epc_2xBhOctQk5KUqij-uZ33yH5RHImE,272
|
|
81
|
+
earthsciencekit/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
82
|
+
earthsciencekit/tests/test_core.py,sha256=EvJuYyiz4-P5N16BnVMZan9gciQTKFYH0bHV4zC6ud8,7140
|
|
83
|
+
earthsciencekit/tests/test_relations.py,sha256=dSMjfvmxqeA5v-8xiE68eLj9mvEf1si4ZDyz-PnP134,1320
|
|
84
|
+
earthsciencekit/units/__init__.py,sha256=7bLbdfnXrUbuWOYMqizOi9SH3hvioJ6UMw5dLImYOhk,2455
|
|
85
|
+
earthsciencekit/visualizers/__init__.py,sha256=3AyeysWp99kXpkDIQz6VZXY74mYrmFPnICYt0COg3zg,1720
|
|
86
|
+
earthsciencekit/volcanology/__init__.py,sha256=Mq_3G3YwMEqDR0xnsqHy_84QLB_A9JOVlpRpuQBB_dw,1582
|
|
87
|
+
earthsciencekit/volcanology/core/__init__.py,sha256=ktY8Tm787xo6VhJe7Y8zzJjvUm9Hf5jy4moXi_XTfBM,145
|
|
88
|
+
earthsciencekit/volcanology/core/base.py,sha256=taxMqJ215X_CfFzop_OBcoRwD42r-z63kKZAa_lqwf0,345
|
|
89
|
+
earthsciencekit/volcanology/systems/__init__.py,sha256=TuhJ19x37v479kCOvhM0jqKhb0TW9JVAr_looxli0uI,63
|
|
90
|
+
earthsciencekit/volcanology/systems/eruptions.py,sha256=XrG5xHfyrbHEEU366wx3mQ7zZggcF8zUWsnbnAsBFvs,7222
|
|
91
|
+
earthsciencekit/volcanology/systems/geochemistry.py,sha256=UZrh-dBgHfVVrMAwBUv3hbKLhn3m3diIfzXEOypppi8,10204
|
|
92
|
+
earthsciencekit/volcanology/systems/geochronology.py,sha256=F9Zs2_xdYZDQWsO8BKmqUY451s3SY6YOkdcaNxAiLD0,11763
|
|
93
|
+
earthsciencekit/volcanology/systems/magma.py,sha256=QXvASPI_6RuZNjCCFstmNynn4JWmmoRzcfnXNY2c9Qg,7925
|
|
94
|
+
earthsciencekit/volcanology/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
|
+
earthsciencekit/volcanology/tests/test_models.py,sha256=SsE2-aFg7LF8vCJukdyw6AYyhlIQ_APstXeyZdx46-o,15079
|
|
96
|
+
earthsciencekit/volcanology/tests/test_physics.py,sha256=9deCwe_MFqxturWrghni2M6jghMmD2Mojrkss_3NPHA,7811
|
|
97
|
+
earthsciencekit/volcanology/visualizers/__init__.py,sha256=IUmbJh9L2VH1Da-jd4ZqnS77da3mn5dlFpd-21jKYi8,273
|
|
98
|
+
earthsciencekit-0.2.0.dist-info/licenses/LICENSE,sha256=MUySpnBDFVdpdnG-6L_cwIvZIsKRy3qhfoyhfOlKBIM,1069
|
|
99
|
+
earthsciencekit-0.2.0.dist-info/METADATA,sha256=uZin6rZM30IoE9QiNHqcqD-YHY0kRmDpl51WEUT1zbY,6490
|
|
100
|
+
earthsciencekit-0.2.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
101
|
+
earthsciencekit-0.2.0.dist-info/top_level.txt,sha256=Rd9KaQaJ5nBkcFfy3INGjOpTncSqSSI54R3GH5npSMA,16
|
|
102
|
+
earthsciencekit-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Charles Poli
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
10
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
11
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
12
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
13
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
14
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
15
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
earthsciencekit
|