We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ENH: missing def for poloidal/toroidal magnetic fields in polar geometry
### Bug report

**Bug summary**

Poloidal and toroidal magnetic fields definitions in polar geometry are missing, see https://github.com/yt-project/yt/blob/e16331088faf7296672ce9d1987a09d036f458ea/yt/fields/magnetic_field.py#L87-L149


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `yt/fields/magnetic_field.py`
Content:
```
1 import numpy as np
2 
3 from yt.fields.derived_field import ValidateParameter
4 from yt.units import dimensions
5 from yt.units.yt_array import ustack  # type: ignore
6 from yt.utilities.math_utils import get_sph_phi_component, get_sph_theta_component
7 
8 from .field_plugin_registry import register_field_plugin
9 
10 cgs_normalizations = {"gaussian": 4.0 * np.pi, "lorentz_heaviside": 1.0}
11 
12 
13 def get_magnetic_normalization(key: str) -> float:
14     if key not in cgs_normalizations:
15         raise ValueError(
16             "Unknown magnetic normalization convention. "
17             f"Got {key!r}, expected one of {tuple(cgs_normalizations)}"
18         )
19     return cgs_normalizations[key]
20 
21 
22 @register_field_plugin
23 def setup_magnetic_field_fields(registry, ftype="gas", slice_info=None):
24     ds = registry.ds
25 
26     unit_system = ds.unit_system
27     pc = registry.ds.units.physical_constants
28 
29     axis_names = registry.ds.coordinates.axis_order
30 
31     if (ftype, f"magnetic_field_{axis_names[0]}") not in registry:
32         return
33 
34     u = registry[ftype, f"magnetic_field_{axis_names[0]}"].units
35 
36     def mag_factors(dims):
37         if dims == dimensions.magnetic_field_cgs:
38             return getattr(ds, "_magnetic_factor", 4.0 * np.pi)
39         elif dims == dimensions.magnetic_field_mks:
40             return ds.units.physical_constants.mu_0
41 
42     def _magnetic_field_strength(field, data):
43         xm = f"relative_magnetic_field_{axis_names[0]}"
44         ym = f"relative_magnetic_field_{axis_names[1]}"
45         zm = f"relative_magnetic_field_{axis_names[2]}"
46 
47         B2 = (data[ftype, xm]) ** 2 + (data[ftype, ym]) ** 2 + (data[ftype, zm]) ** 2
48 
49         return np.sqrt(B2)
50 
51     registry.add_field(
52         (ftype, "magnetic_field_strength"),
53         sampling_type="local",
54         function=_magnetic_field_strength,
55         validators=[ValidateParameter("bulk_magnetic_field")],
56         units=u,
57     )
58 
59     def _magnetic_energy_density(field, data):
60         B = data[ftype, "magnetic_field_strength"]
61         return 0.5 * B * B / mag_factors(B.units.dimensions)
62 
63     registry.add_field(
64         (ftype, "magnetic_energy_density"),
65         sampling_type="local",
66         function=_magnetic_energy_density,
67         units=unit_system["pressure"],
68     )
69 
70     def _plasma_beta(field, data):
71         return data[ftype, "pressure"] / data[ftype, "magnetic_energy_density"]
72 
73     registry.add_field(
74         (ftype, "plasma_beta"), sampling_type="local", function=_plasma_beta, units=""
75     )
76 
77     def _magnetic_pressure(field, data):
78         return data[ftype, "magnetic_energy_density"]
79 
80     registry.add_field(
81         (ftype, "magnetic_pressure"),
82         sampling_type="local",
83         function=_magnetic_pressure,
84         units=unit_system["pressure"],
85     )
86 
87     if registry.ds.geometry == "cartesian":
88 
89         def _magnetic_field_poloidal(field, data):
90             normal = data.get_field_parameter("normal")
91 
92             Bfields = ustack(
93                 [
94                     data[ftype, "relative_magnetic_field_x"],
95                     data[ftype, "relative_magnetic_field_y"],
96                     data[ftype, "relative_magnetic_field_z"],
97                 ]
98             )
99 
100             theta = data["index", "spherical_theta"]
101             phi = data["index", "spherical_phi"]
102 
103             return get_sph_theta_component(Bfields, theta, phi, normal)
104 
105         def _magnetic_field_toroidal(field, data):
106             normal = data.get_field_parameter("normal")
107 
108             Bfields = ustack(
109                 [
110                     data[ftype, "relative_magnetic_field_x"],
111                     data[ftype, "relative_magnetic_field_y"],
112                     data[ftype, "relative_magnetic_field_z"],
113                 ]
114             )
115 
116             phi = data["index", "spherical_phi"]
117             return get_sph_phi_component(Bfields, phi, normal)
118 
119     elif registry.ds.geometry == "cylindrical":
120 
121         def _magnetic_field_poloidal(field, data):
122             bm = data.get_field_parameter("bulk_magnetic_field")
123             r = data["index", "r"]
124             z = data["index", "z"]
125             d = np.sqrt(r * r + z * z)
126             rax = axis_names.find("r")
127             zax = axis_names.find("z")
128             return (data[ftype, "magnetic_field_r"] - bm[rax]) * (r / d) + (
129                 data[ftype, "magnetic_field_z"] - bm[zax]
130             ) * (z / d)
131 
132         def _magnetic_field_toroidal(field, data):
133             ax = axis_names.find("theta")
134             bm = data.get_field_parameter("bulk_magnetic_field")
135             return data[ftype, "magnetic_field_theta"] - bm[ax]
136 
137     elif registry.ds.geometry == "spherical":
138 
139         def _magnetic_field_poloidal(field, data):
140             ax = axis_names.find("theta")
141             bm = data.get_field_parameter("bulk_magnetic_field")
142             return data[ftype, "magnetic_field_theta"] - bm[ax]
143 
144         def _magnetic_field_toroidal(field, data):
145             ax = axis_names.find("phi")
146             bm = data.get_field_parameter("bulk_magnetic_field")
147             return data[ftype, "magnetic_field_phi"] - bm[ax]
148 
149     else:
150 
151         # Unidentified geometry--set to None
152 
153         _magnetic_field_toroidal = None
154         _magnetic_field_poloidal = None
155 
156     registry.add_field(
157         (ftype, "magnetic_field_poloidal"),
158         sampling_type="local",
159         function=_magnetic_field_poloidal,
160         units=u,
161         validators=[
162             ValidateParameter("normal"),
163             ValidateParameter("bulk_magnetic_field"),
164         ],
165     )
166 
167     registry.add_field(
168         (ftype, "magnetic_field_toroidal"),
169         sampling_type="local",
170         function=_magnetic_field_toroidal,
171         units=u,
172         validators=[
173             ValidateParameter("normal"),
174             ValidateParameter("bulk_magnetic_field"),
175         ],
176     )
177 
178     def _alfven_speed(field, data):
179         B = data[ftype, "magnetic_field_strength"]
180         return B / np.sqrt(mag_factors(B.units.dimensions) * data[ftype, "density"])
181 
182     registry.add_field(
183         (ftype, "alfven_speed"),
184         sampling_type="local",
185         function=_alfven_speed,
186         units=unit_system["velocity"],
187     )
188 
189     def _mach_alfven(field, data):
190         return data[ftype, "velocity_magnitude"] / data[ftype, "alfven_speed"]
191 
192     registry.add_field(
193         (ftype, "mach_alfven"),
194         sampling_type="local",
195         function=_mach_alfven,
196         units="dimensionless",
197     )
198 
199     b_units = registry.ds.quan(1.0, u).units
200     if dimensions.current_mks in b_units.dimensions.free_symbols:
201         rm_scale = pc.qp.to("C", "SI") ** 3 / (4.0 * np.pi * pc.eps_0)
202     else:
203         rm_scale = pc.qp**3 / pc.clight
204     rm_scale *= registry.ds.quan(1.0, "rad") / (
205         2.0 * np.pi * pc.me**2 * pc.clight**3
206     )
207     rm_units = registry.ds.quan(1.0, "rad/m**2").units / unit_system["length"]
208 
209     def _rotation_measure(field, data):
210         return (
211             rm_scale
212             * data[ftype, "magnetic_field_los"]
213             * data[ftype, "El_number_density"]
214         )
215 
216     registry.add_field(
217         (ftype, "rotation_measure"),
218         sampling_type="local",
219         function=_rotation_measure,
220         units=rm_units,
221         validators=[ValidateParameter("axis", {"axis": [0, 1, 2]})],
222     )
223 
224 
225 def setup_magnetic_field_aliases(registry, ds_ftype, ds_fields, ftype="gas"):
226     r"""
227     This routine sets up special aliases between dataset-specific magnetic
228     fields and the default magnetic fields in yt so that unit conversions
229     between different unit systems can be handled properly. This is only called
230     from the `setup_fluid_fields` method (for grid dataset) or the
231     `setup_gas_particle_fields` method (for particle dataset) of a frontend's
232     :class:`FieldInfoContainer` instance.
233 
234     Parameters
235     ----------
236     registry : :class:`FieldInfoContainer`
237         The field registry that these definitions will be installed into.
238     ds_ftype : string
239         The field type for the fields we're going to alias, e.g. "flash",
240         "enzo", "athena", "PartType0", etc.
241     ds_fields : list of strings or string
242         The fields that will be aliased. For grid dataset, this should be a
243         list of strings corresponding to the components of magnetic field. For
244         particle dataset, this should be a single string corresponding to the
245         vector magnetic field.
246     ftype : string, optional
247         The resulting field type of the fields. Default "gas".
248 
249     Examples
250     --------
251     >>> from yt.fields.magnetic_field import setup_magnetic_field_aliases
252     >>> class PlutoFieldInfo(ChomboFieldInfo):
253     ...     def setup_fluid_fields(self):
254     ...         setup_magnetic_field_aliases(
255     ...             self, "chombo", ["bx%s" % ax for ax in [1, 2, 3]]
256     ...         )
257     >>> class GizmoFieldInfo(GadgetFieldInfo):
258     ...     def setup_gas_particle_fields(self):
259     ...         setup_magnetic_field_aliases(
260     ...             self, "PartType0", "MagneticField", ftype="PartType0"
261     ...         )
262     """
263     unit_system = registry.ds.unit_system
264     if isinstance(ds_fields, list):
265         # If ds_fields is a list, we assume a grid dataset
266         sampling_type = "local"
267         ds_fields = [(ds_ftype, fd) for fd in ds_fields]
268         ds_field = ds_fields[0]
269     else:
270         # Otherwise, we assume a particle dataset
271         sampling_type = "particle"
272         ds_field = (ds_ftype, ds_fields)
273     if ds_field not in registry:
274         return
275 
276     # Figure out the unit conversion to use
277     if unit_system.base_units[dimensions.current_mks] is not None:
278         to_units = unit_system["magnetic_field_mks"]
279     else:
280         to_units = unit_system["magnetic_field_cgs"]
281     units = unit_system[to_units.dimensions]
282 
283     # Add fields
284     if sampling_type in ["cell", "local"]:
285         # Grid dataset case
286         def mag_field_from_field(fd):
287             def _mag_field(field, data):
288                 return data[fd].to(field.units)
289 
290             return _mag_field
291 
292         for ax, fd in zip(registry.ds.coordinates.axis_order, ds_fields):
293             registry.add_field(
294                 (ftype, f"magnetic_field_{ax}"),
295                 sampling_type=sampling_type,
296                 function=mag_field_from_field(fd),
297                 units=units,
298             )
299     else:
300         # Particle dataset case
301         def mag_field_from_ax(ax):
302             def _mag_field(field, data):
303                 return data[ds_field][:, "xyz".index(ax)]
304 
305             return _mag_field
306 
307         for ax in registry.ds.coordinates.axis_order:
308             fname = f"particle_magnetic_field_{ax}"
309             registry.add_field(
310                 (ds_ftype, fname),
311                 sampling_type=sampling_type,
312                 function=mag_field_from_ax(ax),
313                 units=units,
314             )
315             sph_ptypes = getattr(registry.ds, "_sph_ptypes", tuple())
316             if ds_ftype in sph_ptypes:
317                 registry.alias((ftype, f"magnetic_field_{ax}"), (ds_ftype, fname))
318
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/yt/fields/magnetic_field.py b/yt/fields/magnetic_field.py
--- a/yt/fields/magnetic_field.py
+++ b/yt/fields/magnetic_field.py
@@ -84,6 +84,9 @@
         units=unit_system["pressure"],
     )
 
+    _magnetic_field_toroidal = None
+    _magnetic_field_poloidal = None
+
     if registry.ds.geometry == "cartesian":
 
         def _magnetic_field_poloidal(field, data):
@@ -116,7 +119,7 @@
             phi = data["index", "spherical_phi"]
             return get_sph_phi_component(Bfields, phi, normal)
 
-    elif registry.ds.geometry == "cylindrical":
+    elif registry.ds.geometry in ("cylindrical", "polar"):
 
         def _magnetic_field_poloidal(field, data):
             bm = data.get_field_parameter("bulk_magnetic_field")
@@ -146,34 +149,28 @@
             bm = data.get_field_parameter("bulk_magnetic_field")
             return data[ftype, "magnetic_field_phi"] - bm[ax]
 
-    else:
-
-        # Unidentified geometry--set to None
-
-        _magnetic_field_toroidal = None
-        _magnetic_field_poloidal = None
-
-    registry.add_field(
-        (ftype, "magnetic_field_poloidal"),
-        sampling_type="local",
-        function=_magnetic_field_poloidal,
-        units=u,
-        validators=[
-            ValidateParameter("normal"),
-            ValidateParameter("bulk_magnetic_field"),
-        ],
-    )
-
-    registry.add_field(
-        (ftype, "magnetic_field_toroidal"),
-        sampling_type="local",
-        function=_magnetic_field_toroidal,
-        units=u,
-        validators=[
-            ValidateParameter("normal"),
-            ValidateParameter("bulk_magnetic_field"),
-        ],
-    )
+    if _magnetic_field_toroidal is not None:
+        registry.add_field(
+            (ftype, "magnetic_field_toroidal"),
+            sampling_type="local",
+            function=_magnetic_field_toroidal,
+            units=u,
+            validators=[
+                ValidateParameter("normal"),
+                ValidateParameter("bulk_magnetic_field"),
+            ],
+        )
+    if _magnetic_field_poloidal is not None:
+        registry.add_field(
+            (ftype, "magnetic_field_poloidal"),
+            sampling_type="local",
+            function=_magnetic_field_poloidal,
+            units=u,
+            validators=[
+                ValidateParameter("normal"),
+                ValidateParameter("bulk_magnetic_field"),
+            ],
+        )
 
     def _alfven_speed(field, data):
         B = data[ftype, "magnetic_field_strength"]

{"golden_diff": "diff --git a/yt/fields/magnetic_field.py b/yt/fields/magnetic_field.py\n--- a/yt/fields/magnetic_field.py\n+++ b/yt/fields/magnetic_field.py\n@@ -84,6 +84,9 @@\n         units=unit_system[\"pressure\"],\n     )\n \n+    _magnetic_field_toroidal = None\n+    _magnetic_field_poloidal = None\n+\n     if registry.ds.geometry == \"cartesian\":\n \n         def _magnetic_field_poloidal(field, data):\n@@ -116,7 +119,7 @@\n             phi = data[\"index\", \"spherical_phi\"]\n             return get_sph_phi_component(Bfields, phi, normal)\n \n-    elif registry.ds.geometry == \"cylindrical\":\n+    elif registry.ds.geometry in (\"cylindrical\", \"polar\"):\n \n         def _magnetic_field_poloidal(field, data):\n             bm = data.get_field_parameter(\"bulk_magnetic_field\")\n@@ -146,34 +149,28 @@\n             bm = data.get_field_parameter(\"bulk_magnetic_field\")\n             return data[ftype, \"magnetic_field_phi\"] - bm[ax]\n \n-    else:\n-\n-        # Unidentified geometry--set to None\n-\n-        _magnetic_field_toroidal = None\n-        _magnetic_field_poloidal = None\n-\n-    registry.add_field(\n-        (ftype, \"magnetic_field_poloidal\"),\n-        sampling_type=\"local\",\n-        function=_magnetic_field_poloidal,\n-        units=u,\n-        validators=[\n-            ValidateParameter(\"normal\"),\n-            ValidateParameter(\"bulk_magnetic_field\"),\n-        ],\n-    )\n-\n-    registry.add_field(\n-        (ftype, \"magnetic_field_toroidal\"),\n-        sampling_type=\"local\",\n-        function=_magnetic_field_toroidal,\n-        units=u,\n-        validators=[\n-            ValidateParameter(\"normal\"),\n-            ValidateParameter(\"bulk_magnetic_field\"),\n-        ],\n-    )\n+    if _magnetic_field_toroidal is not None:\n+        registry.add_field(\n+            (ftype, \"magnetic_field_toroidal\"),\n+            sampling_type=\"local\",\n+            function=_magnetic_field_toroidal,\n+            units=u,\n+            validators=[\n+                ValidateParameter(\"normal\"),\n+                ValidateParameter(\"bulk_magnetic_field\"),\n+            ],\n+        )\n+    if _magnetic_field_poloidal is not None:\n+        registry.add_field(\n+            (ftype, \"magnetic_field_poloidal\"),\n+            sampling_type=\"local\",\n+            function=_magnetic_field_poloidal,\n+            units=u,\n+            validators=[\n+                ValidateParameter(\"normal\"),\n+                ValidateParameter(\"bulk_magnetic_field\"),\n+            ],\n+        )\n \n     def _alfven_speed(field, data):\n         B = data[ftype, \"magnetic_field_strength\"]\n", "issue": "ENH: missing def for poloidal/toroidal magnetic fields in polar geometry\n### Bug report\r\n\r\n**Bug summary**\r\n\r\nPoloidal and toroidal magnetic fields definitions in polar geometry are missing, see https://github.com/yt-project/yt/blob/e16331088faf7296672ce9d1987a09d036f458ea/yt/fields/magnetic_field.py#L87-L149\r\n\n", "before_files": [{"content": "import numpy as np\n\nfrom yt.fields.derived_field import ValidateParameter\nfrom yt.units import dimensions\nfrom yt.units.yt_array import ustack  # type: ignore\nfrom yt.utilities.math_utils import get_sph_phi_component, get_sph_theta_component\n\nfrom .field_plugin_registry import register_field_plugin\n\ncgs_normalizations = {\"gaussian\": 4.0 * np.pi, \"lorentz_heaviside\": 1.0}\n\n\ndef get_magnetic_normalization(key: str) -> float:\n    if key not in cgs_normalizations:\n        raise ValueError(\n            \"Unknown magnetic normalization convention. \"\n            f\"Got {key!r}, expected one of {tuple(cgs_normalizations)}\"\n        )\n    return cgs_normalizations[key]\n\n\n@register_field_plugin\ndef setup_magnetic_field_fields(registry, ftype=\"gas\", slice_info=None):\n    ds = registry.ds\n\n    unit_system = ds.unit_system\n    pc = registry.ds.units.physical_constants\n\n    axis_names = registry.ds.coordinates.axis_order\n\n    if (ftype, f\"magnetic_field_{axis_names[0]}\") not in registry:\n        return\n\n    u = registry[ftype, f\"magnetic_field_{axis_names[0]}\"].units\n\n    def mag_factors(dims):\n        if dims == dimensions.magnetic_field_cgs:\n            return getattr(ds, \"_magnetic_factor\", 4.0 * np.pi)\n        elif dims == dimensions.magnetic_field_mks:\n            return ds.units.physical_constants.mu_0\n\n    def _magnetic_field_strength(field, data):\n        xm = f\"relative_magnetic_field_{axis_names[0]}\"\n        ym = f\"relative_magnetic_field_{axis_names[1]}\"\n        zm = f\"relative_magnetic_field_{axis_names[2]}\"\n\n        B2 = (data[ftype, xm]) ** 2 + (data[ftype, ym]) ** 2 + (data[ftype, zm]) ** 2\n\n        return np.sqrt(B2)\n\n    registry.add_field(\n        (ftype, \"magnetic_field_strength\"),\n        sampling_type=\"local\",\n        function=_magnetic_field_strength,\n        validators=[ValidateParameter(\"bulk_magnetic_field\")],\n        units=u,\n    )\n\n    def _magnetic_energy_density(field, data):\n        B = data[ftype, \"magnetic_field_strength\"]\n        return 0.5 * B * B / mag_factors(B.units.dimensions)\n\n    registry.add_field(\n        (ftype, \"magnetic_energy_density\"),\n        sampling_type=\"local\",\n        function=_magnetic_energy_density,\n        units=unit_system[\"pressure\"],\n    )\n\n    def _plasma_beta(field, data):\n        return data[ftype, \"pressure\"] / data[ftype, \"magnetic_energy_density\"]\n\n    registry.add_field(\n        (ftype, \"plasma_beta\"), sampling_type=\"local\", function=_plasma_beta, units=\"\"\n    )\n\n    def _magnetic_pressure(field, data):\n        return data[ftype, \"magnetic_energy_density\"]\n\n    registry.add_field(\n        (ftype, \"magnetic_pressure\"),\n        sampling_type=\"local\",\n        function=_magnetic_pressure,\n        units=unit_system[\"pressure\"],\n    )\n\n    if registry.ds.geometry == \"cartesian\":\n\n        def _magnetic_field_poloidal(field, data):\n            normal = data.get_field_parameter(\"normal\")\n\n            Bfields = ustack(\n                [\n                    data[ftype, \"relative_magnetic_field_x\"],\n                    data[ftype, \"relative_magnetic_field_y\"],\n                    data[ftype, \"relative_magnetic_field_z\"],\n                ]\n            )\n\n            theta = data[\"index\", \"spherical_theta\"]\n            phi = data[\"index\", \"spherical_phi\"]\n\n            return get_sph_theta_component(Bfields, theta, phi, normal)\n\n        def _magnetic_field_toroidal(field, data):\n            normal = data.get_field_parameter(\"normal\")\n\n            Bfields = ustack(\n                [\n                    data[ftype, \"relative_magnetic_field_x\"],\n                    data[ftype, \"relative_magnetic_field_y\"],\n                    data[ftype, \"relative_magnetic_field_z\"],\n                ]\n            )\n\n            phi = data[\"index\", \"spherical_phi\"]\n            return get_sph_phi_component(Bfields, phi, normal)\n\n    elif registry.ds.geometry == \"cylindrical\":\n\n        def _magnetic_field_poloidal(field, data):\n            bm = data.get_field_parameter(\"bulk_magnetic_field\")\n            r = data[\"index\", \"r\"]\n            z = data[\"index\", \"z\"]\n            d = np.sqrt(r * r + z * z)\n            rax = axis_names.find(\"r\")\n            zax = axis_names.find(\"z\")\n            return (data[ftype, \"magnetic_field_r\"] - bm[rax]) * (r / d) + (\n                data[ftype, \"magnetic_field_z\"] - bm[zax]\n            ) * (z / d)\n\n        def _magnetic_field_toroidal(field, data):\n            ax = axis_names.find(\"theta\")\n            bm = data.get_field_parameter(\"bulk_magnetic_field\")\n            return data[ftype, \"magnetic_field_theta\"] - bm[ax]\n\n    elif registry.ds.geometry == \"spherical\":\n\n        def _magnetic_field_poloidal(field, data):\n            ax = axis_names.find(\"theta\")\n            bm = data.get_field_parameter(\"bulk_magnetic_field\")\n            return data[ftype, \"magnetic_field_theta\"] - bm[ax]\n\n        def _magnetic_field_toroidal(field, data):\n            ax = axis_names.find(\"phi\")\n            bm = data.get_field_parameter(\"bulk_magnetic_field\")\n            return data[ftype, \"magnetic_field_phi\"] - bm[ax]\n\n    else:\n\n        # Unidentified geometry--set to None\n\n        _magnetic_field_toroidal = None\n        _magnetic_field_poloidal = None\n\n    registry.add_field(\n        (ftype, \"magnetic_field_poloidal\"),\n        sampling_type=\"local\",\n        function=_magnetic_field_poloidal,\n        units=u,\n        validators=[\n            ValidateParameter(\"normal\"),\n            ValidateParameter(\"bulk_magnetic_field\"),\n        ],\n    )\n\n    registry.add_field(\n        (ftype, \"magnetic_field_toroidal\"),\n        sampling_type=\"local\",\n        function=_magnetic_field_toroidal,\n        units=u,\n        validators=[\n            ValidateParameter(\"normal\"),\n            ValidateParameter(\"bulk_magnetic_field\"),\n        ],\n    )\n\n    def _alfven_speed(field, data):\n        B = data[ftype, \"magnetic_field_strength\"]\n        return B / np.sqrt(mag_factors(B.units.dimensions) * data[ftype, \"density\"])\n\n    registry.add_field(\n        (ftype, \"alfven_speed\"),\n        sampling_type=\"local\",\n        function=_alfven_speed,\n        units=unit_system[\"velocity\"],\n    )\n\n    def _mach_alfven(field, data):\n        return data[ftype, \"velocity_magnitude\"] / data[ftype, \"alfven_speed\"]\n\n    registry.add_field(\n        (ftype, \"mach_alfven\"),\n        sampling_type=\"local\",\n        function=_mach_alfven,\n        units=\"dimensionless\",\n    )\n\n    b_units = registry.ds.quan(1.0, u).units\n    if dimensions.current_mks in b_units.dimensions.free_symbols:\n        rm_scale = pc.qp.to(\"C\", \"SI\") ** 3 / (4.0 * np.pi * pc.eps_0)\n    else:\n        rm_scale = pc.qp**3 / pc.clight\n    rm_scale *= registry.ds.quan(1.0, \"rad\") / (\n        2.0 * np.pi * pc.me**2 * pc.clight**3\n    )\n    rm_units = registry.ds.quan(1.0, \"rad/m**2\").units / unit_system[\"length\"]\n\n    def _rotation_measure(field, data):\n        return (\n            rm_scale\n            * data[ftype, \"magnetic_field_los\"]\n            * data[ftype, \"El_number_density\"]\n        )\n\n    registry.add_field(\n        (ftype, \"rotation_measure\"),\n        sampling_type=\"local\",\n        function=_rotation_measure,\n        units=rm_units,\n        validators=[ValidateParameter(\"axis\", {\"axis\": [0, 1, 2]})],\n    )\n\n\ndef setup_magnetic_field_aliases(registry, ds_ftype, ds_fields, ftype=\"gas\"):\n    r\"\"\"\n    This routine sets up special aliases between dataset-specific magnetic\n    fields and the default magnetic fields in yt so that unit conversions\n    between different unit systems can be handled properly. This is only called\n    from the `setup_fluid_fields` method (for grid dataset) or the\n    `setup_gas_particle_fields` method (for particle dataset) of a frontend's\n    :class:`FieldInfoContainer` instance.\n\n    Parameters\n    ----------\n    registry : :class:`FieldInfoContainer`\n        The field registry that these definitions will be installed into.\n    ds_ftype : string\n        The field type for the fields we're going to alias, e.g. \"flash\",\n        \"enzo\", \"athena\", \"PartType0\", etc.\n    ds_fields : list of strings or string\n        The fields that will be aliased. For grid dataset, this should be a\n        list of strings corresponding to the components of magnetic field. For\n        particle dataset, this should be a single string corresponding to the\n        vector magnetic field.\n    ftype : string, optional\n        The resulting field type of the fields. Default \"gas\".\n\n    Examples\n    --------\n    >>> from yt.fields.magnetic_field import setup_magnetic_field_aliases\n    >>> class PlutoFieldInfo(ChomboFieldInfo):\n    ...     def setup_fluid_fields(self):\n    ...         setup_magnetic_field_aliases(\n    ...             self, \"chombo\", [\"bx%s\" % ax for ax in [1, 2, 3]]\n    ...         )\n    >>> class GizmoFieldInfo(GadgetFieldInfo):\n    ...     def setup_gas_particle_fields(self):\n    ...         setup_magnetic_field_aliases(\n    ...             self, \"PartType0\", \"MagneticField\", ftype=\"PartType0\"\n    ...         )\n    \"\"\"\n    unit_system = registry.ds.unit_system\n    if isinstance(ds_fields, list):\n        # If ds_fields is a list, we assume a grid dataset\n        sampling_type = \"local\"\n        ds_fields = [(ds_ftype, fd) for fd in ds_fields]\n        ds_field = ds_fields[0]\n    else:\n        # Otherwise, we assume a particle dataset\n        sampling_type = \"particle\"\n        ds_field = (ds_ftype, ds_fields)\n    if ds_field not in registry:\n        return\n\n    # Figure out the unit conversion to use\n    if unit_system.base_units[dimensions.current_mks] is not None:\n        to_units = unit_system[\"magnetic_field_mks\"]\n    else:\n        to_units = unit_system[\"magnetic_field_cgs\"]\n    units = unit_system[to_units.dimensions]\n\n    # Add fields\n    if sampling_type in [\"cell\", \"local\"]:\n        # Grid dataset case\n        def mag_field_from_field(fd):\n            def _mag_field(field, data):\n                return data[fd].to(field.units)\n\n            return _mag_field\n\n        for ax, fd in zip(registry.ds.coordinates.axis_order, ds_fields):\n            registry.add_field(\n                (ftype, f\"magnetic_field_{ax}\"),\n                sampling_type=sampling_type,\n                function=mag_field_from_field(fd),\n                units=units,\n            )\n    else:\n        # Particle dataset case\n        def mag_field_from_ax(ax):\n            def _mag_field(field, data):\n                return data[ds_field][:, \"xyz\".index(ax)]\n\n            return _mag_field\n\n        for ax in registry.ds.coordinates.axis_order:\n            fname = f\"particle_magnetic_field_{ax}\"\n            registry.add_field(\n                (ds_ftype, fname),\n                sampling_type=sampling_type,\n                function=mag_field_from_ax(ax),\n                units=units,\n            )\n            sph_ptypes = getattr(registry.ds, \"_sph_ptypes\", tuple())\n            if ds_ftype in sph_ptypes:\n                registry.alias((ftype, f\"magnetic_field_{ax}\"), (ds_ftype, fname))\n", "path": "yt/fields/magnetic_field.py"}], "after_files": [{"content": "import numpy as np\n\nfrom yt.fields.derived_field import ValidateParameter\nfrom yt.units import dimensions\nfrom yt.units.yt_array import ustack  # type: ignore\nfrom yt.utilities.math_utils import get_sph_phi_component, get_sph_theta_component\n\nfrom .field_plugin_registry import register_field_plugin\n\ncgs_normalizations = {\"gaussian\": 4.0 * np.pi, \"lorentz_heaviside\": 1.0}\n\n\ndef get_magnetic_normalization(key: str) -> float:\n    if key not in cgs_normalizations:\n        raise ValueError(\n            \"Unknown magnetic normalization convention. \"\n            f\"Got {key!r}, expected one of {tuple(cgs_normalizations)}\"\n        )\n    return cgs_normalizations[key]\n\n\n@register_field_plugin\ndef setup_magnetic_field_fields(registry, ftype=\"gas\", slice_info=None):\n    ds = registry.ds\n\n    unit_system = ds.unit_system\n    pc = registry.ds.units.physical_constants\n\n    axis_names = registry.ds.coordinates.axis_order\n\n    if (ftype, f\"magnetic_field_{axis_names[0]}\") not in registry:\n        return\n\n    u = registry[ftype, f\"magnetic_field_{axis_names[0]}\"].units\n\n    def mag_factors(dims):\n        if dims == dimensions.magnetic_field_cgs:\n            return getattr(ds, \"_magnetic_factor\", 4.0 * np.pi)\n        elif dims == dimensions.magnetic_field_mks:\n            return ds.units.physical_constants.mu_0\n\n    def _magnetic_field_strength(field, data):\n        xm = f\"relative_magnetic_field_{axis_names[0]}\"\n        ym = f\"relative_magnetic_field_{axis_names[1]}\"\n        zm = f\"relative_magnetic_field_{axis_names[2]}\"\n\n        B2 = (data[ftype, xm]) ** 2 + (data[ftype, ym]) ** 2 + (data[ftype, zm]) ** 2\n\n        return np.sqrt(B2)\n\n    registry.add_field(\n        (ftype, \"magnetic_field_strength\"),\n        sampling_type=\"local\",\n        function=_magnetic_field_strength,\n        validators=[ValidateParameter(\"bulk_magnetic_field\")],\n        units=u,\n    )\n\n    def _magnetic_energy_density(field, data):\n        B = data[ftype, \"magnetic_field_strength\"]\n        return 0.5 * B * B / mag_factors(B.units.dimensions)\n\n    registry.add_field(\n        (ftype, \"magnetic_energy_density\"),\n        sampling_type=\"local\",\n        function=_magnetic_energy_density,\n        units=unit_system[\"pressure\"],\n    )\n\n    def _plasma_beta(field, data):\n        return data[ftype, \"pressure\"] / data[ftype, \"magnetic_energy_density\"]\n\n    registry.add_field(\n        (ftype, \"plasma_beta\"), sampling_type=\"local\", function=_plasma_beta, units=\"\"\n    )\n\n    def _magnetic_pressure(field, data):\n        return data[ftype, \"magnetic_energy_density\"]\n\n    registry.add_field(\n        (ftype, \"magnetic_pressure\"),\n        sampling_type=\"local\",\n        function=_magnetic_pressure,\n        units=unit_system[\"pressure\"],\n    )\n\n    _magnetic_field_toroidal = None\n    _magnetic_field_poloidal = None\n\n    if registry.ds.geometry == \"cartesian\":\n\n        def _magnetic_field_poloidal(field, data):\n            normal = data.get_field_parameter(\"normal\")\n\n            Bfields = ustack(\n                [\n                    data[ftype, \"relative_magnetic_field_x\"],\n                    data[ftype, \"relative_magnetic_field_y\"],\n                    data[ftype, \"relative_magnetic_field_z\"],\n                ]\n            )\n\n            theta = data[\"index\", \"spherical_theta\"]\n            phi = data[\"index\", \"spherical_phi\"]\n\n            return get_sph_theta_component(Bfields, theta, phi, normal)\n\n        def _magnetic_field_toroidal(field, data):\n            normal = data.get_field_parameter(\"normal\")\n\n            Bfields = ustack(\n                [\n                    data[ftype, \"relative_magnetic_field_x\"],\n                    data[ftype, \"relative_magnetic_field_y\"],\n                    data[ftype, \"relative_magnetic_field_z\"],\n                ]\n            )\n\n            phi = data[\"index\", \"spherical_phi\"]\n            return get_sph_phi_component(Bfields, phi, normal)\n\n    elif registry.ds.geometry in (\"cylindrical\", \"polar\"):\n\n        def _magnetic_field_poloidal(field, data):\n            bm = data.get_field_parameter(\"bulk_magnetic_field\")\n            r = data[\"index\", \"r\"]\n            z = data[\"index\", \"z\"]\n            d = np.sqrt(r * r + z * z)\n            rax = axis_names.find(\"r\")\n            zax = axis_names.find(\"z\")\n            return (data[ftype, \"magnetic_field_r\"] - bm[rax]) * (r / d) + (\n                data[ftype, \"magnetic_field_z\"] - bm[zax]\n            ) * (z / d)\n\n        def _magnetic_field_toroidal(field, data):\n            ax = axis_names.find(\"theta\")\n            bm = data.get_field_parameter(\"bulk_magnetic_field\")\n            return data[ftype, \"magnetic_field_theta\"] - bm[ax]\n\n    elif registry.ds.geometry == \"spherical\":\n\n        def _magnetic_field_poloidal(field, data):\n            ax = axis_names.find(\"theta\")\n            bm = data.get_field_parameter(\"bulk_magnetic_field\")\n            return data[ftype, \"magnetic_field_theta\"] - bm[ax]\n\n        def _magnetic_field_toroidal(field, data):\n            ax = axis_names.find(\"phi\")\n            bm = data.get_field_parameter(\"bulk_magnetic_field\")\n            return data[ftype, \"magnetic_field_phi\"] - bm[ax]\n\n    if _magnetic_field_toroidal is not None:\n        registry.add_field(\n            (ftype, \"magnetic_field_toroidal\"),\n            sampling_type=\"local\",\n            function=_magnetic_field_toroidal,\n            units=u,\n            validators=[\n                ValidateParameter(\"normal\"),\n                ValidateParameter(\"bulk_magnetic_field\"),\n            ],\n        )\n    if _magnetic_field_poloidal is not None:\n        registry.add_field(\n            (ftype, \"magnetic_field_poloidal\"),\n            sampling_type=\"local\",\n            function=_magnetic_field_poloidal,\n            units=u,\n            validators=[\n                ValidateParameter(\"normal\"),\n                ValidateParameter(\"bulk_magnetic_field\"),\n            ],\n        )\n\n    def _alfven_speed(field, data):\n        B = data[ftype, \"magnetic_field_strength\"]\n        return B / np.sqrt(mag_factors(B.units.dimensions) * data[ftype, \"density\"])\n\n    registry.add_field(\n        (ftype, \"alfven_speed\"),\n        sampling_type=\"local\",\n        function=_alfven_speed,\n        units=unit_system[\"velocity\"],\n    )\n\n    def _mach_alfven(field, data):\n        return data[ftype, \"velocity_magnitude\"] / data[ftype, \"alfven_speed\"]\n\n    registry.add_field(\n        (ftype, \"mach_alfven\"),\n        sampling_type=\"local\",\n        function=_mach_alfven,\n        units=\"dimensionless\",\n    )\n\n    b_units = registry.ds.quan(1.0, u).units\n    if dimensions.current_mks in b_units.dimensions.free_symbols:\n        rm_scale = pc.qp.to(\"C\", \"SI\") ** 3 / (4.0 * np.pi * pc.eps_0)\n    else:\n        rm_scale = pc.qp**3 / pc.clight\n    rm_scale *= registry.ds.quan(1.0, \"rad\") / (\n        2.0 * np.pi * pc.me**2 * pc.clight**3\n    )\n    rm_units = registry.ds.quan(1.0, \"rad/m**2\").units / unit_system[\"length\"]\n\n    def _rotation_measure(field, data):\n        return (\n            rm_scale\n            * data[ftype, \"magnetic_field_los\"]\n            * data[ftype, \"El_number_density\"]\n        )\n\n    registry.add_field(\n        (ftype, \"rotation_measure\"),\n        sampling_type=\"local\",\n        function=_rotation_measure,\n        units=rm_units,\n        validators=[ValidateParameter(\"axis\", {\"axis\": [0, 1, 2]})],\n    )\n\n\ndef setup_magnetic_field_aliases(registry, ds_ftype, ds_fields, ftype=\"gas\"):\n    r\"\"\"\n    This routine sets up special aliases between dataset-specific magnetic\n    fields and the default magnetic fields in yt so that unit conversions\n    between different unit systems can be handled properly. This is only called\n    from the `setup_fluid_fields` method (for grid dataset) or the\n    `setup_gas_particle_fields` method (for particle dataset) of a frontend's\n    :class:`FieldInfoContainer` instance.\n\n    Parameters\n    ----------\n    registry : :class:`FieldInfoContainer`\n        The field registry that these definitions will be installed into.\n    ds_ftype : string\n        The field type for the fields we're going to alias, e.g. \"flash\",\n        \"enzo\", \"athena\", \"PartType0\", etc.\n    ds_fields : list of strings or string\n        The fields that will be aliased. For grid dataset, this should be a\n        list of strings corresponding to the components of magnetic field. For\n        particle dataset, this should be a single string corresponding to the\n        vector magnetic field.\n    ftype : string, optional\n        The resulting field type of the fields. Default \"gas\".\n\n    Examples\n    --------\n    >>> from yt.fields.magnetic_field import setup_magnetic_field_aliases\n    >>> class PlutoFieldInfo(ChomboFieldInfo):\n    ...     def setup_fluid_fields(self):\n    ...         setup_magnetic_field_aliases(\n    ...             self, \"chombo\", [\"bx%s\" % ax for ax in [1, 2, 3]]\n    ...         )\n    >>> class GizmoFieldInfo(GadgetFieldInfo):\n    ...     def setup_gas_particle_fields(self):\n    ...         setup_magnetic_field_aliases(\n    ...             self, \"PartType0\", \"MagneticField\", ftype=\"PartType0\"\n    ...         )\n    \"\"\"\n    unit_system = registry.ds.unit_system\n    if isinstance(ds_fields, list):\n        # If ds_fields is a list, we assume a grid dataset\n        sampling_type = \"local\"\n        ds_fields = [(ds_ftype, fd) for fd in ds_fields]\n        ds_field = ds_fields[0]\n    else:\n        # Otherwise, we assume a particle dataset\n        sampling_type = \"particle\"\n        ds_field = (ds_ftype, ds_fields)\n    if ds_field not in registry:\n        return\n\n    # Figure out the unit conversion to use\n    if unit_system.base_units[dimensions.current_mks] is not None:\n        to_units = unit_system[\"magnetic_field_mks\"]\n    else:\n        to_units = unit_system[\"magnetic_field_cgs\"]\n    units = unit_system[to_units.dimensions]\n\n    # Add fields\n    if sampling_type in [\"cell\", \"local\"]:\n        # Grid dataset case\n        def mag_field_from_field(fd):\n            def _mag_field(field, data):\n                return data[fd].to(field.units)\n\n            return _mag_field\n\n        for ax, fd in zip(registry.ds.coordinates.axis_order, ds_fields):\n            registry.add_field(\n                (ftype, f\"magnetic_field_{ax}\"),\n                sampling_type=sampling_type,\n                function=mag_field_from_field(fd),\n                units=units,\n            )\n    else:\n        # Particle dataset case\n        def mag_field_from_ax(ax):\n            def _mag_field(field, data):\n                return data[ds_field][:, \"xyz\".index(ax)]\n\n            return _mag_field\n\n        for ax in registry.ds.coordinates.axis_order:\n            fname = f\"particle_magnetic_field_{ax}\"\n            registry.add_field(\n                (ds_ftype, fname),\n                sampling_type=sampling_type,\n                function=mag_field_from_ax(ax),\n                units=units,\n            )\n            sph_ptypes = getattr(registry.ds, \"_sph_ptypes\", tuple())\n            if ds_ftype in sph_ptypes:\n                registry.alias((ftype, f\"magnetic_field_{ax}\"), (ds_ftype, fname))\n", "path": "yt/fields/magnetic_field.py"}]}