beatboxtestbed

beatboxtestbed is the background error analysis testbed with box models.

It contains the data assimilation toy model BEATBOX, which is described in Knote et al., Geoscientific Model Development Discussions, 2017.

Installation

pip install beatboxtestbed

beatboxtestbed needs a number of other packages, all of them available through PyPi. They should automatically be installed when using pip. Please read the installation instructions of the boxmox package, as they contain instructions on how to install the underlying box model BOXMOX.

beatboxtestbed relies on 2 environmental variables to set the absolute path to work and archive directories for beatbox experiments. You should add these directives to your .bashrc, .profile (or similar, depending on your shell):

export BEATBOX_WORK_PATH="/path/to/you/beatbox/work/directory"
export BEATBOX_ARCHIVE_PATH="/path/to/you/beatbox/archive/directory"

Command-line scripts

Conduct cycling run

usage: make_BEATBOX_cycling_run [-h] exp cfg

Positional Arguments

exp experiment name
cfg config file

Plot assimilation diagnostics

usage: plot_BEATBOX_assim_diags [-h] exp cycle

Positional Arguments

exp experiment name
cycle cycle number

Plot time series diagnostics

usage: plot_BEATBOX_time_series_diags [-h] exp spec

Positional Arguments

exp experiment name
spec chemical compound

Example

This is the code to re-create the examples in Knote et al., Geoscientific Model Development Discussions, 2017.

Prepare all necessary BOXMOX mechanisms

We assume that BOXMOX is installed and working. In the shell we compile the mechanisms (MOZART-T1 forward and adjoint, and the Master Chemical Mechanism) used in the example:

prepare_BOXMOX_mechanism MOZART_T1
prepare_BOXMOX_mechanism -a MOZART_T1
prepare_BOXMOX_mechanism MCMv3_3

Make simulations

In the directory where you downloaded the configuration files, make the BEATBOX simulations using these commands from the command line:

make_BEATBOX_cycling_run CH2Oac settings_CH2Oac.cfg
make_BEATBOX_cycling_run CH2Onc settings_CH2Onc.cfg
make_BEATBOX_cycling_run NO2ac settings_NO2ac.cfg
make_BEATBOX_cycling_run NO2nc settings_NO2nc.cfg

Plot results

plot_path = '<OUTPUT PATH WHERE PLOTS ARE WRITTEN>'

import os

import beatboxtestbed.plotting as p
import beatboxtestbed.helpers as h

import boxmox

import chemspectranslator
translator = chemspectranslator.Translator()

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

if not os.path.isdir(plot_path):
    os.makedirs(plot_path)

# shortcut to save figures
saveFigure = lambda f, n: f.savefig(os.path.join(plot_path, n + ".pdf"))

# Figure 3 (unofficial function)
archive_path = h.get_archive_path('NO2nc')

fig = p._regime(archive_path, 'MOZART_T1'); saveFigure(fig, 'fig3_regime'); plt.close()

# Figure 4
archive_path = h.get_archive_path('NO2nc')

fig, axarr = plt.subplots(2, 2, sharex=True, dpi=300)
xlabel='Time in h'
ylabel='Concentration in ppbv'
fig = p.NRCR( archive_path, 'NO2',  translator, ax=axarr[0][0], fig=fig,
              xlabel="", ylabel=ylabel, title=r"NO$_2$", plabel="(a)")
fig = p.NRCR( archive_path, 'O3',   translator, ax=axarr[1][0], fig=fig,
              xlabel=xlabel, ylabel=ylabel, title=r"O$_3$", plabel="(b)")
fig = p.NRCR( archive_path, 'CH2O', translator, ax=axarr[0][1], fig=fig,
              xlabel="", ylabel="", title=r"CH$_2$O", plabel="(c)")
axarr[0][1].legend(loc='best', fontsize='x-small')
fig = p.NRCR( archive_path, 'OH',   translator, ax=axarr[1][1], fig=fig,
              xlabel=xlabel, ylabel="", title=r"OH", plabel="(d)")
saveFigure(fig, 'fig4_NRCR')
plt.tight_layout()
plt.close()

# Figure 5, 6
for exp in [ 'NO2', 'CH2O' ]:
    concies = {}
    for run in [ exp + 'nc', exp + 'ac' ]:
        concies[run] = {}
        archive_path = h.get_archive_path(run)
        for spec in [ 'NO2', 'O3', 'CH2O', 'OH' ]:
            concies[run][spec] = h.read_conc_cycling( translator, archive_path, spec )
