Skip to content

Commit 6590c85

Browse files
committed
Copy over calculator code from PlasmaPy
1 parent 3c9e60f commit 6590c85

File tree

6 files changed

+1069
-1
lines changed

6 files changed

+1069
-1
lines changed
Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,59 @@
1+
"""
2+
Script and utilities to launch the plasma calculator.
3+
"""
4+
5+
__all__ = ["main"]
6+
7+
import argparse
8+
import pathlib
9+
import shlex
10+
import subprocess
11+
12+
_description = """
13+
Plasma calculator is a tool that opens a page in a web browser for
14+
interactive calculation of plasma parameters.
15+
16+
This tool is currently in the prototype stage and is expected to change in
17+
the future. Please raise an issue at the following link to provide suggestions
18+
and feedback: https://github.com/PlasmaPy/PlasmaPy/issues/new
19+
"""
20+
21+
122
def main() -> None:
2-
print("Hello from plasmapy-calculator!")
23+
"""
24+
Stub function for command line tool that launches the plasma calculator notebook.
25+
"""
26+
parser = argparse.ArgumentParser(description=_description)
27+
parser.add_argument(
28+
"--port", type=int, default=8866, help="Port to run the notebook"
29+
)
30+
parser.add_argument(
31+
"--dark", action="store_true", help="Turn on dark mode, reduces eye strain"
32+
)
33+
parser.add_argument(
34+
"--no-browser", action="store_true", help="Do not open the browser"
35+
)
36+
37+
module_path = pathlib.Path(__file__).parent.absolute()
38+
notebook_path = module_path / "plasma_calculator.ipynb"
39+
favicon_path = module_path / "favicon.ico"
40+
41+
args = parser.parse_args()
42+
theme = "dark" if args.dark else "light"
43+
no_browser = "--no-browser" if args.no_browser else ""
44+
45+
command = [
46+
"voila",
47+
notebook_path,
48+
f"--port={args.port}",
49+
f"--theme={theme}",
50+
f"--VoilaConfiguration.file_whitelist={favicon_path}",
51+
]
52+
if no_browser:
53+
command.append(no_browser)
54+
55+
try:
56+
subprocess.call(command) # noqa: S603
57+
except KeyboardInterrupt:
58+
# We'll need to switch from print() to using logging library
59+
print("Stopping calculator! Bye") # noqa: T201
87.9 KB
Binary file not shown.
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
"""
2+
Collection of private functions to load properties and construct widgets.
3+
"""
4+
5+
__all__: list[str] = []
6+
7+
import json
8+
import warnings
9+
from pathlib import Path
10+
11+
import astropy.units as u
12+
from ipywidgets import widgets
13+
14+
from plasmapy.utils.calculator.widget_helpers import (
15+
_calculate_button,
16+
_CheckBox,
17+
_clear_button,
18+
_create_label,
19+
_create_widget,
20+
_FloatBox,
21+
_FunctionInfo,
22+
_IonBox,
23+
_ParticleBox,
24+
_process_queue,
25+
)
26+
27+
warnings.filterwarnings(
28+
action="ignore",
29+
message="Passing unrecognized arguments",
30+
category=DeprecationWarning,
31+
) # see issue 2370 for a deprecation warning from traitlets
32+
33+
LIGHT_BLUE = "#00BFD8"
34+
"""
35+
LIGHT_BLUE: Constant for light blue color 00BFD8
36+
"""
37+
LIGHT_GRAY = "#A9A9A9"
38+
"""
39+
LIGHT_GRAY: Constant for light gray color A9A9A9
40+
"""
41+
42+
grid_data = [
43+
[
44+
_create_label("Parameter", color=LIGHT_BLUE),
45+
_create_label("Value", color=LIGHT_BLUE),
46+
_create_label("Unit", color=LIGHT_BLUE),
47+
],
48+
[
49+
_create_label("B - Magnetic Field Magnitude:"),
50+
*_create_widget(
51+
_FloatBox,
52+
property_name="B",
53+
unit=u.T,
54+
opts=[u.T, u.G, u.uG],
55+
),
56+
],
57+
[
58+
_create_label("Particle:"),
59+
_create_widget(
60+
_ParticleBox,
61+
property_name="particle",
62+
property_alias="particle_type",
63+
placeholder="Enter particle e.g. neutron,He",
64+
),
65+
],
66+
[
67+
_create_label("Ion:"),
68+
_create_widget(
69+
_IonBox,
70+
property_name="ion",
71+
property_alias="ion_type",
72+
placeholder="Enter ion e.g. He 2+",
73+
),
74+
],
75+
[
76+
_create_label("Convert to Hertz:"),
77+
_create_widget(_CheckBox, property_name="to_hz"),
78+
],
79+
[
80+
_create_label("_" * 20, color=LIGHT_BLUE),
81+
_create_label("Density Number"),
82+
_create_label("_" * 20, color=LIGHT_BLUE),
83+
],
84+
[
85+
_create_label("n - Standard Density Number:"),
86+
*_create_widget(
87+
_FloatBox,
88+
property_name="n",
89+
unit=u.m**-3,
90+
opts=[u.m**-3, u.cm**-3, u.mm**-3],
91+
),
92+
],
93+
[
94+
_create_label("n<sub>e</sub> - Electron Density Number:"),
95+
*_create_widget(
96+
_FloatBox,
97+
property_name="n_e",
98+
unit=u.m**-3,
99+
opts=[u.m**-3, u.cm**-3, u.mm**-3],
100+
),
101+
],
102+
[
103+
_create_label("n<sub>i</sub> - Ion Number Density:"),
104+
*_create_widget(
105+
_FloatBox,
106+
property_name="n_i",
107+
unit=u.m**-3,
108+
opts=[u.m**-3, u.cm**-3, u.mm**-3],
109+
),
110+
],
111+
[
112+
_create_label("_" * 20, color=LIGHT_BLUE),
113+
_create_label("Temperature"),
114+
_create_label("_" * 20, color=LIGHT_BLUE),
115+
],
116+
[
117+
_create_label("T - Standard Temperature:"),
118+
_create_widget(_FloatBox, property_name="T", min=0, unit=u.K),
119+
_create_label("K", color=LIGHT_GRAY),
120+
],
121+
[
122+
_create_label("T<sub>e</sub> - Electron Temperature:"),
123+
_create_widget(_FloatBox, property_name="T_e", min=0, unit=u.K),
124+
_create_label("K", color=LIGHT_GRAY),
125+
],
126+
[
127+
_create_label("T<sub>i</sub> - Ion Temperature:"),
128+
_create_widget(_FloatBox, property_name="T_i", min=0, unit=u.K),
129+
_create_label("K", color=LIGHT_GRAY),
130+
],
131+
]
132+
"""
133+
grid_data: Contains widgets layout for input parameters
134+
"""
135+
136+
137+
def _create_interactive_layout():
138+
"""
139+
Interactive grid layout for input parameters populated in grid_data.
140+
"""
141+
grid = widgets.GridspecLayout(18, 3)
142+
grid.layout.margin = "10px"
143+
144+
for i, row in enumerate(grid_data):
145+
for j, cell in enumerate(row):
146+
grid[i, j] = cell
147+
148+
grid[-1, 0] = _calculate_button
149+
grid[-1, 1] = _clear_button
150+
return grid
151+
152+
153+
def _create_output_layout():
154+
"""
155+
Tab layout for output parameters, populated from
156+
``properties_metadata.json``.
157+
"""
158+
app = widgets.Tab()
159+
children = []
160+
161+
properties_metadata = Path("properties_metadata.json")
162+
163+
with properties_metadata.open() as f:
164+
data = json.load(f)
165+
166+
for i, title in enumerate(data):
167+
grid_layout = widgets.GridspecLayout(10, 2, width="100%")
168+
for j, prop in enumerate(data[title]):
169+
fn = _FunctionInfo(prop["module_name"], prop["function_name"])
170+
if "spec_combo" in prop:
171+
for spec_combo in prop["spec_combo"]:
172+
fn.add_combo(spec_combo)
173+
grid_layout[j, 0] = _create_label(prop["function_name"] + ":")
174+
grid_layout[j, 1] = fn.get_output_widget()
175+
_process_queue.append(fn)
176+
children.append(grid_layout)
177+
app.set_title(i, title)
178+
app.children = children
179+
180+
return app
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Calculate plasma parameters"
8+
]
9+
},
10+
{
11+
"cell_type": "code",
12+
"execution_count": null,
13+
"metadata": {},
14+
"outputs": [],
15+
"source": [
16+
"%matplotlib inline"
17+
]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": null,
22+
"metadata": {},
23+
"outputs": [],
24+
"source": [
25+
"import plasmapy.utils.calculator.main_interface as pc"
26+
]
27+
},
28+
{
29+
"cell_type": "code",
30+
"execution_count": null,
31+
"metadata": {},
32+
"outputs": [],
33+
"source": [
34+
"pc._create_interactive_layout()"
35+
]
36+
},
37+
{
38+
"cell_type": "code",
39+
"execution_count": null,
40+
"metadata": {},
41+
"outputs": [],
42+
"source": [
43+
"pc._create_output_layout()"
44+
]
45+
}
46+
],
47+
"metadata": {
48+
"interpreter": {
49+
"hash": "a1fafe92487e6823dbe852514612f53ec74aa37737c5bc2c8ee36ad7d3fbdcd4"
50+
},
51+
"kernelspec": {
52+
"display_name": "Python 3.9.7 64-bit (windows store)",
53+
"name": "python3"
54+
},
55+
"language_info": {
56+
"codemirror_mode": {
57+
"name": "ipython",
58+
"version": 3
59+
},
60+
"file_extension": ".py",
61+
"mimetype": "text/x-python",
62+
"name": "python",
63+
"nbconvert_exporter": "python",
64+
"pygments_lexer": "ipython3",
65+
"version": "3.9.7"
66+
}
67+
},
68+
"nbformat": 4,
69+
"nbformat_minor": 4
70+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"Speed":[
3+
{
4+
"function_name":"Alfven_speed",
5+
"module_name":"plasmapy.formulary"
6+
},
7+
{
8+
"function_name":"thermal_speed",
9+
"module_name":"plasmapy.formulary"
10+
},
11+
{
12+
"function_name":"ion_sound_speed",
13+
"module_name":"plasmapy.formulary"
14+
}
15+
],
16+
"Length":[
17+
{
18+
"function_name":"inertial_length",
19+
"module_name":"plasmapy.formulary"
20+
},
21+
{
22+
"function_name":"gyroradius",
23+
"module_name":"plasmapy.formulary",
24+
"spec_combo":[
25+
["B","particle","Vperp"],
26+
["B","particle","T"]
27+
]
28+
},
29+
{
30+
"function_name":"Debye_length",
31+
"module_name":"plasmapy.formulary"
32+
}
33+
],
34+
"Frequency":[
35+
{
36+
"function_name":"gyrofrequency",
37+
"module_name":"plasmapy.formulary"
38+
},
39+
{
40+
"function_name":"plasma_frequency",
41+
"module_name":"plasmapy.formulary"
42+
},
43+
{
44+
"function_name":"lower_hybrid_frequency",
45+
"module_name":"plasmapy.formulary"
46+
},
47+
{
48+
"function_name":"upper_hybrid_frequency",
49+
"module_name":"plasmapy.formulary"
50+
}
51+
],
52+
"Dimensionless numbers":[
53+
{
54+
"function_name":"Hall_parameter",
55+
"module_name":"plasmapy.formulary"
56+
},
57+
{
58+
"function_name":"Debye_number",
59+
"module_name":"plasmapy.formulary"
60+
}
61+
],
62+
"Magnetics":[
63+
{
64+
"function_name":"magnetic_pressure",
65+
"module_name":"plasmapy.formulary"
66+
},
67+
{
68+
"function_name":"magnetic_energy_density",
69+
"module_name":"plasmapy.formulary"
70+
},
71+
{
72+
"function_name":"Bohm_diffusion",
73+
"module_name":"plasmapy.formulary"
74+
}
75+
]
76+
77+
}

0 commit comments

Comments
 (0)