Skip to main content
Version: Develop 🚧

Python API

uclchem

The UCLCHEM python module is divided into three parts. model contains the functions for running chemical models under different physics. analysis contains functions for reading and plotting output files as well as investigating the chemistry. tests contains functions for testing the code.

uclchem.analysis

read_output_file​

def read_output_file(output_file)

Read the output of a UCLCHEM run created with the outputFile parameter into a pandas DataFrame

Arguments:

  • output_file str - path to file containing a full UCLCHEM output

Returns:

  • pandas.DataFrame - A dataframe containing the abundances and physical parameters of the model at every time step.

create_abundance_plot​

def create_abundance_plot(df, species, figsize=(16, 9), plot_file=None)

Create a plot of the abundance of a list of species through time.

Arguments:

  • df pd.DataFrame - Pandas dataframe containing the UCLCHEM output, see read_output_file
  • species list - list of strings containing species names. Using a $ instead of # or @ will plot the sum of surface and bulk abundances.
  • figsize tuple, optional - Size of figure, width by height in inches. Defaults to (16, 9).
  • plot_file str, optional - Path to file where figure will be saved. If None, figure is not saved. Defaults to None.

Returns:

  • fig,ax - matplotlib figure and axis objects

plot_species​

def plot_species(ax, df, species, legend=True, **plot_kwargs)

Plot the abundance of a list of species through time directly onto an axis.

Arguments:

  • ax pyplot.axis - An axis object to plot on
  • df pd.DataFrame - A dataframe created by read_output_file
  • species str - A list of species names to be plotted. If species name starts with "$" instead of # or @, plots the sum of surface and bulk abundances

Returns:

  • pyplot.axis - Modified input axis is returned

analysis​

def analysis(species_name, result_file, output_file, rate_threshold=0.99)

A function which loops over every time step in an output file and finds the rate of change of a species at that time due to each of the reactions it is involved in. From this, the most important reactions are identified and printed to file. This can be used to understand the chemical reason behind a species' behaviour.

Arguments:

  • species_name str - Name of species to be analysed
  • result_file str - The path to the file containing the UCLCHEM output
  • output_file str - The path to the file where the analysis output will be written
  • rate_threshold float,optional - Analysis output will contain the only the most efficient reactions that are responsible for rate_threshold of the total production and destruction rate. Defaults to 0.99.

total_element_abundance​

def total_element_abundance(element, df)

Calculates that the total elemental abundance of a species as a function of time. Allows you to check conservation.

Arguments:

  • element str - Name of element
  • df pandas.DataFrame - DataFrame from read_output_file()

Returns:

  • pandas.Series - Total abundance of element for all time steps in df.

check_element_conservation​

def check_element_conservation(df,
element_list=["H", "N", "C", "O"],
percent=True)

Check the conservation of major element by comparing total abundance at start and end of model

Arguments:

  • df pandas.DataFrame - UCLCHEM output in format from read_output_file
  • element_list list, optional - List of elements to check. Defaults to ["H", "N", "C", "O"].

Returns:

  • dict - Dictionary containing the change in the total abundance of each element as a fraction of initial value

uclchem.constants

uclchem.model

outputArrays_to_DataFrame​

def outputArrays_to_DataFrame(physicalParameterArray, chemicalAbundanceArray,
specname, physParameter)

Convert the output arrays to a pandas dataframe

Arguments:

  • physicalParameterArray np.array - Array with the output physical parameters
  • chemicalAbundanceArray np.array - Array with the output chemical abundances
  • specname list - List with the names of all the species
  • physParameter list - Array with all the physical parameter names

Returns:

  • _type_ - description

cloud​

def cloud(param_dict=None,
out_species=None,
return_array=False,
return_dataframe=False,
starting_chemistry=None,
timepoints=TIMEPOINTS)

Run cloud model from UCLCHEM

Arguments:

  • param_dict dict,optional - A dictionary of parameters where keys are any of the variables in defaultparameters.f90 and values are value for current run.
  • out_species list, optional - A list of species for which final abundance will be returned. If None, no abundances will be returned.. Defaults to None.
  • return_array bool, optional - A boolean on whether a np.array should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • return_dataframe bool, optional - A boolean on whether a pandas.DataFrame should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • starting_chemistry array, optional - np.array containing the starting chemical abundances needed by uclchem

Returns:

if return_array and return_dataframe are False:

  • A list where the first element is always an integer which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. If the out_species parametere is provided, the remaining elements of this list will be the final abundances of the species in out_species. if return_array is True:
  • physicsArray (array): array containing the physical outputs for each written timestep
  • chemicalAbunArray (array): array containing the chemical abundances for each written timestep
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. if return_dataframe is True:
  • physicsDF (pandas.DataFrame): DataFrame containing the physical outputs for each written timestep
  • chemicalDF (pandas.DataFrame): DataFrame containing the chemical abundances for each written timestep
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details.

collapse​

def collapse(collapse,
physics_output,
param_dict=None,
out_species=None,
return_array=False,
return_dataframe=False,
starting_chemistry=None,
timepoints=TIMEPOINTS)

