paddle 1.1.4__py3-none-any.whl → 1.1.5__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.
- paddle/__init__.py +1 -1
- paddle/nc2pt.py +39 -0
- paddle/pt2nc.py +124 -0
- paddle/setup_profile.py +6 -3
- {paddle-1.1.4.dist-info → paddle-1.1.5.dist-info}/METADATA +52 -3
- paddle-1.1.5.dist-info/RECORD +13 -0
- paddle-1.1.4.dist-info/RECORD +0 -11
- {paddle-1.1.4.dist-info → paddle-1.1.5.dist-info}/WHEEL +0 -0
- {paddle-1.1.4.dist-info → paddle-1.1.5.dist-info}/entry_points.txt +0 -0
- {paddle-1.1.4.dist-info → paddle-1.1.5.dist-info}/licenses/LICENSE +0 -0
paddle/__init__.py
CHANGED
paddle/nc2pt.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#! /usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Read variables in a NetCDF file and write them to jit saved torch tensors.
|
|
5
|
+
Usage: python nc2pt.py input.nc output.pt
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from netCDF4 import Dataset
|
|
9
|
+
import torch
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def save_tensors(tensor_map: dict[str, torch.Tensor], filename: str):
|
|
13
|
+
class TensorModule(torch.nn.Module):
|
|
14
|
+
def __init__(self, tensors):
|
|
15
|
+
super().__init__()
|
|
16
|
+
for name, tensor in tensors.items():
|
|
17
|
+
self.register_buffer(name, tensor)
|
|
18
|
+
|
|
19
|
+
module = TensorModule(tensor_map)
|
|
20
|
+
scripted = torch.jit.script(module) # Needed for LibTorch compatibility
|
|
21
|
+
scripted.save(filename)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
fname = "sod.out0.00019.nc"
|
|
25
|
+
|
|
26
|
+
nc = Dataset(fname, "r")
|
|
27
|
+
out_fname = "sod.out0.00019.pt"
|
|
28
|
+
|
|
29
|
+
data = {}
|
|
30
|
+
for varname in nc.variables:
|
|
31
|
+
var = nc.variables[varname][:]
|
|
32
|
+
if var.ndim == 4: # (time, x1, x2, x3) -> (time, x3, x2, x1)
|
|
33
|
+
data[varname] = torch.tensor(var).permute(0, 3, 2, 1).squeeze()
|
|
34
|
+
elif var.ndim == 3: # (x1, x2, x3) -> (x3, x2, x1)
|
|
35
|
+
data[varname] = torch.tensor(var).permute(2, 1, 0).squeeze()
|
|
36
|
+
else:
|
|
37
|
+
data[varname] = torch.tensor(var).squeeze()
|
|
38
|
+
|
|
39
|
+
save_tensors(data, out_fname)
|
paddle/pt2nc.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Convert a sequence of PyTorch .pt dumps into a CF‐compliant NetCDF4 file
|
|
4
|
+
with dimensions (time, x, y, z) plus a 'species' axis for mole fractions.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import tarfile
|
|
9
|
+
import re
|
|
10
|
+
import torch
|
|
11
|
+
import numpy as np
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from netCDF4 import Dataset
|
|
14
|
+
|
|
15
|
+
# ──────────────────────────────── CONFIG ────────────────────────────────
|
|
16
|
+
INPUT_DIR = "."
|
|
17
|
+
OUTPUT_FILE = "thermo_x_xfrac_to_conc.nc"
|
|
18
|
+
# ────────────────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
# find all .pt files, skip size==0, sort by timestamp
|
|
21
|
+
pt_files = []
|
|
22
|
+
for fn in os.listdir(INPUT_DIR):
|
|
23
|
+
if not fn.endswith(".pt"):
|
|
24
|
+
continue
|
|
25
|
+
full = os.path.join(INPUT_DIR, fn)
|
|
26
|
+
if os.path.getsize(full) == 0:
|
|
27
|
+
continue
|
|
28
|
+
# expect names like thermo_x_xfrac_to_conc_<epoch>.pt
|
|
29
|
+
m = re.search(r"(\d+)\.pt$", fn)
|
|
30
|
+
if not m:
|
|
31
|
+
continue
|
|
32
|
+
pt_files.append((int(m.group(1)), full))
|
|
33
|
+
|
|
34
|
+
pt_files.sort(key=lambda x: x[0])
|
|
35
|
+
times_epoch = [ts for ts, _ in pt_files]
|
|
36
|
+
|
|
37
|
+
# load the first file to infer shapes
|
|
38
|
+
module = torch.jit.load(pt_files[0][1])
|
|
39
|
+
data = {name: param for name, param in module.named_parameters()}
|
|
40
|
+
|
|
41
|
+
temp0 = data["temp"].numpy()
|
|
42
|
+
pres0 = data["pres"].numpy()
|
|
43
|
+
xfrac0 = data["xfrac"].numpy()
|
|
44
|
+
nx3, nx2, nx1 = temp0.shape
|
|
45
|
+
nspecies = xfrac0.shape[3]
|
|
46
|
+
nt = len(pt_files)
|
|
47
|
+
|
|
48
|
+
# pre‐allocate arrays in (time, x1, x2, x3) order
|
|
49
|
+
temp_arr = np.empty((nt, nx1, nx2, nx3), dtype=temp0.dtype)
|
|
50
|
+
pres_arr = np.empty((nt, nx1, nx2, nx3), dtype=pres0.dtype)
|
|
51
|
+
xfrac_arr = np.empty((nspecies, nt, nx1, nx2, nx3), dtype=xfrac0.dtype)
|
|
52
|
+
|
|
53
|
+
# load all timesteps
|
|
54
|
+
for i, (_, path) in enumerate(pt_files):
|
|
55
|
+
module = torch.jit.load(path)
|
|
56
|
+
data = {name: param for name, param in module.named_parameters()}
|
|
57
|
+
t_np = data["temp"].numpy() # (z, y, x)
|
|
58
|
+
p_np = data["pres"].numpy() # (z, y, x)
|
|
59
|
+
x_np = data["xfrac"].numpy() # (species, z, y, x)
|
|
60
|
+
|
|
61
|
+
# reorder to (x, y, z)
|
|
62
|
+
temp_arr[i] = t_np.transpose(2, 1, 0)
|
|
63
|
+
pres_arr[i] = p_np.transpose(2, 1, 0)
|
|
64
|
+
for j in range(nspecies):
|
|
65
|
+
xfrac_arr[j, i] = x_np[:, :, :, j].transpose(2, 1, 0)
|
|
66
|
+
|
|
67
|
+
# create NetCDF4 file
|
|
68
|
+
ds = Dataset(OUTPUT_FILE, "w", format="NETCDF4")
|
|
69
|
+
|
|
70
|
+
# dimensions
|
|
71
|
+
ds.createDimension("time", nt)
|
|
72
|
+
ds.createDimension("x3", nx3)
|
|
73
|
+
ds.createDimension("x2", nx2)
|
|
74
|
+
ds.createDimension("x1", nx1)
|
|
75
|
+
|
|
76
|
+
# coordinate variables
|
|
77
|
+
tvar = ds.createVariable("time", "f4", ("time",))
|
|
78
|
+
tvar.units = "seconds since 1970-01-01 00:00:00 UTC"
|
|
79
|
+
tvar.calendar = "gregorian"
|
|
80
|
+
tvar[:] = np.array(times_epoch, dtype="f4")
|
|
81
|
+
|
|
82
|
+
zvar = ds.createVariable("x1", "f4", ("x1",))
|
|
83
|
+
yvar = ds.createVariable("x2", "f4", ("x2",))
|
|
84
|
+
xvar = ds.createVariable("x3", "f4", ("x3",))
|
|
85
|
+
|
|
86
|
+
xvar.axis = "X"
|
|
87
|
+
yvar.axis = "Y"
|
|
88
|
+
zvar.axis = "Z"
|
|
89
|
+
|
|
90
|
+
xvar[:] = np.arange(nx3)
|
|
91
|
+
yvar[:] = np.arange(nx2)
|
|
92
|
+
zvar[:] = np.arange(nx1)
|
|
93
|
+
|
|
94
|
+
# data variables
|
|
95
|
+
temp_v = ds.createVariable("temp", "f4", ("time", "x1", "x2", "x3"), zlib=True)
|
|
96
|
+
temp_v.units = "K"
|
|
97
|
+
temp_v.long_name = "temperature"
|
|
98
|
+
|
|
99
|
+
pres_v = ds.createVariable("pres", "f4", ("time", "x1", "x2", "x3"), zlib=True)
|
|
100
|
+
pres_v.units = "Pa"
|
|
101
|
+
pres_v.long_name = "pressure"
|
|
102
|
+
|
|
103
|
+
xfrac_v = []
|
|
104
|
+
for i in range(nspecies):
|
|
105
|
+
xfrac_v.append(
|
|
106
|
+
ds.createVariable(f"xfrac{i}", "f4", ("time", "x1", "x2", "x3"), zlib=True)
|
|
107
|
+
)
|
|
108
|
+
xfrac_v[i].units = "1"
|
|
109
|
+
xfrac_v[i].long_name = "mole fraction of each species"
|
|
110
|
+
|
|
111
|
+
# write the data
|
|
112
|
+
temp_v[:] = temp_arr
|
|
113
|
+
pres_v[:] = pres_arr
|
|
114
|
+
for i in range(nspecies):
|
|
115
|
+
xfrac_v[i][:] = xfrac_arr[i]
|
|
116
|
+
|
|
117
|
+
# global metadata
|
|
118
|
+
ds.title = "Debug fields for thermo_x.xfrac_to_conc"
|
|
119
|
+
ds.institution = "University of Michigan"
|
|
120
|
+
ds.source = "converted from .pt files"
|
|
121
|
+
ds.history = f"Created {datetime.utcnow().isoformat()}Z"
|
|
122
|
+
|
|
123
|
+
ds.close()
|
|
124
|
+
print(f"Converted file: {OUTPUT_FILE}")
|
paddle/setup_profile.py
CHANGED
|
@@ -140,7 +140,10 @@ def integrate_dry_adiabat(
|
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
def setup_profile(
|
|
143
|
-
block: snapy.MeshBlock,
|
|
143
|
+
block: snapy.MeshBlock,
|
|
144
|
+
param: dict[str, float] = {},
|
|
145
|
+
method: str = "moist-adiabat",
|
|
146
|
+
verbose: bool = False,
|
|
144
147
|
) -> torch.Tensor:
|
|
145
148
|
"""
|
|
146
149
|
Set up an adiabatic initial condition for the mesh block.
|
|
@@ -227,7 +230,7 @@ def setup_profile(
|
|
|
227
230
|
dz = coord.buffer("dx1f")[ifirst]
|
|
228
231
|
|
|
229
232
|
# half a grid to cell center
|
|
230
|
-
thermo_x.extrapolate_ad(temp, pres, xfrac, grav, dz / 2.0)
|
|
233
|
+
thermo_x.extrapolate_ad(temp, pres, xfrac, grav, dz / 2.0, verbose=verbose)
|
|
231
234
|
|
|
232
235
|
# adiabatic extrapolation
|
|
233
236
|
if method == "isothermal":
|
|
@@ -257,7 +260,7 @@ def setup_profile(
|
|
|
257
260
|
elif method.split("-")[0] == "neutral":
|
|
258
261
|
temp, pres, xfrac = integrate_neutral(thermo_x, temp, pres, xfrac, grav, dz)
|
|
259
262
|
else:
|
|
260
|
-
thermo_x.extrapolate_ad(temp, pres, xfrac, grav, dz)
|
|
263
|
+
thermo_x.extrapolate_ad(temp, pres, xfrac, grav, dz, verbose=verbose)
|
|
261
264
|
|
|
262
265
|
if torch.any(temp < Tmin):
|
|
263
266
|
i_isothermal = i + 1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: paddle
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.5
|
|
4
4
|
Summary: Python Atmospheric Dynamics: Discovery and Learning about Exoplanets. An open-source, user-friendly python frontend of canoe
|
|
5
5
|
Project-URL: Homepage, https://github.com/elijah-mullens/paddle
|
|
6
6
|
Project-URL: Repository, https://github.com/elijah-mullens/paddle
|
|
@@ -22,8 +22,8 @@ Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
|
22
22
|
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
|
|
23
23
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
24
24
|
Requires-Python: >=3.9
|
|
25
|
-
Requires-Dist: kintera>=1.
|
|
26
|
-
Requires-Dist: snapy>=0.
|
|
25
|
+
Requires-Dist: kintera>=1.1.5
|
|
26
|
+
Requires-Dist: snapy>=0.8.2
|
|
27
27
|
Requires-Dist: torch<=2.7.1,>=2.7.0
|
|
28
28
|
Provides-Extra: dev
|
|
29
29
|
Requires-Dist: pytest>=7; extra == 'dev'
|
|
@@ -31,3 +31,52 @@ Description-Content-Type: text/markdown
|
|
|
31
31
|
|
|
32
32
|
# paddle
|
|
33
33
|
Python Atmospheric Dynamics: Discovering and Learning about Exoplanets. An open-source, user-friendly python version of canoe.
|
|
34
|
+
|
|
35
|
+
## Install docker and docker-compose plugin
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## Create a python virtual environment
|
|
39
|
+
```bash
|
|
40
|
+
python -m venv pyenv
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
# Create a docker container
|
|
44
|
+
```bash
|
|
45
|
+
make up
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
# Terminate a docker container
|
|
49
|
+
```bash
|
|
50
|
+
make down
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
# Start a docker container
|
|
54
|
+
```bash
|
|
55
|
+
make start
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
# Build a new docker image (rarely used)
|
|
59
|
+
```bash
|
|
60
|
+
make build
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## For Development
|
|
64
|
+
### Cache your github credential
|
|
65
|
+
```bash
|
|
66
|
+
git config credential.helper 'cache --timeout=86400'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Install paddle package
|
|
70
|
+
```bash
|
|
71
|
+
pip install paddle
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Install pre-commit hook
|
|
75
|
+
```bash
|
|
76
|
+
pip install pre-commit
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Install pre-commit hook
|
|
80
|
+
```bash
|
|
81
|
+
pre-commit install
|
|
82
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
paddle/__init__.py,sha256=McGNGlI-ofIhDsJdizgFYpkgJJwWMwg0oidCOPuXbgA,281
|
|
2
|
+
paddle/crm.py,sha256=HwOLAojR5LBcptqjAC9APEJiWpn8GhxPiAmvvIZ4mTM,1986
|
|
3
|
+
paddle/evolve_kinetics.py,sha256=OWt1-SiLTzaWUCIchwRnBHCjbtcgJIIxrlQ5Lk4iN8c,1541
|
|
4
|
+
paddle/find_init_params.py,sha256=dyRmo-LTwVohbPhSH5LV45jL_XeRmNEcuKPvafBklto,2516
|
|
5
|
+
paddle/nc2pt.py,sha256=LXR0fnUTaOA_uaDsLU4YqdAVFyycB6SvRq12xWhHhLA,1136
|
|
6
|
+
paddle/pt2nc.py,sha256=lLviBm6a2O05RvuPQc8DxV5pGr_VEhlSkrKPV1lQ3yU,3913
|
|
7
|
+
paddle/setup_profile.py,sha256=oJpqPnlq2q1rn_l2flwgbdWwbxbhxx4QOYl4ezWmP-o,8803
|
|
8
|
+
paddle/write_profile.py,sha256=HeBtGaFixGv8DnmJWPiQs-30RsdplSObhMA6ky6eVrg,3908
|
|
9
|
+
paddle-1.1.5.dist-info/METADATA,sha256=e9bgxHKLY-fo1nTgZu2kYrK8toKqXHB4kAmm-Go48II,2197
|
|
10
|
+
paddle-1.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
+
paddle-1.1.5.dist-info/entry_points.txt,sha256=pDR96GW6ylBZrbFd-tRGthW8qTuYaSLjrEt1LFIEYto,48
|
|
12
|
+
paddle-1.1.5.dist-info/licenses/LICENSE,sha256=e6NthgKABUnLRqjuETcBGgsOuA-aJANpNoeXMe9RBso,1071
|
|
13
|
+
paddle-1.1.5.dist-info/RECORD,,
|
paddle-1.1.4.dist-info/RECORD
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
paddle/__init__.py,sha256=_UwSoQUWYoYGzcqdp5ES7q-Z1Dh-7nqkSOOFAl83BIA,281
|
|
2
|
-
paddle/crm.py,sha256=HwOLAojR5LBcptqjAC9APEJiWpn8GhxPiAmvvIZ4mTM,1986
|
|
3
|
-
paddle/evolve_kinetics.py,sha256=OWt1-SiLTzaWUCIchwRnBHCjbtcgJIIxrlQ5Lk4iN8c,1541
|
|
4
|
-
paddle/find_init_params.py,sha256=dyRmo-LTwVohbPhSH5LV45jL_XeRmNEcuKPvafBklto,2516
|
|
5
|
-
paddle/setup_profile.py,sha256=MHxRvFyva8CR5_71QSfrLy9ml2rQnW6yy21ZXaVcTGU,8733
|
|
6
|
-
paddle/write_profile.py,sha256=HeBtGaFixGv8DnmJWPiQs-30RsdplSObhMA6ky6eVrg,3908
|
|
7
|
-
paddle-1.1.4.dist-info/METADATA,sha256=MPjPtUaGGE4X9a6crnB1ktptBQvsD5n28Nz_mjEJfQY,1558
|
|
8
|
-
paddle-1.1.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
9
|
-
paddle-1.1.4.dist-info/entry_points.txt,sha256=pDR96GW6ylBZrbFd-tRGthW8qTuYaSLjrEt1LFIEYto,48
|
|
10
|
-
paddle-1.1.4.dist-info/licenses/LICENSE,sha256=e6NthgKABUnLRqjuETcBGgsOuA-aJANpNoeXMe9RBso,1071
|
|
11
|
-
paddle-1.1.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|