#
    fig, axarr = plt.subplots(4, 2, sharex=True, figsize=[8.0, 11.0], dpi=300)
#
    xlabel='Time in h'
    ylabel='Concentration in ppbv'
#
    run = exp + 'nc'
    archive_path = h.get_archive_path(run)
    fig = p.cycling( translator, archive_path, 'NO2', conc=concies[run]['NO2'],
                     ax=axarr[0][0], fig=fig, plot_legend=('NO2' == exp),
                     xlabel="", ylabel=ylabel, title=r'NO$_2$', plabel='(a)')
    fig = p.cycling( translator, archive_path, 'O3', conc=concies[run]['O3'],
                     ax=axarr[1][0], fig=fig, plot_legend=('O3' == exp),
                     xlabel="", ylabel=ylabel, title=r'O$_3$', plabel='(b)')
    fig = p.cycling( translator, archive_path, 'CH2O', conc=concies[run]['CH2O'],
                     ax=axarr[2][0], fig=fig, plot_legend=('CH2O' == exp),
                     xlabel="", ylabel=ylabel, title=r'CH$_2$O', plabel='(c)')
    fig = p.cycling( translator, archive_path, 'OH', conc=concies[run]['OH'],
                     ax=axarr[3][0], fig=fig, plot_legend=('OH' == exp),
                     xlabel=xlabel, ylabel=ylabel, title=r'OH', plabel='(d)')
#
    run = exp + 'ac'
    archive_path = h.get_archive_path(run)
    fig = p.cycling( translator, archive_path, 'NO2', conc=concies[run]['NO2'],
                     ax=axarr[0][1], fig=fig, plot_legend=False,
                     xlabel="", ylabel="", title=r'NO$_2$', plabel='(e)')
    fig = p.cycling( translator, archive_path, 'O3', conc=concies[run]['O3'],
                     ax=axarr[1][1], fig=fig, plot_legend=False,
                     xlabel="", ylabel="", title=r'O$_3$', plabel='(f)')
    fig = p.cycling( translator, archive_path, 'CH2O', conc=concies[run]['CH2O'],
                     ax=axarr[2][1], fig=fig, plot_legend=False,
                     xlabel="", ylabel="", title=r'CH$_2$O', plabel='(g)')
    fig = p.cycling( translator, archive_path, 'OH', conc=concies[run]['OH'],
                     ax=axarr[3][1], fig=fig, plot_legend=False,
                     xlabel=xlabel, ylabel="", title=r'OH', plabel='(h)')
#
    niceSpec = exp
    if exp == 'CH2O':
        niceSpec = 'CH$_2$O'
#
    if exp == 'NO2':
        niceSpec = 'NO$_2$'
#
    plt.text(0.3, 0.98, r"Only " + niceSpec + " inferred", fontsize=18,
             transform=fig.transFigure, horizontalalignment='center')
    plt.text(0.75, 0.98, r"Whole state vector inferred", fontsize=18,
             transform=fig.transFigure, horizontalalignment='center')
#
    fig.tight_layout(rect=[0.0, 0.0, 1.0, 0.975])
    saveFigure(fig, 'fig56_cycling_' + exp)
    plt.close()


# Figure 7
fig = plt.figure(figsize=[8.0, 8.0], dpi=300)
axarr = []
axarr.append(plt.subplot2grid((4, 12), (0, 0), colspan=11, rowspan=1))
axarr.append(plt.subplot2grid((4, 12), (1, 0), colspan=11, rowspan=1, sharex=axarr[0]))
axarr.append(plt.subplot2grid((4, 12), (0, 11), rowspan=2))
archive_path = h.get_archive_path('NO2ac')
fig = p.sensitivities(archive_path, fig=fig, axarr=axarr, abs_max=100.0)
axarr[0].set_title(r'(a) NO$_2$ assimilation')
axarr = []
axarr.append(plt.subplot2grid((4, 12), (2, 0), colspan=11, rowspan=1))
axarr.append(plt.subplot2grid((4, 12), (3, 0), colspan=11, rowspan=1, sharex=axarr[0]))
axarr.append(plt.subplot2grid((4, 12), (2, 11), rowspan=2))
archive_path = h.get_archive_path('CH2Oac')
fig = p.sensitivities(archive_path, fig=fig, axarr=axarr, abs_max=100.0)
axarr[0].set_title(r'(b) CH$_2$O assimilation')
plt.tight_layout()
saveFigure(fig, 'fig7_sensitivities')
plt.close()