Run collapse model from UCLCHEM based on Priestley et al 2018 AJ 156 51 (https://ui.adsabs.harvard.edu/abs/2018AJ....156...51P/abstract)

Arguments:

  • collapse str - A string containing the collapse type, options are 'BE1.1', 'BE4', 'filament', or 'ambipolar'
  • physics_output(str) - Filename to store physics output, only relevant for 'filament' and 'ambipolar' collapses. If None, no physics output will be saved.
  • param_dict dict,optional - A dictionary of parameters where keys are any of the variables in defaultparameters.f90 and values are value for current run.
  • out_species list, optional - A list of species for which final abundance will be returned. If None, no abundances will be returned.. Defaults to None.
  • return_array bool, optional - A boolean on whether a np.array should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • return_dataframe bool, optional - A boolean on whether a pandas.DataFrame should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • starting_chemistry array, optional - np.array containing the starting chemical abundances needed by uclchem

Returns:

if return_array and return_dataframe are False:

  • A list where the first element is always an integer which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. If the out_species parametere is provided, the remaining elements of this list will be the final abundances of the species in out_species. if return_array is True:
  • physicsArray (array): array containing the physical outputs for each written timestep
  • chemicalAbunArray (array): array containing the chemical abundances for each written timestep
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. if return_dataframe is True:
  • physicsDF (pandas.DataFrame): DataFrame containing the physical outputs for each written timestep
  • chemicalDF (pandas.DataFrame): DataFrame containing the chemical abundances for each written timestep
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details.

hot_core​

def hot_core(temp_indx,
max_temperature,
param_dict=None,
out_species=None,
return_array=False,
return_dataframe=False,
starting_chemistry=None,
timepoints=TIMEPOINTS)

Run hot core model from UCLCHEM, based on Viti et al. 2004 and Collings et al. 2004

Arguments:

  • temp_indx int - Used to select the mass of hot core. 1=1Msun,2=5, 3=10, 4=15, 5=25,6=60]
  • max_temperature float - Value at which gas temperature will stop increasing.
  • param_dict dict,optional - A dictionary of parameters where keys are any of the variables in defaultparameters.f90 and values are value for current run.
  • out_species list, optional - A list of species for which final abundance will be returned. If None, no abundances will be returned.. Defaults to None.
  • return_array bool, optional - A boolean on whether a np.array should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • return_dataframe bool, optional - A boolean on whether a pandas.DataFrame should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • starting_chemistry array, optional - np.array containing the starting chemical abundances needed by uclchem

Returns:

if return_array and return_dataframe are False:

  • A list where the first element is always an integer which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. If the out_species parametere is provided, the remaining elements of this list will be the final abundances of the species in out_species. if return_array is True:
  • physicsArray (array): array containing the physical outputs for each written timestep
  • chemicalAbunArray (array): array containing the chemical abundances for each written timestep
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. if return_dataframe is True:
  • physicsDF (pandas.DataFrame): DataFrame containing the physical outputs for each written timestep
  • chemicalDF (pandas.DataFrame): DataFrame containing the chemical abundances for each written timestep
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details.

cshock​

def cshock(shock_vel,
timestep_factor=0.01,
minimum_temperature=0.0,
param_dict=None,
out_species=None,
return_array=False,
return_dataframe=False,
starting_chemistry=None,
timepoints=TIMEPOINTS)

Run C-type shock model from UCLCHEM

Arguments:

  • shock_vel float - Velocity of the shock in km/s
  • timestep_factor float, optional - Whilst the time is less than 2 times the dissipation time of shock, timestep is timestep_factor*dissipation time. Essentially controls how well resolved the shock is in your model. Defaults to 0.01.
  • minimum_temperature float, optional - Minimum post-shock temperature. Defaults to 0.0 (no minimum). The shocked gas typically cools to initialTemp if this is not set.
  • param_dict dict,optional - A dictionary of parameters where keys are any of the variables in defaultparameters.f90 and values are value for current run.
  • out_species list, optional - A list of species for which final abundance will be returned. If None, no abundances will be returned.. Defaults to None.
  • return_array bool, optional - A boolean on whether a np.array should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • return_dataframe bool, optional - A boolean on whether a pandas.DataFrame should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • starting_chemistry array, optional - np.array containing the starting chemical abundances needed by uclchem

Returns:

if return_array and return_dataframe are False:

  • A list where the first element is always an integer which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. If the model succeeded, the second element is the dissipation time and further elements are the abundances of all species in out_species. if return_array is True:
  • physicsArray (array): array containing the physical outputs for each written timestep
  • chemicalAbunArray (array): array containing the chemical abundances for each written timestep
  • disspation_time (float): dissipation time in years
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. if return_dataframe is True:
  • physicsDF (pandas.DataFrame): DataFrame containing the physical outputs for each written timestep
  • chemicalDF (pandas.DataFrame): DataFrame containing the chemical abundances for each written timestep
  • disspation_time (float): dissipation time in years
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details.

jshock​

def jshock(shock_vel,
param_dict=None,
out_species=None,
return_array=False,
return_dataframe=False,
starting_chemistry=None,
timepoints=TIMEPOINTS)

Run J-type shock model from UCLCHEM

