@@ -24,8 +24,7 @@ class FLEKSFieldInfo(FieldInfoContainer):
2424 rho_units = "code_density"
2525 mass_units = "code_mass"
2626
27- # TODO: find a way to avoid repeating s0, s1...
28- known_other_fields = (
27+ _base_fields = (
2928 ("Bx" , (b_units , ["magnetic_field_x" ], r"B_x" )),
3029 ("By" , (b_units , ["magnetic_field_y" ], r"B_y" )),
3130 ("Bz" , (b_units , ["magnetic_field_z" ], r"B_z" )),
@@ -35,28 +34,23 @@ class FLEKSFieldInfo(FieldInfoContainer):
3534 ("X" , (l_units , [], r"X" )),
3635 ("Y" , (l_units , [], r"Y" )),
3736 ("Z" , (l_units , [], r"Z" )),
38- ("rhos0" , (rho_units , [], r"\rho" )),
39- ("uxs0" , (v_units , [], r"u_x" )),
40- ("uys0" , (v_units , [], r"u_y" )),
41- ("uzs0" , (v_units , [], r"u_z" )),
42- ("pxxs0" , (p_units , [], r"P_{xx}" )),
43- ("pyys0" , (p_units , [], r"P_{yy}" )),
44- ("pzzs0" , (p_units , [], r"P_{zz}" )),
45- ("pxys0" , (p_units , [], r"P_{xy}" )),
46- ("pxzs0" , (p_units , [], r"P_{xz}" )),
47- ("pyzs0" , (p_units , [], r"P_{yz}" )),
48- ("rhos1" , (rho_units , [], r"\rho" )),
49- ("uxs1" , (v_units , [], r"u_x" )),
50- ("uys1" , (v_units , [], r"u_y" )),
51- ("uzs1" , (v_units , [], r"u_z" )),
52- ("pxxs1" , (p_units , [], r"P_{xx}" )),
53- ("pyys1" , (p_units , [], r"P_{yy}" )),
54- ("pzzs1" , (p_units , [], r"P_{zz}" )),
55- ("pxys1" , (p_units , [], r"P_{xy}" )),
56- ("pxzs1" , (p_units , [], r"P_{xz}" )),
57- ("pyzs1" , (p_units , [], r"P_{yz}" )),
5837 )
5938
39+ _species_fields_template = (
40+ ("rho" , (rho_units , [], r"\rho" )),
41+ ("ux" , (v_units , [], r"u_x" )),
42+ ("uy" , (v_units , [], r"u_y" )),
43+ ("uz" , (v_units , [], r"u_z" )),
44+ ("pxx" , (p_units , [], r"P_{xx}" )),
45+ ("pyy" , (p_units , [], r"P_{yy}" )),
46+ ("pzz" , (p_units , [], r"P_{zz}" )),
47+ ("pxy" , (p_units , [], r"P_{xy}" )),
48+ ("pxz" , (p_units , [], r"P_{xz}" )),
49+ ("pyz" , (p_units , [], r"P_{yz}" )),
50+ )
51+
52+ known_other_fields = _base_fields
53+
6054 known_particle_fields = (
6155 ("particle_weight" , (mass_units , ["p_w" ], r"weight" )),
6256 ("particle_position_x" , (l_units , ["p_x" ], "x" )),
@@ -78,11 +72,57 @@ def __init__(self, ds, field_list):
7872 finfo .nodal_flag = ds .nodal_flags [field ]
7973
8074 def setup_fluid_fields (self ):
75+ import re
76+
8177 from yt .fields .magnetic_field import setup_magnetic_field_aliases
8278
8379 for field in self .known_other_fields :
8480 fname = field [0 ]
85- self .alias (("mesh" , fname ), ("boxlib" , fname ))
81+ # Try to alias to boxlib first, then raw
82+ original_name = ("boxlib" , fname )
83+ if original_name not in self :
84+ original_name = ("raw" , fname )
85+
86+ self .alias (("mesh" , fname ), original_name )
87+
88+ # Dynamically alias species fields from the input dataset
89+ # Use field_list instead of index.raw_fields to avoid forcing index construction
90+ species_regex = re .compile (r"^(?P<base>.*)s(?P<idx>\d+)$" )
91+
92+ # field_list typically contains tuples like ('boxlib', 'varname') or ('raw', 'varname')
93+ # We need to scan for on-disk fields.
94+ # Use self.field_list instead of self.ds.field_list to be robust against incomplete ds mocks in tests
95+ for ftype , fname in self .field_list :
96+ # We are interested in fields that might be raw fluid fields
97+ if ftype not in ("boxlib" , "raw" ):
98+ continue
99+
100+ match = species_regex .match (fname )
101+ if match :
102+ base = match .group ("base" )
103+ for template_field , props in self ._species_fields_template :
104+ if base == template_field :
105+ # Construct proper LaTeX display name merging subscripts
106+ base_display = props [2 ]
107+ suffix = f"s{ match .group ('idx' )} "
108+ if "_" in base_display :
109+ name_part , sub_part = base_display .split ("_" , 1 )
110+ if sub_part .startswith ("{" ) and sub_part .endswith ("}" ):
111+ sub_content = sub_part [1 :- 1 ]
112+ display_name = f"{ name_part } _{{{ sub_content } ,{ suffix } }}"
113+ else :
114+ display_name = f"{ name_part } _{{{ sub_part } ,{ suffix } }}"
115+ else :
116+ display_name = f"{ base_display } _{{{ suffix } }}"
117+
118+ # Alias ("mesh", fname) to the found field
119+ self .alias (
120+ ("mesh" , fname ), (ftype , fname ), units = props [0 ]
121+ )
122+
123+ if ("mesh" , fname ) in self :
124+ self [("mesh" , fname )].display_name = display_name
125+ break
86126
87127 # This function is required by yt to correctly handle magnetic field
88128 # units and set up aliases. See:
0 commit comments