# Figure 8
run   = 'CH2Oac'
cycle = 9
archive_path = h.get_archive_path(run)
beatbox_result_path = os.path.join(archive_path, 'fcst_' + str(cycle), 'BEATBOX.p')
fig = plt.figure(figsize=[8.0, 8.0], dpi=300)
axarr = []
axarr.append(plt.subplot2grid((2, 2), (0, 0)))
axarr.append(plt.subplot2grid((2, 2), (0, 1)))
axarr.append(plt.subplot2grid((2, 2), (1, 0)))
axarr.append(plt.subplot2grid((2, 2), (1, 1)))
fig = p.scatter( beatbox_result_path, fig=fig, axarr=axarr, plabels=['(a)', '(b)', '(c)', '(d)'] )
saveFigure(fig, 'fig8_tracer_tracer_' + run + '_' + str(cycle))
plt.tight_layout()
plt.close()

# Figure 9
run   = 'CH2Oac'
cycle = 9
archive_path = os.path.join(h.get_archive_path(run), 'fcst_' + str(cycle))

nr  = boxmox.ExperimentFromExistingRun( os.path.join(archive_path, 'MCMv3_3', 'output') )
cr  = boxmox.ExperimentFromExistingRun( os.path.join(archive_path, 'MOZART_T1', 'output'), filename="25EN")
en  = boxmox.ExperimentFromExistingRun( os.path.join(archive_path, 'MOZART_T1', 'output'), filename="25AR_ens")
hyb = boxmox.ExperimentFromExistingRun( os.path.join(archive_path, 'MOZART_T1', 'output'), filename="25AR_hyb")

moz_flx_lbls = {
                'CH3OH + OH --> VOC_OH + CH2O + HO2':       { "label": r'CH$_3$OH + OH -> CH$_2$O + HO$_2$',                "color": 'cornflowerblue' },
                'CH2O + OH --> VOC_OH + CO + HO2 + H2O':    { "label": r'CH$_2$O + OH -> CO + HO$_2$ + H$_2$O',             "color": 'orange'},
                'CH2O --> CO + 2 HO2':                      { "label": r'CH$_2$O -> CO + 2 HO$_2$',                         "color": 'green'},
                'CH2O --> H2 + CO':                         { "label": r'CH$_2$O -> H$_2$ + CO',                            "color": 'red'},
                'NO + CH3O2 --> RO2_NO + CH2O + NO2 + HO2': { "label": r'NO + CH$_3$O$_2$ -> CH$_2$O + NO$_2$ + HO$_2$',    "color": 'mediumpurple'}
                }

mcm_flx_lbls = {
                'CH3OH + OH --> HCHO + HO2':                { "label": r'CH$_3$OH + OH -> CH$_2$O + HO$_2$',                "color": 'cornflowerblue' },
                'CH3O --> HCHO + HO2':                      { "label": r'CH$_3$O -> CH$_2$O + HO$_2$',                      "color": 'orange'},
                'HCHO --> CO + 2 HO2':                      { "label": r'CH$_2$O -> CO + 2 HO$_2$',                         "color": 'green'},
                'HCHO + OH --> CO + HO2':                   { "label": r'CH$_2$O + OH -> CO + HO$_2$',                      "color": 'red'},
                'HCHO --> H2 + CO':                         { "label": r'CH$_2$O -> H$_2$ + CO',                            "color": 'mediumpurple'}
                }

ylims = ( -0.4, 0.7 )

fig = plt.figure(figsize=[8.0, 10.0], dpi=300)
axarr = []
axarr.append(plt.subplot2grid((3, 2), (0, 0)))
axarr.append(plt.subplot2grid((3, 2), (0, 1)))
axarr.append(plt.subplot2grid((3, 2), (1, 0)))
axarr.append(plt.subplot2grid((3, 2), (1, 1)))
axarr.append(plt.subplot2grid((3, 2), (2, 0)))
nr.plotter.fluxes('HCHO', fig=fig, ax=axarr[0], plabel="(a)", xlabel="", ylim=ylims,
                  plot_netflux=False, plot_xaxlabels=False, flx_labels=mcm_flx_lbls)
