kerrz-python 0.1.0__tar.gz → 0.2.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kerrz_python
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Python wrapper for kerrz. Avoid installing directly, use kerrz[py] unless you know what you are doing.
5
5
  Home-page: https://codeberg.org/astro-group/kerrz-py
6
6
  Author: Fergus Baker
@@ -13,7 +13,7 @@ Classifier: Operating System :: POSIX :: Linux
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Requires-Python: >=3.6
15
15
  Description-Content-Type: text/markdown
16
- Requires-Dist: kerrz_lib>=0.1.15
16
+ Requires-Dist: kerrz_lib>=0.2.0
17
17
  Dynamic: author
18
18
  Dynamic: author-email
19
19
  Dynamic: classifier
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,5 @@
1
+ import kerrz_python.wrappers
2
+ from kerrz_python.wrappers import *
3
+
4
+ __all__ = []
5
+ __all__.extend(kerrz_python.wrappers.__all__)
@@ -0,0 +1,171 @@
1
+ # This file contains wrapper code that directly calls the bindings.
2
+ import ctypes
3
+ import math
4
+ import enum
5
+
6
+ import kerrz_lib.bindings as bindings
7
+
8
+ __all__ = ["Status", "FourVector", "KerrMetric", "TraceResult", "NullGeodesic"]
9
+
10
+ PROTECTED_ATTRIBUTE_NAMES = {"lambda": "lambda_"}
11
+
12
+ REVERSE_ATTRIBUTE_NAMES = {v: k for (k, v) in PROTECTED_ATTRIBUTE_NAMES.items()}
13
+
14
+
15
+ class Status(enum.Enum):
16
+ NONE = 0
17
+ EVENT_HORIZON = 1
18
+ INTERSECTED_DISC = 2
19
+ AT_INFINITY = 3
20
+
21
+
22
+ def _reverse_protected_name(name: str) -> str:
23
+ """The opposite of _protected_name."""
24
+ return REVERSE_ATTRIBUTE_NAMES.get(name, name)
25
+
26
+
27
+ def _protected_name(name: str) -> str:
28
+ """Turns strings that are also Python keywords into things that are not."""
29
+ return PROTECTED_ATTRIBUTE_NAMES.get(name, name)
30
+
31
+
32
+ class AttributeExtender:
33
+
34
+ def __init__(self, backed_type):
35
+ self._backing_type = backed_type
36
+
37
+ def __getattr__(self, name):
38
+ this_attributes = object.__dir__(self)
39
+ if name in this_attributes:
40
+ return __getattribute__(self, name)
41
+
42
+ # Protected names
43
+ return getattr(self._backing_type, _reverse_protected_name(name))
44
+
45
+ def __dir__(self):
46
+ this_attributes = object.__dir__(self)
47
+ # Expose all of the public C bindings
48
+ return this_attributes + [
49
+ _protected_name(i) for i in dir(self._backing_type) if not i.startswith("_")
50
+ ]
51
+
52
+
53
+ class FourVector:
54
+
55
+ def __init__(self, t=0, r=1, theta=math.pi / 2.0, phi=0):
56
+ """Construct a new four-vector in the Boyer-Lindquist coordinates."""
57
+ self._vec = bindings.krz_FourVector(t=t, r=r, th=theta, ph=phi)
58
+
59
+ def __repr__(self) -> str:
60
+ return f"FourVector(t={self.t},r={self.r},theta={self.theta},phi={self.phi})"
61
+
62
+ def __eq__(self, other: "FourVector") -> str:
63
+ return (
64
+ self.t == other.t
65
+ and self.r == other.r
66
+ and self.theta == other.theta
67
+ and self.phi == other.phi
68
+ )
69
+
70
+ @property
71
+ def t(self):
72
+ return self._vec.t
73
+
74
+ @t.setter
75
+ def t(self, value: float):
76
+ self._vec.t = value
77
+
78
+ @property
79
+ def r(self):
80
+ return self._vec.r
81
+
82
+ @r.setter
83
+ def r(self, value: float):
84
+ self._vec.r = value
85
+
86
+ @property
87
+ def theta(self):
88
+ return self._vec.th
89
+
90
+ @theta.setter
91
+ def theta(self, value: float):
92
+ self._vec.th = value
93
+
94
+ @property
95
+ def phi(self):
96
+ return self._vec.ph
97
+
98
+ @phi.setter
99
+ def phi(self, value: float):
100
+ self._vec.ph = value
101
+
102
+
103
+ class KerrMetric(AttributeExtender):
104
+
105
+ def __init__(self, M: float = 1, a: float = 0.998):
106
+ self._metric = bindings.krz_kerrMetric(M, a)
107
+ super().__init__(self._metric)
108
+
109
+ def __repr__(self) -> str:
110
+ return f"KerrMetric(M={self.M},a={self.a})"
111
+
112
+
113
+ class TraceResult(AttributeExtender):
114
+
115
+ def __init__(self, result: bindings.krz_TraceResult):
116
+ self._result = result
117
+ super().__init__(self._result)
118
+
119
+ def __getattr__(self, name: str):
120
+ if name == "status":
121
+ return Status(self._result.status)
122
+ return super().__getattr__(name)
123
+
124
+ def to_xyz(self) -> tuple[float, float, float]:
125
+ x = self.r * math.sin(self.theta) * math.cos(self.phi)
126
+ y = self.r * math.sin(self.theta) * math.sin(self.phi)
127
+ z = self.r * math.cos(self.theta)
128
+ return (x, y, z)
129
+
130
+
131
+ class NullGeodesic(AttributeExtender):
132
+
133
+ def __init__(
134
+ self,
135
+ metric: KerrMetric,
136
+ x_init: FourVector = FourVector(r=1e4, theta=0.2),
137
+ alpha=1.0,
138
+ beta=2.0,
139
+ ):
140
+ self.x_init = x_init
141
+ self.metric = metric
142
+ self.alpha = alpha
143
+ self.beta = beta
144
+
145
+ # Private attributes
146
+ self._path_builder = None
147
+ self._initial_conditions = bindings.krz_InitialConditions()
148
+ bindings.krz_fromImpactParameters(
149
+ ctypes.byref(self._initial_conditions),
150
+ self.metric._metric,
151
+ self.x_init._vec,
152
+ self.alpha,
153
+ self.beta,
154
+ )
155
+
156
+ super().__init__(self._initial_conditions)
157
+
158
+ def _get_pathbuilder(self):
159
+ if self._path_builder is None:
160
+ pb = bindings.krz_PathBuilder()
161
+ bindings.krz_PathBuilder_init(
162
+ ctypes.byref(pb), self.metric._metric, self._initial_conditions
163
+ )
164
+ self._path_builder = pb
165
+ return self._path_builder
166
+
167
+ def at_mino_time(self, mino_time: float) -> TraceResult:
168
+ result = bindings.krz_at_mino_time(
169
+ ctypes.byref(self._get_pathbuilder()), mino_time
170
+ )
171
+ return TraceResult(result)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kerrz_python
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Python wrapper for kerrz. Avoid installing directly, use kerrz[py] unless you know what you are doing.
5
5
  Home-page: https://codeberg.org/astro-group/kerrz-py