Arguments:

  • shock_vel float - Velocity of the shock

  • param_dict dict,optional - A dictionary of parameters where keys are any of the variables in defaultparameters.f90 and values are value for current run.

  • out_species list, optional - A list of species for which final abundance will be returned. If None, no abundances will be returned.. Defaults to None.

  • return_array bool, optional - A boolean on whether a np.array should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file

  • return_dataframe bool, optional - A boolean on whether a pandas.DataFrame should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file

  • starting_chemistry array, optional - np.array containing the starting chemical abundances needed by uclchem

    Returns:if return_array and return_dataframe are False:

    • A list where the first element is always an integer which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. If the model succeeded, the second element is the dissipation time and further elements are the abundances of all species in out_species. if return_array is True:
    • physicsArray (array): array containing the physical outputs for each written timestep
    • chemicalAbunArray (array): array containing the chemical abundances for each written timestep
    • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
    • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. if return_dataframe is True:
    • physicsDF (pandas.DataFrame): DataFrame containing the physical outputs for each written timestep
    • chemicalDF (pandas.DataFrame): DataFrame containing the chemical abundances for each written timestep
    • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
    • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details.

postprocess​

def postprocess(param_dict=None,
out_species=None,
return_array=False,
return_dataframe=False,
starting_chemistry=None,
time_array=None,
density_array=None,
gas_temperature_array=None,
dust_temperature_array=None,
zeta_array=None,
radfield_array=None,
coldens_H_array=None,
coldens_H2_array=None,
coldens_CO_array=None,
coldens_C_array=None)

Run cloud model from UCLCHEM

Arguments:

  • param_dict dict,optional - A dictionary of parameters where keys are any of the variables in defaultparameters.f90 and values are value for current run.
  • out_species list, optional - A list of species for which final abundance will be returned. If None, no abundances will be returned.. Defaults to None.
  • return_array bool, optional - A boolean on whether a np.array should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • return_dataframe bool, optional - A boolean on whether a pandas.DataFrame should be returned to a user, if both return_array and return_dataframe are false, this function will default to writing outputs to a file
  • starting_chemistry array, optional - np.array containing the starting chemical abundances needed by uclchem

Returns:

if return_array and return_dataframe are False:

  • A list where the first element is always an integer which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. If the out_species parametere is provided, the remaining elements of this list will be the final abundances of the species in out_species. if return_array is True:
  • physicsArray (array): array containing the physical outputs for each written timestep
  • chemicalAbunArray (array): array containing the chemical abundances for each written timestep
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details. if return_dataframe is True:
  • physicsDF (pandas.DataFrame): DataFrame containing the physical outputs for each written timestep
  • chemicalDF (pandas.DataFrame): DataFrame containing the chemical abundances for each written timestep
  • abundanceStart (array): array containing the chemical abundances of the last timestep in the format uclchem needs in order to perform an additional run after the initial model
  • success_flag (integer): which is negative if the model failed to run and can be sent to uclchem.utils.check_error() to see more details.

uclchem.utils

cshock_dissipation_time​

def cshock_dissipation_time(shock_vel, initial_dens)

A simple function used to calculate the dissipation time of a C-type shock. Use to obtain a useful timescale for your C-shock model runs. Velocity of ions and neutrals equalizes at dissipation time and full cooling takes a few dissipation times.

Arguments:

  • shock_vel float - Velocity of the shock in km/s
  • initial_dens float - Preshock density of the gas in cmβˆ’3^{-3}

Returns:

  • float - The dissipation time of the shock in years

check_error​

def check_error(error_code)

Converts the UCLCHEM integer result flag to a simple messaging explaining what went wrong"

Arguments:

  • error_code int - Error code returned by UCLCHEM models, the first element of the results list.

Returns:

  • str - Error message

get_species_table​

def get_species_table()

A simple function to load the list of species in the UCLCHEM network into a pandas dataframe.

Returns:

  • pandas.DataFrame - A dataframe containing the species names and their details

get_species​

def get_species() -> list[str]

A simple function to load the list of species present in the UCLCHEM network

Returns:

list[str] : A list of species names

get_reaction_table​

def get_reaction_table()

A function to load the reaction table from the UCLCHEM network into a pandas dataframe.

Returns:

  • pandas.DataFrame - A dataframe containing the reactions and their rates

uclchem.debug

Functions to help debugging UCLCHEM

get_f2py_signature​

def get_f2py_signature(write=False) -> str

Get the signature of the UCLCHEM fortran code

Arguments:

  • write bool, optional - Write to disk. Defaults to False.

Returns:

  • str - Signature of the UCLCHEM fortran code from the f2py wrapper

uclchem.tests

test_ode_conservation​

def test_ode_conservation(element_list=["H", "N", "C", "O"])

Test whether the ODEs conserve elements. Useful to run each time you change network. Integrator errors may still cause elements not to be conserved but they cannot be conserved if the ODEs are not correct.

Arguments:

  • element_list list, optional - A list of elements for which to check the conservation. Defaults to ["H", "N", "C", "O"].

Returns:

  • dict - A dictionary of the elements in element list with values representing the total rate of change of each element.

uclchem.makerates.species

is_number​

def is_number(s) -> bool

Try to convert input to a float, if it succeeds, return True.

Arguments:

  • s - Input element to check for

Returns:

  • bool - True if a number, False if not.

Species Objects​

class Species()

Species is a class that holds all the information about an individual species in the network. It also has convenience functions to check whether the species is a gas or grain species and to help compare between species.