axarr[0].set_title(r"NR (MCM v3.3)")
cr.plotter.fluxes('CH2O', fig=fig, ax=axarr[1], plabel="(b)", xlabel="", ylabel="", ylim=ylims,
                  plot_netflux=False, plot_xaxlabels=False, flx_labels=moz_flx_lbls)
axarr[1].set_title(r"EN (MOZART-4)")
en.plotter.fluxes('CH2O', fig=fig, ax=axarr[2], plabel="(c)", xlabel="", ylim=ylims,
                  plot_netflux=False, plot_xaxlabels=False, flx_labels=moz_flx_lbls)
axarr[2].set_title(r"AR_ens (MOZART-4)")
hyb.plotter.fluxes('CH2O', fig=fig, ax=axarr[3], plabel="(d)", ylabel="", ylim=ylims,
                   plot_netflux=False, flx_labels=moz_flx_lbls)
axarr[3].set_title("AR_hyb (MOZART-4)")

p._net_fluxes({ 'NR': 'HCHO'  , 'EN': 'CH2O'   , 'AR_ens': 'CH2O'    , 'AR_hyb': 'CH2O'   },
              { 'NR': nr      , 'EN': cr       , 'AR_ens': en        , 'AR_hyb': hyb      },
              { 'NR': 'black' , 'EN': 'red'    , 'AR_ens': 'green'   , 'AR_hyb': 'blue'   },
              fig=fig, ax=axarr[4], plabel="(e)", scale_factor=3600.0*1000.0, ylim= ( -0.2, 0.1 ) )

saveFigure(fig, 'fig9_fluxes_CH2O')
plt.tight_layout()
plt.close()

Frequently asked questions

Speed up your simulations

There are 2 easy ways to improve the speed of your simulations:

  • Use optimized compiler settings when creating the BOXMOX mechanisms

    By default, BOXMOX mechanisms are compiled with the “-g” flag. Remove the flag, add an “-O” optimizing flag and recompile.

  • Parallelize your runs

    Install the joblib python package. beatboxtestbed can now use multiple CPUs for the ensemble runs (if your computer does indeed have multiple CPUs…). The ncpus setting in the settings.cfg defines how many CPUs are used. The default setting of -2 states that one CPUs less than available on the machine are used.

API

beatbox

beatboxtestbed.beatbox.run(translator, exp_path)

This is the main function of the data assimilation code, organized as follows:

  • loading concentrations
  • calculating sensitivities
  • generating observations
  • inflate ensembles if necessary
  • compute the analysis
  • write the outputs

multimox

beatboxtestbed.multimox.create_input(ds, ds_args, tuv, translator, exp, exp_path)

Creates input data for a beatbox experiment

beatboxtestbed.multimox.run(exp, exp_path, nfcst)

Runs the box model for all beatbox experiment members

cycling

beatboxtestbed.cycling.create_input_from_output(fname, conc_state, out)

A BOXMOX concentration output file is taken and with the final concentrations a new BOXMOX initial conditions file is written. The final concentrations of some species can be replaced in the new input file.

Parameters:
  • fname (str) – BOXMOX concentration output file
  • conc_state (dict) – Concentrations to be replaced in the new input file (species name must be part of the species in the BOXMOX concentration output file)
  • out (str) – a new BOXMOX initial conditions filename which will be generated
beatboxtestbed.cycling.gen_ass_IC(exp, ifcst)

Generate new initial condition from an analysis to run subsequent forecast

Parameters:
  • exp (str) – name of the experiment
  • ifcst (int) – forecast number
beatboxtestbed.cycling.gen_ass_input(exp, ifcst)

Copy all the input files from the analysis to the correct directories

Parameters:
  • exp (str) – name of the experiment
  • ifcst (int) – forecast number
beatboxtestbed.cycling.get_ens_tag(fname)

The ensemble tag of a multiMOX output file is computed from its filename.

Parameters:fname (str) – multiMOX output file
Returns:the ensemble tag of that file
Return type:int
beatboxtestbed.cycling.new_experiment(exp)

Create directory for a new experiment

beatboxtestbed.cycling.remove_experiment(exp)

Remove directories from a given experiment