6
6
  Author: Fergus Baker
@@ -13,7 +13,7 @@ Classifier: Operating System :: POSIX :: Linux
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Requires-Python: >=3.6
15
15
  Description-Content-Type: text/markdown
16
- Requires-Dist: kerrz_lib>=0.1.15
16
+ Requires-Dist: kerrz_lib>=0.2.0
17
17
  Dynamic: author
18
18
  Dynamic: author-email
19
19
  Dynamic: classifier
@@ -3,8 +3,10 @@ pyproject.toml
3
3
  setup.py
4
4
  kerrz_python/VERSION
5
5
  kerrz_python/__init__.py
6
+ kerrz_python/wrappers.py
6
7
  kerrz_python.egg-info/PKG-INFO
7
8
  kerrz_python.egg-info/SOURCES.txt
8
9
  kerrz_python.egg-info/dependency_links.txt
9
10
  kerrz_python.egg-info/requires.txt
10
- kerrz_python.egg-info/top_level.txt
11
+ kerrz_python.egg-info/top_level.txt
12
+ test/test_basics.py
@@ -0,0 +1 @@
1
+ kerrz_lib>=0.2.0
@@ -15,7 +15,7 @@ setup(
15
15
  long_description=readme,
16
16
  long_description_content_type="text/markdown",
17
17
  python_requires=">=3.6",
18
- install_requires=["kerrz_lib>=0.1.15"],
18
+ install_requires=["kerrz_lib>=0.2.0"],
19
19
  license="GPL-3.0-or-later",
20
20
  name=package_name,
21
21
  version=version,
@@ -31,5 +31,6 @@ setup(
31
31
  "Programming Language :: Python :: 3",
32
32
  ],
33
33
  include_package_data=True,
34
+ extas_require={"test": ["numpy", "pytest"]},
34
35
  package_data={package_name: ["VERSION"]},
35
36
  )