__init__​

def __init__(inputRow)

A class representing chemical species, it reads in rows which are formatted as follows: NAME,MASS,BINDING ENERGY,SOLID FRACTION,MONO FRACTION,VOLCANO FRACTION,ENTHALPY

Arguments:

inputRow (list):

get_name​

def get_name() -> str

Get the name of the chemical species.

Returns:

  • str - The name

get_mass​

def get_mass() -> int

Get the molecular mass of the chemical species

Returns:

  • int - The molecular mass

set_desorb_products​

def set_desorb_products(new_desorbs: list[str]) -> None

Set the desorption products for species on the surface or in the bulk. It is assumed that there is only one desorption pathway.

Arguments:

  • new_desorbs list[str] - The new desorption products

get_desorb_products​

def get_desorb_products() -> list[str]

Obtain the desorbtion products of ice species

Returns:

  • list[str] - The desorption products

set_freeze_products​

def set_freeze_products(product_list: list[str], freeze_alpha: float) -> None

Add the freeze products of the species, one species can have several freeze products.

Arguments:

get_freeze_products​

def get_freeze_products() -> dict[list[str], float]

Obtain the product to which the species freeze out

Returns:

dict[str, float]: Reactions and their respective freeze out ratios.

Yields:

Iterator[dict[str, float]]: Iterator that returns all of the freeze out reactions with ratios

get_freeze_products_list​

def get_freeze_products_list() -> list[list[str]]

Returns all the freeze products without their ratios

Returns:

  • list[list[str]] - List of freeze products

get_freeze_alpha​

def get_freeze_alpha(product_list: list[str]) -> float

Obtain the freeze out ratio of a species for a certain reaction

Arguments:

  • product_list list[str] - For a specific reaction, get the freezeout ratio

Returns:

  • float - The freezeout ratio

is_grain_species​

def is_grain_species() -> bool

Return whether the species is a species on the grain

Returns:

  • bool - True if it is a grain species.

is_surface_species​

def is_surface_species() -> bool

Checks if the species is on the surface

Returns:

  • bool - True if a surface species

is_bulk_species​

def is_bulk_species() -> bool

Checks if the species is in the bulk

Returns:

  • bool - True if a bulk species

is_ion​

def is_ion() -> bool

Checks if the species is ionized, either postively or negatively.

Returns:

  • bool - True if it is an ionized

add_default_freeze​

def add_default_freeze() -> None

Adds a defalt freezeout, which is freezing out to the species itself, but with no ionization.

find_constituents​

def find_constituents()

Loop through the species' name and work out what its consituent atoms are. Then calculate mass and alert user if it doesn't match input mass.

get_n_atoms​

def get_n_atoms() -> int

Obtain the number of atoms in the molecule

Returns:

  • int - The number of atoms

set_n_atoms​

def set_n_atoms(new_n_atoms: int) -> None

Set the number of atoms

Arguments:

  • new_n_atoms int - The new number of atoms

__eq__​

def __eq__(other)

Check for equality based on either a string or another Species instance.

Arguments:

  • other str, Species - Another species

Raises:

  • NotImplementedError - We can only compare between species or strings of species.

Returns:

  • bool - True if two species are identical.

__lt__​

def __lt__(other) -> bool

Compare the mass of the species

Arguments:

  • other Species - Another species instance

Returns:

  • bool - True if less than the other species

__gt__​

def __gt__(other) -> bool

Compare the mass of the species

Arguments:

  • other Species - Another species instance

Returns:

  • bool - True if larger than than the other species

uclchem.makerates

uclchem.makerates.makerates

run_makerates​

def run_makerates(configuration_file: str = "user_settings.yaml",
write_files: bool = True) -> Network

The main run wrapper for makerates, it loads a configuration, parses it in Network and then returns the Network. It by default writes to the uclchem fortran directory, but this can be skipped.

Arguments:

  • configuration_file str, optional - A UCLCHEM Makerates configuration file. Defaults to "user_settings.yaml".
  • write_files bool, optional - Whether to write the fortran files to the src/fortran_src. Defaults to True.

Raises:

  • KeyError - The configuration cannot be found

Returns:

  • Network - A chemical network instance.

get_network​

def get_network(path_to_input_file: Union[str, bytes, os.PathLike] = None,
path_to_species_file: Union[str, bytes, os.PathLike] = None,
path_to_reaction_file: Union[str, bytes, os.PathLike] = None,
verbosity=None)

In memory equivalent of Makerates, can either be used on the original input files for makerates, or on the output files that makerates generates. So either specify:

path_to_input_file exclusive OR (path_to_species_file and path_to_reaction_file)

The latter scenario allows you to reload a reaction network from a network already written by Makerates.

Arguments:

  • path_to_input_file Union[str, bytes, os.PathLike], optional - Path to input file. Defaults to None.
  • path_to_species_file Union[str, bytes, os.PathLike], optional - Path to a species.csv in/from the src directory. Defaults to None.
  • path_to_reaction_file Union[str, bytes, os.PathLike], optional - Path to a reactions.csv in/from the src directory. Defaults to None.
  • verbosity LEVEL, optional - The verbosity level as specified in logging. Defaults to None.

Raises:

  • ValueError - You cannot specify both an input configuration and species+reaction.

