diff --git a/doc/source/index.rst b/doc/source/index.rst index 0ee59abb98..564a0e5b9c 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1,11 +1,11 @@ Trident Documentation ===================== -Trident is a Python package for creating synthetic absorption-line spectra -from astrophysical hydrodynamics simulations. It utilizes the yt package -to read in simulation datasets and extends it to provide realistic -synthetic observations appropriate for studies of the interstellar, -circumgalactic, and intergalactic media. +Trident is a Python package for calculating ion populations and creating +synthetic absorption-line spectra from astrophysical hydrodynamics simulations. +It utilizes the yt package to read in simulation datasets and extends it to +provide realistic synthetic observations appropriate for studies of the +interstellar, circumgalactic, and intergalactic media. To avoid confusion, make sure you are viewing the correct documentation for the version of Trident you are using: diff --git a/doc/source/installation.rst b/doc/source/installation.rst index 2983dad521..ca438cee0c 100644 --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -10,48 +10,42 @@ Follow these steps to successfully install Trident and its dependencies. Versions of Trident ------------------- -Previously, there were three versions of Trident: the `stable version -`_, the `developent version -`_, and the `demeshening version +There are two versions of Trident: the `stable version +`_, and the `developent version +`_. The stable version is tried and +tested, and it operates on the most recent stable version of yt. The +development version is actively being updated with new features, and it is +also tied to the development version of yt, so occasionally unforseen bugs +can crop up as these new features are added. + +If you are dealing with an SPH or Voronoi Tesselation code like Gadget, Gizmo, +AREPO, Gasoline, or Changa, you will get best and fastest results from using the +development versions of Trident and yt, since there have been a number of +updates to these codes to better treat particle data natively (previously +referred to as the demeshening. For more details about the demeshening, see +`this notebook `_. -The stable version is tried and tested, and it normally operates on a stable -version of yt. The development version is actively being updated with new -features, and it is also tied to the development version of yt, so occasionally -unforseen bugs can crop up as these new features are added. The demeshening -version is currently in beta and active development and is used for better -results on particle-based datasets. - -After Trident 1.2 was released on September 19, 2019, the demeshening version -was merged with the main development branch. Now, there are only the stable -version and the development version. - -The installation steps are slightly different between the two versions, -so pay attention in the steps below. Don't worry if you want to change later, -you can always switch between the two versions easily enough by following the -directions in :ref:`uninstallation`. - -.. note:: - The demeshening (development) version treats particle-based - datasets more natively. The demeshening version will give faster and more - accurate results with less memory overhead for particle-based datasets. - For more information about the demeshening version, please see our - `demeshening notebook - `_. **Note, the installation instructions in the notebook should be ignored.** - Instead, follow the instructions for :ref:`install-dev`. + +The installation steps are slightly different between the two versions, in that +the stable version of Trident requires a stable release of yt, whereas +the development version of Trident requires the development version of yt, both +built from source. Don't worry if you want to change later, you can always +switch between the two versions easily enough by following the directions in +:ref:`uninstallation`. .. _step-1: -Step 1: Install yt +Step 1: Install yt ------------------ -`yt `_ is a python-based software package for the -analysis and visualization of a variety of different datasets, including +`yt `_ is a python-based software package for the +analysis and visualization of a variety of different datasets, including astrophysical hydrodynamical data. yt is a dependency of Trident, so you -must install it before Trident will work. There are several methods for -installing yt, which are all discussed in detail in the `yt installation -documentation `_. +must install it before Trident will work. There are several methods for +installing yt, which are all discussed in detail in the `yt installation +documentation `_. -We find that the easiest way to install yt is with the all-in-one install +We find that the easiest way to install yt is with the all-in-one install script, which installs yt and its dependencies via a new conda installation:: $ wget https://raw.githubusercontent.com/yt-project/yt/master/doc/install_script.sh @@ -61,7 +55,7 @@ script, which installs yt and its dependencies via a new conda installation:: $ ... update your path flag as described by the install_script.sh Alternatively, if you already have conda installed, you can skip the commands -above and just run the following command to get yt and its dependencies. +above and just run the following command to get yt and its dependencies. To get the nightly build of the development version of yt, type:: $ conda install -c http://use.yt/with_conda/ -c conda-forge yt @@ -84,9 +78,9 @@ You can install the most recent stable release of Trident using pip:: Installing the Development Version ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To get the development version, you'll pull the source code from its -repository using git, which should be installed as part of your yt -installation. If it isn't try: ``conda install git``. After that, you'll +To get the development version, you'll pull the source code from its +repository using git, which should be installed as part of your yt +installation. If it isn't try: ``conda install git``. After that, you'll use pip to install the source directly. The development version of Trident requires the yt-4.0 development version of yt as well. Go to your desired source code installation directory and run:: @@ -106,29 +100,30 @@ source code installation directory and run:: Step 3: Get Ionization Table and Verify Installation ---------------------------------------------------- -In order to calculate the ionization fractions for various ions from -density, temperature, metallicity fields, you will need an ionization table +In order to calculate the ionization fractions for various ions from +density, temperature, metallicity fields, you will need an ionization table datafile and a configuration file. Because this datafile can be large, it is -not packaged with the main source code. The first time you try to do anything -that requires it, Trident will attempt to automatically set this all up for -you with a series of interactive prompts. **This step requires an internet -connection the first time you run it.** +not packaged with the main source code. The first time that you import +Trident, you will be prompted to download these files through a series of +interactive prompts. **This step requires an internet connection the first +time you run it.** To initiate this directly, run the ``trident.auto_config()``. -In addition, Trident provides a simple test function to verify that your +In addition, Trident provides a simple test function to verify that your install is functioning correctly. This function not only tries to set up -your configuration and download your ion table file, but it will -create a simple one-zone dataset, generate a ray through it, and -create a spectrum from that ray. This should execute very quickly, -and if it succeeds it demonstrates that your installation has been totally +your configuration and download your ion table file, but it will +create a simple one-zone dataset, generate a ray through it, and +create a spectrum from that ray. This should execute very quickly, +and if it succeeds it demonstrates that your installation has been totally successful:: $ python >>> import trident - >>> trident.verify() + >>> trident.auto_config() ...Series of Interactive Prompts... + >>> trident.verify() If you cannot directly access the internet on this computer, or you lack write -access to your ``$HOME`` directory, or this step fails for any reason, please +access to your ``$HOME`` directory, or this step fails for any reason, please follow our documentation on :ref:`manual-config`. .. _step-4: @@ -136,9 +131,9 @@ follow our documentation on :ref:`manual-config`. Step 4: Science! ---------------- -Congratulations, you're now ready to use Trident! Please refer to the -documentation for how to use it with your data or with one of our sample -datasets. Please join our :ref:`mailing list +Congratulations, you're now ready to use Trident! Please refer to the +documentation for how to use it with your data or with one of our sample +datasets. Please join our :ref:`mailing list ` for announcements and when new features are added to the code. .. _manual-config: @@ -148,12 +143,12 @@ Manually Installing your Ionization Table If for some reason you are unable to install the config file and ionization table data automatically, you must set it up manually. When Trident runs, -it looks for a configuration file called ``config.tri`` in the -``$HOME/.trident`` directory or alternatively in the current working -directory (for users lacking write access to their ``$HOME`` directories). -This configuration file is simple in that it tells Trident a few things about -your install including the location and filename of your desired ionization -table. Manually create a text file called ``config.tri`` with contents +it looks for a configuration file called ``config.tri`` in the +``$HOME/.trident`` directory or alternatively in the current working +directory (for users lacking write access to their ``$HOME`` directories). +This configuration file is simple in that it tells Trident a few things about +your install including the location and filename of your desired ionization +table. Manually create a text file called ``config.tri`` with contents following the form:: [Trident] @@ -161,14 +156,14 @@ following the form:: ion_table_file = hm2012_hr.h5 To manually obtain an ion table datafile, download and gunzip one from: -http://trident-project.org/data/ion_table . While the ``config.tri`` file needs +http://trident-project.org/data/ion_table . While the ``config.tri`` file needs to exist in your ``$HOME/.trident`` directory or in the working directory -when you import trident, the ion_table datafile can exist anywhere on the -file system. Just assure that the config file points to the proper location +when you import trident, the ion_table datafile can exist anywhere on the +file system. Just assure that the config file points to the proper location and filename of the ion table datafile. Now, to confirm everything is working properly, verify your installation -following :ref:`step-3`. If this fails or you have additional problems, +following :ref:`step-3`. If this fails or you have additional problems, please contact our mailing list. .. _uninstallation: @@ -176,7 +171,7 @@ please contact our mailing list. Uninstallation or Switching Code Versions ----------------------------------------- -Uninstallation of the Trident source code is easy. If you installed the +Uninstallation of the Trident source code is easy. If you installed the stable version of the code via pip, just run:: $ pip uninstall trident @@ -192,8 +187,8 @@ If you want to switch between the two stable and development versions, just version as described in :ref:`install-trident` To fully remove the code from your system, remember to remove any ion table -datafiles you may have downloaded in your ``$HOME/.trident`` directory, -and follow the instructions for how to `uninstall yt +datafiles you may have downloaded in your ``$HOME/.trident`` directory, +and follow the instructions for how to `uninstall yt `_. .. _updating: @@ -202,12 +197,12 @@ Updating to the Latest Version ------------------------------ If you want more recent features, you should periodically update your Trident -codebase. +codebase. Updating to the Latest Stable Release ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you installed the "stable" version of the code using pip, then +If you installed the "stable" version of the code using pip, then you can easily update your trident and yt installations:: $ pip install -U trident @@ -224,6 +219,6 @@ involved:: $ pip install -e . $ yt update -For more information on updating your yt installation, see the `yt update -instructions +For more information on updating your yt installation, see the `yt update +instructions `_. diff --git a/tests/test_config.py b/tests/test_config.py index 9d11614105..7064b05044 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -13,9 +13,7 @@ from trident.config import \ trident, \ - trident_path, \ - create_config, \ - parse_config + trident_path def test_banner(): """ @@ -28,7 +26,3 @@ def test_path(): Tests that the trident path is working ok. """ trident_path() - -# Need to make a test_config but this necessitates changing the config -# code around a bunch. - diff --git a/trident/__init__.py b/trident/__init__.py index b192ab1e94..7ec5898f8e 100644 --- a/trident/__init__.py +++ b/trident/__init__.py @@ -17,14 +17,9 @@ __version__ = "1.3.dev1" -# Must run import_check() before anything else is imported to avoid -# astropy error when importing trident in trident package directory -from trident.utilities import import_check -import_check() - from trident.config import \ parse_config, \ - create_config, \ + auto_config, \ trident, \ trident_path, \ verify @@ -73,3 +68,6 @@ # Making installation path global path = trident_path() + +# Check that configuration is correct +parse_config(first_parse=True) diff --git a/trident/config.py b/trident/config.py index a5083dc02b..94c802f3d9 100644 --- a/trident/config.py +++ b/trident/config.py @@ -17,13 +17,16 @@ NoSectionError import shutil import tempfile -import sys from trident.utilities import \ ensure_directory, \ get_datafiles, \ make_onezone_dataset +from trident.exceptions import \ + NotConfiguredError, \ + NoIonBalanceTableError + def trident(): """ Print a Trident ASCII logo to the screen. @@ -56,36 +59,30 @@ def trident_path(): # Here, __file__ refers to this file (config.py) return os.path.split(__file__)[0] -def create_config(): +def auto_config(): """ Create a Trident configuration file using interaction with the user. - This function is called by :class:`~trident.parse_config` if it appears - that the configuration has not yet been set up for the user. It will - attempt to create a configuration file and download an ion table - datafile from the web. It does this using user interaction from the - python prompt. + If it appears that the configuration has not yet been set up for the user, + Trident suggests running this function. It will attempt to create a + configuration file and download an ion table datafile from the web. It + does this using user interaction from the python prompt. """ default_dir = os.path.expanduser(os.path.join('~', '.trident')) - trident() - print("It appears that this is your first time using Trident. To finalize your") - print("Trident installation, you must:") + + print("") + print("Let's try to set up your Trident configuration automatically.") + print("We will attempt to:") print(" * create a `~/.trident` directory") print(" * create a config.tri file in your `~/.trident` directory") print(" * download an ion table file for calculating ionization fractions") print("") - print("You can do this manually by following the installation docs, or we can") - print("do it automatically now if you have web access.") - print("") - print("Would you like to do this automatically? ([y]/n)") - value = input().rstrip() - if not value == '' and not value == 'y': - sys.exit('Instructions at http://trident.readthedocs.org/en/latest/installation.html') - + print("If this fails, please follow the installation documents to do this") + print("manually.") print("") print("Where would you like Trident to store the ion table file?") print("[%s]" % default_dir) - # First assure that the .trident directory is created for storing + # First ensure that the .trident directory is created for storing # the config file. ensure_directory(default_dir) @@ -117,20 +114,38 @@ def create_config(): print("") print("Installation complete. I recommend verifying your installation") - print("to assure that everything is working. Try: trident.verify()") + print("to ensure that everything is working. Try: trident.verify()") - # Return the config file path so we can load it and get parameters. - return config_filename +def config_warning(): + """ + Print warning to STDOUT about the configuration being incorrect if first + time. + """ + trident() + print("It appears that this is your first time using Trident. To finalize your") + print("Trident installation, you must:") + print(" * create a `~/.trident` directory") + print(" * create a config.tri file in your `~/.trident` directory") + print(" * download an ion table file for calculating ionization fractions") + print("") + print("You can do this manually by following the installation docs, or we can") + print("do it automatically now if you have web access. Most functionality") + print("will fail until you accomplish this configuration step.") + print("") + print("To proceed automatically, please run: trident.auto_config()") + print("") + return -def parse_config(variable=None): +def parse_config(variable=None, first_parse=False): """ Parse the Trident local configuration file. This function is called - whenever Trident is imported, and it assures that Trident knows where + whenever Trident is imported, and it ensure that Trident knows where the default ion table datafiles exist. If a ``config.tri`` file doesn't exist in ``$HOME/.trident`` or in the current working directory, then - Trident will launch the :class:`~trident.create_config` function to - try to automatically generate one for the user. For more information - on this process, see the installation documentation. + Trident will launch the request the user run the + :class:`~trident.auto_config` function to automatically generate one for the + user. For more information on this process, see the installation + documentation. **Parameters** @@ -138,9 +153,16 @@ def parse_config(variable=None): If you wish to get the value a variable is set to in the config file, specify that variable name here. Will return the result - value of that variable. Default: None + value of that variable. If None set, returns ion balance filepath. + Default: None + + :first_parse: boolean, optional + + If this is the first time parsing the configuration and it isn't + correct, then give a verbose error message. + Default: False """ - # Assure the ~/.trident directory exists, and read in the config file. + # Ensure the ~/.trident directory exists, and read in the config file. home = os.path.expanduser("~") directory = os.path.join(home, '.trident') config_filename = os.path.join(directory, 'config.tri') @@ -155,26 +177,20 @@ def parse_config(variable=None): parser.read(config_filename) ion_table_dir = parser.get('Trident', 'ion_table_dir') ion_table_file = parser.get('Trident', 'ion_table_file') + ion_table_dir = os.path.abspath(os.path.expanduser(ion_table_dir)) + ion_table_filepath = os.path.join(ion_table_dir, ion_table_file) except NoSectionError: - config_filename = create_config() - parser = ConfigParser() - parser.read(config_filename) - ion_table_dir = parser.get('Trident', 'ion_table_dir') - ion_table_file = parser.get('Trident', 'ion_table_file') - - ion_table_dir = os.path.abspath(os.path.expanduser(ion_table_dir)) - if not os.path.exists(os.path.join(ion_table_dir, - ion_table_file)): - print("") - print("No ion table data file found in %s" % ion_table_dir) - ion_table_file = get_datafiles(ion_table_dir) - parser.set('Trident', 'ion_table_file', ion_table_file) - with open(config_filename, 'w') as configfile: - parser.write(configfile) + if first_parse: + config_warning() + return + else: + raise NotConfiguredError("Trident not configured. Try: trident.auto_config()") + if not os.path.exists(ion_table_filepath): + raise NoIonBalanceTableError("No ion balance file found in %s" % ion_table_dir) # value to return depends on what was set for "variable" if variable is None: - return ion_table_dir, ion_table_file + return ion_table_filepath else: return parser.get('Trident', variable) @@ -262,18 +278,3 @@ def verify(save=False): print("Congratulations, you have verified that Trident is installed correctly.") print("Now let's science!") print("") - -# Each time Trident is imported, we determine the settings from the config -# file or try to create a config file. But don't do this on readthedocs, or -# it will fail in the build. In readthedocs environment, just set a dummy -# filepath so readthedocs can parse the docstrings OK. - - -on_rtd = os.environ.get('READTHEDOCS') == 'True' -if on_rtd: - ion_table_dir = trident_path() - ion_table_file = '__init__.py' - ion_table_filepath = os.path.join(ion_table_dir, ion_table_file) -else: - ion_table_dir, ion_table_file = parse_config() - ion_table_filepath = os.path.join(ion_table_dir, ion_table_file) diff --git a/trident/exceptions.py b/trident/exceptions.py new file mode 100644 index 0000000000..5031f7b832 --- /dev/null +++ b/trident/exceptions.py @@ -0,0 +1,31 @@ +""" +Trident exceptions + +""" + +#----------------------------------------------------------------------------- +# Copyright (c) 2017, Trident Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file LICENSE, distributed with this software. +#----------------------------------------------------------------------------- + +class TridentError(Exception): + """ + Trident Base Class Error + """ + pass + +class NotConfiguredError(TridentError): + """ + When Trident hasn't been configured properly with a config file. + """ + pass + +class NoIonBalanceTableError(TridentError): + """ + When Trident is missing its ion balance file and needs it. + """ + pass + diff --git a/trident/ion_balance.py b/trident/ion_balance.py index d23974096d..1bc803ba1a 100644 --- a/trident/ion_balance.py +++ b/trident/ion_balance.py @@ -23,7 +23,7 @@ import copy import os from trident.config import \ - ion_table_filepath + parse_config from trident.line_database import \ LineDatabase, \ uniquify @@ -56,7 +56,7 @@ def __init__(self, filename=None, atom=None): Name of the HDF5 file that contains the ionization table data. - Default: it uses the table specified in ~/.trident/config + Default: it uses the table specified in ~/.trident/config.tri :atom: string, optional @@ -65,7 +65,7 @@ def __init__(self, filename=None, atom=None): Default: None """ if filename is None: - filename = ion_table_filepath + filename = parse_config() self.filename = filename self.parameters = [] self.ion_fraction = [] @@ -194,7 +194,7 @@ def add_ion_fields(ds, ions, ftype='gas', Path to an appropriately formatted HDF5 table that can be used to compute the ion fraction as a function of density, temperature, metallicity, and redshift. When set to None, it uses the table - specified in ~/.trident/config + specified in ~/.trident/config.tri Default: None :field_suffix: boolean, optional @@ -238,7 +238,7 @@ def add_ion_fields(ds, ions, ftype='gas', ion_list = [] if ionization_table is None: - ionization_table = ion_table_filepath + ionization_table = parse_config() # Parse the ions given following the LineDatabase syntax @@ -320,7 +320,7 @@ def add_ion_fraction_field(atom, ion, ds, ftype="gas", Path to an appropriately formatted HDF5 table that can be used to compute the ion fraction as a function of density, temperature, metallicity, and redshift. By default, it uses the table specified in - ~/.trident/config + ~/.trident/config.tri :field_suffix: boolean, optional Determines whether or not to append a suffix to the field name that @@ -348,7 +348,7 @@ def add_ion_fraction_field(atom, ion, ds, ftype="gas", """ if ionization_table is None: - ionization_table = ion_table_filepath + ionization_table = parse_config() if ("gas", "log_nH") not in ds.derived_field_list: _add_field(ds, ("gas", "log_nH"), function=_log_nH, units="", @@ -439,7 +439,7 @@ def add_ion_number_density_field(atom, ion, ds, ftype="gas", Path to an appropriately formatted HDF5 table that can be used to compute the ion fraction as a function of density, temperature, metallicity, and redshift. By default, it uses the table specified in - ~/.trident/config + ~/.trident/config.tri :field_suffix: boolean, optional @@ -468,7 +468,8 @@ def add_ion_number_density_field(atom, ion, ds, ftype="gas", """ if ionization_table is None: - ionization_table = ion_table_filepath + ionization_table = parse_config() + atom = atom.capitalize() # if neutral ion field, alias X_number_density to X_p0_number_density field field = "%s_p%d_number_density" % (atom, ion-1) @@ -536,7 +537,7 @@ def add_ion_density_field(atom, ion, ds, ftype="gas", Path to an appropriately formatted HDF5 table that can be used to compute the ion fraction as a function of density, temperature, metallicity, and redshift. By default, it uses the table specified in - ~/.trident/config + ~/.trident/config.tri :field_suffix: boolean, optional @@ -565,7 +566,8 @@ def add_ion_density_field(atom, ion, ds, ftype="gas", """ if ionization_table is None: - ionization_table = ion_table_filepath + ionization_table = parse_config() + atom = atom.capitalize() # if neutral ion field, alias X_number_density to X_p0_number_density field @@ -634,7 +636,7 @@ def add_ion_mass_field(atom, ion, ds, ftype="gas", Path to an appropriately formatted HDF5 table that can be used to compute the ion fraction as a function of density, temperature, metallicity, and redshift. By default, it uses the table specified in - ~/.trident/config + ~/.trident/config.tri :field_suffix: boolean, optional @@ -663,7 +665,8 @@ def add_ion_mass_field(atom, ion, ds, ftype="gas", """ if ionization_table is None: - ionization_table = ion_table_filepath + ionization_table = parse_config() + atom = atom.capitalize() # if neutral ion field, alias X_number_density to X_p0_number_density field diff --git a/trident/ray_generator.py b/trident/ray_generator.py index 9e6d9f1c7d..3f08fb3726 100644 --- a/trident/ray_generator.py +++ b/trident/ray_generator.py @@ -15,8 +15,6 @@ LightRay from yt.convenience import \ load -from trident.config import \ - ion_table_filepath from trident.line_database import \ LineDatabase, \ uniquify @@ -68,7 +66,7 @@ def make_simple_ray(dataset_file, start_position, end_position, **Parameters** :dataset_file: string or yt Dataset object - + Either a yt dataset or the filename of a dataset on disk. If you are passing it a filename, consider usage of the ``load_kwargs`` and ``setup_function`` kwargs. @@ -110,7 +108,7 @@ def make_simple_ray(dataset_file, start_position, end_position, Default: None :data_filename: string, optional - + Output filename for ray data stored as an HDF5 file. Note that at present, you *must* save a ray to disk in order for it to be returned by this function. If set to None, defaults to 'ray.h5'. @@ -163,10 +161,8 @@ def make_simple_ray(dataset_file, start_position, end_position, :ionization_table: string, optional - For use with the :lines: keyword. Path to an appropriately formatted - HDF5 table that can be used to compute the ion fraction as a function - of density, temperature, metallicity, and redshift. When set to None, - it uses the table specified in ~/.trident/config + The keyword is deprecated. To explicitly set an ionization table, + set it using add_ion_fields(). Default: None **Example** @@ -195,9 +191,6 @@ def make_simple_ray(dataset_file, start_position, end_position, lr = LightRay(ds, load_kwargs=load_kwargs) - if ionization_table is None: - ionization_table = ion_table_filepath - # Include some default fields in the ray to assure it's processed correctly. fields = _add_default_fields(ds, fields) @@ -241,8 +234,7 @@ def make_compound_ray(parameter_filename, simulation_type, deltaz_min=0.0, minimum_coherent_box_fraction=0.0, find_outputs=False, seed=None, setup_function=None, load_kwargs=None, - line_database=None, ionization_table=None, - field_parameters = None): + line_database=None, field_parameters = None): """ Create a yt LightRay object for multiple consecutive datasets (eg IGM). This is a wrapper function around yt's LightRay interface to reduce some @@ -284,7 +276,7 @@ def make_compound_ray(parameter_filename, simulation_type, in the dataset volume, the compound ray requires the near_redshift and far_redshift to determine which datasets to use to get full coverage in redshift space as the ray propagates from near_redshift to far_redshift. - + Like the simple ray produced by :class:`~trident.make_simple_ray`, each gas cell intersected by the LightRay is sampled for the desired fields and stored. Several additional fields are created and stored @@ -424,14 +416,6 @@ def make_compound_ray(parameter_filename, simulation_type, and :lines:='all', it will add every ion of every element up to Zinc. Default: None - :ionization_table: string, optional - - For use with the :lines: keyword. Path to an appropriately formatted - HDF5 table that can be used to compute the ion fraction as a function - of density, temperature, metallicity, and redshift. When set to None, - it uses the table specified in ~/.trident/config - Default: None - :field_parameters: optional, dict Used to set field parameters in light rays. For example, if the 'bulk_velocity' field parameter is set, the relative @@ -475,9 +459,6 @@ def make_compound_ray(parameter_filename, simulation_type, minimum_coherent_box_fraction=minimum_coherent_box_fraction, load_kwargs=load_kwargs) - if ionization_table is None: - ionization_table = ion_table_filepath - # We use the final dataset from the light ray solution in order to test it for # what fields are present, etc. This all assumes that the fields present # in this output will be present in ALL outputs. Hopefully this is true, diff --git a/trident/spectrum_generator.py b/trident/spectrum_generator.py index f3538d5247..56560afb01 100644 --- a/trident/spectrum_generator.py +++ b/trident/spectrum_generator.py @@ -27,9 +27,10 @@ YTArray from trident.config import \ - ion_table_dir, \ - ion_table_file, \ - ion_table_filepath + parse_config, \ + trident_path +from trident.exceptions import \ + NoIonBalanceTableError from trident.instrument import \ Instrument from trident.ion_balance import \ @@ -41,8 +42,6 @@ LSF from trident.plotting import \ plot_spectrum -from trident.config import \ - trident_path from yt.utilities.on_demand_imports import \ _h5py, \ _astropy @@ -227,15 +226,18 @@ def __init__(self, instrument=None, lambda_min=None, lambda_max=None, if ionization_table is not None: # figure out where the user-specified files lives - if os.path.isfile(ion_table_file): - self.ionization_table = ion_table_file - elif os.path.isfile(ion_table_filepath): - self.ionization_table = ion_table_filepath + local_filepath = os.path.join(os.getcwd(), ionization_table) + config_dir = parse_config('ion_table_dir') + config_dir_filepath = os.path.join(config_dir, ionization_table) + if os.path.isfile(local_filepath): + self.ionization_table = local_filepath + elif os.path.isfile(config_dir_filepath): + self.ionization_table = config_dir_filepath else: - raise RuntimeError("ionization_table %s is not found in local " - "directory or in %s" % - (ion_table_file.split(os.sep)[-1], - ion_table_dir)) + raise NoIonBalanceTableError("No ion balance file %s found in " + "CWD or in %s" % (ionization_table, config_dir)) + + mylog.info("Using ionization table %s" % self.ionization_table) else: self.ionization_table = None diff --git a/trident/utilities.py b/trident/utilities.py index f8816d9c78..45fd70f7ff 100644 --- a/trident/utilities.py +++ b/trident/utilities.py @@ -448,16 +448,3 @@ def make_onezone_ray(density=1e-26, temperature=1000, metallicity=0.3, ray.domain_right_edge = ray.domain_right_edge.to('code_length') return ray - -def import_check(): - """ - """ - # Avoid astropy error when importing from trident package directory. - plist = os.path.dirname(os.path.abspath(__file__)).split(os.sep) - package_path = os.sep.join(plist[:-1]) - if os.getcwd() == package_path: - raise RuntimeError( - """ - -The Trident package does not work correctly when imported from its -installation directory. Please try moving to another directory.""")