User Guide#
General#
Stand-alone TUV-x can be run from the command-line as:
./tuv-x configuration_file.json
The configuration_file.json
contains the TUV-x configuration information described in
configuration.
If photolysis rate constants are included in the configuration,
TUV-x will output a file named photolysis_rate_constants.nc
in the working directory. This
file will contain the photolysis rate constants for each reaction at each vertical level
for every time specified in the configuration file.
If dose rates are included in the configuration,
TUV-x will output a file named dose_rates.nc
in the working directory.
This file will contain the calculated dose rates at
each vertical level for every time specified in the configuration.
Some example configurations are available in the examples
folder.
These will be copied to the build folder during the CMake build step.
To run an example, from the build folder run:
./tuv-x examples/full_config.json
Configuration#
The TUV-x configuration JSON file is used to set up TUV-x to calculate a set of user-selected photolysis rate constants and/or dose rates. It also allows you to specify details about how these are calculated (solver options, which absorbing species should be considered in determining the radiation field, etc.) and the conditions they should be calculated for (temperature, solar flux, solar zenith angle, etc.).
Configuration data for specific components of TUV-x may
include paths to needed data files. These paths can be absolute
or relative to the folder in which you run the tuvx
executable.
(There are no hard-coded paths to data files in the TUV-x source
code; they are all specified in the JSON configuration file.)
TUV-x JSON data include a number of required and optional
elements.
Users can additionally decorate the JSON file with
custom elements by using a “__
” prefix for the custom key.
TUV-x will ignore all key-value pairs whose key includes this
prefix.
These can be useful for including notes, descriptions,
or references.
They can also be useful if TUV-x is embedded
in an application that needs to attach specific information
to TUV-x objects.
{
"tuv object": {
"a TUV-x required key": "foo",
"a TUV-x optional key": "sometimes bar",
"__my note": "TUV-x will ignore this",
"__user provided data" : {
"will TUV-x ignore this object?": true
}
}
}
The TUV-x configuration JSON file has six objects:
{
"O2 absorption": { ... },
"grids": [ ... ],
"profiles": [ ... ],
"radiative transfer": { ... },
"photolysis": { ... },
"dose rates": { ... }
"enable diagnostics" : false,
}
We use elipses (...
) here and throughout this section for
JSON data that are described in a separate sub-section of this
page.
The first four objects
(O2 absorption,
grids,
profiles, and
radiative transfer)
are required for every TUV-x run.
The last two objects
(photolysis rate constants and
dose rates)
are optional and allow the user to
calculate photolysis rates or dose rates or both.
Finally, the enable diagnostics
field is used to output diagnostics from
the core of tuv-x. If set to true, a folder called output will be created.
This flag is optional and defaults to false.
The following sections describe each of these six JSON object.
O2 Absorption#
This object describes how TUV-x calculates the special Lyman–Alpha and Shumann–Runge absorption bands for O2. It has a single required data member that provides the path to a text file containing parameters needed in these calculations:
"O2 absorption": {
"cross section parameters file": "data/cross_sections/O2_parameters.txt"
}
This file is a hold-over from the original TUV and has
not yet been converted into a NetCDF file. It can be found
in the location shown above relative to the tuv-x/
root
directory.
Grids#
Grids define axes along which TUV-x data are distributed or calculations
are performed.
Depending on your use case, certain grids may or may not
need to be included.
At minimum, you will need to include a height
grid (units: km
) that defines the vertical grid TUV-x operates on,
and a wavelength
grid (units: nm
), that defines the wavelength
bins for which optical property data is provided.
For stand-alone TUV-x, you will also need to provide a time
grid
(units: hours
) that provides the time of day for which to calculate
the photolysis and/or dose rates.
There are three key-value pairs that are required for every grid, type
, units
, and name
.
The type
is a string that describes how the grid data is specified,
and must be one of equal interval
,
from csv file
, and from config file
.
These types are described below.
The units
are the units for the grid values and are used to ensure
consistency throughout configuration inputs and
with TUV conventions.
Equal Interval#
This grid type is defined by start and end points, and a cell width:
{
"name": "my grid"
"type": "equal interval",
"units": "foos",
"begins at": 12.0,
"ends at": 112.0,
"cell delta": 10.0
}
From CSV File#
This grid type is defined by data from a text file. The first line of the file is ignored and can be used for header info. The remaining lines should each include a single real number that will be used to define the grid. Values should be monotonic and increasing.
{
"name": "my grid"
"type": "from csv file",
"units": "bars",
"file path": "path/to/file"
}
From Config File#
The values for each cell of this grid type are included directly in the configuration file. Values should be monotonically increasing.
{
"name": "my grid"
"type": "from config file",
"units": "foos",
"values": [ 1.0, 7.0, 12.5 ]
}
Profiles#
Profiles define parameters on a grid. Similar to grids, depending on your use case, certain profiles may or may not need to be included. At minimum, you will need to include the key-value pairs listed in the following table.
profile |
grid |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
The air profile defines the number density (molecules cm-3) of air as a function of height.
In addition to the required profiles, profiles of atmospheric constituents that affect the radiation field by absorbing or scattering light should be included when these exist as radiators in the radiative transfer object.
As with grids, there are two key-value pairs required for every
profile, type
, units
, and name
.
The units
are the units for the profile data and are used to ensure
consistency throughout the configuration data and
with expectations in the code.
The type
is a string that describes how the profile data is specified.
There are two general-use types that can be used for any profile,
from csv file
and from config file
.
In addition, there are several profile types that are useful for describing
specific types of profiles, O2
, O3
, air
, solar zenith angle
,
Earth-Sun distance
, and extraterrestrial flux
.
The specific profile types are described below.
From CSV file#
This profile type loads profile data from a text file where the
data is expected to be space-separated with the first column being
the grid-point value and the second column being the value of the
profile at that grid-point.
Any number of header lines can be included at the top of the file
by prefixing them with any of #!$%*
.
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
|
required |
|
optional |
|
optional |
The format for the profile is:
{
"name": "my profile"
"type": "from csv file",
"units": "foos",
"file path": "path/to/file",
"grid": {
"name": "bar",
"units": "bazes"
}
}
An optional interpolator
key can be used to specify the
interpolation strategy to apply to the incoming data if needed.
The possible values are:
linear
Standard linear interpolation scheme. This is the default interpolator used when one is not specified in the configuration data.conserving
Linear interpolation that conserves the area under the curve.fractional source
Interpolation scheme for profiles that are integrated values. The interpolation is based on the fractional overlap between source and target grid sections relative to the source grid width.fractional target
Interpolation scheme for profiles that are integrated values. The interpolation is based on the fractional overlap between source and target grid sections relative to the target grid width.
From Config File#
This profile type extracts profile data directly from the configuration
data file. There are two options for this profile format. Each option will
require that type
and units
be present in the configuration file.
The grid
option is required. In the case of values
, the grid ensures
that the number of elements in values
matches the length of the grid.
When using the uniform value
option, the edge_val
, or the edges of the
cells, are determined from the grid.
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
|
required |
|
optional |
|
optional |
The first option specifies a single uniform value at every grid point:
{
"name": "my profile"
"type": "from config file",
"units": "bars",
"uniform value": 12.3,
"grid": {
"name": "foo",
"units": "bazes"
}
}
The second option specifies values at each grid point in an array:
{
"name": "my profile"
"type": "from config file",
"units": "bars",
"values": [ 12.3, 32.4, 103.2 ],
"grid": {
"name": "foo",
"units": "bazes"
}
}
From Host#
Todo
fill this out
Solar Zenith Angle#
This profile is specifically for calculating the solar zenith angle as a function of time.
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
|
required |
|
required |
|
required |
|
required |
|
required |
|
optional |
Its configuration takes the form:
{
"name": "solar zenith angle",
"type": "solar zenith angle",
"units": "degrees",
"year" : 2002,
"month": 3,
"day": 21,
"longitude": 0.0,
"latitude": 0.0
}
The latitude and longitude are in degrees. There is an optional
argument time zone
that defaults to 0, and is an offset
in hours to adjust for a specific time zone relative to GMT.
Earth-Sun Distance#
This profile is specifically for calculating the Earth-Sun distance
as a function of time. This profile requires that a grid named time
be
defined in the Grids section.
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
|
required |
|
required |
|
required |
|
optional |
Its configuration takes the form:
{
"name": "Earth-Sun distance",
"type": "Earth-Sun distance",
"units": "AU",
"year" : 2002,
"month": 3,
"day": 21
}
There is an optional argument time zone
that defaults to 0,
and is an offset in hours to adjust for a specific time zone
relative to GMT.
Other Profiles#
The remaining profile types support legacy code from the original implementation of TUV. These will be gradually removed as configurations employing the general-use profile types are developed.
These can be used as follows (note that file paths are relative
to the root tuv-x/
folder):
{
"name": "O3",
"type": "O3",
"units": "molecule cm-3",
"file path": "data/profiles/atmosphere/ussa.ozone"
},
{
"name": "air",
"type": "air",
"units": "molecule cm-3",
"file path": "data/profiles/atmosphere/ussa.dens"
},
{
"name": "O2",
"type": "O2",
"units": "molecule cm-3",
"file path": "data/profiles/atmosphere/ussa.dens"
},
{
"name": "extraterrestrial flux",
"type": "extraterrestrial flux",
"units": "photon cm-2 s-1",
"file path": ["data/profiles/solar/susim_hi.flx",
"data/profiles/solar/atlas3_1994_317_a.dat",
"data/profiles/solar/sao2010.solref.converted",
"data/profiles/solar/neckel.flx"],
"interpolator": ["","","","fractional target"]
}
Air Keys#
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
|
required |
Extraterrestrial Flux Keys#
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
|
required |
|
required |
|
optional |
The regressoin tests compare the new version of TUV-x to the old version. One way is by directly comparing output. The enable diagnostics allows for this ouptut to be disabled. If this is enabled, a folder named output will be created in the same directory TUV-x is run from.
O2 Keys#
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
|
required |
|
optional |
|
optional |
O3 Keys#
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
|
required |
|
optional |
|
optional |
|
optional |
Radiative Transfer#
Solvers#
Radiative transfer specifies how the radiation field is calculated. The general format for radiative transfer is:
"radiative transfer": {
"cross sections": [
{
"name": "foo",
"type": "base",
"netcdf files": [ "my/data/file.nc" ]
}
],
"radiators": [
{
"name": "foo",
"type": "base",
"cross section": "foo",
"vertical profile": "foo",
"vertical profile units": "molecule cm-3"
}
],
"solver": {
"type": "delta eddington"
}
}
The cross sections
and radiators
are required arrays
(even if they are of zero length).
The cross sections
define the absorption cross sections
for the radiators.
Cross section configuration formats are described
below.
The radiators
define the atmospheric constituents that
should be considered in the calculation of the radiation
field.
Radiator configuration formats are described
below.
The solver
key is required and specifies the solver to
use for radiative transfer.
There are currently two options, described below.
Delta Eddington#
This is a fast 2-stream solver based on: Toon et al., J.Geophys.Res., v94 (D13), Nov 20, 1989. The configuration format for the delta-Eddington solver is:
"type" : "delta eddington"
There are no configuration options for this solver.
Discrete Ordinate#
This is an n
-stream solver, where n
is an
even number between 2 and 32.
The configuration format for the discrete ordinate solver is:
"type": "discrete ordinate",
"number of streams": 4
The number of streams
is required and specifies the number
of streams to solve for.
The value must be an even number between 2 and 32.
Radiators#
Radiators represent atmospheric constituents that attenuate solar radiation and will be considered in calculations of the radiation field.
Base#
The generic configuration data format for standard radiators is as follows:
{
"type": "base",
"name": "foo",
"treat as air": true,
"cross section": "foo",
"vertical profile": "foo",
"vertical profile units": "molecule cm-3",
"enable diagnostics": false
}
keys |
Required/Optional |
---|---|
|
optional |
|
required |
|
optional |
|
required |
|
required |
|
required |
|
optional |
The regression tests compare the new version of TUV-x to the old version. One
way is by directly comparing output. The enable diagnostics
allows for this
ouptut to be disabled. If this is enabled, a folder named output
will be
created in the same directory TUV-x is run from.
The treat as air
flag can be used to indicate that the radiator
should be treated in a unique way specific to air in the calculation
of optical properties.
The default value is false.
The cross section
must be the name of a cross
section in the list of cross sections
in the
Radiative Transfer object.
The vertical profile must be the name of a profile with
the provided units that is present in the list of
Profiles.
These profiles should describe the concentration of
the constituent on the height
grid.
From NetCDF file#
This radiator type allows loading the optical properties of a radiator from a NetCDF file. The optical properties will remain constant throughout the calculations.
{
"name": "foo",
"type": "from netcdf file",
"file path": "path/to/file.nc"
}
keys |
Required/Optional |
---|---|
|
required |
|
required |
|
required |
The file path
should be a string containing the absolute
or relative path to the NetCDF file containing the optical
properties.
The NetCDF file should be structured as follows:
dimensions:
heights = NUMBER_OF_VERTICAL_LAYERS ;
wavelengths = NUMBER_OF_WAVELENGTH_BINS ;
variables:
double optical_depth(wavelengths, heights) ;
double single_scattering_albedo(wavelengths, heights) ;
double asymmetry_factor(wavelengths, heights) ;
The NUMBER_OF_VERTICAL_LAYERS
and NUMBER_OF_WAVELENGTH_BINS
must correspond to the number of bins in the height
and
wavelength
grids specified in the TUV-x configuration file.
(Note that these optical properties are per grid section and not at
grid edges.) No interpolation is performed on this data set.
Aerosols#
A special radiator type exists for aerosols, which provides fixed optical depths at each wavelength. An example of the aerosol configuration is provided below.
{
"name": "aerosols",
"type": "aerosol",
"optical depths": [2.40e-01, 1.06e-01, 4.56e-02, 1.91e-02, 1.01e-02, 7.63e-03,
5.38e-03, 5.00e-03, 5.15e-03, 4.94e-03, 4.82e-03, 4.51e-03,
4.74e-03, 4.37e-03, 4.28e-03, 4.03e-03, 3.83e-03, 3.78e-03,
3.88e-03, 3.08e-03, 2.26e-03, 1.64e-03, 1.23e-03, 9.45e-04,
7.49e-04, 6.30e-04, 5.50e-04, 4.21e-04, 3.22e-04, 2.48e-04,
1.90e-04, 1.45e-04, 1.11e-04, 8.51e-05, 6.52e-05, 5.00e-05,
3.83e-05, 2.93e-05, 2.25e-05, 1.72e-05, 1.32e-05, 1.01e-05,
7.72e-06, 5.91e-06, 4.53e-06, 3.46e-06, 2.66e-06, 2.04e-06,
1.56e-06, 1.19e-06, 9.14e-07],
"single scattering albedo": 0.99,
"asymmetry factor": 0.61,
"550 nm optical depth": 0.235,
"enable diagnostics": false
}
keys |
Required/Optional |
---|---|
|
optional |
|
required |
|
required |
|
required |
|
required |
|
optional |
|
optional |
The regression tests compare the new version of TUV-x to the old version. One way is by directly comparing output. The enable diagnostics allows for this ouptut to be disabled. If this is enabled, a folder named output will be created in the same directory TUV-x is run from.
The optical depths are expected to be on the wavelength
grid.
From Host#
Todo
fill this out
Photolysis Reactions#
The configuration for photolysis reactions takes the following form:
"photolysis": {
"enable diagnostics": false,
"reactions": [
{
"name": "my first reaction",
"cross section": { ... },
"quantum yield": { ... },
"scaling factor": 1.3
},
{
"name": "my second reaction",
"cross section": { ... },
"quantum yield": { ... },
}
]
}
Each member of reactions
describes a photolysis
reaction that TUV-x will calculate a rate constant for at runtime.
The name for each photolysis reaction is user-defined,
associated with the calculated rate constant,
and can be used for mapping to a chemistry solver or other
package.
Each reaction must have a cross section
, whose configuration
format is described here.
Each reaction must also have a quantum yield
, whose
configuration is described here.
The scaling factor
is a optional scaling factor that will be
applied to the calculated rate constant.
Diagnostic output can be enabled by setting enable diagnostics
to true
.
This keyword is not required and is false
by default.
When enabled, a folder named
output will be created with some diagnostic output for the cross sections
and quantum yields. This is only used for regression tests and will be removed
in the future.
The file data/photolysis_rate_constants.json
contains
configuration data for every photolysis rate constant that
can be calculated from data available in the data/
folder.
Dose Rates#
The configuration for dose rates takes the following form:
"dose rates": {
"my first dose rate": {
"weights": { ... }
},
"my second dose rate": {
"weights": { ... }
}
}
Each member of dose rates
describes a dose rate that
TUV-x will calculate at runtime.
The key for each dose rate is a user-defined name that
will be associated with the calculated rate.
Each dose rate must have a weights
object that
defines a spectral weight, whose configuration format
is described here.
Additionally, diagnostic output can be enabled by adding enable diagnostics
to the
json configuration like in the sample below. In this case, a folder named
output will be created with some diagnostic output for the cross sections
and quantum yields. This is only used for regression tests and will be removed
in the future.
"dose rates": {
"enable diagnostics" : true,
"my first dose rate": {
"weights": { ... }
},
"my second dose rate": {
"weights": { ... }
}
}
Additional Objects#
These configuration JSON objects are used in one or more of the six high-level JSON objects in the TUV-x data file.
Cross Sections#
The configuration for a standard cross section is as follows:
{
"type": "base",
"netcdf files": [
{
"file path": "path/to/my/netcdf/file.nc",
"lower extrapolation": {
"type": "boundary"
},
"upper extrapotion": {
"type": "constant",
"value": 0.0
},
"zero below": 215.4,
"zero above": 768.4
}
],
"override bands": [
{
"band": "lyman-alpha",
"value": 0.32
}
],
"apply O2 bands": true
}
The NetCDF file should be structured as follows:
dimensions:
bins = NUMBER_OF_WAVELENGTH_BINS ;
parameters = 1 ;
variables:
double wavelength(bins) ;
wavelength:units = "nm" ;
double cross_section_parameters(parameters, bins) ;
Here, NUMBER_OF_WAVELENGTH_BINS
is the number of wavelength
bins the cross section values are provided on.
The cross_section_parameters
array should hold the value
of the cross section at each wavelength.
TUV-x will interpolate the cross section
data onto the TUV-x wavelength grid, as specified by the
“wavelength” grid.
For objects in the netcdf files
array, the file path
is required. The remaining keys are optional.
The lower extrapolation
and upper extrapolation
keys will append data beyond the lower and upper limits
of the input data set, respectively. When the type
is boundary
, the last data point in the data set is
used for all points beyond the last point. When the
type
is constant
a user-specified value
is
used for all points beyond the last point.
The zero above
and zero below
keys are used to
zero all points from the file above or below the
specified wavelength values AFTER INTERPOLATION.
An override bands
array can be included to specify
fixed values over specific bands. These values will be
applied immediately before returning the cross section
and thus override any calculated or interpolated values.
Valid band
values are lyman-alpha
,
schumann-runge
, and schumann-runge continuum
.
The wavelength grid must cover the Lyman-alpha and
Schumann-Runge bands if an override is specified,
otherwise a configuration error is returned.
The apply O2 bands
flag can be added to photolysis
rates that dissociate O2
. If this flag is set to
true
, cross section values in the Lyman-alpha and
Schumann-Runge wavelength bands will be overwritten with
TUV-x’s custom cross section values for O2 in these bands.
A number of custom cross section types have been developed
when more complex algorithms are needed to calculate
cross sections.
These generally apply to a specific photolysis reaction.
Their configuration data formats are demonstrated
in data/photolysis_rate_constants.json
.
Quantum Yields#
The configuration for a standard quantum yield can be of two forms. The first describes a quantum yield that is a constant value at all wavelengths:
{
"type": "base",
"constant value": 1.0
}
The second describes a quantum yield that is read from a NetCDF file:
{
"type": "base",
"netcdf files": [ "path/to/my/netcdf/file.nc" ]
}
The NetCDF file should be structured as follows:
dimensions:
bins = NUMBER_OF_WAVELENGTH_BINS ;
parameters = 1 ;
variables:
double wavelength(bins) ;
wavelength:units = "nm" ;
double quantum_yield_parameters(parameters, bins) ;
quantum_yield_parameters:units = "fraction" ;
Here, NUMBER_OF_WAVELENGTH_BINS
is the number of wavelength
bins the quantum yield values are provided on.
The quantum_yield_parameters
array should hold the value
of the quantum yield at each wavelength.
TUV-x will perform interpolation of the quantum yield data
to the native wavelength grid.
For either type of quantum yield, an override bands
array can be included:
{
"type": "base",
"constant value": 1.0,
"override bands": [
{
"band": "lyman-alpha",
"value": 0.32
}
]
}
An override bands
array instructs TUV-x to apply
fixed values over specific bands. These values will be
applied immediately before returning the quantum yield
and thus override any calculated or interpolated values.
Valid band
values are lyman-alpha
,
schumann-runge
, and schumann-runge continuum
.
The wavelength grid must cover the Lyman-alpha and
Schumann-Runge bands if an override is specified,
otherwise a configuration error is returned.
A number of custom quantum yield types have been developed
when more complex algorithms are needed to calculate
quantum yields.
These generally apply to a specific photolysis reaction.
Their configuration data formats are demonstrated
in data/photolysis_rate_constants.json
.
Spectral Weights#
Standard spectral weight types load spectral weights from a NetCDF file. Their configuration format is as follows:
{
"type": "base",
"netcdf files": [ "path/to/my/netcdf/file.nc" ]
}
The NetCDF file should be structured as follows:
dimensions:
bins = NUMBER_OF_WAVELENGTH_BINS ;
parameters = 1 ;
variables:
double wavelength(bins) ;
wavelength:units = "nm" ;
double spectral_weight_parameters(parameters, bins) ;
spectral_weight_parameters:hdr = "" ;
Here, NUMBER_OF_WAVELENGTH_BINS
is the number of wavelength
bins the spectral weight values are provided on.
The spectral_weight_parameters
array should hold the value
of the spectral weight at each wavelength.
TUV-x will perform interpolation of the spectral weight data
to the native wavelength grid.
The type
and netcdf files
keys are required. There are
also two optional key-value pairs: lower extrapolation
and
upper extrapolation
.
These both have the same structure.
An example of the lower extrapolation
follows.
"lower extrapolation": {
"type": "boundary"
}
The value of type
can be boundary
or constant
.
If boundary
is selected, the value at the lower (or upper)
boundary of the input data will be extended to the
lower (or upper) extent of the TUV-x wavelength grid.
If constant
is selected, a key-value pair value
must also be present:
"lower extrapolation": {
"type": "constant",
"value": 12.2
}
This value will be used between the lower (or upper) boundaries of the input data and TUV-x wavelength grids. If no lower or upper extrapolation is specified, the values between the input data and TUV-x wavelength grids will be 0.
A number of custom spectral weight types have been developed
when more complex algorithms are needed to calculate
spectral weights.
Their configuration data formats are demonstrated
in data/dose_rates.json
.