Returns:

  • Network - A chemical reaction network.

uclchem.makerates.network

This python file contains all functions for de-duplicating species and reaction lists, checking for common errors, and automatic addition of reactions such as freeze out, desorption and bulk reactions for three phase models.

Network Objects​

class Network()

The network class stores all the information about reaction network.

__init__​

def __init__(species: list[Species],
reactions: list[Reaction],
three_phase: bool = False,
user_defined_bulk: list = [])

A class to store network information such as indices of important reactions.

The class fully utilizes getters and setters, which can be used to add/remove reactions and the species involved. Important is that you do not directly edit the internal dictionaries that store the species and reactions, unless you know what you are doing. The network by default checks for duplicates in species and identical reactions that overlap in temperature ranges, potentially causing problems.

Arguments:

  • species list[Species] - A list of chemical species that are added to the network
  • reactions list[Reaction] - A list of chemical reactions that are added to the network
  • three_phase bool, optional - Whether to use a three phase model (gas, surface, bulk). Defaults to False.
  • user_defined_bulk list, optional - List of user defined bulk. Defaults to [].

add_reactions​

def add_reactions(reactions: Union[Union[Reaction, str], list[Union[Reaction,
str]]])

Add a reaction, list of inputs to the Reaction class or list of reactions to the network.

Arguments:

  • reactions Union[Union[Reaction, str], list[Union[Reaction, str]]] - Reaction or list or reactions

find_similar_reactions​

def find_similar_reactions(reaction: Reaction) -> dict[int, Reaction]

Reactions are similar if the reaction has the same reactants and products, find all reactions that are similar, returning their index and the reaction itself.

Arguments:

  • reaction Reaction - Reaction with possible identical (but for temperature range) reactions in the network

Returns:

dict[int, Reaction]: A dict with the identical reactions.

remove_reaction_by_index​

def remove_reaction_by_index(reaction_idx: int) -> None

Remove a reaction by its index in the internal _reactions_dict, this is the only way to remove reactions that are defined piecewise across temperature ranges.

Arguments:

  • reaction_idx int - Index of the reaction to remove

remove_reaction​

def remove_reaction(reaction: Reaction) -> None

Remove the reaction by giving the object itself, this only works if the reaction is not piecewise defined across the temperature ranges.

Arguments:

  • reaction Reaction - The reaction you wish to delete.

get_reaction​

def get_reaction(reaction_idx: int) -> Reaction

Obtain a reaction from the reaction set given an index of the internal _reactions_dict.

Arguments:

  • reaction_idx int - The reaction index

Returns:

  • Reaction - the desired reaction

set_reaction​

def set_reaction(reaction_idx: int, reaction: Reaction) -> None

This setter explicitely sets the reaction for a certain index.

Arguments:

  • reaction_idx int - The index to be written to
  • reaction Reaction - The reaction to be added to the index.

get_reaction_dict​

def get_reaction_dict() -> dict[int, Reaction]

Returns the whole internal reaction dictionary.

Returns:

dict[int, Reaction]: A copy of the internal reactions dictionary.

set_reaction_dict​

def set_reaction_dict(new_dict: dict[int, Reaction]) -> None

Override the reactions dictionary with a new dictionar.

Arguments:

  • new_dict dict[int, Reaction] - The new reactions_dictionary.

get_reaction_list​

def get_reaction_list() -> list[Reaction]

Obtain all the reactions in the Network.

Returns:

  • list[Reaction] - A list with all the reaction objects

sort_reactions​

def sort_reactions() -> None

Sort the reaction dictionary by reaction type first and by the first reactant second.

add_species​

def add_species(species: Union[Union[Species, str], list[Union[Species,
str]]])

Add species to the network, given a (list of) species. If it is a list of strings, it tries to instantiate a species class with it. It also checks for duplicate entries and filters out attempts to add reaction types to the species.

Arguments:

  • species Union[Union[Species, str], list[Union[Species, str]]] - A (list of) species or strings.

Raises:

  • ValueError - If we cannot parse the (list of) reactions
  • ValueError - If an ice specie with binding energy of zero is added.

remove_species​

def remove_species(specie_name: str) -> None

Remove a specie from the network

Arguments:

  • specie_name str - Species to remove

get_species_list​

def get_species_list() -> list[Species]

Obtain a list with all the species in the network

Returns:

  • list[Species] - A list of all the species in the reaction network

get_species_dict​

def get_species_dict() -> dict[str, Species]

Get the internal dictionary that stores all the species, it consists of all species' names as key, with the species object as value.

Returns:

dict[str, Species]: A dictionary with the species

get_specie​

def get_specie(specie_name: str) -> Species

Get the species of the reaction network (from the internal dictionary)

Arguments:

  • specie_name str - the name of the species as a string

Returns:

  • Species - The species object

set_specie​

def set_specie(species_name: str, species: Species) -> None

Set the species of the reaction network in the internal dictionary

Arguments:

  • species_name str - The name of the species as string
  • species Species - The Species object to set

set_species_dict​

def set_species_dict(new_species_dict: dict[str, Species]) -> None

Set the internal species dict

Arguments:

  • new_species_dict dict[str, Species] - The new dictionary to set

sort_species​

def sort_species() -> None

