physkit 0.1.17__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.
physkit/conversions.py ADDED
@@ -0,0 +1,124 @@
1
+ # Physkit - A Python toolkit for constants, unit conversions, and equations.
2
+ # Copyright (C) 2024 sapphimars
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+
17
+ """
18
+ conversions.py
19
+
20
+ Convenience functions for unit conversions, using the shared Pint
21
+ UnitRegistry from config.py.
22
+
23
+ The user-facing API only takes/returns floats and strings:
24
+ - convert_unit(value, from_unit, to_unit)
25
+ - convert_to_base_units(value, from_unit)
26
+ - convert_unit_system(value, from_unit, system_name="cgs")
27
+
28
+ Under the hood, we use Pint's UnitRegistry (from config.py) to do
29
+ all conversions. The user never interacts with Pint objects.
30
+ """
31
+
32
+ import pint
33
+ from .config import get_ureg # , set_default
34
+
35
+
36
+ def convert_unit(value: float, from_unit: str, to_unit: str) -> float:
37
+ """
38
+ Convert a numeric value from `from_unit` to `to_unit`.
39
+
40
+ Args:
41
+ value (float): The numeric value to convert.
42
+ from_unit (str): The current unit of `value`.
43
+ to_unit (str): The target unit.
44
+
45
+ Returns:
46
+ float: The numeric value converted to the `to_unit`.
47
+
48
+ Example:
49
+ convert_unit(5, "erg", "J") -> 5e-7
50
+ convert_unit(1, "meter", "foot") -> ~3.28084
51
+ """
52
+ ureg = get_ureg()
53
+ quantity = value * ureg(from_unit)
54
+ converted = quantity.to(to_unit)
55
+ return converted.magnitude
56
+
57
+
58
+ def convert_to_base_units(value: float, from_unit: str) -> tuple[float, str]:
59
+ """
60
+ Convert a numeric value from `from_unit` to the *default base units*
61
+ of the shared UnitRegistry. Typically this is SI base units unless
62
+ you've called set_default_system(...) to change it.
63
+
64
+ Args:
65
+ value (float): input value
66
+ from_unit (str): input unit
67
+
68
+ Returns:
69
+ tuple[float, str]: output value and its unit
70
+
71
+ Example:
72
+ # If default system is SI:
73
+ convert_to_base_units(39.37, "inch") -> ~1.0 (meter)
74
+ """
75
+ ureg = get_ureg()
76
+ quantity = value * ureg(from_unit)
77
+ base_converted = quantity.to_base_units()
78
+ return base_converted.magnitude, f"{base_converted.units:~}"
79
+
80
+
81
+ def convert_unit_system(
82
+ value: float, from_unit: str, system_name: str = "cgs"
83
+ ) -> tuple[float, str]:
84
+ """
85
+ Convert a numeric value from `from_unit` in the shared default registry
86
+ to the base units of a different unit system (e.g., 'cgs', 'imperial', etc.)
87
+ without changing the global default system.
88
+
89
+ Creates a temporary pint.UnitRegistry with the specified system,
90
+ converts `value` to base SI, then interprets that SI quantity in
91
+ the temporary system's base units.
92
+
93
+ Args:
94
+ value (float): input value
95
+ from_unit (str): input unit
96
+ system_name (str, optional): output unit system. Defaults to "cgs".
97
+
98
+ Returns:
99
+ tuple[float, str]: output value and its unit
100
+
101
+ Example:
102
+ # Suppose global default is SI
103
+ # We convert 1 meter (in SI) to the base units of cgs -> centimeter
104
+ convert_unit_system(1, "meter", system_name="cgs") -> 100.0 (centimeter)
105
+ """
106
+
107
+ # Convert the input to base SI using the shared registry
108
+ shared_ureg = get_ureg()
109
+ si_quantity = (value * shared_ureg(from_unit)).to_base_units()
110
+
111
+ # Create a temporary registry in the chosen system
112
+ temp_ureg = pint.UnitRegistry(system=system_name)
113
+
114
+ # Build the quantity in the temporary registry
115
+
116
+ magnitude_si = si_quantity.magnitude
117
+ unit_si_str = str(si_quantity.u)
118
+
119
+ new_qty_in_temp = magnitude_si * temp_ureg(unit_si_str)
120
+
121
+ # Convert to the base units of the new system
122
+ base_in_temp_system = new_qty_in_temp.to_base_units()
123
+
124
+ return base_in_temp_system.magnitude, f"{base_in_temp_system.units:~}"
@@ -0,0 +1,33 @@
1
+ # Physkit - A Python toolkit for constants, unit conversions, and equations.
2
+ # Copyright (C) 2024 sapphimars
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+
17
+
18
+ def define_custom_units(ureg):
19
+ """
20
+ Define custom units that Pint doesn't include by default.
21
+ Call this AFTER creating the UnitRegistry in config.py.
22
+
23
+ Args:
24
+ ureg (pint.UnitRegistry): global ureg object from config.py
25
+ """
26
+ # Jansky (Jy)
27
+ ureg.define("jansky = 1e-26 watt / meter^2 / hertz = Jy")
28
+
29
+ # Solar luminosity: 1 L_sun = 3.828e26 W
30
+ ureg.define("solar_luminosity = 3.828e26 watt = L_sun")
31
+
32
+ # Solar mass: 1 M_sun = 1.98847e30 kg
33
+ ureg.define("solar_mass = 1.98847e30 kg = M_sun")
physkit/equations.py ADDED
@@ -0,0 +1,117 @@
1
+ # Physkit - A Python toolkit for constants, unit conversions, and equations.
2
+ # Copyright (C) 2024 sapphimars
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+
17
+
18
+ from .config import get_ureg
19
+ from .constants import constants
20
+
21
+
22
+ class Equations:
23
+
24
+ @staticmethod
25
+ def gravitational_radius(
26
+ mass_value: float, mass_unit: str = "kg", out_unit: str = "m"
27
+ ) -> tuple[float, str]:
28
+ """
29
+ Compute the gravitational radius for a given mass.
30
+ r_g = G * M / c^2
31
+
32
+ Args:
33
+ mass_value (float): input mass
34
+ mass_unit (str, optional): unit for input mass. Defaults to "kg".
35
+ out_unit (str, optional): unit for output radius. Defaults to "m".
36
+
37
+ Returns:
38
+ (float, str): output radius and its unit
39
+ """
40
+
41
+ # Get the shared registry
42
+ ureg = get_ureg()
43
+
44
+ # Get pint Quantity for mass
45
+ mass_qty = mass_value * ureg(mass_unit)
46
+
47
+ # Retrieve constants from the constants module
48
+ G_val, G_unit = constants.G
49
+ c_val, c_unit = constants.c
50
+
51
+ # Get Pint Quantities for constants
52
+ G_qty = G_val * ureg(G_unit)
53
+ c_qty = c_val * ureg(c_unit)
54
+
55
+ r_g_qty = G_qty * mass_qty / (c_qty**2)
56
+
57
+ # Convert to output unit
58
+ r_g_converted = r_g_qty.to(out_unit)
59
+
60
+ return r_g_converted.magnitude, f"{r_g_converted.units:~}"
61
+
62
+ @staticmethod
63
+ def schwartzschild_radius(
64
+ mass_value: float, mass_unit: str = "kg", out_unit: str = "m"
65
+ ) -> tuple[float, str]:
66
+ """
67
+ Compute the Schwartzschild radius for a given mass.
68
+
69
+ Args:
70
+ mass_value (float): input mass
71
+ mass_unit (str, optional): unit for input mass. Defaults to "kg".
72
+ out_unit (str, optional): unit for output radius. Defaults to "m".
73
+
74
+ Returns:
75
+ tuple[float, str]: output radius and its unit
76
+ """
77
+ mag, unit_str = Equations.gravitational_radius(mass_value, mass_unit, out_unit)
78
+ mag *= 2
79
+ return mag, unit_str
80
+
81
+ @staticmethod
82
+ def eddington_luminosity(
83
+ mass_value: float, mass_unit: str = "kg", out_unit: str = "W"
84
+ ) -> tuple[float, str]:
85
+ """
86
+ Compute the Eddington luminosity for a given mass.
87
+
88
+ Args:
89
+ mass_value (float): input mass
90
+ mass_unit (str, optional): unit for input mass. Defaults to "kg".
91
+ out_unit (str, optional): unit for output luminosity. Defaults to "W".
92
+
93
+ Returns:
94
+ tuple[float, str]: output luminosity and its unit
95
+ """
96
+ ureg = get_ureg()
97
+ mass_qty = mass_value * ureg(mass_unit)
98
+
99
+ pi, _ = constants.pi
100
+ G_val, G_unit = constants.G # e.g. (6.6743e-11, "m^3 / kg / s^2")
101
+ c_val, c_unit = constants.c # e.g. (3.0e8, "m / s")
102
+ m_p_val, m_p_unit = constants.m_p
103
+ sigma_T_val, sigma_T_unit = constants.sigma_T
104
+
105
+ G_qty = G_val * ureg(G_unit)
106
+ c_qty = c_val * ureg(c_unit)
107
+ m_p_qty = m_p_val * ureg(m_p_unit)
108
+ sigma_T_qty = sigma_T_val * ureg(sigma_T_unit)
109
+
110
+ L_edd_qty = 4 * pi * G_qty * m_p_qty * c_qty * mass_qty / sigma_T_qty
111
+
112
+ L_edd_converted = L_edd_qty.to(out_unit)
113
+
114
+ return L_edd_converted.magnitude, f"{L_edd_converted.units:~}"
115
+
116
+
117
+ equations = Equations()
physkit/plot_styler.py ADDED
@@ -0,0 +1,115 @@
1
+ # Physkit - A Python toolkit for constants, unit conversions, and equations.
2
+ # Copyright (C) 2024 sapphimars
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+
17
+
18
+ import matplotlib.pyplot as plt
19
+
20
+
21
+ def plot_styler(
22
+ xdata,
23
+ ydata,
24
+ title: str = None,
25
+ xlabel: str = None,
26
+ ylabel: str = None,
27
+ xlims: list = None,
28
+ ylims: list = None,
29
+ color: str = None,
30
+ label: str = None,
31
+ marker: str = None,
32
+ line: str = None,
33
+ markersize: int = 4,
34
+ linewidth: float = None,
35
+ yerr: list = None,
36
+ minorgrid: bool = False,
37
+ loglog: bool = False,
38
+ ax=None,
39
+ scatter: bool = False,
40
+ ) -> None:
41
+ """
42
+ Helper function which adds styling to each plot in the way we want.
43
+
44
+ Args:
45
+ xdata (list or np.ndarray),
46
+ ydata (list or np.ndarray),
47
+ title (str optional),
48
+ xlabel (str optional),
49
+ ylabel (str optional),
50
+ xlims (list optional),
51
+ ylims (list optional),
52
+ color (str optional),
53
+ label (str optional),
54
+ marker (str optional),
55
+ line (str optional)
56
+ markersize (int default = 4),
57
+ linewidth (float optional),
58
+ yerr (np.ndarray optional),
59
+ minorgrid (bool default = False),
60
+ loglog (bool default = False),
61
+ ax (matplotlib.axes.Axes optional),
62
+ scatter (bool default = False),
63
+ """
64
+
65
+ if ax is None:
66
+ ax = plt # Default to using the global plt object if no axis
67
+
68
+ if loglog:
69
+ ax.set_xscale("log")
70
+ ax.set_yscale("log")
71
+
72
+ if yerr is not None:
73
+ ax.errorbar(
74
+ xdata,
75
+ ydata,
76
+ fmt=marker,
77
+ yerr=yerr,
78
+ color=color,
79
+ markersize=markersize,
80
+ label=label,
81
+ linewidth=linewidth,
82
+ )
83
+ elif scatter:
84
+ ax.scatter(xdata, ydata, marker=marker, color=color, label=label)
85
+ else:
86
+ ax.plot(
87
+ xdata,
88
+ ydata,
89
+ marker=marker,
90
+ color=color,
91
+ markersize=markersize,
92
+ label=label,
93
+ linewidth=linewidth,
94
+ )
95
+
96
+ if title:
97
+ ax.set_title(title, fontsize=15)
98
+ if xlabel:
99
+ ax.set_xlabel(xlabel, fontsize=12)
100
+ if ylabel:
101
+ ax.set_ylabel(ylabel, fontsize=12)
102
+ if xlims:
103
+ ax.set_xlim(xlims)
104
+ if ylims:
105
+ ax.set_ylim(ylims)
106
+
107
+ ax.grid(which="major", color="#CCCCCC")
108
+ if minorgrid:
109
+ ax.minorticks_on()
110
+ ax.grid(which="minor", color="#EEEEEE", linestyle=":")
111
+
112
+ ax.set_axisbelow(True)
113
+
114
+ if label:
115
+ ax.legend()
@@ -0,0 +1,169 @@
1
+ Metadata-Version: 2.1
2
+ Name: physkit
3
+ Version: 0.1.17
4
+ Summary: A Python toolkit providing physical constants, unit conversions, and plotting styles
5
+ Keywords: physics,units,pint,plotting
6
+ Author: sapphimars
7
+ License: GPL-3.0-or-later
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
10
+ Classifier: Operating System :: OS Independent
11
+ Project-URL: Homepage, https://github.com/sapphimars/physkit
12
+ Project-URL: Repository, https://github.com/sapphimars/physkit
13
+ Project-URL: Bug Tracker, https://github.com/sapphimars/physkit/issues
14
+ Requires-Python: >=3.12
15
+ Requires-Dist: pint>=0.24.4
16
+ Requires-Dist: matplotlib>=3.10.0
17
+ Requires-Dist: pdm-backend>=2.4.3
18
+ Description-Content-Type: text/markdown
19
+
20
+ # Physkit - A Python toolkit for constants, unit conversions, and equations
21
+
22
+ [![Build Status](https://github.com/sapphimars/physkit/actions/workflows/test.yml/badge.svg)](https://github.com/sapphimars/physkit/actions/workflows/test.yml)
23
+ [![PyPI Version](https://img.shields.io/pypi/v/physkit)](https://pypi.org/project/physkit/)
24
+ [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
25
+
26
+ **Physkit** is a Python library for performing scientific computations, unit conversions, and working with physical constants and equations.
27
+ It provides tools for astrophysical and physical calculations, supporting multiple unit systems and CLI functionalities.
28
+
29
+ <figure>
30
+ <img src="https://github.com/sapphimars/physkit/blob/main/assets/physkit_icon_wide.png?raw=true" alt="drawing" />
31
+ </figure>
32
+
33
+ ###### Icon created by [astroastra](https://github.com/astroastrastudio)
34
+
35
+ ---
36
+
37
+ ## **License**
38
+
39
+ This project is licensed under the terms of the **GNU General Public License v3.0**.
40
+ See the [LICENSE](https://github.com/sapphimars/physkit/blob/main/LICENSE) file for details.
41
+
42
+ Copyright (C) 2024 [sapphimars](https://github.com/sapphimars)
43
+
44
+ ---
45
+
46
+ ### **Third-Party Licenses**
47
+
48
+ This project makes use of the following third-party libraries:
49
+
50
+ - **[Matplotlib](https://matplotlib.org/)** - Licensed under the Matplotlib License Agreement. See [licenses/LICENSE-MATPLOTLIB.txt](https://github.com/sapphimars/physkit/blob/main/licenses/LICENSE-MATPLOTLIB.txt) or [directly on their repository](https://github.com/matplotlib/matplotlib/tree/main/LICENSE).
51
+ - **[Pint](https://github.com/hgrecco/pint)** - Licensed under the BSD 3-Clause License. See [licenses/LICENSE-PINT.txt](https://github.com/sapphimars/physkit/blob/main/licenses/LICENSE-PINT.txt) or [directly on their repository](https://github.com/hgrecco/pint/blob/master/LICENSE).
52
+
53
+ Note: Third-party libraries included in this project are licensed under their respective terms. See the `licenses/` directory for full details.
54
+
55
+ ---
56
+
57
+ ## **Installation**
58
+
59
+ ### **Requirements**
60
+
61
+ - Python **3.12** or higher
62
+ - Dependencies:
63
+ - **Matplotlib** >= 3.5
64
+ - **Pint** >= 0.20
65
+
66
+ ---
67
+
68
+ ### **Install via pip**
69
+ ```bash
70
+ pip install physkit
71
+ ```
72
+
73
+ ---
74
+
75
+ ### **For Development**
76
+ ```bash
77
+ pdm install
78
+ ```
79
+
80
+ To install test dependencies:
81
+ ```bash
82
+ pdm install -G test
83
+ ```
84
+
85
+ ---
86
+
87
+ ## **Usage Examples**
88
+
89
+ ### **Access Constants**
90
+ ```python
91
+ import physkit as pk
92
+ from physkit.constants import constants as csts
93
+
94
+ print(csts.G) # Gravitational constant in SI
95
+ pk.set_default("cgs")
96
+ print(csts.G) # Gravitational constant in CGS
97
+ ```
98
+
99
+ ---
100
+
101
+ ### **Unit Conversion**
102
+ ```python
103
+ from physkit.conversions import convert_unit
104
+
105
+ result = convert_unit(1, 'm', 'cm')
106
+ print(result) # Outputs: 100.0
107
+ ```
108
+
109
+ ---
110
+
111
+ ### **Equations**
112
+ ```python
113
+ from physkit.equations import equations
114
+
115
+ # Default units are SI. Specify other units explicitly, like so:
116
+ mass = 1.0 # Solar mass
117
+ radius = equations.gravitational_radius(mass, 'M_sun', 'km') # input mass in solar masses
118
+ print(radius) # Gravitational radius in km
119
+ ```
120
+
121
+ ---
122
+ ### **Plot Styling**
123
+ This is just a quick way to make good looking plots simply.
124
+ ```python
125
+ import physkit as pk
126
+ import matplotlib.pyplot as plt
127
+
128
+ x_data = [...] # Example data for x and y
129
+ y_data = [...]
130
+
131
+ fig, ax = plt.subplots()
132
+ pk.plot_styler(x_data, y_data, ax=ax, title="test",
133
+ ylabel="y label", xlabel="x label", loglog=True)
134
+ plt.show()
135
+
136
+ ```
137
+ ---
138
+ ### **Command Line Interface (CLI)**
139
+ ```bash
140
+ physkit constant G --system cgs
141
+ ```
142
+ ```bash
143
+ physkit convert 1 m cm
144
+ ```
145
+
146
+ ---
147
+
148
+ ## **Contributing**
149
+
150
+ Contributions are welcome!
151
+
152
+ 1. Fork the repository.
153
+ 2. Create a new branch (`git checkout -b feature-name`).
154
+ 3. Commit changes (`git commit -m "Add new feature"`).
155
+ 4. Push to your branch (`git push origin feature-name`).
156
+ 5. Open a Pull Request.
157
+
158
+ ---
159
+
160
+ ## **Issues**
161
+
162
+ If you encounter any issues or have suggestions, feel free to open an issue on [GitHub](https://github.com/sapphimars/physkit/issues).
163
+
164
+ ---
165
+
166
+ ## **Contact**
167
+
168
+ For inquiries, contact me via GitHub: [sapphimars](https://github.com/sapphimars)
169
+
@@ -0,0 +1,13 @@
1
+ physkit-0.1.17.dist-info/METADATA,sha256=iE5KzzzjHS7CGRQmQRdna_jSPl8uR4QYNERyRD7UgVQ,4851
2
+ physkit-0.1.17.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ physkit-0.1.17.dist-info/entry_points.txt,sha256=GOPyeWV9vsHwYs8FvWvR1kLPnIC6_o1kuRxjM_2dZ9M,61
4
+ physkit-0.1.17.dist-info/licenses/LICENSE,sha256=5X8cMguM-HmKfS_4Om-eBqM6A1hfbgZf6pfx2G24QFI,35150
5
+ physkit/__init__.py,sha256=Kjhw8VH2KZ8Rpz2leY2oR1MiJ7zY98hIma0OvxV7DSE,1324
6
+ physkit/cli.py,sha256=sUGnTyHKhuqhzfqyxmosA7crPmeLW9ofp2psY0lICwE,3130
7
+ physkit/config.py,sha256=wQaZGIFsjEVWER0Oi5K-vmbirBrsqrlaIeXU_Z6q-eo,1282
8
+ physkit/constants.py,sha256=YpsRAjOMcEynREJGYLI0Gefbus6hrCA2N0Mv7XZ5r8w,14868
9
+ physkit/conversions.py,sha256=Q2Vp5UhLEuiHUFU-UviY-APuzzn2JJUkKCad8L0qb14,4203
10
+ physkit/custom_units.py,sha256=769knoVgg5FOlChwoFp7BzSVB75DW0AS-lZ4w58Whkk,1277
11
+ physkit/equations.py,sha256=hMFuV4SYXXcsN_f3xjNs4ZvYFKialv11myMkkGC-An0,3881
12
+ physkit/plot_styler.py,sha256=ZAgmW7k3DjTsIHnIzk2tKawWBOSAp6IglKx5YUAa-Bc,3138
13
+ physkit-0.1.17.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: pdm-backend (2.4.3)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,5 @@
1
+ [console_scripts]
2
+ physkit = physkit.cli:main
3
+
4
+ [gui_scripts]
5
+