@@ -0,0 +1,24 @@
1
+ import kerrz_python as kpy
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+
5
+
6
+ def test_path_construction():
7
+ metric = kpy.KerrMetric(a=0.998)
8
+ x_init = kpy.FourVector(r=1e2)
9
+
10
+ geod = kpy.NullGeodesic(metric, x_init, beta=1e-3, alpha=6.5)
11
+
12
+ times = np.linspace(0.0, 0.75, 32)
13
+ path = [geod.at_mino_time(t).to_xyz() for t in times]
14
+
15
+ assert path[0] == (
16
+ 100.00000000000271,
17
+ 0.0,
18
+ 6.1232339957369325e-15,
19
+ )
20
+ assert path[-1] == (
21
+ -0.8615892868245583,
22
+ 0.6429150669138306,
23
+ 0.0001664544488992621,
24
+ )
@@ -1 +0,0 @@
1
- 0.1.0
@@ -1,68 +0,0 @@
1
- import dataclasses
2
- import ctypes
3
- import enum
4
- import kerrz_lib.bindings as bindings
5
-
6
-
7
- class Status(enum.Enum):
8
- NONE = 0
9
- EVENT_HORIZON = 1
10
- INTERSECTED_DISC = 2
11
- AT_INFINITY = 3
12
-
13
-
14
- @dataclasses.dataclass
15
- class GeodesicPoint:
16
- status: Status
17
- t: float
18
- r: float
19
- theta: float
20
- phi: float
21
- winding: int
22
-
23
-
24
- @dataclasses.dataclass
25
- class TurningPoints:
26
- r_0: float
27
- r_1: float
28
- theta_0: float
29
- theta_1: float
30
-
31
-
32
- class NullGeodesic:
33
-
34
- def __init__(self, path_builder: bindings.krz_PathBuilder):
35
- self._path_builder = path_builder
36
-
37
- def at_mino_time(self, mino_time) -> GeodesicPoint:
38
- result = bindings.krz_at_mino_time(ctypes.byref(self._path_builder), mino_time)
39
- return GeodesicPoint(
40
- status=result.status,
41
- t=result.t,
42
- r=result.r,
43
- theta=result.theta,
44
- phi=result.phi,
45
- winding=int(result.winding),
46
- )
47
-
48
- def turning_points(self) -> TurningPoints:
49
- p = bindings.krz_mino_time_to_turning_points(self._path_builder)
50
- return TurningPoints(theta_0=p.theta_0, theta_1=p.theta_1, r_0=p.r_0, r_1=p.r_1)
51
-
52
-
53
- def trace_impact_parameters(
54
- alpha, beta, r=1e4, theta=1.0, a=0.998, M=1.0
55
- ) -> NullGeodesic:
56
- metric = bindings.krz_kerrMetric(M, a)
57
- ic = bindings.krz_InitialConditions()
58
- x_init = bindings.krz_FourVector(t=0.0, r=r, th=theta, ph=0.0)
59
-
60
- bindings.krz_fromImpactParameters(ctypes.byref(ic), metric, x_init, alpha, beta)
61
-
62
- pb = bindings.krz_PathBuilder()
63
- bindings.krz_PathBuilder_init(ctypes.byref(pb), metric, ic)
64
-
65
- return NullGeodesic(pb)
66
-
67
-
68
- __all__ = [Status, GeodesicPoint, TurningPoints, NullGeodesic, trace_impact_parameters]
@@ -1 +0,0 @@
1
- kerrz_lib>=0.1.15
File without changes
File without changes