Sort the species based on their mass in ascending order. We always make sure the Electron is last.

check_network​

def check_network() -> None

Run through the list of reactions and check for obvious errors such as duplicate reactions, multiple freeze out routes (to warn, not necessarily an error), etc.

check_and_filter_species​

def check_and_filter_species() -> None

Check every speces in network appears in at least one reaction. Remove any that do not and alert user.

add_bulk_species​

def add_bulk_species() -> None

For three phase models, MakeRates will produce the version of the species in the bulk so that the user doesn't have to endlessly relist the same species

check_freeze_and_desorbs​

def check_freeze_and_desorbs() -> None

add_freeze_reactions() and add_desorb_reactions() automatically generate all desorption and freeze out reactions. However, user may want to change a species on freeze out eg C+ becomes C rather than C+. This function checks for that and updates species so they'll freeze or desorb correctly when reactions are generated.

add_freeze_reactions​

def add_freeze_reactions() -> None

Save the user effort by automatically generating freeze out reactions

add_desorb_reactions​

def add_desorb_reactions() -> None

Save the user effort by automatically generating desorption reactions

add_chemdes_reactions​

def add_chemdes_reactions() -> None

We have the user list all Langmuir-Hinshelwood and Eley-Rideal reactions once. Then we duplicate so that the reaction branches with products on grain and products desorbing.

check_for_excited_species​

def check_for_excited_species() -> bool

Check if there are any exicted species in the network, true if there are any.

add_excited_surface_reactions​

def add_excited_surface_reactions() -> None

All excited species will relax to the ground state if they do not react the vibrational frequency of the species is used as a pseudo approximation of the rate coefficient We assume all grain reactions have an excited variant. For example: A, B LH C will have the variants: A, B EXSOLID C and A, B EXSOLID C If only one of the reactants in the base reaction has an excited counterpart then only one excited version of that reaction is created.

add_bulk_reactions​

def add_bulk_reactions() -> None

We assume any reaction that happens on the surface of grains can also happen in the bulk (just more slowly due to binding energy). The user therefore only lists surface reactions in their input reaction file and we duplicate here.

freeze_checks​

def freeze_checks() -> None

Check that every species freezes out and alert the user if a species freezes out via mutiple routes. This isn't necessarily an error so best just print.

duplicate_checks​

def duplicate_checks() -> None

Check reaction network to make sure no reaction appears twice unless they have different temperature ranges.

index_important_reactions​

def index_important_reactions() -> None

We have a whole bunch of important reactions and we want to store their indices. We find them all here.

index_important_species​

def index_important_species() -> None

Obtain the indices for all the important reactions.

branching_ratios_checks​

def branching_ratios_checks() -> None

Check that the branching ratios for the ice reactions sum to 1.0. If they do not, correct them. This needs to be done for LH and LHDES separately since we already added the desorption to the network.

LoadedNetwork Objects​

class LoadedNetwork(Network)

Network version that skips all steps and just loads two lists. This is another here be dragons version, use this with exceeding caution as no checks are performed for you.

Arguments:

  • Network type - description

__init__​

def __init__(species: list[Species], reactions: list[Reaction]) -> None

A loader of networks without any checks.

Here be dragons.

Arguments:

  • species list[Species] - A list of species objects
  • reactions list[Reaction] - A list of reaction objects.

uclchem.makerates.io_functions

Functions to read in the species and reaction files and write output files

read_species_file​

def read_species_file(file_name: Path) -> list[Species]

Reads in a Makerates species file

Arguments:

  • fileName str - path to file containing the species list

Returns:

  • list - List of Species objects

read_reaction_file​

def read_reaction_file(file_name: Path, species_list: list[Species],
ftype: str) -> tuple[list[Reaction], list[Reaction]]

Reads in a reaction file of any kind (user, UMIST, KIDA) produces a list of reactions for the network, filtered by species_list

Arguments:

  • file_name str - A file name for the reaction file to read.
  • species_list list[Species] - A list of chemical species to be used in the reading.
  • ftype str - 'UMIST','UCL', or 'KIDA' to describe format of file_name

Returns:

  • list,list - Lists of kept and dropped reactions.

check_reaction​

def check_reaction(reaction_row, keep_list) -> bool

Checks a row parsed from a reaction file and checks it only contains acceptable things. It checks if all species in the reaction are present, and adds the temperature range is none is specified.

Arguments:

  • reaction_row list - List parsed from a reaction file and formatted to be able to called Reaction(reaction_row)
  • keep_list list - list of elements that are acceptable in the reactant or product bits of row

Returns:

  • bool - Whether the row contains acceptable entries.

kida_parser​

def kida_parser(kida_file)

KIDA used a fixed format file so we read each line in the chunks they specify and use python built in classes to convert to the necessary types. NOTE KIDA defines some of the same reaction types to UMIST but with different names and coefficients. We fix that by converting them here.

output_drops​

def output_drops(dropped_reactions: list[Reaction],
output_dir: str = None,
write_files: bool = True)

Writes the reactions that are dropped to disk/logs

Arguments:

  • dropped_reactions list[Reaction] - The reactions that were dropped
  • output_dir str - The directory that dropped_reactions.csv will be written to.
  • write_files bool, optional - Whether or not to write the file. Defaults to True.