beatboxtestbed.cycling.run(ds, ds_args, tuv, translator, exp, cfg_path)

Runs the experiment through the desired cycles called by ./make_cycling_run exp cfg

Parameters:
  • ds (frappedata.Dataset) – BOXMOX input dataset
  • ds_args (dict) – BOXMOX input dataset input settings dictionary
  • tuv (tuv.DB) – TUV database
  • translator (chemspectranslator.Translator) – chemspectranslator
  • exp (str) – name of the experiment
  • cfg_path (str) – the path to the .cfg file that defines the experiment parameters
Returns:

path where the calculations are made

Return type:

str

beatboxtestbed.cycling.write_config(ds, ds_args, exp, ifcst)

Read and write the settings.cfg file for diurnal cycles and inflation inflation values from the analysis are written on the settings.cfg files

Parameters:
  • exp (str) – name of the experiment
  • ifcst (int) – forecast number

plotting

beatboxtestbed.plotting.NRCR(runDir, spec, translator, conc=None, scaleFactor=1000.0, ax=None, fig=None, xlabel='', ylabel='', title='', plabel=None, plot_legend=False)

Plot only nature run and control run

beatboxtestbed.plotting.cycling(translator, runDir, spec, conc=None, runTypes=['obs', 'NR', 'CR', 'EN', 'AR_var', 'AR_ens', 'AR_hyb'], ax=None, fig=None, plot_legend=True, xlabel='', ylabel='', title='', plabel=None, scaleFactor=1000.0)

Plot time series of a cycling run

beatboxtestbed.plotting.relative_to_NR(BEATBOX)

Plot performance relative to nature run

beatboxtestbed.plotting.scatter(BEATBOX, obs_spec=None, scaleFactor=1000.0, axarr=None, fig=None, plabels=None)

Scatter plot

beatboxtestbed.plotting.sensitivities(runDir, max_val=1000.0, ncolors=21, abs_max=60.0, fig=None, axarr=None)

Plot sensitivities over time

beatboxtestbed.plotting.skill_across_state(BEATBOX)

Plot the skill score of a beatbox experiment for all state vector species

helpers

beatboxtestbed.helpers.apply_inflation(ensemble, lambd, locz)

Apply the inflation coefficient to each ensemble member a security clamping is also applied to reset negatives values to their original values (just in case), this should not happen if posdef_infl() is used, see below

Parameters:
  • ensemble (numpy.ndarray) – the ensemble distribution of dimensions (n ensembles, m state_variables)
  • lambd (float) – the inflation coefficient
Returns:

inflated distribution

Return type:

<numpy.ndarray> dimensions (n ensembles, m state_variables)

beatboxtestbed.helpers.archive(exp_path, exp)

Archive BEATBOX experiment

beatboxtestbed.helpers.calc_ens_sen(ens_TS, state, obs)

The concentration time series of each ensemble member of an ensemble run are taken and the ensemble sensitivities of the species in the state vector to the observed species are calculated.

Calculation of ensemble sensitvities:
corr(xobs,xstate) * stdev(xstate) / stdev(xobs)
= sensitivity of state species “xstate” to the observed species
“xobs” (standard deviation and correlation with respect to the “number of ensembles”-dimension at every timestep)
Parameters:
  • ens_TS (numpy.ndarray) – Concentration time series of N ensembles and of dim_state species shape: (“number of ensembles”, dim_time, dim_state)
  • state (str/list) – state vector; single species or list of species which exists/exist in the BOXMOX run
  • obs (str/list) – Observed species; single species or list of species which exists/exist in the BOXMOX run
Returns:

ensemble sensitivity of the species in the state vector to the observed species

Return type:

numpy.ndarray; shape: (dim_time, dim_obs, dim_state)

beatboxtestbed.helpers.calc_infl(mod_obs_mean, mod_err, obs_val, obs_err, lambd, lambd_var)

Estimation of the inflation value following Anderson(2006)

Parameters:
  • mod_obs_mean (float) – ensemble mean
  • mod_err (float) – ensemble spread
  • obs_val (float) – observation value
  • obs_err (float) – observatio error
Returns:

lambd, inflation value

Returns:

lambd_var: inflation variance value

Return type:

float, float

beatboxtestbed.helpers.calc_infl_simple(mod_obs_mean, mod_err, obs_val, obs_err, lambd, lambd_var)

