geopack-vectorize 2.0.2__tar.gz → 2.0.3__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.
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/CHANGELOG.md +9 -0
- {geopack_vectorize-2.0.2/geopack_vectorize.egg-info → geopack_vectorize-2.0.3}/PKG-INFO +1 -1
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/__init__.py +1 -1
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/coordinates_complex.py +2 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/models/t01.py +2 -1
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/models/t96.py +4 -4
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3/geopack_vectorize.egg-info}/PKG-INFO +1 -1
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/pyproject.toml +1 -1
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/setup.py +1 -1
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/tests/test_coordinate_broadcasting.py +16 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/tests/test_model_input_regressions.py +29 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/LICENSE +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/MANIFEST.in +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/README.md +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/01_coordinate_transformations_guide.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/02_magnetic_field_models_guide.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/03_performance_comparison.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/04_accuracy_validation.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/05_field_line_tracing_guide.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/06_field_line_tracing_validation.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/07_fieldline_geometry_and_derivatives.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/directional_derivatives_maps/dipole_field_directional_derivatives.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/directional_derivatives_maps/t96_field_directional_derivatives.ipynb +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/python_code_samples/_helpers.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/python_code_samples/basic_usage.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/python_code_samples/field_line_9_derivatives_example.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/python_code_samples/field_line_geometry_example.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/python_code_samples/magnetic_field_simple_sample.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/readme_examples.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/Mageometry/__init__.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/Mageometry/field_line_directional_derivatives.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/Mageometry/field_line_geometry.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/core.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/geopack.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/igrf_coeffs/igrf10coeffs.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/igrf_coeffs/igrf11coeffs.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/igrf_coeffs/igrf12coeffs.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/igrf_coeffs/igrf13coeffs.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/igrf_coeffs/igrf14coeffs.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/igrf_coeffs/igrf9coeffs.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/models/__init__.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/models/t01.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/models/t04.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/models/t89.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/models/t96.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/print_structure.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/t01.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/t04.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/t89.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/t96.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/__init__.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/condip1_exact.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/coordinates.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/igrf.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/models/__init__.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/models/t04.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/models/t89.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/trace.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack_vectorize.egg-info/SOURCES.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack_vectorize.egg-info/dependency_links.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack_vectorize.egg-info/requires.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack_vectorize.egg-info/top_level.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/requirements.txt +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/setup.cfg +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/tests/installed_smoke.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/tests/test_distribution.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/tests/test_trace_vectorized.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/tests/test_trace_vectorized_with_vectorized_models.py +0 -0
- {geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/tests/test_vectorized_models.py +0 -0
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.3] - 2026-11-07
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Return NaN fields for NaN coordinates in vectorized T01/T96 instead of
|
|
14
|
+
leaving zero outputs when no magnetopause region matches. Valid points
|
|
15
|
+
in the same batch retain their scalar-reference values.
|
|
16
|
+
- Normalize Cartesian-to-spherical longitude in vectorized `sphcar` to
|
|
17
|
+
match the scalar convention of [0, 2*pi), retaining phi=0 at the poles.
|
|
18
|
+
|
|
10
19
|
## [2.0.2] - 2026-11-04
|
|
11
20
|
|
|
12
21
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: geopack-vectorize
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: Python implementation of geopack and Tsyganenko models with optimized vectorization
|
|
5
5
|
Home-page: https://github.com/Butadiene/geopack-vectorize
|
|
6
6
|
Author: geopack-vectorize contributors
|
{geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/vectorized/coordinates_complex.py
RENAMED
|
@@ -23,6 +23,7 @@ def sphcar(r, theta, phi, j):
|
|
|
23
23
|
-------
|
|
24
24
|
tuple of (float or ndarray)
|
|
25
25
|
Transformed coordinates (x,y,z if j>0, r,theta,phi if j<0)
|
|
26
|
+
For j<0, phi is in [0, 2*pi), with phi=0 at the poles.
|
|
26
27
|
"""
|
|
27
28
|
# Check if input is scalar
|
|
28
29
|
scalar_input = all(np.isscalar(c) for c in (r, theta, phi))
|
|
@@ -50,6 +51,7 @@ def sphcar(r, theta, phi, j):
|
|
|
50
51
|
|
|
51
52
|
# Handle conditional logic for phi
|
|
52
53
|
phi_out = np.where(sq != 0, np.arctan2(y, x), 0.0)
|
|
54
|
+
phi_out = np.where(phi_out < 0, phi_out + 2 * np.pi, phi_out)
|
|
53
55
|
|
|
54
56
|
# Handle conditional logic for theta
|
|
55
57
|
theta_out = np.where(sq != 0,
|
|
@@ -249,7 +249,8 @@ def extall(iopgen,iopt,iopb,iopr,a,ntot,pdyn,dst,byimf,bzimf,vbimf1,vbimf2,ps,x,
|
|
|
249
249
|
mask_interp = (sigma >= (s0 - dsig)) & (sigma < (s0 + dsig))
|
|
250
250
|
mask_out = sigma >= (s0 + dsig)
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
# NaN sigma matches no region, so invalid coordinates must stay undefined.
|
|
253
|
+
bx, by, bz = np.full_like(x, np.nan), np.full_like(y, np.nan), np.full_like(z, np.nan)
|
|
253
254
|
|
|
254
255
|
# Case 1: Inside the magnetosphere
|
|
255
256
|
bx = np.where(mask_in, bbx, bx)
|
|
@@ -125,10 +125,10 @@ def t96(parmod, ps, x, y, z):
|
|
|
125
125
|
sqrt_arg = np.maximum(sqrt_arg, 0) # Ensure non-negative
|
|
126
126
|
sigma = np.sqrt((aro + axx0 + np.sqrt(sqrt_arg)) / (2.0 * asq))
|
|
127
127
|
|
|
128
|
-
#
|
|
129
|
-
bx = np.
|
|
130
|
-
by = np.
|
|
131
|
-
bz = np.
|
|
128
|
+
# NaN sigma matches no region, so invalid coordinates must stay undefined.
|
|
129
|
+
bx = np.full_like(x, np.nan)
|
|
130
|
+
by = np.full_like(y, np.nan)
|
|
131
|
+
bz = np.full_like(z, np.nan)
|
|
132
132
|
|
|
133
133
|
# Define masks for three regions
|
|
134
134
|
mask_inside = sigma < (s0 - dsig)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: geopack-vectorize
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: Python implementation of geopack and Tsyganenko models with optimized vectorization
|
|
5
5
|
Home-page: https://github.com/Butadiene/geopack-vectorize
|
|
6
6
|
Author: geopack-vectorize contributors
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "geopack-vectorize"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.3"
|
|
8
8
|
description = "Python implementation of geopack and Tsyganenko models with optimized vectorization"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Sheng Tian", email = "ts0110@atmos.ucla.edu"}
|
|
@@ -6,7 +6,7 @@ with open('README.md', 'r', encoding='utf-8') as fh:
|
|
|
6
6
|
|
|
7
7
|
setuptools.setup(
|
|
8
8
|
name='geopack-vectorize',
|
|
9
|
-
version='2.0.
|
|
9
|
+
version='2.0.3',
|
|
10
10
|
author='geopack-vectorize contributors',
|
|
11
11
|
author_email='',
|
|
12
12
|
description='Vectorized Python implementation of geopack and Tsyganenko models (fork of tsssss/geopack)',
|
|
@@ -65,6 +65,22 @@ class TestCoordinateBroadcasting(unittest.TestCase):
|
|
|
65
65
|
result = getattr(coordinates_complex, name)(*base)
|
|
66
66
|
self.assertTrue(all(isinstance(c, float) for c in result))
|
|
67
67
|
|
|
68
|
+
def test_cartesian_to_spherical_longitude_matches_scalar_in_all_quadrants(self):
|
|
69
|
+
# Include the negative x axis, signed zero, both poles, and the origin.
|
|
70
|
+
points = np.array([[1., 1., 0.], [-1., 1., 0.], [-1., -1., 0.], [1., -1., 0.],
|
|
71
|
+
[-1., 0., 0.], [-1., -0., 0.], [1., -0., 0.],
|
|
72
|
+
[0., 0., 1.], [0., 0., -1.], [0., 0., 0.]])
|
|
73
|
+
for point in points:
|
|
74
|
+
with self.subTest(point=point):
|
|
75
|
+
actual = coordinates_complex.sphcar(*point, -1)
|
|
76
|
+
self.assertTrue(all(isinstance(c, float) for c in actual))
|
|
77
|
+
np.testing.assert_allclose(actual, scalar.sphcar(*point, -1), atol=1e-14)
|
|
78
|
+
self.assertGreaterEqual(actual[2], 0.)
|
|
79
|
+
self.assertLess(actual[2], 2 * np.pi)
|
|
80
|
+
self.assert_pointwise(coordinates_complex.sphcar, scalar.sphcar, points.T, (-1,))
|
|
81
|
+
self.assert_pointwise(coordinates_complex.sphcar, scalar.sphcar,
|
|
82
|
+
(np.array([-1., 1.])[:, None], np.array([-1., 1.]), 0.), (-1,))
|
|
83
|
+
|
|
68
84
|
def test_igrf_cartesian_wrappers_broadcast(self):
|
|
69
85
|
for name in ('igrf_gsm', 'igrf_gsw'):
|
|
70
86
|
for coords in ((5., np.array([1., 2.]), 1.),
|
|
@@ -12,6 +12,35 @@ PARMOD = [2., -20., 2., -5., 1., 1., 1., 1., 1., 1.]
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class TestModelInputRegressions(unittest.TestCase):
|
|
15
|
+
def test_nan_coordinates_return_nan_for_scalar_inputs(self):
|
|
16
|
+
for name in ('t01', 't96'):
|
|
17
|
+
for axis in range(3):
|
|
18
|
+
point = [-6., 1., 2.]
|
|
19
|
+
point[axis] = np.nan
|
|
20
|
+
with self.subTest(model=name, nan_axis=axis), np.errstate(invalid='ignore'):
|
|
21
|
+
expected = getattr(models, name)(PARMOD, .2, *point)
|
|
22
|
+
actual = getattr(vectorized, name)(PARMOD, .2, *point)
|
|
23
|
+
self.assertTrue(np.all(np.isnan(expected)))
|
|
24
|
+
self.assertTrue(np.all(np.isnan(actual)))
|
|
25
|
+
self.assertTrue(all(isinstance(c, float) for c in actual))
|
|
26
|
+
|
|
27
|
+
def test_nan_coordinates_preserve_valid_points_in_multidimensional_batches(self):
|
|
28
|
+
valid_points = np.array([[-6., 1., 2.], [10.0655881232758, 2., 1.], [15., 3., 1.]])
|
|
29
|
+
for name in ('t01', 't96'):
|
|
30
|
+
expected = np.full((3, len(valid_points), 2), np.nan)
|
|
31
|
+
expected[:, :, 0] = np.array([
|
|
32
|
+
getattr(models, name)(PARMOD, .2, *point) for point in valid_points
|
|
33
|
+
]).T
|
|
34
|
+
self.assertTrue(np.all(np.isfinite(expected[:, :, 0])))
|
|
35
|
+
for axis in range(3):
|
|
36
|
+
points = np.repeat(valid_points[:, None, :], 2, axis=1)
|
|
37
|
+
points[:, 1, axis] = np.nan
|
|
38
|
+
with self.subTest(model=name, nan_axis=axis), np.errstate(invalid='ignore'):
|
|
39
|
+
actual = getattr(vectorized, name)(PARMOD, .2, *np.moveaxis(points, -1, 0))
|
|
40
|
+
self.assertEqual(np.shape(actual), expected.shape)
|
|
41
|
+
np.testing.assert_allclose(actual, expected, rtol=1e-10, atol=1e-6,
|
|
42
|
+
equal_nan=True)
|
|
43
|
+
|
|
15
44
|
def test_t01_imf_interconnection_preserves_clock_angle(self):
|
|
16
45
|
# With G1/G2 held fixed, the IMF dependence is exactly the prescribed
|
|
17
46
|
# T01 interconnection field, including outside the magnetopause.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/notebooks/04_accuracy_validation.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/python_code_samples/_helpers.py
RENAMED
|
File without changes
|
{geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/examples/python_code_samples/basic_usage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack/Mageometry/field_line_geometry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack_vectorize.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{geopack_vectorize-2.0.2 → geopack_vectorize-2.0.3}/geopack_vectorize.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|