write_outputs​

def write_outputs(network: Network, output_dir: str = None) -> None

Write the ODE and Network fortran source files to the fortran source.

Arguments:

  • network network - The makerates Network class
  • output_dir bool - The directory to write to.

write_f90_constants​

def write_f90_constants(
replace_dict: Dict[str, int],
output_file_name: Path,
template_file_path: Path = "fortran_templates") -> None

Write the physical reactions to the f2py_constants.f90 file after every run of makerates, this ensures the Fortran and Python bits are compatible with one another.

Arguments:

  • replace_dict Dict[str, int] - The dictionary with keys to replace and their values
  • output_file_name Path - The path to the target f2py_constants.f90 file
  • template_file_path Path, optional - The file to use as the template. Defaults to "fortran_templates".

write_python_constants​

def write_python_constants(replace_dict: Dict[str, int],
python_constants_file: Path) -> None

Function to write the python constants to the constants.py file after every run, this ensure the Python and Fortran bits are compatible with one another.

Arguments:

  • replace_dict Dict[str, int]] - Dict with keys to replace and their values
  • python_constants_file Path - Path to the target constant files.

write_species​

def write_species(file_name: Path, species_list: list[Species]) -> None

Write the human readable species file. Note UCLCHEM doesn't use this file.

Arguments:

  • fileName str - path to output file
  • species_list list - List of species objects for network

write_reactions​

def write_reactions(fileName, reaction_list) -> None

Write the human readable reaction file. Note UCLCHEM doesn't use this file.

Arguments:

  • fileName str - path to output file
  • reaction_list list - List of reaction objects for network

write_odes_f90​

def write_odes_f90(file_name: Path, species_list: list[Species],
reaction_list: list[Reaction], three_phase: bool) -> None

Write the ODEs in Modern Fortran. This is an actual code file.

Arguments:

  • file_name str - Path to file where code will be written
  • species_list list - List of species describing network
  • reaction_list list - List of reactions describing network
  • three_phase bool - Flag for whether this is a 3 phase network

write_jacobian​

def write_jacobian(file_name: Path, species_list: list[Species]) -> None

Write jacobian in Modern Fortran. This has never improved UCLCHEM's speed and so is not used in the code as it stands. Current only works for three phase model.

Arguments:

  • file_name str - Path to jacobian file
  • species_list species_list - List of species AFTER being processed by build_ode_string

build_ode_string​

def build_ode_string(species_list: list[Species],
reaction_list: list[Reaction], three_phase: bool) -> str

A long, complex function that does the messy work of creating the actual ODE code to calculate the rate of change of each species. Test any change to this code thoroughly because ODE mistakes are very hard to spot.

Arguments:

  • species_list list - List of species in network
  • reaction_list list - List of reactions in network
  • three_phase bool - Bool denoting if this is a three phase network

Returns:

  • str - One long string containing the entire ODE fortran code.

species_ode_string​

def species_ode_string(n: int, species: Species) -> str

Build the string of Fortran code for a species once it's loss and gains strings have been produced.

Arguments:

  • n int - Index of species in python format
  • species Species - species object

Returns:

  • str - the fortran code for the rate of change of the species

write_evap_lists​

def write_evap_lists(network_file, species_list: list[Species]) -> None

Two phase networks mimic episodic thermal desorption seen in lab (see Viti et al. 2004) by desorbing fixed fractions of material at specific temperatures. Three phase networks just use binding energy and that fact we set binding energies in bulk to water by default. This function writes all necessary arrays to the network file so these processes work.

Arguments:

  • network_file file - Open file object to which the network code is being written
  • species_list list[Species] - List of species in network

truncate_line​

def truncate_line(input_string: str, lineLength: int = 72) -> str

Take a string and adds line endings at regular intervals keeps us from overshooting fortran's line limits and, frankly, makes for nicer ode.f90 even if human readability isn't very important

Arguments:

  • input_string str - Line of code to be truncated
  • lineLength int, optional - rough line length. Defaults to 72.

Returns:

  • str - Code string with line endings at regular intervals

write_network_file​

def write_network_file(file_name: Path, network: Network)

Write the Fortran code file that contains all network information for UCLCHEM. This includes lists of reactants, products, binding energies, formationEnthalpies and so on.

Arguments:

  • file_name str - The file name where the code will be written.
  • network Network - A Network object built from lists of species and reactions.

find_reactant​

def find_reactant(species_list: list[str], reactant: str) -> int

Try to find a reactant in the species list

Arguments:

  • species_list list[str] - A list of species in the network
  • reactant str - The reactant to be indexed

Returns:

  • int - The index of the reactant, if it is not found, 9999

get_desorption_freeze_partners​

def get_desorption_freeze_partners(
reaction_list: list[Reaction]) -> list[Reaction]

Every desorption has a corresponding freeze out eg desorption of CO and freeze of CO. This find the corresponding freeze out for every desorb so that when desorb>>freeze we can turn off freeze out in UCLCHEM.

Arguments:

  • reaction_list list - Reactions in network

Returns:

  • list - list of indices of freeze out reactions matching order of desorptions.

array_to_string​

def array_to_string(name: str,
array: np.array,
type: str = "int",
parameter: bool = True) -> str

Write an array to fortran source code