Naive / simple way of estimating the inflation factor

Parameters:
  • mod_obs_mean (float) – ensemble mean
  • mod_err (float) – ensemble spread
  • obs_val (float) – observation value
  • obs_err (float) – observation error
  • lambd (float) – (unused)
  • lambd_var (float) – (unused)
Returns:

lambd, inflation value

Return type:

float

beatboxtestbed.helpers.get_archive_path(exp)

Get absolute path to archived experiment exp

beatboxtestbed.helpers.load_config(cfgFile)

Read parameters from the settings.cfg file

Parameters:cfgFile (str) – settings.cfg file
Returns:
  • mech_NR <str> : nature run mechanism
  • mech_CR <str> : control run and assimilation runs mechanism
  • runDir <str> : running directory
  • nens <int> : number of ensembles
  • state <list> : list of the state vector variables
  • obs <list> or <str> : observed variable(s)
  • localization <list> or <str> : list of variables to infer
  • is_obs_rel <bool> : if True, the observation error is a fraction of
    the obs value (relative) obs error = obs * rel_obs_err if False, then the observation error is an absolute value obs error = abs_obs_err
  • rel_obs_err <float> : relative obs error
  • abs_obs_err <float> : absolute obs error
  • mod_err_coef_in <float> : for the single adjoint diagonal value of B diag(B) = mod_err_coef_in * H(x)
  • use_inflation <bool> : True: inflation is used, False: no inflation
  • prior_lambd_ens <float> : initial inflation, will change through cycles
  • prior_lambd_hyb <float> : initial inflation, will change through cycles
  • prior_lambd_var_ens <float> : initial inflation, will change through cycles
  • prior_lambd_var_hyb <float> : initial inflation, will change through cycles
  • verbose <bool> : verbose output?
beatboxtestbed.helpers.load_obs_cycling(runDir)

Read the observation parameters from the BEATBOX.p on a given cycle

Parameters:runDir (str) – where the file to read is
Returns:obs parameters
Return type:dict
beatboxtestbed.helpers.loc_func(state, localization)

Defines a localization function between variables

beatboxtestbed.helpers.make_exp_path(exp, createDir=False, overwrite=False)

Returns the absolute path of a BEATBOX experiment, creates the directory if createDir = True, overwrites existing directories if overwrite = True

beatboxtestbed.helpers.posdef_infl(ensemble, lambd, locz)

Filter the inflation coefficient to ensure that the inflated ensemble distribution is positive definite, this will avoid clamping on ensemble members and then ensure a more physical evolution of the ensemble

Parameters:
  • ensemble (numpy.ndarray) – the ensemble distribution of dimensions (n ensembles, m state_variables)
  • lambd (float) – the inflation coefficient
Returns:

lambd, the filtered inflation coefficient

Return type:

float

beatboxtestbed.helpers.print_table(col_names, *col_values)

A table is printed, like this:

col_names [0]     col_names [1]     ...
col_values[0][1]  col_values[1][1]  ...
col_values[0][2]  col_values[1][2]  ...
     ...                ...
Parameters:
  • col_names (str/list) – column name/s
  • col_values (list) – values of a column; first <col_values> corresponds to first <col_names> and so on
beatboxtestbed.helpers.read_conc_cycling(translator, runDir, spec)

Read the concentration after the forecast is done for the analysis to be performed

Parameters:
  • runDir (str) – where are the concentration files,
  • spec (str) – state variable used in the analysis
Returns:

concentration values and ensembles indexed by NR,CR,AR,var,hyb,ens

Return type:

dict

beatboxtestbed.helpers.str_to_list(values, dtype=<type 'str'>)

A string out of comma-separated values is taken a list of the values is returned.

Parameters:
  • values (str) – Comma_separated string
  • dtype (type) – Function which converts a string value to a certain data type; default=str
Returns:

list of values

Return type:

list

Example:

str_to_list('1, 2,34,5', dtype=int)
[1,2,34,5]
beatboxtestbed.helpers.translate_spec_list(translator, spec_list, mech_NR, mech_CR)

Operate name translations for NR, CR and ARs using the chemspectranslator

Parameters:
  • spec_list (str/list) – Species list
  • mech_NR (str) – Nature run mechanism name
  • mech_CR (str) – Control run mechanism name
Returns:

translated species by mechanism

Return type:

dict