Skip to content

Commit

Permalink
More contribution function comparisons to IDL functions (#290)
Browse files Browse the repository at this point in the history
* move out env setup to make testing easier

* add another Fe IX G(T) comparison test

* numpy v2 compatibility

* add new Fe IX G(T) to examples page
  • Loading branch information
wtbarnes authored Jul 18, 2024
1 parent f7e2560 commit 7cba8b8
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 38 deletions.
19 changes: 14 additions & 5 deletions examples/idl_comparisons/goft_comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,16 @@ def plot_idl_comparison(x, y_idl, y_python, fig, n_rows, i_row, quantity_name, t


################################################
# Next, plot the comparison between the ionization fraction results
# Next, plot the comparison between the contribution function results
# for a selected number of ions. The regions highlighted in red denote
# places where the contribution function is less than :math:`10^{-6}` times
# the peak of the ionization fraction. In these regions, the comparison is
# the peak of the contribution function. In these regions, the comparison is
# between the two results is not as critical as the contribution function
# is comparatively small in these regions.
goft_files = [
'goft_20_15_200.972',
'goft_26_9_171.073',
'goft_26_9_188.496',
'goft_26_11_188.497',
'goft_26_14_197.862',
'goft_26_16_262.984',
Expand All @@ -87,8 +88,16 @@ def plot_idl_comparison(x, y_idl, y_python, fig, n_rows, i_row, quantity_name, t
idx = np.argmin(np.abs(transitions - idl_result['wavelength']))
# NOTE: Multiply by 0.83 because the fiasco calculation does not include the n_H/n_e ratio
goft = contribution_func[:, 0, idx] * 0.83
axes = plot_idl_comparison(ion.temperature, idl_result['contribution_function'], goft,
fig, len(goft_files), 3*i, f'{ion.ion_name_roman}')
line_label = f'{ion.ion_name_roman} {idl_result["wavelength"]:latex_inline}'
axes = plot_idl_comparison(
ion.temperature,
idl_result['contribution_function'],
goft,
fig,
len(goft_files),
3*i,
line_label,
)
axes[0].legend()
print(f'IDL code to produce {ion.ion_name_roman} contribution function result:')
print(f'IDL code to produce {line_label} contribution function result:')
print(template_env.from_string(idl_result['idl_script']).render(**idl_result))
27 changes: 2 additions & 25 deletions fiasco/tests/idl/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import os
import pytest

from astropy.utils.data import get_pkg_data_path
from .helpers import setup_idl_environment


@pytest.fixture(scope="session")
Expand All @@ -14,26 +13,4 @@ def idl_env(ascii_dbase_root, request):
idl_codebase_root = request.config.getoption('--idl-codebase-root')
if idl_executable is None or idl_codebase_root is None:
return None
try:
import hissw
except ImportError:
return None
extra_paths = [d for d, _, _ in os.walk(idl_codebase_root)]
header = f'''
defsysv,'!xuvtop','{ascii_dbase_root}'
defsysv,'!abund_file',''
defsysv,'!ioneq_file',''
'''
extra_paths += [get_pkg_data_path('ssw_gen_functions', package='fiasco.tests.idl')]
env = hissw.Environment(
idl_only=True,
idl_home=idl_executable,
header=header,
extra_paths=extra_paths
)
try:
_ = env.run('print,!xuvtop')
except (hissw.util.SSWIDLError, hissw.util.IDLLicenseError):
return None
else:
return env
return setup_idl_environment(ascii_dbase_root, idl_codebase_root, idl_executable)
Binary file not shown.
55 changes: 54 additions & 1 deletion fiasco/tests/idl/helpers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
"""
Helpers for tests related to comparing with IDL output
"""
import os
import pathlib

from astropy.utils.data import get_pkg_data_path

__all__ = ['get_idl_test_output_filepath', 'read_idl_test_output', 'run_idl_script']
__all__ = [
'get_idl_test_output_filepath',
'read_idl_test_output',
'setup_idl_environment',
'run_idl_script',
]


def get_idl_test_output_filepath(name, version):
Expand All @@ -24,6 +30,53 @@ def read_idl_test_output(name, version, keys=None):
return output


def setup_idl_environment(ascii_dbase_root,
idl_codebase_root,
idl_executable,
ssw_gen_root=None):
"""
Setup an IDL environment for CHIANTI
.. note:: If `hissw` is not installed or IDL or SSW are not installed, this
function will return None.
Parameters
----------
ascii_dbase_root: path-like
Path to top of IDL database tree
idl_codebase_root: path-like
Path to top of CHIANTI IDL software tree
idl_executable: path-like
Path to IDL executable
"""
try:
import hissw
except ImportError:
return None
extra_paths = [d for d, _, _ in os.walk(idl_codebase_root)]
header = f'''
defsysv,'!xuvtop','{ascii_dbase_root}'
defsysv,'!abund_file',''
defsysv,'!ioneq_file',''
'''
if ssw_gen_root is None:
extra_paths += [get_pkg_data_path('ssw_gen_functions', package='fiasco.tests.idl')]
else:
extra_paths += [d for d, _, _ in os.walk(ssw_gen_root)]
env = hissw.Environment(
idl_only=True,
idl_home=idl_executable,
header=header,
extra_paths=extra_paths
)
try:
_ = env.run('print,!xuvtop', verbose=False)
except (hissw.util.SSWIDLError, hissw.util.IDLLicenseError):
return None
else:
return env


def run_idl_script(idl_env, script, input_args, save_vars, file_name, version, format_func=None, write_file=True):
"""
Helper function for running CHIANTI IDL via hissw in tests
Expand Down
16 changes: 10 additions & 6 deletions fiasco/tests/idl/test_idl_goft.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@
# by wavelength so I have to run the g_of_t function once with the GUI selector to work out
# what integer index corresponds to which wavelength. For any additional test that is added to
# the list below, this index will need to be computed and added to the list below.
# NOTE: These indices will change with database version number so they'll need to be updated
# or we will have to find a way to select them automatically.
INDEX_WAVE_MAPPING = {
200.972*u.Angstrom: 297,
171.073*u.Angstrom: 13946,
188.497*u.Angstrom: 22527,
197.862*u.Angstrom: 27964,
262.984*u.Angstrom: 1415,
'Ca XV 200.972 Angstrom': 297,
'Fe IX 171.073 Angstrom': 13946,
'Fe IX 188.496 Angstrom': 18403,
'Fe XI 188.497 Angstrom': 22527,
'Fe XIV 197.862 Angstrom': 27964,
'Fe XVI 262.984 Angstrom': 1415,
}


@pytest.mark.parametrize(('ion_name', 'wavelength'), [
('Ca XV', 200.972*u.Angstrom),
('Fe IX', 171.073*u.Angstrom),
('Fe IX', 188.496*u.Angstrom),
('Fe XI', 188.497*u.Angstrom),
('Fe XIV', 197.862*u.Angstrom),
('Fe XVI', 262.984*u.Angstrom),
Expand Down Expand Up @@ -54,7 +58,7 @@ def test_idl_compare_goft(idl_env, hdf5_dbase_root, dbase_version, ion_name, wav
'iz': iz,
'wavelength': wavelength,
'wave_window': 1 * u.angstrom,
'index': INDEX_WAVE_MAPPING[wavelength],
'index': INDEX_WAVE_MAPPING[f'{ion_name} {wavelength}'],
'density': 1e+10 * u.cm**(-3),
'abundance': 'sun_coronal_1992_feldman_ext',
'ioneq': 'chianti',
Expand Down
2 changes: 1 addition & 1 deletion fiasco/util/setup_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,5 +199,5 @@ def build_hdf5_dbase(ascii_dbase_root, hdf5_dbase_root, files=None, check_hash=F
if 'ion_index' in hf:
del hf['ion_index']
ion_list = list_ions(hdf5_dbase_root)
ds = hf.create_dataset('ion_index', data=np.array(ion_list).astype(np.string_))
ds = hf.create_dataset('ion_index', data=np.array(ion_list).astype(np.bytes_))
ds.attrs['unit'] = 'SKIP'

0 comments on commit 7cba8b8

Please sign in to comment.