Arguments:

  • name str - Variable name of array in Fortran
  • array iterable - List of values of array
  • type str, optional - The array's type. Must be one of "int","float", or "string".Defaults to "int".
  • parameter bool, optional - Whether the array is a Fortran PARAMETER (constant). Defaults to True.

Raises:

  • ValueError - Raises an error if type isn't "int","float", or "string"

Returns:

  • str - String containing the Fortran code to declare this array.

uclchem.makerates.reaction

Reaction Objects​

class Reaction()

get_reactants​

def get_reactants() -> list[str]

Get the four reactants present in the reaction, padded with NAN for nonexistent

Returns:

  • list[str] - The four reactants names

get_sorted_reactants​

def get_sorted_reactants() -> list[str]

Get the four reactants present in the reaction, sorted for fast comparisons

Arguments:

  • reactants list[str] - The four sorted reactant names

set_reactants​

def set_reactants(reactants: list[str]) -> None

Set the four reactants present in the reaction, padded with NAN for nonexistent

Arguments:

  • reactants list[str] - The four reactants names

get_products​

def get_products() -> list[str]

Get the four products present in the reaction, padded with NAN for nonexistent

Arguments:

  • reactants list[str] - The four products names

get_sorted_products​

def get_sorted_products() -> list[str]

Get the four products present in the reaction, sorted for fast comparisons

Arguments:

  • products list[str] - The four sorted products names

set_products​

def set_products(products: list[str]) -> None

Set the four products present in the reaction, padded with NAN for nonexistent

Arguments:

  • products list[str] - The four products names

get_alpha​

def get_alpha() -> float

Get the alpha parameter from the Kooij-Arrhenius equation

Returns:

  • float - the alpha parameter of the reaction

set_alpha​

def set_alpha(alpha: float) -> None

Set the alpha parameter from the Kooij-Arrhenius equation

Arguments:

  • alpha float - the alpha parameter of the reaction

get_beta​

def get_beta() -> float

Get the beta parameter from the Kooij-Arrhenius equation

Returns:

  • float - the beta parameter of the reaction

set_beta​

def set_beta(beta: float) -> None

Set the beta parameter from the Kooij-Arrhenius equation

Arguments:

  • beta float - the beta parameter of the reaction

set_gamma​

def set_gamma(gamma: float) -> None

Set the gamma parameter from the Kooij-Arrhenius equation

Arguments:

  • gamma float - the gamma parameter of the reaction

get_gamma​

def get_gamma() -> float

Get the gamma parameter from the Kooij-Arrhenius equation

Returns:

  • float - the gamma parameter of the reaction

set_templow​

def set_templow(templow: float) -> None

Set the lower temperature boundary of the reaction in Kelvin

Arguments:

  • templow float - the lower temperature boundary

get_templow​

def get_templow() -> float

Get the lower temperature boundary of the reaction in Kelvin

Returns:

  • float - the lower temperature boundary

set_temphigh​

def set_temphigh(temphigh: float) -> None

Set the higher temperature boundary of the reaction in Kelvin

Arguments:

  • templow float - the higher temperature boundary

get_temphigh​

def get_temphigh() -> float

Get the higher temperature boundary of the reaction in Kelvin

Returns:

  • float - the higher temperature boundary

NANCheck​

def NANCheck(a)

Convert any Falsy statement to a NAN string

Arguments:

  • a - thing to check for falsiness

Returns:

  • bool - input a if truthy, otherwise NAN

get_reaction_type​

def get_reaction_type() -> str

Get the type of a reaction from the reactants First check the third reactant for a reaction type, then the second. If there are none in there, it will be regarded as a two body reaction.

Returns:

str:

get_source​

def get_source() -> str

Get the source of the reaction

Returns:

  • str - The source of the reaction

set_source​

def set_source(source: str) -> None

Set the source of the reaction

Arguments:

  • source str - The source of the reaction

convert_to_bulk​

def convert_to_bulk() -> None

Convert the surface species to bulk species in place for this reaction.

__eq__​

def __eq__(other) -> bool

Check for equality against another reaction based on the products and reactants. Note that it does not check for the temperature ranges that the reactions might have! The Reaction.check_temperature_collision can be used for this purpose.

Arguments:

  • other - Another reaction set.

Returns:

  • bool - equality

check_temperature_collision​

def check_temperature_collision(other) -> bool

Check if two reactions have overlapping temperature ranges, returning True means there is a collision.

Arguments:

  • other - Another reaction

Raises:

  • NotImplementedError - Currently we can only compare against instantiated Reaction objects.

Returns:

  • bool - Whether there is a collision (True), or not (False)

changes_surface_count​

def changes_surface_count()

This checks whether a grain reaction changes number of particles on the surface 2 reactants to 2 products won't but two reactants combining to one will.

changes_total_mantle​

def changes_total_mantle()

Check if the total grains on the mantle are changed by the reaction.

generate_ode_bit​

def generate_ode_bit(i: int, species_names: list, three_phase: bool)

Every reaction contributes a fixed rate of change to whatever species it affects. We create the string of fortran code describing that change here.

Arguments:

  • i int - index of reaction in network in python format (counting from 0)
  • species_names list - List of species names so we can find index of reactants in species list
  • three_phase bool - Bool indicating whether this is three phase network