diff --git a/pr-preview/pr-63/.buildinfo b/pr-preview/pr-63/.buildinfo deleted file mode 100644 index d9f31a76..00000000 --- a/pr-preview/pr-63/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 1aeaaa61ffdae84808dc072253a78bd0 -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/pr-preview/pr-63/.doctrees/code-structure.doctree b/pr-preview/pr-63/.doctrees/code-structure.doctree deleted file mode 100644 index 7a14354f..00000000 Binary files a/pr-preview/pr-63/.doctrees/code-structure.doctree and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/config.doctree b/pr-preview/pr-63/.doctrees/config.doctree deleted file mode 100644 index eb0e805c..00000000 Binary files a/pr-preview/pr-63/.doctrees/config.doctree and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/environment.doctree b/pr-preview/pr-63/.doctrees/environment.doctree deleted file mode 100644 index 8d10489f..00000000 Binary files a/pr-preview/pr-63/.doctrees/environment.doctree and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/environment.pickle b/pr-preview/pr-63/.doctrees/environment.pickle deleted file mode 100644 index 43c1b26d..00000000 Binary files a/pr-preview/pr-63/.doctrees/environment.pickle and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/features.doctree b/pr-preview/pr-63/.doctrees/features.doctree deleted file mode 100644 index 356f0626..00000000 Binary files a/pr-preview/pr-63/.doctrees/features.doctree and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/functions.doctree b/pr-preview/pr-63/.doctrees/functions.doctree deleted file mode 100644 index 77eaf125..00000000 Binary files a/pr-preview/pr-63/.doctrees/functions.doctree and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/howtorun.doctree b/pr-preview/pr-63/.doctrees/howtorun.doctree deleted file mode 100644 index 4681a0d0..00000000 Binary files a/pr-preview/pr-63/.doctrees/howtorun.doctree and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/index.doctree b/pr-preview/pr-63/.doctrees/index.doctree deleted file mode 100644 index 123b8699..00000000 Binary files a/pr-preview/pr-63/.doctrees/index.doctree and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/jobs.doctree b/pr-preview/pr-63/.doctrees/jobs.doctree deleted file mode 100644 index b3223875..00000000 Binary files a/pr-preview/pr-63/.doctrees/jobs.doctree and /dev/null differ diff --git a/pr-preview/pr-63/.doctrees/namelists.doctree b/pr-preview/pr-63/.doctrees/namelists.doctree deleted file mode 100644 index d22625df..00000000 Binary files a/pr-preview/pr-63/.doctrees/namelists.doctree and /dev/null differ diff --git a/pr-preview/pr-63/_images/processing_chain_workflow_icon_art.png b/pr-preview/pr-63/_images/processing_chain_workflow_icon_art.png deleted file mode 100644 index 4a5164d0..00000000 Binary files a/pr-preview/pr-63/_images/processing_chain_workflow_icon_art.png and /dev/null differ diff --git a/pr-preview/pr-63/_modules/index.html b/pr-preview/pr-63/_modules/index.html deleted file mode 100644 index cdb6d164..00000000 --- a/pr-preview/pr-63/_modules/index.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - Overview: module code — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/biofluxes.html b/pr-preview/pr-63/_modules/jobs/biofluxes.html deleted file mode 100644 index 6576d481..00000000 --- a/pr-preview/pr-63/_modules/jobs/biofluxes.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - jobs.biofluxes — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.biofluxes

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-
-from . import tools, prepare_cosmo
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Prepare biofluxes files for COSMO simulations. - - Copies biofluxes files from the project folder (:attr:`cfg.vprm['dir']`) - to the int2lm input folder on scratch (:attr:`cfg.int2lm_input`/vprm). - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - prepare_cosmo.set_cfg_variables(cfg) - - scratch_path = os.path.join(cfg.int2lm_input, 'vprm') - - tools.create_dir(scratch_path, "biofluxes input") - - for time in tools.iter_hours(cfg.startdate_sim, cfg.enddate_sim): - logging.info(time) - - for prefix in cfg.vprm['prefix']: - filename = os.path.join(cfg.vprm['dir'], - prefix + time.strftime('%Y%m%d%H.nc')) - filename_sc = os.path.join(scratch_path, - prefix + time.strftime('%Y%m%d%H.nc')) - if not (os.path.isfile(filename)): - logging.error( - "File %s not found. Consider using the vprmsplit.py script prior", - filename) - #tools.vprmsplit.main(time.strftime("%Y%m%d%H"),cfg.vprm['dir']_orig,cfg.vprm['dir']_proc,cfg) - - tools.copy_file(filename, scratch_path) - - if not os.path.isfile(filename_sc): - logging.error( - "Splitting or copying of GPP or/and RA files to scratch failed." - )
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/check_output.html b/pr-preview/pr-63/_modules/jobs/check_output.html deleted file mode 100644 index 1caed8e8..00000000 --- a/pr-preview/pr-63/_modules/jobs/check_output.html +++ /dev/null @@ -1,1081 +0,0 @@ - - - - - - jobs.check_output — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.check_output

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import logging
-import os
-from os.path import dirname, realpath, basename
-import shutil
-from distutils.dir_util import copy_tree
-import datetime as dt
-import glob
-import numpy as np
-import xarray as xr
-import pandas as pd
-import cartopy.crs as ccrs
-import cartopy.feature as cfeature
-import sys
-import multiprocessing
-import subprocess
-from matplotlib import gridspec
-from PIL import Image
-
-import matplotlib.pyplot as plt
-
-plt.switch_backend('Agg')
-
-try:
-    from . import tools
-except ImportError:
-    import tools
-
-BASIC_PYTHON_JOB = True
-
-
-def pkl_path(folder, pid=None):
-    """ Returns the path (and creates it, if necessary) to the stored
-    pandas data file.
-
-    Parameters
-    ----------	
-    folder : str
-        Path to the chain_root or the output_root
-    pid : int
-        Process ID in case of parallel exectution
-
-    Returns
-    -------
-    output_path : str
-        Full file path to pickle file
-    
-    """
-    if pid is None:
-        # Main file with complete content
-        filename = 'data.pkl'
-    else:
-        # Split file per process
-        filename = 'data_' + str(pid) + '.pkl'
-
-    if pid is None:
-        output_folder = os.path.join(folder, 'check_output')
-    else:
-        output_folder = os.path.join(folder, 'check_output', 'data')
-    tools.create_dir(output_folder, 'check_output')
-    output_path = os.path.join(output_folder, filename)
-
-    return output_path
-
-
-def timeseries_path(cfg):
-    """ Returns the path (and creates it, if necessary) to the timeseries
-    plots.
-
-    Parameters
-    ----------	
-    cfg : Config
-        Object holding all user-configuration parameters as attributes
-
-    Returns
-    -------
-    output_path : str
-        Full file path to timeseries directory
-    """
-    output_folder = os.path.join(cfg.output_root, 'check_output', 'timeseries')
-    tools.create_dir(output_folder, 'timeseries')
-    output_path = os.path.join(cfg.output_root, 'check_output', 'timeseries')
-
-    return output_path
-
-
-def maps_path(cfg):
-    """ Returns the path (and creates it, if necessary) to the map plots.
-
-    Parameters
-    ----------	
-    cfg : Config
-        Object holding all user-configuration parameters as attributes
-
-    Returns
-    -------
-    output_folder : str
-        Full file path to maps directory
-    """
-    output_folder = os.path.join(cfg.chain_root, 'check_output', 'maps')
-    tools.create_dir(output_folder, 'check_output maps')
-
-    return output_folder
-
-
-def animations_path(cfg):
-    """ Returns the path (and creates it, if necessary) to the animations.
-
-    Parameters
-    ----------	
-    cfg : Config
-        Object holding all user-configuration parameters as attributes
-
-    Returns
-    -------
-    output_folder : str
-        Full file path to animations directory
-    """
-    output_folder = os.path.join(cfg.output_root, 'check_output', 'animations')
-    tools.create_dir(output_folder, 'animations')
-    output_path = os.path.join(cfg.output_root, 'check_output', 'animations')
-
-    return output_path
-
-
-def tracername2gas(tracername):
-    """ Returns the chemical symbol from the COSMO tracer name to be 
-    recognized by the helper convert_unit() function.
-
-    Parameters
-    ----------	
-    tracername : str
-        Full name of the tracer in COSMO output file
-
-    Returns
-    -------
-    gas : str
-        Chemical symbol as used in helper
-    """
-    gas = tracername.split('_')[0]
-    if gas == 'NOX':
-        gas = 'NO2'
-    elif gas == 'C14':
-        gas = '14CO2'
-
-    return gas
-
-
-def get_variable_names(cols):
-    """ Get unique variable names from dataframe.
-    
-    Parameters
-    ----------	
-    cols : list of str
-        List of column names from dataframe 
-
-    Returns
-    -------
-    varnames : list of str
-        List of unique variable names (e.g., CO2_A, NOX_BG, ...)
-    
-    """
-    todels = ['max', 'min', 'ground', 'mean', 'std']
-    varnames = []
-    for col in cols:
-        split_col = col.split('_')
-        for todel in todels:
-            split_col = list(filter(lambda x: x != todel, split_col))
-        varnames.append('_'.join(split_col))
-    varnames = list(dict.fromkeys(varnames))
-
-    return varnames
-
-
-def get_units(infiles, varnames):
-    """ Get units of variables from netCDF files.
-
-    Parameters
-    ----------
-    infiles : list of str
-        List of netCDF files 
-    varnames : list of str
-        List of unique variable names (e.g., CO2_A, NOX_BG, ...)
-
-    Returns
-    -------
-    units : dict
-        Dictionary containing units of variable names
-    
-    """
-    DS = xr.open_dataset(infiles[0])
-    starttime = DS.time.values[-1].astype(dt.datetime)
-    units = {}
-    for infile in infiles:
-        DS = xr.open_dataset(infile)
-        time = DS.time.values[-1].astype(dt.datetime)
-        if time > starttime:
-            break
-        for varname in varnames:
-            try:
-                if not varname in units:
-                    units[varname] = DS[varname].units
-            except KeyError:
-                continue
-
-    return units
-
-
-def plot_timeseries(cfg, units):
-    """ Plot of the min, max, mean and std values as time series. 
-    
-    Parameters
-    ----------	
-    cfg : Config
-        Object holding all user-configuration parameters as attributes
-    units : dict
-        Dictionary containing units os variables
-    
-    """
-    data_path = pkl_path(cfg.output_root)
-    df = pd.read_pickle(data_path)
-    ts_path = timeseries_path(cfg)
-
-    varnames = get_variable_names(df.columns.values)
-
-    # Tweak figure properties
-    style_label = 'seaborn-whitegrid'
-    (fig_width, fig_height) = plt.rcParams['figure.figsize']
-    fig_size = [fig_width * 2.2, fig_height * 1.8]
-
-    for varname in varnames:
-        logging.info('Plotting %s.png' % varname)
-
-        # Get diagnostic values
-        vmean = df[varname + '_mean']
-        vstd = df[varname + '_std']
-        vmin = df[varname + '_min']
-        vmax = df[varname + '_max']
-
-        # Unit conversion
-        if (varname.startswith('CO2_') or varname.startswith('CO_')
-                or varname.startswith('CH4_') or varname.startswith('C14_')
-                or varname.startswith('NOX_') or varname.startswith('NO2_')):
-            gas = tracername2gas(varname)
-            in_unit = units[varname]
-            out_unit = tools.helper.common_unit(gas)
-            vmean = tools.helper.convert_unit(vmean, in_unit, out_unit, gas)
-            vstd = tools.helper.convert_unit(vstd, in_unit, out_unit, gas)
-            vmin = tools.helper.convert_unit(vmin, in_unit, out_unit, gas)
-            vmax = tools.helper.convert_unit(vmax, in_unit, out_unit, gas)
-        else:
-            out_unit = units[varname]
-
-        # Figure options
-        fig, axes = plt.subplots(ncols=1,
-                                 nrows=3,
-                                 num=style_label,
-                                 figsize=fig_size,
-                                 squeeze=True)
-        fig.suptitle(cfg.casename)
-
-        axes[0].plot(df.index, vmean, linestyle='-')
-        axes[0].set_title('Ground-level mean values')
-
-        axes[1].plot(df.index, vmin, linestyle='-')
-        axes[1].set_title('Global minimum values')
-
-        axes[2].plot(df.index, vmax, linestyle='-')
-        axes[2].set_title('Global maximum values')
-
-        for ax in axes:
-            ylabel = '%s (%s)' % (varname, out_unit)
-            ax.set_ylabel(ylabel)
-            ax.grid()
-
-        axes[2].set_xlabel('Datetime')
-
-        fig.tight_layout(rect=[0, 0, 1, 0.95])
-        plt.savefig(os.path.join(ts_path, varname + '.png'))
-
-        plt.close('all')
-
-
-def get_data_single_file(infile, chain_src_dir, casename, chain_root):
-    """Fetches the diagnostic data from COSMO output files.
-
-    Parameters
-    ----------
-    infile : str
-        Full file name to be read
-    chain_src_dir : str
-        Path to the directory where the processing chain is ran
-    casename : str
-        Name of the current case
-    chain_root : str
-        Path to the processing chain directory
-    """
-    logging.info(infile)
-
-    DS = xr.open_dataset(infile)
-
-    ground_level = DS.level.values[-1]
-    nctime = DS.time.values[-1]
-
-    # Read values from variables.csv
-    alternate_csv_file = os.path.join(chain_src_dir, 'cases', casename,
-                                      'variables.csv')
-    variables = tools.helper.find_variables_file(alternate_csv_file)
-
-    # Drop variables without min/max values
-    variables['min_value'].replace('', np.nan, inplace=True)
-    variables['max_value'].replace('', np.nan, inplace=True)
-    variables['min_value'].replace(' ', np.nan, inplace=True)
-    variables['max_value'].replace(' ', np.nan, inplace=True)
-    variables.dropna(subset=['min_value'], inplace=True)
-    variables.dropna(subset=['max_value'], inplace=True)
-
-    # Get variable names
-    varnames = variables.index.values
-
-    data_values = dict()
-
-    # Loop over variables
-    for varname in varnames:
-        try:
-            da = DS[varname].sel(time=nctime).values
-        except KeyError:
-            #logging.warning('%s: Variable not in output file \n%s' %(varname,infile))
-            continue
-        if 'level' in DS[varname].dims:
-            da_ground = DS[varname].sel(level=ground_level, time=nctime)\
-                        .values.flatten()
-        else:
-            da_ground = da.flatten()
-
-        da = da.flatten()
-        minval = float(variables.loc[varname, 'min_value'])
-        maxval = float(variables.loc[varname, 'max_value'])
-        logging.info("{:10s} (min: {:11.4e}, max: {:11.4e})".format(
-            varname, minval, maxval))
-
-        varmin = np.nanmin(da)
-        varmax = np.nanmax(da)
-        varmin_ground = np.nanmin(da_ground)
-        varmax_ground = np.nanmax(da_ground)
-        varmean = np.mean(da_ground)
-        varstd = np.std(da_ground)
-
-        data_values[varname + '_min'] = varmin
-        data_values[varname + '_max'] = varmax
-        data_values[varname + '_min_ground'] = varmin_ground
-        data_values[varname + '_max_ground'] = varmax_ground
-        data_values[varname + '_mean'] = varmean
-        data_values[varname + '_std'] = varstd
-
-        if np.isnan(da).any():
-            error_msg = ('Variable %s in file %s has NaNs!' %
-                         (varname, infile))
-            logging.error(error_msg)
-        if (varmin < minval):
-            error_msg = ('Variable %s in file %s falls below minimum value!\n'
-                         'Allowed min = %e\n'
-                         'Actual min = %e' % (varname, infile, minval, varmin))
-            logging.error(error_msg)
-        if (varmax > maxval):
-            error_msg = ('Variable %s in file %s exceeds maximum value!\n'
-                         'Allowed max = %e\n'
-                         'Actual max = %e' % (varname, infile, maxval, varmax))
-            logging.error(error_msg)
-
-    # Get the time from the name
-    time_str = os.path.basename(infile)[4:14]
-    ctime = dt.datetime.strptime(time_str, '%Y%m%d%H')
-
-    data = pd.DataFrame(data_values, index=[ctime])
-
-    # Store the time series of min and max in a pandas file format.
-    pid = os.getpid()
-    logging.info('Storing data to %s' % pkl_path(chain_root, pid))
-    store_data(data, chain_root, pid)
-
-
-def merge_data(cfg):
-    """ Merges multiple pickle files into one.
-
-    Parameters
-    ----------	
-    cfg : Config
-        Object holding all user-configuration parameters as attributes
-
-    Returns
-    -------
-    data : pandas.DataFrame
-        Dataframe containing the whole diagnostic data 
-    """
-    output_path = pkl_path(cfg.output_root)
-    input_path = os.path.join(cfg.chain_root, 'check_output', 'data')
-    infiles = sorted(glob.glob(os.path.join(input_path, "data_*.pkl")))
-    for infile in infiles:
-        data = pd.read_pickle(infile)
-        os.remove(infile)
-        if os.path.exists(output_path):
-            history = pd.read_pickle(output_path)
-            history = history.combine_first(data)
-            history.sort_index(inplace=True)
-            history.to_pickle(output_path)
-        else:
-            data.sort_index(inplace=True)
-            data.to_pickle(output_path)
-
-    data = pd.read_pickle(output_path)
-
-    return data
-
-
-def store_data(data, folder, pid=None):
-    """ Stores the time series diagnostic data in a pandas dataframe.
-    Appends it to the existing file, without overwriting the previous dates. 
-    This is useful if this is a continuous run with a spin-up period or 
-    when using binary restart files.
-
-    Parameters
-    ----------	
-    data: pandas.DataFrame
-        Dataframe containing diagnostic values for each variable
-    folder : str
-        Path to the folder where the results are stored
-    pid : int
-        Process ID in case of parallel exectution
-    """
-    output_path = pkl_path(folder, pid)
-
-    if os.path.exists(output_path):
-        history = pd.read_pickle(output_path)
-        history = history.combine_first(data)
-        history.sort_index(inplace=True)
-        history.to_pickle(output_path)
-    else:
-        data.sort_index(inplace=True)
-        data.to_pickle(output_path)
-
-
-def write_footnotetext(field):
-    """ Formats the footnote text for map plots.
-    
-    Parameter
-    ---------
-    field : numpy.array
-        Two-dimensional field of data to be shown in the plot
-
-    Returns
-    -------
-    footnotetext : str
-        Formatted footnote text with min/max/mean values of the field
-    """
-    fmin = np.min(field)
-    fmax = np.max(field)
-    fmean = np.mean(field)
-
-    footnotetext = 'min: ' + "{:.1f}".format(fmin) + \
-                   '  max: ' + "{:.1f}".format(fmax) + \
-                   '  mean: ' + "{:.1f}".format(fmean)
-
-    return footnotetext
-
-
-def get_infiles(path):
-    """ Returns a sorted file list of COSMO output files without *c.nc file. 
-
-    Parameter
-    ---------
-    path : str
-        Path to the COSMO output folder
-
-    Returns
-    -------
-    infiles : list of str
-        Sorted List of filenames of COSMO ouputs
-    """
-    infiles = sorted(glob.glob(os.path.join(path, "lffd*.nc")))
-    infiles = [
-        infile for infile in infiles
-        if os.path.split(infile)[1].split('lffd', 1)[1][10] != 'c'
-    ]
-
-    # If this is a spin-up simulation, skip the first output files
-    timestr = basename(dirname(dirname(realpath(path))))
-    times = timestr.split("_")
-    spinup_time = int(times[1])
-    start = dt.datetime.strptime(times[0], '%Y%m%d%H')
-
-    if spinup_time < 0:
-        for f in infiles.copy():
-            fname = basename(f)
-            ftime = dt.datetime.strptime(fname[4:14], '%Y%m%d%H')
-            if ftime < start:
-                infiles.remove(f)
-
-    return infiles
-
-
-def plot_single_map(data, infile, output_path, varnames):
-    """ Plots 2D maps of certain variables from a netCDF file.
-
-    Parameters
-    ----------	
-    data: pandas.DataFrame
-        Dataframe containing diagnostic values for each variable
-    infile : str
-        Full file name to be read
-    output_path: str
-        Full path where output files should be generated
-    varnames : list of str
-        Names of variables to be processed
-    """
-    # Read in files
-    logging.info(infile)
-
-    DS = xr.open_dataset(infile)
-
-    ground_level = DS.level.values[-1]
-    nctime = DS.time.values[-1]
-    ts = nctime.astype(dt.datetime)
-    ts = dt.datetime.utcfromtimestamp(ts / 1e9)
-    timestr = ts.strftime("%Y%m%d%H")
-
-    rlon = DS['rlon'].values
-    rlat = DS['rlat'].values
-    lon = DS['lon'].values
-    lat = DS['lat'].values
-    pollon = DS["rotated_pole"].attrs["grid_north_pole_longitude"]
-    pollat = DS["rotated_pole"].attrs["grid_north_pole_latitude"]
-    startlon = rlon[0]
-    endlon = rlon[-1]
-    startlat = rlat[0]
-    endlat = rlat[-1]
-
-    domain = tools.helper.Domain('COSMO',
-                                 startlon,
-                                 startlat,
-                                 endlon,
-                                 endlat,
-                                 pollon=pollon,
-                                 pollat=pollat)
-
-    # Check for rotated pole coordinates
-    if not isinstance(domain.proj, ccrs.RotatedPole):
-        raise NotImplementedError('domain needs to use rotated pole coords')
-
-    for varname in varnames:
-        try:
-            field = DS[varname].sel(time=nctime).values
-        except KeyError:
-            logging.warning('%s: Variable not in output file \n%s' %
-                            (varname, infile))
-            continue
-        if len(np.shape(field)) == 3:
-            field = DS[varname].sel(level=ground_level, time=nctime).values
-
-        convert = False
-        # Unit conversion
-        if (varname.startswith('CO2_') or varname.startswith('CO_')
-                or varname.startswith('CH4_') or varname.startswith('C14_')
-                or varname.startswith('NOX_') or varname.startswith('NO2_')):
-            convert = True
-            gas = tracername2gas(varname)
-            in_unit = DS[varname].units
-            out_unit = tools.helper.common_unit(gas)
-            field = tools.helper.convert_unit(field, in_unit, out_unit, gas)
-        else:
-            out_unit = DS[varname].units
-
-        # Set min/max for colorbar and convert if needed
-        vmin = data[varname + "_min_ground"].min()
-        vmax = data[varname + "_max_ground"].max()
-        if convert:
-            vmin = tools.helper.convert_unit(vmin, in_unit, out_unit, gas)
-            vmax = tools.helper.convert_unit(vmax, in_unit, out_unit, gas)
-
-        # Set manual min/max range in case they are equal
-        if vmax == vmin:
-            vmax == vmin + 1
-
-        # Create figure and axes objects
-        fig = plt.figure()
-        gs = gridspec.GridSpec(1, 2, width_ratios=[9, 1])
-        ax = plt.subplot(gs[0], projection=domain.proj)
-        cax = plt.subplot(gs[1])
-
-        # Dimensions
-        dlon = rlon[1] - rlon[0]
-        left = rlon[0] - dlon / 2.0
-        right = rlon[-1] + dlon / 2.0
-        dlat = rlat[1] - rlat[0]
-        bottom = rlat[0] - dlat / 2.0
-        top = rlat[-1] + dlat / 2.0
-        ax.set_xlim(domain.startlon, domain.stoplon)
-        ax.set_ylim(domain.startlat, domain.stoplat)
-
-        # Annotations
-        ax.set_title(varname, loc='left', pad=10.0)
-        ax.set_title(timestr, loc='right', pad=10.0)
-        footnotetext = write_footnotetext(field)
-        ax.annotate(footnotetext, (0, 0), (0, -4),
-                    xycoords='axes fraction',
-                    textcoords='offset points',
-                    va='top')
-
-        # Add coastlines
-        ax.coastlines(resolution='10m', color="black", linewidth=1)
-        lines = cfeature.NaturalEarthFeature(
-            category='cultural',
-            name='admin_0_boundary_lines_land',
-            scale='10m',
-        )
-        ax.add_feature(lines,
-                       edgecolor="grey",
-                       facecolor='none',
-                       linewidth=0.75)
-
-        # Fill the plot
-        im = ax.imshow(field,
-                       vmin=vmin,
-                       vmax=vmax,
-                       cmap='viridis',
-                       extent=(left, right, bottom, top),
-                       interpolation=None,
-                       transform=domain.proj)
-
-        # Colorbar
-        cax.cla()
-        ticks = np.linspace(vmin, vmax, 8, endpoint=True)
-        cb = plt.colorbar(im, cax=cax, ticks=ticks)
-        cb.ax.set_yticklabels(["{:.1f}".format(i) for i in ticks])
-        cb.ax.set_title(out_unit)
-
-        # Save figure
-        output_folder = os.path.join(output_path, varname)
-        fig.savefig(os.path.join(output_folder,
-                                 varname + '_' + timestr + '.png'),
-                    bbox_inches='tight')
-        plt.close('all')
-
-
-def create_map_directories(cfg, data, units):
-    """Create folders for the 2D maps of variables.
-
-    Parameters
-    ----------	
-    cfg : Config
-        Object holding all user-configuration parameters as attributes
-    data: pandas.DataFrame
-        Dataframe containing diagnostic values for each variable
-    units : dict
-        Dictionary of units per variable name
-    """
-    output_path = maps_path(cfg)
-    data_path = pkl_path(cfg.output_root)
-    df = pd.read_pickle(data_path)
-
-    # Get variable names
-    varnames = get_variable_names(df.columns.values)
-    # Create directories per variable for map plots
-    for varname in varnames:
-        output_folder = os.path.join(output_path, varname)
-        tools.create_dir(output_folder, varname)
-
-
-def create_animations(cfg):
-    """Creates animated *.gif files from map plots.
-
-    Parameters
-    ----------	
-    cfg : Config
-        Object holding all user-configuration parameters as attributes
-    """
-    data_path = pkl_path(cfg.output_root)
-    df = pd.read_pickle(data_path)
-
-    # Get variable names
-    varnames = get_variable_names(df.columns.values)
-
-    map_path = os.path.join(cfg.output_root, 'check_output', 'maps')
-    output_path = animations_path(cfg)
-    for varname in varnames:
-        infile_path = os.path.join(map_path, varname)
-        infiles = sorted(glob.glob(os.path.join(infile_path, "*.png")))
-        frames = []
-        for i in infiles:
-            new_frame = Image.open(i)
-            frames.append(new_frame)
-
-        # Save into a GIF file
-        outfile = os.path.join(output_path, varname + '.gif')
-        frames[0].save(outfile,
-                       format='GIF',
-                       append_images=frames[1:],
-                       save_all=True,
-                       duration=300)
-
-
-
[docs]def main(cfg): - """Check output variables for physical reasonability and create plots. - - This function checks the output variables to ensure they are in a physically - reasonable range. It stores the time series of the minimum, maximum, mean, and - standard deviation of the variables as a pandas object into a pickle file. - - It also creates per-variable plots from the stored time series data. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - date = dt.datetime.today() - - to_print = """check_output - -===================================================== -============== POST PROCESSING BEGINS =============== -============== StartTime: %s -=====================================================""" % date.strftime("%s") - - logging.info(to_print) - - # if cfg.compute_host!="daint": - # logging.error("The check_output script is supposed to be run on daint only, " - # "not on %s" % cfg.compute_host) - # sys.exit(1) - """Wait for Cosmo to finish first""" - tools.check_job_completion(cfg.log_finished_dir, "cosmo", - waittime=300) # check every 30 seconds - - # Get list of files - logging.info('Getting list of input files') - infiles = get_infiles(cfg.cosmo_output) - - # Get data from COSMO output files - logging.info('Getting data from COSMO output files') - to_write = """#!/usr/bin/env bash -#SBATCH --partition=debug -#SBATCH --account=em05 -#SBATCH --job-name="check_output_{cfg.startdate_sim_yyyymmddhh}_{cfg.forecasttime}" -#SBATCH --open-mode=append -#SBATCH --time=00:30:00 -#SBATCH --constraint=mc -#SBATCH --ntasks=1 -#SBATCH --output={cfg.logfile} - - -export EASYBUILD_PREFIX=/store/empa/em05/easybuild -export ECCODES_DEFINITION_PATH=/store/empa/em05/easybuild/software/ecCodes/2.12.5-CrayGNU-19.10/share/eccodes/definitions/ - -module load daint-mc -module load EasyBuild-custom - -module load daint-mc -module load EasyBuild-custom - -module load cray-python/3.8.5.0 -module load PyExtensions/python3-CrayGNU-20.11 - -module load GEOS -module load PROJ/4.9.3-CrayGNU-20.11 -module load ecCodes -#module load GDAL # FIXME: currently easybuild install is not working - -# source /store/empa/em05/pyvenv-3.8/bin/activate -source ~/python/stem2/bin/activate - -srun python jobs/check_output.py {casename} {cosmo_output} {output_root} {chain} {chain_root} {action} -""" - to_write_fmt = to_write.format(cfg=cfg, - casename=cfg.casename, - cosmo_output=cfg.cosmo_output, - output_root=cfg.output_root, - work_log=cfg.log_working_dir, - logfile=cfg.logfile, - chain=cfg.chain_src_dir, - chain_root=cfg.chain_root, - action='get_data') - - output_file = os.path.join(cfg.cosmo_work, "get_data.job") - - with open(output_file, 'w') as outf: - outf.write(to_write_fmt) - - result = subprocess.run(["sbatch", "--wait", output_file]) - exitcode = result.returncode - - if exitcode != 0: - raise RuntimeError("sbatch returned exitcode {}".format(exitcode)) - - # Merge data to single pickle file - logging.info('Merging data to single pickle file') - data = merge_data(cfg) - - # Get variable names - logging.info('Getting variable names') - varnames = get_variable_names(data.columns.values) - logging.info(varnames) - - # Get units - logging.info('Reading units') - units = get_units(infiles, varnames) - logging.info(units) - - # Plots - logging.info('Creating timeseries plots in %s' % timeseries_path(cfg)) - plot_timeseries(cfg, units) - - logging.info('Creating map plots in %s' % maps_path(cfg)) - create_map_directories(cfg, data, units) - - to_write_fmt = to_write.format(cfg=cfg, - casename=cfg.casename, - cosmo_output=cfg.cosmo_output, - output_root=cfg.output_root, - logfile=cfg.logfile, - chain=cfg.chain_src_dir, - chain_root=cfg.chain_root, - action='plot_maps') - - output_file = os.path.join(cfg.cosmo_work, "plot_maps.job") - - with open(output_file, 'w') as outf: - outf.write(to_write_fmt) - - result = subprocess.run(["sbatch", "--wait", output_file]) - exitcode = result.returncode - - if exitcode != 0: - raise RuntimeError("sbatch returned exitcode {}".format(exitcode)) - - # Move map plots to output directory - src_folder = os.path.join(cfg.chain_root, 'check_output', 'maps') - dest_folder = os.path.join(cfg.output_root, 'check_output') - logging.info('Move map plots to %s' % dest_folder) - try: - shutil.move(src_folder, dest_folder) - except: - for varname in varnames: - fromDirectory = os.path.join(src_folder, varname) - toDirectory = os.path.join(dest_folder, 'maps', varname) - copy_tree(fromDirectory, toDirectory) - - # Animations - logging.info('Creating animations in %s' % animations_path(cfg)) - create_animations(cfg) - - date = dt.datetime.today() - to_print = """===================================================== -============== POST PROCESSING ENDS ================== -============== EndTime: %s -=====================================================""" % date.strftime("%s") - logging.info(to_print) - - # Check for errors - with open(cfg.logfile) as f: - if 'ERROR' in f.read(): - raise RuntimeError('Logfile containing errors! See %s' % - cfg.logfile)
- - -if __name__ == '__main__': - args = sys.argv - - casename = args[1] - cosmo_output = args[2] - output_root = args[3] - chain_src_dir = args[4] - chain_root = args[5] - action = args[6] - - output_folder = os.path.join(chain_root, 'check_output') - data_path = os.path.join(output_root, 'check_output', 'data.pkl') - infiles = get_infiles(cosmo_output) - - nthread = 36 - - if action == 'plot_maps': - with multiprocessing.Pool(nthread) as pool: - data = pd.read_pickle(data_path) - # Get variable names - output_path = os.path.join(output_folder, 'maps') - varnames = get_variable_names(data.columns.values) - pool.starmap(plot_single_map, - [(data, infile, output_path, varnames) - for infile in infiles]) - - elif action == 'get_data': - # Loop over all files and check values - with multiprocessing.Pool(nthread) as pool: - pool.starmap(get_data_single_file, - [(infile, chain_src_dir, casename, chain_root) - for infile in infiles]) -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/cosmo.html b/pr-preview/pr-63/_modules/jobs/cosmo.html deleted file mode 100644 index a1cc0002..00000000 --- a/pr-preview/pr-63/_modules/jobs/cosmo.html +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - jobs.cosmo — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.cosmo

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import logging
-import os
-import subprocess
-from pathlib import Path
-
-from datetime import datetime
-from .tools import write_cosmo_input_ghg
-from . import tools, prepare_cosmo
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Setup the namelists for a COSMO run and submit the job to the queue. - - Create necessary directory structure to run COSMO (run, output, and - restart directories, defined in ``cfg.cosmo_run``, ``cfg.cosmo_output``, - and ``cfg.cosmo_restart_out``). - - Copy the COSMO-executable from - ``cfg.cosmo['binary_file']`` to ``cfg.cosmo_run/cfg.cosmo['execname']``. - - Convert the tracer csv file to a COSMO namelist file. - - Format the COSMO namelist templates using the information in ``cfg``. - - Format the runscript template and submit the job. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - prepare_cosmo.set_cfg_variables(cfg) - - logging.info("Setup the namelist for a COSMO tracer run and " - "submit the job to the queue") - - # Create directories - tools.create_dir(cfg.cosmo_run, "cosmo_run") - tools.create_dir(cfg.cosmo_output, "cosmo_output") - - # Total number of processes - np_tot = int(cfg.cosmo['np_x'] * cfg.cosmo['np_y'] / - cfg.ntasks_per_node) + cfg.cosmo['np_io'] - - # If an laf* file is used for initialization, - # copy this to to 'cosmo/input/initial/' or merge with fieldextra - if hasattr(cfg, 'laf_startfile'): - tools.create_dir(cfg.cosmo_input, "cosmo_input") - ini_dir = os.path.join(cfg.cosmo_input, "initial") - tools.create_dir(ini_dir, "cosmo_input_initial") - startfiletime = datetime.strptime(cfg.laf_startfile[-10:], "%Y%m%d%H") - if cfg.startdate_sim >= startfiletime: - work_root = os.path.dirname(os.path.dirname(cfg.chain_root)) - last_output_path = os.path.join(work_root, cfg.casename, - cfg.chunk_id_prev, 'cosmo', - 'output') - laf_output_refdate = cfg.startdate_sim.strftime("%Y%m%d%H") - last_laf_filename = "laf" + laf_output_refdate - # At the beginning, use original laf_startfile - if cfg.startdate_sim == startfiletime: - last_laf_startfile = cfg.laf_startfile - else: - last_laf_startfile = os.path.join(last_output_path, - last_laf_filename) - - # Check if fieldextra is used - if hasattr(cfg, 'fieldextra_bin') and \ - hasattr(cfg, 'fieldextra_control_file'): - # Check if merge should be done for initial file - if not hasattr(cfg, 'do_merge_at_start'): - setattr(cfg, 'do_merge_at_start', False) - if cfg.startdate_sim == startfiletime and not cfg.do_merge_at_start: - # Just copy the existing laf file - tools.copy_file(last_laf_startfile, ini_dir) - else: - out_file = os.path.join(ini_dir, last_laf_filename) - ifs_in_file = os.path.join(cfg.int2lm_output, - last_laf_filename) - # Write control file for fieldextra script (merge.ctl) - with open(cfg.fieldextra_control_file) as input_file: - to_write = input_file.read() - - output_file_merge = os.path.join(ini_dir, "merge.ctl") - with open(output_file_merge, "w") as outf: - outf.write( - to_write.format( - cfg=cfg, - in_file=last_laf_startfile, - ifs_in_file=ifs_in_file, - out_file=out_file, - laf_output_refdate=laf_output_refdate, - )) - # Execute fieldextra - with open(cfg.logfile, "a+") as log: - result = subprocess.run( - [cfg.fieldextra_bin, output_file_merge], - stdout=log) - exitcode = result.returncode - if exitcode != 0: - raise RuntimeError( - "Fieldextra returned exitcode {}".format(exitcode)) - else: - # Just copy the existing laf file - tools.copy_file(last_laf_startfile, ini_dir) - else: - raise ValueError( - "Start time %s must not be smaller than in laf_starttime %s." % - (str(cfg.starttime_sim), str(startfiletime))) - - # Create restart directory if feature is present and - # if there is no spinup - if 'restart' in cfg.workflow['features'] and not \ - hasattr(cfg, 'spinup'): - tools.create_dir(cfg.cosmo_restart_out, "cosmo_restart_out") - - # Copy cosmo executable - cfg.cosmo_execname = Path(cfg.cosmo['binary_file']).name - tools.copy_file(cfg.cosmo['binary_file'], - cfg.cosmo_run / cfg.cosmo_execname) - - # Prepare namelist and submit job - tracer_csvfile = os.path.join(cfg.chain_src_dir, 'cases', cfg.casename, - 'cosmo_tracers.csv') - if hasattr(cfg, 'cams') or hasattr(cfg, 'mozart'): - namelist_names = ['AF', 'ORG', 'IO', 'DYN', 'GHG', 'PHY', 'DIA', 'ASS'] - elif hasattr(cfg, 'photo_rate'): - namelist_names = [ - 'ART', 'ASS', 'DIA', 'DYN', 'EPS', 'INI', 'IO', 'ORG', 'PHY' - ] - if hasattr(cfg, 'oem_dir'): - # When doing online emissions in COSMO-ART, an additional - # namelist is required - namelist_names += ['OAE'] - elif hasattr(cfg, 'cosmo'): - namelist_names = ['ORG', 'IO', 'DYN', 'PHY', 'DIA', 'ASS', 'SAT'] - - for section in namelist_names: - namelist_file = os.path.join( - cfg.chain_src_dir, 'cases', cfg.casename, - cfg.cosmo['namelist_prefix'] + section + ".cfg") - with open(namelist_file) as input_file: - cosmo_namelist = input_file.read() - - output_file = os.path.join(cfg.cosmo_run, "INPUT_" + section) - with open(output_file, "w") as outf: - if hasattr(cfg, 'spinup'): - # no built-in restarts - cosmo_namelist = cosmo_namelist.format(cfg=cfg, - **cfg.cosmo, - **cfg.oem, - restart_start=12, - restart_stop=0, - restart_step=12) - else: - # built-in restarts - cosmo_namelist = cosmo_namelist.format( - cfg=cfg, - **cfg.cosmo, - **cfg.oem, - restart_start=0, - restart_stop=cfg.restart_step_hours, - restart_step=cfg.restart_step_hours) - outf.write(cosmo_namelist) - - # Append INPUT_GHG namelist with tracer definitions from csv file - if os.path.isfile(tracer_csvfile): - if hasattr(cfg, 'cams') or hasattr(cfg, 'mozart'): - input_ghg_filename = os.path.join(cfg.cosmo_run, 'INPUT_GHG') - - write_cosmo_input_ghg.main(tracer_csvfile, input_ghg_filename, cfg) - - # Write run script (run.job) - runscript_file = os.path.join(cfg.chain_src_dir, 'cases', cfg.casename, - cfg.cosmo['runjob_filename']) - with open(runscript_file) as input_file: - cosmo_runscript = input_file.read() - - Path(cfg.cosmo_run).mkdir(parents=True, exist_ok=True) - script = (cfg.cosmo_run / 'run_cosmo.job') - with open(script, "w") as outf: - outf.write( - cosmo_runscript.format(cfg=cfg, - **cfg.cosmo, - np_tot=np_tot, - logfile=cfg.logfile, - logfile_finish=cfg.logfile_finish)) - - # Submit job - cfg.submit('cosmo', script)
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/emissions.html b/pr-preview/pr-63/_modules/jobs/emissions.html deleted file mode 100644 index 382de31e..00000000 --- a/pr-preview/pr-63/_modules/jobs/emissions.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - jobs.emissions — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.emissions

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-
-from . import tools, prepare_cosmo
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Copy emission files to the int2lm input directory. - - Necessary for both COSMO and COSMOART simulations. - - Copy emission files from project folder (``cfg.emissions['dir']``) to - int2lm input folder on scratch (``cfg.int2lm_input/emissions``). - - For COSMO simulations, converts the netCDF-variable-names - from ``string`` to ``char`` (necessary for int2lm). - - If there are multiple emission-datasets (cfg.emissions['dir'] is a list of - paths), they are copied as follows:: - - cfg.emissions['dir'][0]/cfg.emissions['gridname'][0]YYYYMMDD.nc -> int2lm_input/emissions/emis_YYYYMMDD.nc - cfg.emissions['dir'][1]/cfg.emissions['gridname'][1]YYYYMMDD.nc -> int2lm_input/emissions2/emis_YYYYMMDD.nc - cfg.emissions['dir'][2]/cfg.emissions['gridname'][2]YYYYMMDD.nc -> int2lm_input/emissions3/emis_YYYYMMDD.nc - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - prepare_cosmo.set_cfg_variables(cfg) - dest_prefix = "emis_" - - if not isinstance(cfg.emissions['dir'], list): - emis_dirs = [cfg.emissions['dir']] - else: - emis_dirs = cfg.emissions['dir'] - if not isinstance(cfg.emissions['gridname'], list): - emis_prefixes = [cfg.emissions['gridname']] - else: - emis_prefixes = cfg.emissions['gridname'] - - assert len(emis_dirs) == len(emis_prefixes), ( - "Different number of cfg.emissions['dir'] and cfg.emissions['gridname']" - ) - - for i, (emis_dir, emis_prefix) in enumerate(zip(emis_dirs, emis_prefixes)): - # create directory - if i == 0: - target_dir = os.path.join(cfg.int2lm_input, "emissions") - tools.create_dir(target_dir, "emissions input") - else: - target_dir = os.path.join(cfg.int2lm_input, - "emissions" + str(i + 1)) - tools.create_dir(target_dir, "emissions input") - # copy data - for time in tools.iter_hours(cfg.startdate_sim, cfg.enddate_sim): - logging.info(time) - filename_ending = time.strftime('%Y%m%d%H.nc') - source_path = os.path.join(emis_dir, emis_prefix + filename_ending) - dest_path = os.path.join(target_dir, dest_prefix + filename_ending) - tools.copy_file(source_path, dest_path) - - # convert grid_mapping_name from string (NF90_STRING) to char - # (NF90_CHAR) (needed for int2lm to work) - if hasattr(cfg, 'cosmo'): - tools.string2char.main(dest_path)
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/icon.html b/pr-preview/pr-63/_modules/jobs/icon.html deleted file mode 100644 index 4260b16b..00000000 --- a/pr-preview/pr-63/_modules/jobs/icon.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - jobs.icon — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.icon

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import logging
-from pathlib import Path
-from . import tools, prepare_icon
-
-BASIC_PYTHON_JOB = False
-
-
-
[docs]def main(cfg): - """Setup the namelists for an ICON run and submit the job to - the queue. - - Copy the ICON-executable from - ``cfg.icon_binary_file`` to ``cfg.icon_work/icon.exe``. - - Format the ICON-namelist-templates: - ``icon_master.namelist.cfg, icon_NAMELIST_NWP.cfg``, - using the information in ``cfg``. - - Format the runscript-template and submit the job. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - prepare_icon.set_cfg_variables(cfg) - tools.change_logfile(cfg.logfile) - - logging.info("Setup the namelist for an ICON run and " - "submit the job to the queue") - - # Copy icon executable - cfg.icon_execname = Path(cfg.icon['binary_file']).name - tools.create_dir(cfg.icon_work, "icon_work") - tools.copy_file(cfg.icon_binary_file, cfg.icon_work / cfg.icon_execname) - - # Symlink the restart file to the last run into the icon/run folder - if cfg.lrestart == '.TRUE.': - tools.symlink_file(cfg.restart_file, cfg.restart_file_scratch) - - # Get name of initial file - if hasattr(cfg, 'inicond_filename'): - inidata_filename = cfg.icon_input_icbc / cfg.inicond_filename - else: - inidata_filename = cfg.icon_input_icbc / str( - cfg.startdate_sim.strftime(cfg.meteo['prefix'] + - cfg.meteo['nameformat']) + '.nc') - - # Write run script (run_icon.job) - template = (cfg.case_path / cfg.icon_runjob_filename).read_text() - script_str = template.format(cfg=cfg, inidata_filename=inidata_filename) - script = (cfg.icon_work / 'run_icon.job') - script.write_text(script_str) - - # Submit run script - cfg.submit('icon', script)
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/icontools.html b/pr-preview/pr-63/_modules/jobs/icontools.html deleted file mode 100644 index 3fbc1608..00000000 --- a/pr-preview/pr-63/_modules/jobs/icontools.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - jobs.icontools — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.icontools

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import logging
-import os
-import xarray as xr
-import numpy as np
-from . import tools, prepare_icon
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """ - - Add GEOSP to all meteo files - - Submit the runscript for the DWD ICON tools to remap the meteorological files. - - All runscripts specified in ``cfg.icontools_runjobs`` are submitted. - - The meteorological files are read from the original input directory - (``cfg.input_root_meteo``), and the remapped meteorological files are saved - in the input folder on scratch (``cfg.icon_input/icbc``). - """ - prepare_icon.set_cfg_variables(cfg) - tools.change_logfile(cfg.logfile) - - #----------------------------------------------------- - # Create LBC datafile lists (each at 00 UTC and others) - #----------------------------------------------------- - datafile_list = [] - datafile_list_rest = [] - datafile_list_chem = [] - for time in tools.iter_hours(cfg.startdate_sim, cfg.enddate_sim, - cfg.meteo['inc']): - meteo_file = cfg.icon_input_icbc / ( - cfg.meteo['prefix'] + time.strftime(cfg.meteo['nameformat'])) - if hasattr(cfg, 'art_input_folder'): - chem_file = cfg.icon_input_icbc / ( - cfg.chem['prefix'] + time.strftime(cfg.chem_nameformat)) - datafile_list_chem.append(str(chem_file) + cfg.chem['suffix']) - if str(meteo_file).endswith('00'): - datafile_list.append(str(meteo_file) + cfg.meteo['suffix']) - else: - datafile_list_rest.append(str(meteo_file) + cfg.meteo['suffix']) - datafile_list = ' '.join([str(v) for v in datafile_list]) - datafile_list_rest = ' '.join([str(v) for v in datafile_list_rest]) - datafile_list_chem = ' '.join([str(v) for v in datafile_list_chem]) - - #----------------------------------------------------- - # Write and submit ICONTOOLS runscripts - #----------------------------------------------------- - dep_id = None - for runscript in cfg.icontools_runjobs: - with (cfg.case_path / runscript).open() as input_file: - to_write = input_file.read() - runscript_path = cfg.icon_work / f"{runscript}.job" - with runscript_path.open("w") as outf: - outf.write( - to_write.format(cfg=cfg, - meteo=cfg.meteo, - logfile=cfg.logfile, - logfile_finish=cfg.logfile_finish, - datafile_list=datafile_list, - datafile_list_rest=datafile_list_rest, - datafile_list_chem=datafile_list_chem)) - - # Submitting icontools runscripts sequentially - logging.info(f" Starting icontools runscript {runscript}.") - dep_id = cfg.submit('icontools', runscript_path, add_dep=dep_id) - - logging.info("Add GEOSP to all meteo files") - for time in tools.iter_hours(cfg.startdate_sim, cfg.enddate_sim, - cfg.meteo['inc']): - # Specify file names - geosp_filename = time.replace( - hour=0).strftime(cfg.meteo['prefix'] + - cfg.meteo['nameformat']) + '_lbc.nc' - geosp_file = os.path.join(cfg.icon_input_icbc, geosp_filename) - src_filename = time.strftime(cfg.meteo['prefix'] + - cfg.meteo['nameformat']) + '_lbc.nc' - src_file = os.path.join(cfg.icon_input_icbc, src_filename) - merged_filename = time.strftime(cfg.meteo['prefix'] + - cfg.meteo['nameformat']) + '_merged.nc' - merged_file = os.path.join(cfg.icon_input_icbc, merged_filename) - - # Copy GEOSP file from last run if not present - if hasattr(cfg, - 'icon_input_icbc_prev') and not os.path.exists(geosp_file): - geosp_src_file = os.path.join(cfg.icon_input_icbc_prev, - geosp_filename) - tools.copy_file(geosp_src_file, - cfg.icon_input_icbc, - output_log=True) - - # Load GEOSP data array as da_geosp at time 00: - ds = xr.open_dataset(src_file) - ds_geosp = xr.open_dataset(geosp_file) - da_geosp = ds_geosp['GEOSP'] - - # Merge GEOSP-dataset with other timesteps - if (time.hour != 0): - # Change values of time dimension to current time - da_geosp = da_geosp.assign_coords(time=[np.datetime64(time)]) - # Merge GEOSP into temporary file - ds_merged = xr.merge([ds, da_geosp]) - ds_merged.attrs = ds.attrs - ds_merged.to_netcdf(merged_file) - # Logging info for merging GEOSP - logging.info("Added GEOSP to file {}".format(merged_file)) - # Rename file to get original file name - tools.rename_file(merged_file, src_file) - logging.info('OK')
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/int2lm.html b/pr-preview/pr-63/_modules/jobs/int2lm.html deleted file mode 100644 index 5f928448..00000000 --- a/pr-preview/pr-63/_modules/jobs/int2lm.html +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - jobs.int2lm — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.int2lm

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-import shutil
-import pytz
-
-from datetime import datetime
-from . import tools, prepare_cosmo
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Setup the namelist for int2lm and submit the job to the queue. - - Necessary for both COSMO and COSMOART simulations. - - Decide if the soil model should be TERRA or TERRA multi-layer depending on - `startdate` of the simulation. - - Create necessary directory structure to run int2lm (run and output - directories, defined in ``cfg.int2lm`` and ``cfg.int2lm['output']``). - - Copy the int2lm-executable from ``cfg.int2lm['binary_file']`` to - ``cfg.int2lm['work']/int2lm``. - - Copy the extpar-file ``cfg.int2lm['extpar_file']`` to - ``cfg.int2lm_run/work``. - - COSMOART: Copy the ``libgrib_api`` files to - ``cfg.int2lm['work']/libgrib_api``. - - COSMO: Convert the tracer-csv-files into an int2lm-namelist file. - - Format the int2lm-namelist-template using the information in ``cfg``. - - Format the runscript-template and submit the job. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - prepare_cosmo.set_cfg_variables(cfg) - - # Total number of processes - np_tot = cfg.int2lm['np_x'] * cfg.int2lm['np_y'] - - # Set folder names - int2lm_run = os.path.join(cfg.int2lm_run) - int2lm_output = os.path.join(cfg.int2lm_output) - - # Create int2lm directories - tools.create_dir(int2lm_run, "int2lm_run") - tools.create_dir(int2lm_output, "int2lm_output") - - tools.copy_file(cfg.int2lm['binary_file'], - os.path.join(int2lm_run, "int2lm")) - - # Copy extpar file to input/extpar directory - extpar_dir = os.path.join(cfg.int2lm_input, "extpar") - tools.create_dir(extpar_dir, "int2lm extpar") - tools.copy_file( - os.path.join(cfg.int2lm['extpar_dir'], cfg.int2lm['extpar_filename']), - extpar_dir) - - # Copy landuse and plant-functional-type files - if hasattr(cfg, 'photo_rate'): - lu_file_src = cfg.int2lm['lu_file'] - lu_file_dst = os.path.join(extpar_dir, 'landuse.nc') - tools.copy_file(lu_file_src, lu_file_dst) - - pft_file_src = cfg.int2lm['pft_file'] - pft_file_dst = os.path.join(extpar_dir, 'pft.nc') - tools.copy_file(pft_file_src, pft_file_dst) - - # Copy libgrib_api - dest = os.path.join(cfg.int2lm['work'], 'libgrib_api') - try: - # delete so no error when forcing this job - shutil.rmtree(dest) - except FileNotFoundError: - pass - try: - shutil.copytree(src=cfg.int2lm['libgrib_dir'], - dst=dest, - symlinks=True) - except FileNotFoundError: - logging.error("libgrib_api directory not found") - raise - except (PermissionError, OSError): - logging.error("Copying libgrib_api failed") - raise - - # Write INPUT_ART from csv file if present - tracer_csvfile = os.path.join(cfg.chain_src_dir, 'cases', cfg.casename, - 'int2lm_tracers.csv') - if os.path.isfile(tracer_csvfile): - datasets_csvfile = os.path.join(cfg.chain_src_dir, 'cases', - cfg.casename, 'int2lm_datasets.csv') - input_art_filename = os.path.join(int2lm_run, 'INPUT_ART') - - tools.write_int2lm_input_art.main(tracer_csvfile, datasets_csvfile, - input_art_filename) - - # Change of soil model from TERRA to TERRA multi-layer on 2 Aug 2007 - if cfg.startdate_sim < datetime(2007, 8, 2, tzinfo=pytz.UTC): - multi_layer = ".FALSE." - else: - multi_layer = ".TRUE." - - # Prepare namelist - with open(os.path.join(cfg.case_path, - cfg.int2lm['namelist_filename'])) as input_file: - int2lm_namelist = input_file.read() - - # Int2lm processing always starts at hstart=0, thus modifying inidate - hstart_int2lm = 0 - hstop_int2lm = cfg.forecasttime - - output_file = os.path.join(int2lm_run, "INPUT") - with open(output_file, "w") as outf: - outf.write( - int2lm_namelist.format( - cfg=cfg, - **cfg.int2lm, - hstart_int2lm=hstart_int2lm, - hstop_int2lm=hstop_int2lm, - multi_layer=multi_layer, - meteo_prefix=cfg.meteo['prefix'], - )) - - # Prepare runscript - with open(os.path.join(cfg.case_path, - cfg.int2lm['runjob_filename'])) as input_file: - int2lm_runscript = input_file.read() - - script = (cfg.int2lm_run / 'run_int2lm.job') - with open(script, "w") as outf: - outf.write( - int2lm_runscript.format(cfg=cfg, - **cfg.int2lm, - int2lm_run=int2lm_run, - ini_day=cfg.startdate_sim_yyyymmddhh[0:8], - ini_hour=cfg.startdate_sim_yyyymmddhh[8:], - np_tot=np_tot, - hstop_int2lm=hstop_int2lm, - logfile=cfg.logfile, - logfile_finish=cfg.logfile_finish)) - - # Submit job - cfg.submit('int2lm', script)
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/obs_nudging.html b/pr-preview/pr-63/_modules/jobs/obs_nudging.html deleted file mode 100644 index 460e5781..00000000 --- a/pr-preview/pr-63/_modules/jobs/obs_nudging.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - jobs.obs_nudging — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.obs_nudging

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-
-from datetime import timedelta
-from . import tools
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Copy and rename the obs_nudging files to the **COSMO** input directory. - - In the folder ``cfg.obs_nudging_dir``, the files are saved in the format - ``{prefix}-YYYYMMDD000000-YYYYMMDD000000``. **COSMO** expects files in the - format ``{prefix}x``, where ``x`` is ``[nothing], .2, .3, .4, ...``. This - job handles this filename-change and copies them to the **COSMO** input - folder on scratch (``cfg.cosmo_input/obs_nudging``). - - Missing observation files are ignored. - - Also copies the blacklist-file blklsttmp. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - dest_dir = os.path.join(cfg.cosmo_input, "obs_nudging") - tools.create_dir(dest_dir, "obs nudging input") - - logging.info("Copying obs_nudging files from {} to {}".format( - cfg.obs_nudging_dir, dest_dir)) - - for i, t in enumerate( - tools.iter_hours(cfg.startdate_sim, cfg.enddate_sim, step=24)): - i += 1 - for prefix in cfg.obs_nudging_prefixes: - src_filename = ( - prefix + t.strftime(cfg.obs_nudging_date_format) + - (t + timedelta(days=1)).strftime(cfg.obs_nudging_date_format)) - src_path = os.path.join(cfg.obs_nudging_dir, src_filename) - if i == 1: - dest_path = os.path.join(dest_dir, prefix) - else: - dest_path = os.path.join(dest_dir, "{}.{}".format(prefix, i)) - - try: - tools.copy_file(src_path, dest_path) - except BlockingIOError: - continue - logging.info("Copied file {} to {}".format(src_filename, - dest_path)) - - tools.copy_file(os.path.join(cfg.obs_nudging_dir, 'blklsttmp'), dest_dir) - - logging.info("Copied blacklist-file to {}".format(dest_dir))
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/octe.html b/pr-preview/pr-63/_modules/jobs/octe.html deleted file mode 100644 index e52d55f2..00000000 --- a/pr-preview/pr-63/_modules/jobs/octe.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - jobs.octe — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.octe

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import logging
-
-import numpy as np
-
-from os import scandir
-from os.path import join, basename
-from netCDF4 import Dataset
-
-from . import tools
-
-BASIC_PYTHON_JOB = True
-
-
-def create_dir_and_copy_input(dest_dir, lambdas_src, maps_src):
-    """Create a directory at dest_dir (**COSMO** input) and copy src there.
-
-    lambdas_src -> dest_dir/lambdas.nc
-    maps_src   -> dest_dir/maps.nc
-
-    Parameters
-    ----------
-    dest_dir : str
-    lambdas_src : str
-    maps_src : str
-    """
-    tools.create_dir(dest_dir, "input data for OCTE")
-    tools.copy_file(lambdas_src, join(dest_dir, 'lambdas.nc'))
-    tools.copy_file(maps_src, join(dest_dir, 'maps.nc'))
-
-
-def read_lambdas(nc_dataset):
-    """Read the lambda values from the nc_dataset.
-
-    The relevant lambda values are the last ones along the
-    dimension ~nparam~. They are returned in a list of length
-    ~nensembles~.
-
-    Parameters
-    ----------
-    nc_dataset : netCDF4.Dataset
-        Contains a variable called ~lambda~ with dimensions,
-        ~(nensembles, nparam)~
-
-    Returns
-    -------
-    list(float)
-    """
-    lambda_var = nc_dataset['lambda']
-    assert len(lambda_var.dimensions) == 2, (
-        "Number of dimensions of 'lambda' variable doesn't match")
-    # this would not be a problem in python, but COSMO breaks if
-    # this doesn't hold:
-    assert lambda_var.dimensions[1] == 'nparam', (
-        "Dimension ordering of 'lambda' variable incorrect")
-
-    return list(lambda_var[:, -1])
-
-
-def perturb_bg_in_dataset(nc_dataset, lambdas):
-    """Create BG fields from lambdas in nc_dataset.
-
-    Perturb the background CO2 field in nc_dataset based on lambda values in
-    lambdas.
-    The pertubation is just a global scaling of the field by one
-    of the lambda values. For each ensemble member (=each lambda), a new
-    variable is created.
-
-    The perturbed fields are created by multiplying the values of
-    a variable called ~CO2_BG~ with one of the lambda-values. The new
-    field is stored in a newly created variable called ~CO2_BGnnn~,
-    where ~nnn~ runs from ~001~ to ~{nensembles:03d}~.
-
-    If there is no variable ~CO2_BG~ in nc_dataset, do nothing.
-
-    Parameters
-    ----------
-    nc_dataset : netCDF4.Dataset
-        If this doesn't contain a variable ~CO2_BG~, do nothing. If it does,
-        create a new variable for each lambda value with the original field
-        scaled.
-    lambdas : list(float)
-        For each value in the list, create an ensemble member
-    """
-    basevar_name = 'CO2_BG'
-    filename = basename(nc_dataset.filepath())
-
-    if basevar_name not in nc_dataset.variables:
-        logging.info("No BG in dataset {}, doing nothing".format(filename))
-        return
-
-    basevar = nc_dataset[basevar_name]
-
-    field = np.array(basevar[:])
-    dtype = basevar.datatype
-    dims = basevar.dimensions
-    attr_names = basevar.ncattrs()
-    try:
-        # Remove fill value from ncattrs because setting it after
-        # construction is not possible
-        attr_names.remove('_FillValue')
-        fill_value = basevar.getncattr('_FillValue')
-    except ValueError:
-        fill_value = None
-
-    attrs = dict((name, basevar.getncattr(name)) for name in attr_names)
-
-    for i, lambda_ in enumerate(lambdas):
-        name = basevar_name + '{:03d}'.format(i + 1)
-        var = nc_dataset.createVariable(varname=name,
-                                        datatype=dtype,
-                                        dimensions=dims,
-                                        fill_value=fill_value)
-        var[:] = field * lambda_
-        for attrname, attrval in attrs.items():
-            var.setncattr(name=attrname, value=attrval)
-
-    logging.info("Created BG ensemble in dataset {}".format(filename))
-
-
-def perturb_bgs_in_dir(lambdas_nc, directory):
-    """Create perturbed BG fields from read lambda values in all NetCDF-files
-    in the directory.
-
-    Perturb the background CO2 field in all the NetCDF-files
-    found in directory based on lambda values from lambdas_nc.
-    The pertubation is just a global scaling of the field by one
-    lambda value. For each ensemble, a new variable is created.
-
-    Lambda values and the number of ensembles are read from the file
-    lambdas_nc. The lambda-value for the BG is assumed to be the last
-    value along the ~nparam~-dimension of the ~lambda~-variable.
-
-    The perturbed fields are then created by multiplying the values of
-    a variable called ~CO2_BG~ with one of the lambda-values. The new
-    field is stored in a newly created variable called ~CO2_BGnnn~,
-    where ~nnn~ runs from ~001~ to ~{nensembles:03d}~
-
-    Parameters
-    ----------
-    lambdas_nc : str
-        Path to the file storing the lambda-values.
-        Contains a variable called ~lambda~ with dimensions,
-        ~(nensembles, nparam)~.
-    directory : str
-        Path to the output-dir of int2lm. Add perturbed BG-fields to all
-        netcdf-files there containing a variable called ~CO2_BG~.
-
-    """
-    with Dataset(lambdas_nc) as lambdas_file:
-        lambdas = read_lambdas(lambdas_file)
-
-    with scandir(directory) as dir_iterator:
-        for entry in dir_iterator:
-            if not entry.name.startswith('.') and entry.is_file():
-                try:
-                    with Dataset(entry.path, 'a') as nc_dataset:
-                        perturb_bg_in_dataset(nc_dataset, lambdas)
-                except OSError:
-                    logging.info("File {} is not a netCDF-file.".format(
-                        entry.name))
-
-
-
[docs]def main(cfg): - """Copy necessary input files for **COSMO** and perturb BG. - - Copies the NetCDF-files found at ``cfg.octe_maps`` and ``cfg.octe_lambdas`` to - the **COSMO** input-directory. - - Perturbs the background tracer field. To do that, it reads the lambda-value - from the ``cfg.octe_lambdas`` (last value along the nparam-dimension) and - scales the BG-field produced by int2lm, creating a new variable for each - ensemble. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - dest_dir = join(cfg.cosmo_input, 'octe') - create_dir_and_copy_input(dest_dir=dest_dir, - lambdas_src=cfg.octe_lambdas, - maps_src=cfg.octe_maps) - logging.info("Copied OCTE files {} and {} to {}".format( - cfg.octe_lambdas, cfg.octe_maps, dest_dir)) - - logging.info("Starting to create BG-ensembles in " + cfg.int2lm_output) - perturb_bgs_in_dir(cfg.octe_lambdas, cfg.int2lm_output) - logging.info("Finished creating BG-ensembles")
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/oem.html b/pr-preview/pr-63/_modules/jobs/oem.html deleted file mode 100644 index ae2d44b8..00000000 --- a/pr-preview/pr-63/_modules/jobs/oem.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - - - jobs.oem — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.oem

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-
-from . import tools, prepare_cosmo
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Copy emission and profile files to the **cosmo** or **icon** input - directory. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - - Raises - ------ - RuntimeError - If an error occurs during the process. - """ - tools.change_logfile(cfg.logfile) - prepare_cosmo.set_cfg_variables(cfg) - - oem_dir = cfg.oem['dir'] - oem_gridded_emissions_nc = os.path.join(oem_dir, - cfg.oem['gridded_emissions_nc']) - oem_vertical_profiles_nc = os.path.join(oem_dir, - cfg.oem['vertical_profiles_nc']) - - # Temporal profiles can be given as hourofday, dayofweek, monthofyear - # AND/OR as hourofyear. We copy all files indicated in cfg, but make - # sure at least one type is present - hod_tps = True - hoy_tps = True - try: - oem_hourofday_nc = os.path.join(oem_dir, cfg.oem['hourofday_nc']) - oem_dayofweek_nc = os.path.join(oem_dir, cfg.oem['dayofweek_nc']) - oem_monthofyear_nc = os.path.join(oem_dir, cfg.oem['monthofyear_nc']) - except AttributeError: - hod_tps = False - try: - oem_hourofyear_nc = os.path.join(oem_dir, cfg.oem['hourofyear_nc']) - except AttributeError: - hoy_tps = False - - if not (hod_tps or hoy_tps): - raise RuntimeError("At least one of (hod/dow/moy) or (hoy) netcdfs " - " have to be given for online emissions") - - if hasattr(cfg, 'icon'): - input_dir = cfg.icon_input - elif hasattr(cfg, 'cosmo'): - input_dir = cfg.cosmo_input - dest_dir = os.path.join(input_dir, "oem") - tools.create_dir(dest_dir, "online emissions input") - - logging.info("Copying oem files from {} to {}".format(oem_dir, dest_dir)) - - if hod_tps: - tools.copy_file( - oem_gridded_emissions_nc, - os.path.join(dest_dir, cfg.oem['gridded_emissions_nc'])) - tools.copy_file( - oem_vertical_profiles_nc, - os.path.join(dest_dir, cfg.oem['vertical_profiles_nc'])) - tools.copy_file(oem_hourofday_nc, - os.path.join(dest_dir, cfg.oem['hourofday_nc'])) - tools.copy_file(oem_dayofweek_nc, - os.path.join(dest_dir, cfg.oem['dayofweek_nc'])) - tools.copy_file(oem_monthofyear_nc, - os.path.join(dest_dir, cfg.oem['monthofyear_nc'])) - if hoy_tps: - tools.copy_file(oem_hourofyear_nc, - os.path.join(dest_dir, cfg.oem['hourofyear_nc'])) - - # Additional files for ICON simulations - if cfg.oem.get('ens_reg_nc') is not None: - tools.copy_file(os.path.join(oem_dir, cfg.oem['ens_reg_nc']), - os.path.join(dest_dir, cfg.oem['ens_reg_nc'])) - if cfg.oem.get('oem_ens_lambda_nc') is not None: - tools.copy_file(os.path.join(oem_dir, cfg.oem['ens_lambda_nc']), - os.path.join(dest_dir, cfg.oem['ens_lambda_nc']))
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/online_vprm.html b/pr-preview/pr-63/_modules/jobs/online_vprm.html deleted file mode 100644 index 9c4ad219..00000000 --- a/pr-preview/pr-63/_modules/jobs/online_vprm.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - jobs.online_vprm — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.online_vprm

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-
-from . import tools, prepare_cosmo
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Copy MODIS surface reflectance data and vegetation class fraction file - to the **cosmo** input directory. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - prepare_cosmo.set_cfg_variables(cfg) - dest_modis = 'modis.nc' - dest_vegetation = 'vegetation.nc' - - src_dir = cfg.online_vprm['dir'] - dest_dir = os.path.join(cfg.cosmo_input, "vprm") - tools.create_dir(dest_dir, "input data for vprm") - - modis_data_nc = os.path.join(src_dir, cfg.online_vprm['modis_filename']) - logging.info("Copying MODIS file from {} to {}".format(src_dir, dest_dir)) - tools.copy_file(modis_data_nc, os.path.join(dest_dir, dest_modis)) - - vegetation_data_nc = os.path.join(src_dir, - cfg.online_vprm['vegetation_filename']) - logging.info("Copying vegetation class fraction file from {} to {}".format( - src_dir, dest_dir)) - tools.copy_file(vegetation_data_nc, os.path.join(dest_dir, - dest_vegetation))
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/photo_rate.html b/pr-preview/pr-63/_modules/jobs/photo_rate.html deleted file mode 100644 index cdf545f4..00000000 --- a/pr-preview/pr-63/_modules/jobs/photo_rate.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - jobs.photo_rate — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.photo_rate

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-
-from . import tools
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Copy photolysis-rate file to the **COSMOART** input directory. - - Only necessary for **COSMOART** simulations. - - Copy the photolysis-rate file from the project (`cfg.photo_rate_file`) to - the **COSMOART** input folder on scratch (`cfg.cosmo_input/art_photolysis`). - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - - logging.info("Copying photolysis-rate file from {} to {}".format( - cfg.photo_rate_file, - os.path.join(cfg.cosmo_input, "art_photolysis", "papa_data.p"))) - - tools.create_dir(os.path.join(cfg.cosmo_input, "art_photolysis"), - "photolysis rate input") - - src_file = cfg.photo_rate_file - dest_path = os.path.join(cfg.cosmo_input, 'art_photolysis', 'papa_data.d') - - tools.copy_file(src_file, dest_path) - - logging.info("Finished")
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/post_cosmo.html b/pr-preview/pr-63/_modules/jobs/post_cosmo.html deleted file mode 100644 index a8446134..00000000 --- a/pr-preview/pr-63/_modules/jobs/post_cosmo.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - jobs.post_cosmo — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.post_cosmo

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import logging
-import os
-import datetime
-
-from . import tools, prepare_cosmo
-
-BASIC_PYTHON_JOB = True
-
-
-def logfile_header_template():
-    """Returns a template for the logfile-header"""
-    return ("\n=====================================================\n"
-            "============== POST PROCESSING {}\n"
-            "============== {}\n"
-            "=====================================================\n\n")
-
-
-def runscript_header_template():
-    """Returns a template for the runscript-header (#SBATCH-directives)"""
-    return '\n'.join([
-        "#SBATCH --job-name=post_cosmo", "#SBATCH --partition=xfer",
-        "#SBATCH --constraint={constraint}",
-        "#SBATCH --account={compute_account}", "#SBATCH --output={logfile}",
-        "#SBATCH --open-mode=append", "#SBATCH --chdir={cosmo_run}",
-        "#SBATCH --time=00:30:00", "", ""
-    ])
-
-
-def runscript_commands_template():
-    """Return a template for the commands in the runscript.
-
-    To ensure the bash-commands have the intended behaviour, make sure to strip
-    trailing slashes from the directory names (they are added as needed in the
-    template).
-    """
-    commands = list()
-
-    return '\n'.join([
-        "srun cp -Rafv {int2lm_run_src}/. {int2lm_run_dest}/",
-        "srun cp -Rafv {cosmo_run_src}/. {cosmo_run_dest}/",
-        "srun cp -Rafv {cosmo_output_src}/. {cosmo_output_dest}/",
-        "srun cp -Rafv {logs_src}/. {logs_dest}/", "unset SLURM_MEM_PER_CPU"
-    ])
-
-
-
[docs]def main(cfg): - """Copy the output of a **COSMO**-run to a user-defined position. - - Write a runscript to copy all files (**COSMO** settings & output, - **int2lm** settings, logfiles) from ``cfg.cosmo_run``, - ``cfg.cosmo_output``, ``cfg.int2lm_run``, ``cfg.log_finished_dir`` to - ``cfg.output_root/...``. - If the job ``reduce_output`` has been run before ``post_cosmo``, a - directory ``cfg.cosmo_output_reduced`` is created. In this case, - ``cfg.cosmo_output_reduced`` is copied instead of ``cfg.cosmo_output``. - - Submit the job to the xfer-queue. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - tools.change_logfile(cfg.logfile) - prepare_cosmo.set_cfg_variables(cfg) - - copy_path = os.path.join( - cfg.post_cosmo['output_root'], - cfg.startdate_sim_yyyymmddhh + "_" + cfg.enddate_sim_yyyymmddhh) - - logging.info(logfile_header_template().format( - "STARTS", str(datetime.datetime.today()))) - - # Prepare the runscript - runscript_content = "#!/bin/bash\n" - runscript_content += runscript_header_template().format( - compute_account=cfg.compute_account, - logfile=cfg.logfile, - constraint=cfg.constraint, - cosmo_run=cfg.cosmo_run) - - if os.path.isdir(cfg.cosmo_output_reduced): - cosmo_output_src = str(cfg.cosmo_output_reduced).rstrip('/') - cosmo_output_dest = os.path.join(copy_path, - "cosmo_output_reduced").rstrip('/') - else: - cosmo_output_src = str(cfg.cosmo_output).rstrip('/') - cosmo_output_dest = os.path.join(copy_path, "cosmo_output").rstrip('/') - - # Create new directories - os.makedirs(os.path.join(copy_path, "int2lm_run"), exist_ok=True) - os.makedirs(os.path.join(copy_path, "cosmo_run"), exist_ok=True) - os.makedirs(cosmo_output_dest, exist_ok=True) - os.makedirs(os.path.join(copy_path, "logs"), exist_ok=True) - - int2lm_run_path = os.path.abspath(os.path.join(copy_path, "int2lm_run")) - cosmo_run_path = os.path.abspath(os.path.join(copy_path, "cosmo_run")) - cosmo_output_dest_path = os.path.abspath(cosmo_output_dest) - logs_path = os.path.abspath(os.path.join(copy_path, "logs")) - - # Format the runscript - runscript_content += runscript_commands_template().format( - target_dir=copy_path.rstrip('/'), - int2lm_run_src=str(cfg.int2lm_run).rstrip('/'), - int2lm_run_dest=int2lm_run_path.rstrip('/'), - cosmo_run_src=str(cfg.cosmo_run).rstrip('/'), - cosmo_run_dest=cosmo_run_path.rstrip('/'), - cosmo_output_src=cosmo_output_src, - cosmo_output_dest=cosmo_output_dest_path, - logs_src=str(cfg.log_finished_dir).rstrip('/'), - logs_dest=logs_path.rstrip('/')) - - os.makedirs(cfg.cosmo_run, exist_ok=True) - script = (cfg.cosmo_run / 'run_post_cosmo.job') - with open(script, "w") as outf: - outf.write(runscript_content) - - logging.info("Submitting the copy job to the xfer queue") - logging.info("Make sure you have the module 'xalt' unloaded!") - - # Submit job - cfg.submit('post_cosmo', script)
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/post_int2lm.html b/pr-preview/pr-63/_modules/jobs/post_int2lm.html deleted file mode 100644 index a7ac48ca..00000000 --- a/pr-preview/pr-63/_modules/jobs/post_int2lm.html +++ /dev/null @@ -1,338 +0,0 @@ - - - - - - jobs.post_int2lm — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.post_int2lm

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import logging
-import os
-import glob
-import netCDF4 as nc
-
-from datetime import datetime, timedelta
-from . import tools, prepare_cosmo
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """Combine multiple **int2lm** tracer-output files into a single one for - **COSMO**. - - Only necessary for **COSMO** simulations. - - **int2lm** puts tracers into different netCDF files. Combine the files - specified in ``cfg.post_int2lm_species`` into a single netCDF file for - **COSMO**. - - If ``cfg.spinup`` and ``cfg.post_int2lm_species_spinup`` are present, - also read in the specified variables and take them as an input for - **COSMO**. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - prepare_cosmo.set_cfg_variables(cfg) - tools.change_logfile(cfg.logfile) - - # Int2lm processing always starts at hstart=0, thus modifying inidate - inidate_int2lm_yyyymmddhh = cfg.startdate_sim_yyyymmddhh - - chem_list = cfg.post_int2lm['species'] - - date = datetime.today() - - to_print = """POST_INT2LM - -===================================================== -============== POST PROCESSING BEGINS =============== -============== StartTime: %s -=====================================================""" % date.strftime('%s') - - logging.info(to_print) - - logging.info( - 'BOUNDARY CONDITIONS: Adding tracers from lbfd*t.nc files to regular int2lm files.' - ) - # Add background tracers in all 'lbfd**t.nc' files to - # normal lbfd files, because CAMS tracers are only every 3 hours. - # We add it 4 times to hour-1, hour+0, hour+1 and hour+2 - for f in sorted(glob.glob(os.path.join(cfg.int2lm_output, 'lbfd*t.nc'))): - logging.info(f'Reading tracer file {f}') - yyyymmddhh_str = os.path.basename(f)[4:-4] - yyyymmddhh = datetime.strptime(yyyymmddhh_str, '%Y%m%d%H') - yyyymmddhh_prev = yyyymmddhh - timedelta(hours=1) - yyyymmddhh_next2 = yyyymmddhh + timedelta(hours=2) - - for hour in tools.iter_hours(yyyymmddhh_prev, yyyymmddhh_next2, 1): - outfile = os.path.join(cfg.int2lm_output, - hour.strftime('lbfd%Y%m%d%H' + '.nc')) - if os.path.exists(outfile): - with nc.Dataset(outfile, 'a') as outf, nc.Dataset(f) as inf: - for chem in chem_list: - try: - outf.createVariable(chem, inf[chem].dtype, - inf[chem].dimensions) - for attr in inf[chem].ncattrs(): - outf[chem].setncattr(attr, - inf[chem].getncattr(attr)) - logging.info(f'Variable {chem} added to {outfile}') - except RuntimeError: - logging.warning( - 'Variable {} already present in {}'.format( - chem, outfile)) - outf[chem][:] = inf[chem][:] - logging.info("OK") - - # Meteo spinup simulation with tracer recycling - if hasattr(cfg, 'spinup') and \ - cfg.post_int2lm.get('species_spinup') is not None and not cfg.first_one: - var_list = cfg.post_int2lm['species_spinup'] - logging.info( - 'INITIAL CONDITIONS (RECYCLING): Adding tracers %s from last COSMO run (%s) to regular int2lm files.' - % (str(var_list), cfg.last_cosmo_output)) - - infile_name = 'lffd' + cfg.startdate_sim_yyyymmddhh + '*.nc' - infile_paths = sorted( - glob.glob(os.path.join(cfg.last_cosmo_output, infile_name))) - outfile_name = 'laf' + inidate_int2lm_yyyymmddhh + '.nc' - outfile_path = os.path.join(cfg.int2lm_output, outfile_name) - - for infile_path in infile_paths: - with nc.Dataset(infile_path) as inf, nc.Dataset(outfile_path, - 'a') as outf: - for var in var_list: - if var in inf.variables.keys(): - if var in outf.variables.keys(): - logging.warning( - 'Recycling: Variable {} already present in {}'. - format(var, outfile_path)) - else: - outf.createVariable(varname=var, - datatype=inf[var].dtype, - dimensions=inf[var].dimensions) - logging.info('Recycled variable ' + var + - ' from ' + infile_path) - logging.info('into ' + outfile_path) - outf[var][:] = inf[var][:] - for attr in inf[var].ncattrs(): - outf[var].setncattr(attr, inf[var].getncattr(attr)) - # Normal run - else: - logging.info( - 'INITIAL CONDITIONS: Adding tracers from laf*t.nc files to regular int2lm files.' - ) - infile = os.path.join(cfg.int2lm_output, - "laf" + inidate_int2lm_yyyymmddhh + "t.nc") - if os.path.exists(infile): - outfile = infile[:-4] + ".nc" - try: - with nc.Dataset(infile) as inf, nc.Dataset(outfile, - "a") as outf: - for chem in chem_list: - if chem in outf.variables.keys(): - logging.warning( - 'Variable %s already present in file %s' % - (chem, outfile)) - else: - outf.createVariable(chem, inf[chem].dtype, - inf[chem].dimensions) - outf[chem][:] = inf[chem][:] - for attr in inf[chem].ncattrs(): - outf[chem].setncattr(attr, - inf[chem].getncattr(attr)) - logging.info( - 'Variable %s added as initial condition.' % - chem) - except: - logging.error( - 'Appending tracers %s from file %s to file %s failed.' % - (str(chem_list), infile, outfile)) - - date = datetime.today() - to_print = """===================================================== -============== POST PROCESSING ENDS ================== -============== EndTime: %s -=====================================================""" % date.strftime('%s') - - logging.info(to_print)
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/prepare_cosmo.html b/pr-preview/pr-63/_modules/jobs/prepare_cosmo.html deleted file mode 100644 index 919a758e..00000000 --- a/pr-preview/pr-63/_modules/jobs/prepare_cosmo.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - jobs.prepare_cosmo — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.prepare_cosmo

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from pathlib import Path
-import logging
-import csv
-import os
-from datetime import timedelta
-from . import tools
-
-BASIC_PYTHON_JOB = True
-
-
-def set_cfg_variables(cfg):
-    cfg.int2lm_root = cfg.chain_root / 'int2lm'
-    cfg.int2lm_input = cfg.int2lm_root / 'input'
-    cfg.int2lm_run = cfg.chain_root / 'int2lm' / 'run'
-    cfg.int2lm_output = cfg.chain_root / 'int2lm' / 'output'
-
-    cfg.cosmo_base = cfg.chain_root / 'cosmo'
-    cfg.cosmo_input = cfg.chain_root / 'cosmo' / 'input'
-    cfg.cosmo_run = cfg.chain_root / 'cosmo' / 'run'
-    cfg.cosmo_output = cfg.chain_root / 'cosmo' / 'output'
-    cfg.cosmo_output_reduced = cfg.chain_root / 'cosmo' / 'output_reduced'
-
-    # Number of tracers
-    if 'tracers' in cfg.workflow['features']:
-        tracer_csvfile = cfg.chain_src_dir / 'cases' / cfg.casename / 'cosmo_tracers.csv'
-        if tracer_csvfile.is_file():
-            with open(tracer_csvfile, 'r') as csv_file:
-                reader = csv.DictReader(csv_file, delimiter=',')
-                reader = [r for r in reader if r[''] != '#']
-                cfg.in_tracers = len(reader)
-        else:
-            raise FileNotFoundError(f"File not found: {tracer_csvfile}")
-
-        # tracer_start namelist parameter for spinup simulation
-        if hasattr(cfg, 'spinup'):
-            if cfg.first_one:
-                cfg.tracer_start = 0
-            else:
-                cfg.tracer_start = cfg.spinup
-        else:
-            cfg.tracer_start = 0
-
-    # asynchronous I/O
-    if hasattr(cfg, 'cfg.cosmo_np_io'):
-        if cfg.cosmo_np_io == 0:
-            cfg.lasync_io = '.FALSE.'
-            cfg.num_iope_percomm = 0
-        else:
-            cfg.lasync_io = '.TRUE.'
-            cfg.num_iope_percomm = 1
-
-    # If nested run: use output of mother-simulation
-    if 'nesting' in cfg.workflow['features'] and not os.path.isdir(
-            cfg.meteo.dir):
-        # if ifs_hres_dir doesn't point to a directory,
-        # it is the name of the mother run
-        mother_name = cfg.meteo.dir
-        cfg.meteo.dir = cfg.work_root / mother_name / cfg.chunk_id / 'cosmo' / 'output'
-        cfg.meteo.inc = 1
-        cfg.meteo.prefix = 'lffd'
-
-
-
[docs]def main(cfg): - """ - **COSMO Data Preparation** - - This function prepares input data for COSMO simulations by creating necessary directories, - copying meteorological files, and handling specific data processing. - - - Copy meteorological files to **int2lm** input. - - Create the necessary directory ``cfg.int2lm_input/meteo``. - - Copy meteorological files from the project directory (``cfg.meteo['dir']/cfg.meteo['prefix']YYYYMMDDHH``) - to the int2lm input folder on scratch (``cfg.int2lm_input/meteo``). - - For nested runs (meteorological files are COSMO output: ``cfg.meteo['prefix'] == 'lffd'``), - also copy the ``*c.nc``-file with constant parameters. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - - Raises - ------ - RuntimeError - If any subprocess returns a non-zero exit code during execution. - """ - set_cfg_variables(cfg) - tools.change_logfile(cfg.logfile) - - logging.info('COSMO analysis data for IC/BC') - - dest_path = cfg.int2lm_input / 'meteo' - tools.create_dir(dest_path, "meteo input") - - source_nameformat = cfg.meteo['nameformat'] - if cfg.meteo['prefix'] == 'lffd': - # nested runs use cosmoart-output as meteo data - # have to copy the *c.nc-file - src_file = (cfg.meteo['dir'] / - cfg.startdate_sim.strftime(source_nameformat + 'c.nc')) - - tools.copy_file(src_file, dest_path, output_log=True) - - logging.info("Copied constant-param file from {} to {}".format( - src_file, dest_path)) - - # extend nameformat with ending to match cosmo-output - source_nameformat += '.nc' - - if cfg.meteo['prefix'] == 'efsf': - source_nameformat = cfg.meteo['prefix'] + '%y%m%d%H' - - num_steps = 0 - meteo_dir = cfg.meteo['dir'] - subdir = meteo_dir / cfg.startdate_sim.strftime('%y%m%d%H') - for time in tools.iter_hours(cfg.startdate_sim, cfg.enddate_sim, - cfg.meteo['inc']): - dest_path = cfg.int2lm_input / 'meteo' - src_file = meteo_dir / time.strftime(source_nameformat) - - if cfg.meteo['prefix'] == 'efsf': - if time == cfg.startdate_sim: - src_file = subdir / ('eas' + time.strftime('%Y%m%d%H')) - if not src_file.exists() and cfg.meteo.get('dir_alt') \ - is not None: - meteo_dir = cfg.meteo['dir_alt'] - subdir = meteo_dir / cfg.startdate_sim.strftime('%y%m%d%H') - src_file = subdir / ('eas' + time.strftime('%Y%m%d%H')) - dest_path = cfg.int2lm_input / 'meteo' / (cfg.meteo['prefix'] + - '00000000') - else: - td = time - cfg.startdate_sim - timedelta(hours=6 * num_steps) - days = str(td.days).zfill(2) - hours = str(td.seconds // 3600).zfill(2) - td_total = time - cfg.startdate_sim - days_total = str(td_total.days).zfill(2) - hours_total = str(td_total.seconds // 3600).zfill(2) - - src_file = subdir / (cfg.meteo['prefix'] + days + hours + - '0000') - dest_path = cfg.int2lm_input / 'meteo' / ( - cfg.meteo['prefix'] + days_total + hours_total + '0000') - - # Next time, change directory - checkdir = meteo_dir / time.strftime('%y%m%d%H') - if checkdir.is_dir(): - num_steps += 1 - subdir = checkdir - elif cfg.meteo.get('dir_alt') is not None: - checkdir = cfg.meteo['dir_alt'] / time.strftime('%y%m%d%H') - if checkdir.is_dir(): - num_steps += 1 - subdir = checkdir - meteo_dir = cfg.meteo['dir_alt'] - logging.info( - "Switching to other input directory from {} to {}". - format(cfg.meteo['dir'], cfg.meteo['dir_alt'])) - elif not src_file.exists(): - # special case for MeteoSwiss COSMO-7 data - archive = Path('/store/mch/msopr/owm/COSMO-7') - yy = time.strftime("%y") - path = archive / 'ANA' + yy - src_file = path / time.strftime(source_nameformat) - - # copy meteo file from project folder to - tools.copy_file(src_file, dest_path, output_log=True) - - logging.info("Copied file from {} to {}".format(src_file, dest_path)) - - # Other IC/BC data - inv_to_process = [] - if hasattr(cfg, 'cams'): - try: - CAMS = dict(fullname="CAMS", - nickname="cams", - executable="cams4int2cosmo", - indir=cfg.cams['dir_orig'], - outdir=cfg.cams['dir_proc'], - param=[{ - 'inc': cfg.cams['inc'], - 'suffix': cfg.cams['suffix'] - }]) - inv_to_process.append(CAMS) - except AttributeError: - pass - try: - CT = dict(fullname="CarbonTracker", - nickname="ct", - executable="ctnoaa4int2cosmo", - indir=cfg.ct_dir_orig, - outdir=cfg.ct_dir_proc, - param=cfg.ct_parameters) - inv_to_process.append(CT) - except AttributeError: - pass - elif hasattr(cfg, 'mozart'): - try: - MOZART = dict(fullname='MOZART', - nickname='mozart', - executable='mozart2int2lm', - indir=cfg.mozart_file_orig, - outdir=cfg.mozart_dir_proc, - param=[{ - 'inc': cfg.mozart_inc, - 'suffix': cfg.mozart_prefix - }]) - inv_to_process.append(MOZART) - except AttributeError: - pass - - if inv_to_process: - logging.info("Processing " + - ", ".join([i["fullname"] - for i in inv_to_process]) + " data") - - scratch_path = cfg.int2lm_input / 'icbc' - tools.create_dir(scratch_path, "icbc input") - - for inv in inv_to_process: - logging.info(inv["fullname"] + " files") - tools.create_dir(inv["outdir"], "processed " + inv["fullname"]) - - for p in inv["param"]: - inc = p["inc"] - for time in tools.iter_hours(cfg.startdate_sim, - cfg.enddate_sim, inc): - logging.info(time) - - filename = inv["outdir"] / ( - p["suffix"] + "_" + time.strftime("%Y%m%d%H") + ".nc") - if not filename.exists(): - logging.info(filename) - try: - to_call = getattr(tools, inv["executable"]) - to_call.main(time, inv["indir"], inv["outdir"], p) - except: - logging.error("Preprocessing " + inv["fullname"] + - " data failed") - raise - - # copy to (temporary) run input directory - tools.copy_file(filename, scratch_path, output_log=True) - - logging.info("OK")
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/prepare_icon.html b/pr-preview/pr-63/_modules/jobs/prepare_icon.html deleted file mode 100644 index 8467a57d..00000000 --- a/pr-preview/pr-63/_modules/jobs/prepare_icon.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - jobs.prepare_icon — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.prepare_icon

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from pathlib import Path
-import logging
-from . import tools
-
-BASIC_PYTHON_JOB = True
-
-
-def set_cfg_variables(cfg):
-    cfg.icon_base = cfg.chain_root / 'icon'
-    cfg.icon_input = cfg.icon_base / 'input'
-    cfg.icon_input_icbc = cfg.icon_input / 'icbc'
-    cfg.icon_work = cfg.icon_base / 'run'
-    cfg.icon_output = cfg.icon_base / 'output'
-    cfg.icon_output_reduced = cfg.icon_base / 'output_reduced'
-    cfg.icon_restart_out = cfg.icon_base / 'restart'
-    if cfg.chunk_id_prev:
-        cfg.icon_restart_in = cfg.chain_root_prev / 'icon' / 'run'
-        cfg.icon_input_icbc_prev = cfg.chain_root_prev / 'icon' / 'input' / 'icbc'
-
-    cfg.input_files_scratch = {}
-    for dsc, file in cfg.input_files.items():
-        cfg.input_files[dsc] = (p := Path(file))
-        cfg.input_files_scratch[dsc] = cfg.icon_input / p.name
-
-    cfg.create_vars_from_dicts()
-
-    cfg.ini_datetime_string = cfg.startdate.strftime('%Y-%m-%dT%H:00:00Z')
-    cfg.end_datetime_string = cfg.enddate.strftime('%Y-%m-%dT%H:00:00Z')
-
-    if cfg.lrestart == '.TRUE.':
-        cfg.restart_filename = 'restart_atm_DOM01.nc'
-        cfg.restart_file = cfg.icon_restart_in / cfg.restart_filename
-        cfg.restart_file_scratch = cfg.icon_work / cfg.restart_filename
-
-    # Nudge type (global or nothing)
-    cfg.nudge_type = 2 if hasattr(cfg,
-                                  'era5') and cfg.era5_global_nudging else 0
-    # Time step for global nudging in seconds
-    cfg.nudging_step_seconds = cfg.nudging_step * 3600 if hasattr(
-        cfg, 'nudging_step') else None
-    # Prescribed initial conditions for CH4, CO and/or OH
-    cfg.iart_init_gas = 4 if hasattr(
-        cfg, 'species_inicond') and cfg.species_inicond else 0
-
-    cfg.startdate_sim_yyyymmdd_hh = cfg.startdate_sim.strftime('%Y%m%d_%H')
-
-
-
[docs]def main(cfg): - """ - **ICON Data Preparation** - - This function prepares input data for ICON simulations by creating necessary directories, - copying meteorological files, and handling specific data processing. - - - Create working directories and copy input files - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - - Raises - ------ - RuntimeError - If any subprocess returns a non-zero exit code during execution. - """ - set_cfg_variables(cfg) - tools.change_logfile(cfg.logfile) - - # Create directories - tools.create_dir(cfg.icon_work, "icon_work") - tools.create_dir(cfg.icon_input_icbc, "icon_input_icbc") - tools.create_dir(cfg.icon_output, "icon_output") - tools.create_dir(cfg.icon_restart_out, "icon_restart_out") - - logging.info('Copy ICON input data (IC/BC) to working directory') - # Copy input files to scratch - if cfg.machine == 'daint': - script_lines = [ - '#!/usr/bin/env bash', - f'#SBATCH --job-name="copy_input_{cfg.casename}_{cfg.startdate_sim_yyyymmddhh}_{cfg.enddate_sim_yyyymmddhh}"', - f'#SBATCH --account={cfg.compute_account}', - '#SBATCH --time=00:10:00', - f'#SBATCH --partition={cfg.compute_queue}', - f'#SBATCH --constraint={cfg.constraint}', '#SBATCH --nodes=1', - f'#SBATCH --output={cfg.logfile}', '#SBATCH --open-mode=append', - f'#SBATCH --chdir={cfg.icon_work}', '' - ] - elif cfg.machine == 'euler': - script_lines = [ - '#!/usr/bin/env bash', - f'#SBATCH --job-name="copy_input_{cfg.casename}_{cfg.startdate_sim_yyyymmddhh}_{cfg.enddate_sim_yyyymmddhh}"', - '#SBATCH --time=00:10:00', - f'#SBATCH --partition={cfg.compute_queue}', - f'#SBATCH --constraint={cfg.constraint}', '#SBATCH --ntasks=1', - f'#SBATCH --output={cfg.logfile}', '#SBATCH --open-mode=append', - f'#SBATCH --chdir={cfg.icon_work}', '' - ] - for target, destination in zip(cfg.input_files.values(), - cfg.input_files_scratch.values()): - script_lines.append(f'rsync -av {target} {destination}') - - with (script := cfg.icon_work / 'copy_input.job').open('w') as f: - f.write('\n'.join(script_lines)) - - cfg.submit('prepare_icon', script) - logging.info("OK")
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/reduce_output.html b/pr-preview/pr-63/_modules/jobs/reduce_output.html deleted file mode 100644 index 5a7df864..00000000 --- a/pr-preview/pr-63/_modules/jobs/reduce_output.html +++ /dev/null @@ -1,350 +0,0 @@ - - - - - - jobs.reduce_output — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.reduce_output

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import logging
-import os
-import sys
-import shutil
-import datetime as dt
-import glob
-import netCDF4 as nc
-import subprocess
-import numpy as np
-from datetime import datetime
-import math
-
-from . import tools
-
-BASIC_PYTHON_JOB = True
-
-
-
[docs]def main(cfg): - """ - Calculates 2D column data and writes them into a new netCDF file. - Only a fixed number of levels from **COSMO** output are considered. - Those files are written into a new directory ``cosmo_output_reduced``. - - The number of levels is set by the configuration variable - ``cfg.reduce_output['output_levels']`` (default = all levels). - - **Important**: If several ``GRIBOUT`` sections are used to split the output - data, then this code only works in case of the following: - The tracers, for which the column-averaged dry-air (``X``) and - moist-air (``Y``) mole fractions are calculated, have to be - - 1. saved in a separate output file and - 2. the output file appears alphabetically **after** the meteorological - variables. - - For example, use a GRIBOUT section suffix ``_met`` for standard **COSMO** - output, and ``_trc`` for tracers. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes - """ - tools.change_logfile(cfg.logfile) - cosmo_output = cfg.cosmo_output - output_path = cfg.cosmo_output_reduced - - date = dt.datetime.today() - - to_print = """reduce_output - -===================================================== -============== POST PROCESSING BEGINS =============== -============== StartTime: %s -=====================================================""" % date.strftime("%s") - - logging.info(to_print) - - tools.create_dir(output_path, "output") - - if cfg.compute_host != "daint": - logging.error( - "The reduce_output script is supposed to be run on daint only, " - "not on %s" % cfg.compute_host) - sys.exit(1) - - # Wait for Cosmo to finish first - tools.check_job_completion(cfg.log_finished_dir, "cosmo") - - # Number of levels and switch for unit conversion for 'reduce_output' job - if not hasattr(cfg, 'output_levels'): - cfg.output_levels = -1 - if not hasattr(cfg, 'convert_gas'): - cfg.convert_gas = True - """Get list of constant files""" - cfiles = [] - read_cfile = False - for infile in sorted( - glob.glob(os.path.join(cosmo_output, "lffd*[0-9]c*.nc"))): - cfiles.append(infile) - if not read_cfile: - # Read the first constant file and store height value - logging.info(infile) - with nc.Dataset(infile) as inf: - h = np.array(inf.variables['HHL'][0]) - read_cfile = True - logging.info('Successfully read constant file %s' % infile) - - if not read_cfile: - logging.error('Constant file could not be read') - """Copy constant file directly""" - if os.path.exists(cfiles[0]): - shutil.copy(cfiles[0], output_path) - logging.info('Copied constant file %s to %s.' % - (cfiles[0], output_path)) - else: - logging.error('Constant file could not be copied.') - """Get list of files""" - infiles = sorted(glob.glob(os.path.join(cosmo_output, "lffd*.nc"))) - mytimes = [] - for infile in list(infiles): - basename = os.path.split(infile)[1] - timestr = basename.split('lffd', 1)[1][:10] - mytimes.append(datetime.strptime(timestr, '%Y%m%d%H')) - - str_startdate = mytimes[0].strftime('%Y-%m-%d %H') - str_enddate = mytimes[-1].strftime('%Y-%m-%d %H') - """Compute time step for parallel tasks""" - ncores = 36 - total_time = mytimes[-1] - mytimes[0] - nout_times = int(total_time.total_seconds() // 3600) + 1 - output_step = int(max(math.ceil(nout_times / ncores), 2)) - """Execute parallel bash script""" - dir_path = os.path.dirname(os.path.realpath(__file__)) - tool_path = os.path.join(dir_path, 'tools') - bash_file = os.path.join(tool_path, 'reduce_output_parallel.bash') - py_file = os.path.join(tool_path, 'reduce_output_start_end.py') - alternate_csv_file = os.path.join(cfg.chain_src_dir, 'cases', cfg.casename, - 'variables.csv') - logging.info('Submitting job to the queue...') - - result = subprocess.run([ - "sbatch", '--output=' + cfg.logfile, '--open-mode=append', '--wait', - bash_file, py_file, cosmo_output, output_path, str_startdate, - str_enddate, - str(cfg.reduce_output['output_levels']), - str(output_step), alternate_csv_file, - str(cfg.reduce_output['convert_gas']) - ]) - exitcode = result.returncode - - if exitcode != 0: - raise RuntimeError("sbatch returned exitcode {}".format(exitcode)) - """Check if all files have been processed""" - cfile_names = [] - for cfile in cfiles: - cfile_names.append(os.path.basename(cfile)) - files_cosmo = sorted([ - name for name in os.listdir(cosmo_output) - if os.path.isfile(os.path.join(cosmo_output, name)) - and name not in cfile_names - ]) - files_reduced = sorted([ - name for name in os.listdir(output_path) - if os.path.isfile(os.path.join(output_path, name)) - and name not in cfile_names - ]) - - if not files_cosmo == files_reduced: - logging.error(set(files_cosmo).symmetric_difference(files_reduced)) - logging.error('Reduced output files differ from original output!') - raise RuntimeError('Error in reduce_output job') - """Check for corrupted files""" - for f in [ - os.path.join(output_path, name) for name in os.listdir(output_path) - ]: - with nc.Dataset(f) as _: - logging.info('File %s is not corrupted' % f) - - date = dt.datetime.today() - to_print = """===================================================== -============== POST PROCESSING ENDS ================== -============== EndTime: %s -=====================================================""" % date.strftime("%s") - - logging.info(to_print)
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/cams4int2cosmo.html b/pr-preview/pr-63/_modules/jobs/tools/cams4int2cosmo.html deleted file mode 100644 index 9025ad4a..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/cams4int2cosmo.html +++ /dev/null @@ -1,557 +0,0 @@ - - - - - - jobs.tools.cams4int2cosmo — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.tools.cams4int2cosmo

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# Author: Dominik Brunner (DB), Empa, Switzerland
-#       DB, 15 May 2017: first implementation on daint.cscs.ch
-#       DB, 06 Jun 2017: modified to add surface pressure fields
-#       hjm, 22 Jun 2018: Translated to Python
-######################
-## Problems:
-## - when comparing to the "processed2" icbc form Gerrit, PSURF is slightly different
-## - when checking the website, the b levels are not the same as in CAMS
-## - It is not possible to delete a variable from a netcdf4 file, so resort to calling ncks at the end
-
-import argparse
-import os
-import logging
-import shutil
-import netCDF4 as nc
-import numpy as np
-from subprocess import call
-import sys
-import importlib
-
-###############################
-##  Constants : CAMS levels  ##
-###############################
-# hybrid coefficients of the 137 model level version
-# http://www.ecmwf.int/en/forecasts/documentation-and-support/137-model-levels
-a_half_137 = [
-    0.0000000000e+00, 2.0003650188e+00, 3.1022410393e+00, 4.6660838127e+00,
-    6.8279771805e+00, 9.7469663620e+00, 1.3605423927e+01, 1.8608930588e+01,
-    2.4985717773e+01, 3.2985710144e+01, 4.2879241943e+01, 5.4955463409e+01,
-    6.9520576477e+01, 8.6895881653e+01, 1.0741574097e+02, 1.3142550659e+02,
-    1.5927940369e+02, 1.9133856201e+02, 2.2796894836e+02, 2.6953958130e+02,
-    3.1642074585e+02, 3.6898236084e+02, 4.2759249878e+02, 4.9261602783e+02,
-    5.6441345215e+02, 6.4333990479e+02, 7.2974414062e+02, 8.2396783447e+02,
-    9.2634490967e+02, 1.0372011719e+03, 1.1568536377e+03, 1.2856103516e+03,
-    1.4237701416e+03, 1.5716229248e+03, 1.7294489746e+03, 1.8975192871e+03,
-    2.0760959473e+03, 2.2654316406e+03, 2.4657705078e+03, 2.6773481445e+03,
-    2.9003913574e+03, 3.1351193848e+03, 3.3817436523e+03, 3.6404682617e+03,
-    3.9114904785e+03, 4.1949306641e+03, 4.4908173828e+03, 4.7991494141e+03,
-    5.1198950195e+03, 5.4529907227e+03, 5.7983447266e+03, 6.1560742188e+03,
-    6.5269467773e+03, 6.9118706055e+03, 7.3118691406e+03, 7.7274121094e+03,
-    8.1593540039e+03, 8.6085253906e+03, 9.0764003906e+03, 9.5626826172e+03,
-    1.0065978516e+04, 1.0584631836e+04, 1.1116662109e+04, 1.1660067383e+04,
-    1.2211547852e+04, 1.2766873047e+04, 1.3324668945e+04, 1.3881331055e+04,
-    1.4432139648e+04, 1.4975615234e+04, 1.5508256836e+04, 1.6026115234e+04,
-    1.6527322266e+04, 1.7008789062e+04, 1.7467613281e+04, 1.7901621094e+04,
-    1.8308433594e+04, 1.8685718750e+04, 1.9031289062e+04, 1.9343511719e+04,
-    1.9620042969e+04, 1.9859390625e+04, 2.0059931641e+04, 2.0219664062e+04,
-    2.0337863281e+04, 2.0412308594e+04, 2.0442078125e+04, 2.0425718750e+04,
-    2.0361816406e+04, 2.0249511719e+04, 2.0087085938e+04, 1.9874025391e+04,
-    1.9608572266e+04, 1.9290226562e+04, 1.8917460938e+04, 1.8489707031e+04,
-    1.8006925781e+04, 1.7471839844e+04, 1.6888687500e+04, 1.6262046875e+04,
-    1.5596695312e+04, 1.4898453125e+04, 1.4173324219e+04, 1.3427769531e+04,
-    1.2668257812e+04, 1.1901339844e+04, 1.1133304688e+04, 1.0370175781e+04,
-    9.6175156250e+03, 8.8804531250e+03, 8.1633750000e+03, 7.4703437500e+03,
-    6.8044218750e+03, 6.1685312500e+03, 5.5643828125e+03, 4.9937968750e+03,
-    4.4573750000e+03, 3.9559609375e+03, 3.4892343750e+03, 3.0572656250e+03,
-    2.6591406250e+03, 2.2942421875e+03, 1.9615000000e+03, 1.6594765625e+03,
-    1.3875468750e+03, 1.1432500000e+03, 9.2650781250e+02, 7.3499218750e+02,
-    5.6806250000e+02, 4.2441406250e+02, 3.0247656250e+02, 2.0248437500e+02,
-    1.2210156250e+02, 6.2781250000e+01, 2.2835937500e+01, 3.7578129768e+00,
-    0.0000000000e+00, 0.0000000000e+00
-]
-b_half_137 = [
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 3.8199999608e-08, 6.7607002165e-06,
-    2.4348000807e-05, 5.8921999880e-05, 1.1191429803e-04, 1.9857739971e-04,
-    3.4037968726e-04, 5.6155532366e-04, 8.8969792705e-04, 1.3528055279e-03,
-    1.9918379840e-03, 2.8571242001e-03, 3.9709536359e-03, 5.3778146394e-03,
-    7.1333767846e-03, 9.2614600435e-03, 1.1806022376e-02, 1.4815628529e-02,
-    1.8318451941e-02, 2.2354844958e-02, 2.6963520795e-02, 3.2176095992e-02,
-    3.8026399910e-02, 4.4547960162e-02, 5.1773015410e-02, 5.9728413820e-02,
-    6.8448252976e-02, 7.7958308160e-02, 8.8285736740e-02, 9.9461667240e-02,
-    1.1150465161e-01, 1.2444812804e-01, 1.3831289113e-01, 1.5312503278e-01,
-    1.6891041398e-01, 1.8568944931e-01, 2.0349121094e-01, 2.2233286500e-01,
-    2.4224400520e-01, 2.6324188709e-01, 2.8535401821e-01, 3.0859845877e-01,
-    3.3293908834e-01, 3.5825419426e-01, 3.8436332345e-01, 4.1112476587e-01,
-    4.3839120865e-01, 4.6600329876e-01, 4.9380031228e-01, 5.2161920071e-01,
-    5.4930114746e-01, 5.7669216394e-01, 6.0364806652e-01, 6.3003581762e-01,
-    6.5573596954e-01, 6.8064302206e-01, 7.0466899872e-01, 7.2773873806e-01,
-    7.4979656935e-01, 7.7079755068e-01, 7.9071676731e-01, 8.0953603983e-01,
-    8.2725608349e-01, 8.4388113022e-01, 8.5943180323e-01, 8.7392926216e-01,
-    8.8740754128e-01, 8.9990049601e-01, 9.1144818068e-01, 9.2209565639e-01,
-    9.3188077211e-01, 9.4085955620e-01, 9.4906443357e-01, 9.5654952526e-01,
-    9.6335172653e-01, 9.6951341629e-01, 9.7507840395e-01, 9.8007160425e-01,
-    9.8454189301e-01, 9.8849952221e-01, 9.9198400974e-01, 9.9500250816e-01,
-    9.9763011932e-01, 1.0000000000e+00
-]
-
-# hybrid coefficients of the 60 model level version
-# http://www.ecmwf.int/en/forecasts/documentation-and-support/60-model-levels
-a_half_60 = [
-    0.0000000000e+00, 2.0000000000e+01, 3.8425338745e+01, 6.3647796631e+01,
-    9.5636962891e+01, 1.3448330688e+02, 1.8058435059e+02, 2.3477905273e+02,
-    2.9849584961e+02, 3.7397192383e+02, 4.6461816406e+02, 5.7565112305e+02,
-    7.1321801758e+02, 8.8366040039e+02, 1.0948347168e+03, 1.3564746094e+03,
-    1.6806403809e+03, 2.0822739258e+03, 2.5798886719e+03, 3.1964216309e+03,
-    3.9602915039e+03, 4.9067070312e+03, 6.0180195312e+03, 7.3066328125e+03,
-    8.7650546875e+03, 1.0376125000e+04, 1.2077445312e+04, 1.3775324219e+04,
-    1.5379804688e+04, 1.6819472656e+04, 1.8045183594e+04, 1.9027695312e+04,
-    1.9755109375e+04, 2.0222203125e+04, 2.0429863281e+04, 2.0384480469e+04,
-    2.0097402344e+04, 1.9584328125e+04, 1.8864750000e+04, 1.7961359375e+04,
-    1.6899468750e+04, 1.5706449219e+04, 1.4411125000e+04, 1.3043218750e+04,
-    1.1632757812e+04, 1.0209500000e+04, 8.8023554688e+03, 7.4388046875e+03,
-    6.1443164062e+03, 4.9417773438e+03, 3.8509133301e+03, 2.8876965332e+03,
-    2.0637797852e+03, 1.3859125977e+03, 8.5536181641e+02, 4.6733349609e+02,
-    2.1039389038e+02, 6.5889236450e+01, 7.3677425385e+00, 0.0000000000e+00,
-    0.0000000000e+00
-]
-b_half_60 = [
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00, 0.0000000000e+00,
-    7.5823496445e-05, 4.6139489859e-04, 1.8151560798e-03, 5.0811171532e-03,
-    1.1142909527e-02, 2.0677875727e-02, 3.4121163189e-02, 5.1690407097e-02,
-    7.3533833027e-02, 9.9674701691e-02, 1.3002252579e-01, 1.6438430548e-01,
-    2.0247590542e-01, 2.4393314123e-01, 2.8832298517e-01, 3.3515489101e-01,
-    3.8389211893e-01, 4.3396294117e-01, 4.8477154970e-01, 5.3570991755e-01,
-    5.8616840839e-01, 6.3554745913e-01, 6.8326860666e-01, 7.2878581285e-01,
-    7.7159661055e-01, 8.1125342846e-01, 8.4737491608e-01, 8.7965691090e-01,
-    9.0788388252e-01, 9.3194031715e-01, 9.5182150602e-01, 9.6764522791e-01,
-    9.7966271639e-01, 9.8827010393e-01, 9.9401944876e-01, 9.9763011932e-01,
-    1.0000000000e+00
-]
-
-
-
[docs]def main(date, inpath, outpath, param): - """Prepare CAMS CO2, CO and NOx boundary conditions for - **int2lm/int2cosmo** for the project SMARTCARB. - - The CAMS data consists of - - - CO2 and CO fields of experiment gf39, class RD (approx. 15 km - resolution, 137 levels). See - https://atmosphere.copernicus.eu/change-log-gf39 - - NO and NO2 from the CAMS operational product, exp 0001, class MC - (60 km resolution) - - The data sets are retrieved as individual 3-hourly files from the MARS - archive at ECMWF with names:: - - cams_0001_2015010500.nc # for NO and NO2 - sfc_0001_2015010500.nc # for log of surface pressure - cams_gf39_2015010500.nc # for CO and CO2 - sfc_gf39_2015010500.nc # for log of surface pressure - - The path to the directory of the CAMS data can optionally be supplied, - otherwise the script should be invoked in the directory of the CAMS data. - - The script generates 8 individual 3-hourly IC/BC files:: - - cams_nox_yyyymmddhh.nc - cams_co2_yyyymmddhh.nc - - Usage:: - - python cams4int2cosmo.py date [-i inpath -o outpath] - - Output: - - ``cams_NOX_YYYYMMDD00.nc`` to ``cams_NOX_YYYYMMDD21.nc`` - ``cams_CO2_YYYYMMDD00.nc`` to ``cams_CO2_YYYYMMDD21.nc`` - - Parameters - ---------- - date : str - date in format YYYYMMDD - inpath : str - path of original CAMS files (default is current path) - outpath : str - path where output files should be generated (default is current path) - param : dict - """ - try: - os.makedirs(outpath, exist_ok=True) - except (OSError, PermissionError): - logging.error("Creating output directory failed") - raise - - tracer2dict = { - 'CO2': dict(name="CO2_BG", - short_name="co2", - long_name="carbon_dioxide"), - 'CO': dict(name="CO_BG", short_name="co", long_name="carbon_monoxide"), - 'CH4': dict(name="CH4_BG", short_name="ch4", long_name="methane"), - 'NOX': dict(name="NOX_BG", - short_name="NOx", - long_name="nitrogen_oxide"), - } - - species = [] - for s in param["species"]: - logging.info(s) - logging.info(tracer2dict[s]) - try: - species.append(tracer2dict[s]) - except KeyError: - logging.error("Variable " + s + - " is not part of the available list of variables.") - - main_process(date, inpath, outpath, species, param)
- - -def main_process(date, inpath, outpath, species, param): - if param["lev"] == 137: - a_half = a_half_137 #defined globally - b_half = b_half_137 #defined globally - offset = 37 # only levels 38 to 137 are retrieved from MARS - elif param["lev"] == 60: - a_half = a_half_60 #defined globally - b_half = b_half_60 #defined globally - offset = 0 # all levels - else: - logging.error( - "The list of hybrid parameters for the amount of levels " + - param["lev"] + "is not defined.") - raise - - hyam = [(a_half[i] + a_half[i + 1]) / 2. - for i in range(offset, - len(a_half) - 1)] - hybm = [(b_half[i] + b_half[i + 1]) / 2. - for i in range(offset, - len(a_half) - 1)] - - to_print = ",".join( - [species[i]["short_name"] for i in range(len(species))]) - logging.info('Processing ' + to_print + ' for time ' + - date.strftime("%Y%m%d%H")) - - infile = os.path.join( - inpath, param["prefix1"] + "_" + date.strftime("%Y%m%d%H") + ".nc") - sfcfile = os.path.join( - inpath, param["prefix2"] + "_" + date.strftime("%Y%m%d%H") + ".nc") - - outfile = os.path.join( - outpath, param["suffix"] + "_" + date.strftime("%Y%m%d%H") + ".nc") - - try: - shutil.copy(infile, outfile) - except FileNotFoundError: - logging.error("file " + infile + " not found") - raise - except (PermissionError, OSError): - logging.error("Copying file " + infile + " failed") - raise - - with nc.Dataset(outfile, "a", format="NETCDF4") as outf: - # copy surface pressure from surface file - with nc.Dataset(sfcfile, "r") as inf: - lnsp = inf.variables["lnsp"] - outf.createVariable("PSURF", "f8", lnsp.dimensions) - outf.variables["PSURF"][:] = np.exp(lnsp[:]) - outf["PSURF"].setncattr("long_name", "surface pressure") - outf["PSURF"].setncattr("units", "Pa") - - # change the calender attribute to proleptic_gregorian - outf["time"].setncattr("calendar", "proleptic_gregorian") - - # rename fields according to Carbosense4D definitions - for s in species: - if s["name"] != "NOX_BG": - outf.renameVariable(s["short_name"], s["name"]) - else: - # Create NOX from NO and NO2 - outf.createVariable("NOX_BG", "f8", outf["no"].dimensions) - outf["NOX_BG"][:] = outf["no"][:] + outf["no2"][:] - - outf.renameDimension("latitude", "lat") - outf.renameDimension("longitude", "lon") - outf.renameVariable("latitude", "lat") - outf.renameVariable("longitude", "lon") - - # Reverse latitude for all fields so that startlat < endlat - for v in outf.variables: - dims = outf[v].dimensions - if 'lat' in dims: - lat_ind = dims.index('lat') - if lat_ind == 0: - outf[v][:] = outf[v][::-1] - elif lat_ind == 1: - outf[v][:] = outf[v][:, ::-1] - elif lat_ind == 2: - outf[v][:] = outf[v][:, :, ::-1] - elif lat_ind == 3: - outf[v][:] = outf[v][:, :, :, ::-1] - elif lat_ind == 4: - outf[v][:] = outf[v][:, :, :, :, ::-1] - - # Add the units; these must match those in $int2cosmo/src/trcr_gribtabs.f90 - for s in species: - chem = s["name"] - long = s["long_name"] - outf[chem].setncattr("units", "kg kg-1") - outf[chem].setncattr("units_desc", - "kg of substance per kg of dry air") - outf[chem].setncattr( - "long_name", - "mass mixing ratio of " + chem[:-3] + " from outside domain") - outf[chem].setncattr("standard_name", - "mass_fraction_of_" + long + "_in_air") - - # Add hybrid coefficients - outf.createVariable("hyam", np.float64, "level") - outf.createVariable("hybm", np.float64, "level") - outf["hyam"][:] = hyam - outf["hybm"][:] = hybm - outf["hyam"].setncattr("units", "Pa") - outf["hybm"].setncattr("units", "1") - outf["hyam"].setncattr("long_name", - "hybrid A coefficient at layer midpoints") - outf["hybm"].setncattr("long_name", - "hybrid B coefficient at layer midpoints") - - # create new dimension lev1 - outf.createDimension("lev1", 1) - outf.createVariable("P0", float, "lev1") - outf["P0"][:] = [1] - outf["P0"].setncattr("units", "Pa") - outf["P0"].setncattr("long_name", "reference pressure") - - # if NOX_BG, delete no and no2 - for s in species: - if s["name"] == "NOX_BG": - if "no" in outf.variables and "no2" in outf.variables: - call([ - "ncks", "--overwrite", "-x", "-v", "no,no2", outfile, - outfile - ]) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description= - "Prepare CAMS CO2, CO, CH4 and NOx boundary conditions for int2lm/int2cosmo", - formatter_class=argparse.RawTextHelpFormatter) - - parser.add_argument('date', type=str, help='date in format YYYYMMDD') - parser.add_argument('param', type=str, help='dictionary of the parameters') - parser.add_argument( - '-i', - type=str, - metavar="inpath", - help='path of original CAMS files (default is current path)', - default=os.getcwd()) - parser.add_argument( - '-o', - type=str, - metavar="outpath", - help= - "path where output files should be generated (default is inpath/processed)", - ) - - indir = parser.get_default("i") - parser.set_defaults(o=os.path.join(indir, "processed")) - - args = parser.parse_args() - - main(args.date, args.i, args.o, args.param) -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/check_model.html b/pr-preview/pr-63/_modules/jobs/tools/check_model.html deleted file mode 100644 index 3c672b7c..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/check_model.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - jobs.tools.check_model — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.tools.check_model

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-
-
[docs]def check_model(cfg, model='COSMO'): - """Check that the model specified in cfg matched the prescribed model. - - Check that cfg.workflow_name == model. If not, raises a value-error. - Ignores capitalization of the strings - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - - model : str - Prescribed model - """ - #don't care about capitalization - if not cfg.workflow_name.lower() == model.lower(): - raise ValueError("The model specified in the configuration file is {}" - ", but the job only applies to {}.".format( - cfg.workflow_name, model))
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/comp_nc.html b/pr-preview/pr-63/_modules/jobs/tools/comp_nc.html deleted file mode 100644 index 0dc1814b..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/comp_nc.html +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - jobs.tools.comp_nc — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.tools.comp_nc

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Compare two netCDF-files
-
-# Author: dao, david.ochsner@empa.ch
-
-import argparse
-import netCDF4 as nc
-import numpy as np
-
-colors = {"green": '\033[32m', "red": '\033[31m', "yellow": '\033[33m'}
-
-
-def ccprint(text, color=None, verbose=True):
-    """Print-wrapper that Conditionally prints Colored text
-
-    Parameters
-    ----------
-    text : str
-        Text to print
-    color : str
-        Color of the text
-        One of 'red','green' or 'yellow', or 'None' for black
-    verbose : bool
-        If 'True' the text is printed, if 'False' nothing happens
-    """
-    if not verbose:
-        return
-
-    if color is not None:
-        try:
-            print(colors[color] + text + '\033[0m')
-        except KeyError:
-            raise ValueError("Unrecognized color")
-    else:
-        print(text)
-
-
-def import_data(path):
-    """Imports the data at path into a netCDF4-Dataset
-
-    Parameters
-    ----------
-    path : str
-        Path to the .nc file
-    """
-    return nc.Dataset(path)
-
-
-
[docs]def datasets_equal(dataset1, dataset2, variables, verbose=True): - """Compare the contents of dataset1 and dataset2 - - Compare with numpy.isclose whether the two datasets are equal. No check for - equality (of the values or bitwise of the files) is performed, as numerical - errors can produce slightly different files for essentially identical - computations. Rather, the values are compared to absolute and relative - tolerances, check np.isclose documentation for more detail. - - If variables is not empty, only the provided variables are compared. - - Parameters - ---------- - dataset1 : netCDF4.Dataset - dataset2 : netCDF4.Dataset - variables : list of str - List of the variables to be compared. If it is empty, all variables - are compared. - verbose : bool - If True, results will be printed to stdout. - Returns - ------- - bool - True if the datasets, or if provided the selected variables, are equal, - False otherwise. - """ - if not variables: - variables = set(dataset1.variables.keys()) - variables2 = set(dataset2.variables.keys()) - - if not variables == variables2: - ccprint("Files don't contain the same variables.", "red", verbose) - ccprint("The following variables are in only " - "one of the files:", None, verbose) - ccprint(variables.symmetric_difference(variables2), None, verbose) - ccprint("The common variables are:", None, verbose) - ccprint(variables.intersection(variables2), None, verbose) - return False - else: - assert set(dataset1.variables.keys()).issuperset(variables), ( - "Dataset 1 doesn't contain all variables that should be compared") - assert set(dataset2.variables.keys()).issuperset(variables), ( - "Dataset 2 doesn't contain all variables that should be compared") - - result = True - for var in variables: - if not dataset1[var].dtype == dataset2[var].dtype: - ccprint("{} has different types.".format(var), "red", verbose) - result = False - - if (dataset1[var].dtype in np.sctypes['float'] - or dataset1[var].dtype in np.sctypes['int']): - if np.allclose(dataset1[var], dataset2[var]): - ccprint("{} is equal.".format(var), None, verbose) - else: - ccprint("{} is not equal".format(var), "red", verbose) - result = False - else: - ccprint( - "{} is not a numeric type " - "and not compared.".format(var), None, verbose) - - return result
- - -if __name__ == '__main__': - parser = argparse.ArgumentParser("Compare two netCDF files.") - parser.add_argument("Dataset1", - type=str, - help="Path to the first dataset.") - parser.add_argument("Dataset2", - type=str, - help="Path to the second dataset.") - parser.add_argument("-v", - "--variables", - nargs='*', - default=[], - dest="variables", - help="Variables to be compared. If " - "none are given, all variables in the files are " - "compared.") - args = parser.parse_args() - - if datasets_equal(import_data(args.Dataset1), import_data(args.Dataset2), - args.variables): - ccprint("Provided files are equal", color="green") - else: - ccprint("Provided files are not equal", color="red") -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/ctnoaa4int2cosmo.html b/pr-preview/pr-63/_modules/jobs/tools/ctnoaa4int2cosmo.html deleted file mode 100644 index 81707f46..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/ctnoaa4int2cosmo.html +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - jobs.tools.ctnoaa4int2cosmo — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.tools.ctnoaa4int2cosmo

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import sys
-import numpy as np
-from netCDF4 import Dataset
-import argparse
-import os
-
-half_a = (0, 7.367743, 210.39389, 855.361755, 2063.779785, 3850.91333,
-          6144.314941, 8802.356445, 11632.75879, 14411.12402, 16899.46875,
-          18864.75, 20097.40234, 20429.86328, 19755.10938, 18045.18359,
-          15379.80566, 12077.44629, 8765.053711, 6018.019531, 3960.291504,
-          1680.640259, 713.218079, 298.495789, 95.636963, 0)
-half_b = (1, 0.99401945, 0.97966272, 0.95182151, 0.90788388, 0.84737492,
-          0.77159661, 0.68326861, 0.58616841, 0.48477158, 0.38389215,
-          0.28832296, 0.2024759, 0.13002251, 0.07353383, 0.03412116,
-          0.01114291, 0.00181516, 0.00007582, 0, 0, 0, 0, 0, 0, 0)
-
-
-
[docs]def main(date, indir, outdir, param): - """Process all CarbonTracker files of a single date to a format - compatible with int2lm - - Parameters - ---------- - date : str - date in format YYYYMMDD. - indir : str - directory of original CarbonTracker files (default is current path). - outdir : str - utput directory of processed files (default is indir/processed). - param : dict - dictionary of the parameters - """ - try: - os.makedirs(outdir, exist_ok=True) - except (OSError, PermissionError): - logging.error("Creating output directory failed") - raise - - ifile = Dataset( - os.path.join(indir, param["prefix"] + "_" + date.strftime('%Y-%m-%d') + - '.nc'), 'r') - levs = ifile.variables['level'][:] - lats = ifile.variables['latitude'][:] - lons = ifile.variables['longitude'][:] - - co2 = np.squeeze(ifile.variables['co2'][:]) - p_bound = np.squeeze(ifile.variables['pressure'][:]) - ifile.close() - - lats_tf = (lats <= 63.) & (lats >= 35.) - lons_tf = (lons <= 34.5) & (lons >= -10.5) - lats = lats[np.logical_and(lats >= 35., lats <= 63.)] - lons = lons[np.logical_and(lons >= -10.5, lons <= 34.5)] - - co2 = co2[:, :, lats_tf, :][:, :, :, - lons_tf] * 0.04401 / 0.02896 # * mmCO2/mmAir - p_bound = p_bound[:, :, lats_tf, :][:, :, :, lons_tf] - p = np.empty(shape=(8, 25, 15, 16)) - for i in range(0, 24): - p[:, i, :, :] = (p_bound[:, i, :, :] + p_bound[:, i + 1, :, :]) / 2. - sp = np.squeeze(p[:, 0, :, :]) - - hyam = np.empty(len(half_a) - 1) - hybm = np.empty(len(half_a) - 1) - for i in range(len(hyam) - 1): - hyam[i] = (half_a[i] + half_a[i + 1]) / 2. - hybm[i] = (half_b[i] + half_b[i + 1]) / 2. - - ttt = ("00", "03", "06", "09", "12", "15", "18", "21") - - for ti, tt in enumerate(ttt): - - with Dataset(os.path.join( - outdir, - param["suffix"] + "_" + date.strftime('%Y%m%d') + tt + '.nc'), - mode='w') as ofile: - - olev = ofile.createDimension('level', len(levs)) - olat = ofile.createDimension('lat', len(lats)) - olon = ofile.createDimension('lon', len(lons)) - odate = ofile.createDimension('date', 1) - - olat = ofile.createVariable('lat', np.float64, ('lat', )) - olon = ofile.createVariable('lon', np.float64, ('lon', )) - olev = ofile.createVariable('level', np.float64, ('level', )) - otime = ofile.createVariable('time', np.float64, ('date', )) - odate = ofile.createVariable('date', np.float64, ('date', )) - - ohyam = ofile.createVariable('hyam', np.float32, ('level', )) - ohybm = ofile.createVariable('hybm', np.float32, ('level', )) - - oco2 = ofile.createVariable('CO2_BG', - np.float32, - ('date', 'level', 'lat', 'lon'), - fill_value=-999.99) - op = ofile.createVariable('pressure', - np.float32, - ('date', 'level', 'lat', 'lon'), - fill_value=-999.99) - osp = ofile.createVariable('PSURF', - np.float32, ('date', 'lat', 'lon'), - fill_value=-999.99) - op0 = ofile.createVariable('P0', - np.float32, ('date'), - fill_value=-999.99) - - odate.comment = 'time-interval average, centered on times in the date axis' - odate.long_name = 'UTC dates and times' - odate.units = 'days since ' + date.strftime('%Y%m%d') + ' 00:00:00' - # otime.dtype = 'double' - - otime.units = 'seconds since ' + date.strftime( - '%Y%m%d') + ' 00:00:00' - otime.calendar = 'proleptic_gregorian' - - olat.standard_name = 'latitude' - olat.long_name = 'latitude' - olat.units = 'degree_north' - olat.axis = 'Y' - - olon.standard_name = 'longitude' - olon.long_name = 'longitude' - olon.units = 'degree_east' - olon.axis = 'X' - - ohyam.long_name = 'hybrid A coefficient at layer midpoints' - ohyam.units = 'Pa' - - ohybm.long_name = 'hybrid B coefficient at layer midpoints' - ohybm.units = '1' - - olev.positive = 'up' - olev.units = 'levels' - - oco2.standard_name = 'mass_fraction_of_carbon_dioxide_in_air' - oco2.long_name = 'mass mixing ratio of CO2 from outside Europe' - oco2.units = 'kg kg-1' - - op.long_name = 'pressure_at_center_levels' - op.units = 'Pa' - op.standard_name = 'air pressure' - - op0.units = 'Pa' - - osp.cell_methods = 'level:mean' - osp.units = 'Pa' - osp.long_name = 'surface pressure' - osp.table = '128' - osp.lev = '1' - - olat[:] = lats - olon[:] = lons - olev[:] = levs - odate[:] = 3. * ti / 24. - otime[:] = ti * 3 * 3600 - - oco2[:] = co2[ti, :] - osp[:] = sp[ti, :] - op[:] = p[ti, :] - op0[:] = 1. - ohyam[:] = hyam - ohybm[:] = hybm
- - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description= - "Process all CarbonTracker files of a single date to a format compatible with int2lm", - formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument('date', type=str, help='date in format YYYYMMDD') - parser.add_argument('param', help='dictionary of the parameters') - parser.add_argument( - '-i', - type=str, - metavar="indir", - help= - 'directory of original CarbonTracker files (default is current path)', - default=os.getcwd()) - parser.add_argument( - '-o', - type=str, - metavar="outdir", - help="output directory of processed files (default is indir/processed)" - ) - - indir = parser.get_default("i") - parser.set_defaults(o=os.path.join(indir, "processed")) - - args = parser.parse_args() - - print(args.param) - main(args.date, args.i, args.o, args.param) -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/mozart2int2lm.html b/pr-preview/pr-63/_modules/jobs/tools/mozart2int2lm.html deleted file mode 100644 index 50dee303..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/mozart2int2lm.html +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - jobs.tools.mozart2int2lm — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.tools.mozart2int2lm

-import numpy as np
-
-from datetime import time, date, datetime
-from netCDF4 import Dataset
-from os.path import join
-
-from .nc_operations import VariableCreator, VariableCopier, DimensionCopier
-
-
-def date_from_days_since_0(days_since_00000101):
-    """Convert a float counting days since days since 0000-01-01 00:00:00
-    to a datetime object.
-    """
-
-    def add_years(d, years):
-        """Return a date that's `years` years after the date (or datetime)
-        object `d`. Return the same calendar date (month and day) in the
-        destination year, if it exists, otherwise use the following day
-        (thus changing February 29 to March 1).
-        """
-        # from https://stackoverflow.com/a/15743908
-        try:
-            return d.replace(year=d.year + years)
-        except ValueError:
-            return d + (date(d.year + years, 1, 1) - date(d.year, 1, 1))
-
-    full_days = int(days_since_00000101)
-    # fromordinal starts from day 0
-    timestamp_date = date.fromordinal(full_days + 1)
-    # fromordinal starts at year 1
-    timestamp_date = add_years(timestamp_date, -1)
-
-    hours = int((days_since_00000101 - full_days) * 24)
-    assert hours == (days_since_00000101 - full_days) * 24, (
-        "Can't convert to time at not full hour.")  # too lazy
-    timestamp_time = time(hour=hours)
-
-    return datetime.combine(timestamp_date, timestamp_time)
-
-
-def extract_data(in_path, time_index, dim_ops, var_ops, out_path_template):
-    """Extract and transform indicated data from time_index to
-    out_path_template.
-
-    Create a new netcdf-file at out_path_template after replacing the
-    placeholders with the date from the time_index in in_path.
-
-    Create a 'time' dimension and variable of size 1.
-    Add the ncattr calendar: 'proleptic_gregorian' to the time-variable.
-
-    Copy and transform the dimensions specified in the dim_ops.
-
-    Copy and transform the variables specified in the var_ops.
-
-    Adjust longitude from [0, 360) to (-180, 180].
-    """
-    with Dataset(in_path) as inf:
-        timestamp = date_from_days_since_0(inf.variables['time'][time_index])
-
-        out_path = timestamp.strftime(out_path_template)
-
-        with Dataset(out_path, 'w') as of:
-            of.createDimension(dimname='time', size=1)
-
-            # Create time variable
-            (VariableCreator(
-                var_args={
-                    'varname': 'time',
-                    'datatype': 'f8'
-                },
-                var_attrs={
-                    'axis': 'T',
-                    'calendar': 'proleptic_gregorian',
-                    'long_name': 'simulation_time',
-                    'standard_name': 'time',
-                    'units':
-                    timestamp.strftime('seconds since %Y-%m-%d %H:%M:%S')
-                },
-                var_vals=0).apply_to(of))
-
-            # Create date variable
-            (VariableCreator(var_args={
-                'varname': 'date',
-                'datatype': 'i4',
-                'dimensions': ('time', )
-            },
-                             var_attrs={
-                                 'long_name': ('current date as 8 digit'
-                                               ' integer (YYYYMMDD)')
-                             },
-                             var_vals=int(
-                                 timestamp.strftime('%Y%m%d'))).apply_to(of))
-
-            # Create datesec variable
-            sec_from_midnight = ((timestamp - timestamp.replace(
-                hour=0, minute=0, second=0, microsecond=0)).total_seconds())
-            (VariableCreator(var_args={
-                'varname': 'datesec',
-                'datatype': 'i4',
-                'dimensions': ('time', )
-            },
-                             var_attrs={
-                                 'long_name':
-                                 ('seconds to complete', 'current date'),
-                                 'units':
-                                 's'
-                             },
-                             var_vals=sec_from_midnight).apply_to(of))
-
-            # Transfer specified dimensions and variables
-            for op in dim_ops + var_ops:
-                op.apply_to(inf, of)
-
-            # Transform longitude: [0,360) -> [-180,180)
-            for i in range(len(of['lon'])):
-                if of['lon'][i] > 180:
-                    of['lon'][i] -= 360
-
-
-
[docs]def main(_, infile, outdir, params): - """Extract each timeslice from infile into seperate file in outdir. - - Copies dimensions, renaming 'lev' -> 'level'. - - Copies, renames and combines variables (see source code for specifics). - - Transforms 'lon' to [-180, 180) range. - - Parameters - ---------- - _ - Ignored - infile : str - Path to file to extract from - outdir : str - Path to the directory where the output files are written to - params : dict - Only entry: 'suffix' - Processed files are stored as ``outdir/{suffix}_YYYYMMDDHH.nc`` - """ - outname_template = join(outdir, params['suffix'] + '_%Y%m%d%H.nc') - - dimpairs = [ - ( - 'lev', # name in src - 'level'), # name in dst - ('lat', 'lat'), - ('lon', 'lon'), - ('ilev', 'ilev') - ] - - dim_copiers = [ - DimensionCopier(src_name, dst_name) for src_name, dst_name in dimpairs - ] - - varpairs_to_copy = [ - (['CH3CHO_VMR_inst', 'GLYALD_VMR_inst'], 'ALD'), - ( - 'CO_VMR_inst', # name in src, lists added toghether - 'CO'), # name in dst - ('CRESOL_VMR_inst', 'CSL'), - ('C2H6_VMR_inst', 'ETH'), - ('GLYOXAL_VMR_inst', 'GLY'), - ('H2O2_VMR_inst', 'H2O2'), - ('C3H8_VMR_inst', 'HC3'), - ('HNO3_VMR_inst', 'HNO3'), - ('BIGALK_VMR_inst', 'HC5'), - ('CH2O_VMR_inst', 'HCHO'), - ('HO2NO2_VMR_inst', 'HNO4'), - ('HO2_VMR_inst', 'HO2'), - ('ISOP_VMR_inst', 'ISO'), - (['CH3COCH3_VMR_inst', 'HYAC_VMR_inst', 'MEK_VMR_inst'], 'KET'), - (['MVK_VMR_inst', 'MACR_VMR_inst'], 'MACR'), - ('CH3COCHO_VMR_inst', 'MGLY'), - ('MPAN_VMR_inst', 'MPAN'), - ('N2O5_VMR_inst', 'N2O5'), - ('NH3_VMR_inst', 'NH3'), - ('NO_VMR_inst', 'NO'), - ('NO2_VMR_inst', 'NO2'), - ('NO3_VMR_inst', 'NO3'), - ('OH_VMR_inst', 'OH'), - ('C2H4_VMR_inst', 'OL2'), - ('ONIT_VMR_inst', 'ONIT'), - ('CH3OOH_VMR_inst', 'OP1'), - ('C2H5OOH_VMR_inst', 'OP2'), - ('CH3COOH_VMR_inst', 'ORA2'), - ('O3_VMR_inst', 'OZONE'), - ('CH3COOOH_VMR_inst', 'PAA'), - ('PAN_VMR_inst', 'PAN'), - ('SO2_VMR_inst', 'SO2'), - ('T', 'T'), - ('TOLUENE_VMR_inst', 'TOL'), - ('DUST1', 'VSOILA'), - ('DUST2', 'VSOILB'), - ('DUST3', 'VSOILC') - ] - - varpairs_to_copy_dimchange = [('NH4_VMR_inst', 'VNH4Jm'), - (['OC1_VMR_inst', - 'OC2_VMR_inst'], 'VORG1Jm'), - ('SO4_VMR_inst', 'VSO4Jm'), - (['CB1_VMR_inst', 'CB2_VMR_inst'], 'VSOOTJ')] - - for time_index in range(Dataset(infile).dimensions['time'].size): - # Have to give dimensions explicitly because 'lev' changes to 'level' - # Have to give var_val_indices explicitly because we only copy one - # time index - spacial_variable_options = { - 'var_args': { - 'dimensions': ('time', 'level', 'lat', 'lon') - }, - 'var_val_indices': np.s_[time_index, :] - } - - # 3D variables that simply get copied - var_opts = [{ - 'src_names': src, - 'dst_name': dst, - **spacial_variable_options - } for src, dst in varpairs_to_copy] - - # 3D variables with dimchange to mol/mol - var_opts += [{ - 'src_names': src, - 'dst_name': dst, - 'var_attrs': { - 'units': 'mol/mol' - }, - **spacial_variable_options - } for src, dst in varpairs_to_copy_dimchange] - - # Others - var_opts += [{ - 'src_names': 'lat', - 'dst_name': 'lat' - }, { - 'src_names': 'lev', - 'dst_name': 'level', - 'var_args': { - 'dimensions': ('level', ) - } - }, { - 'src_names': 'lon', - 'dst_name': 'lon' - }, { - 'src_names': 'P0', - 'dst_name': 'P0' - }, { - 'src_names': 'PS', - 'dst_name': 'PSURF', - 'var_args': { - 'dimensions': ('time', 'lat', 'lon') - }, - 'var_val_indices': np.s_[time_index, :] - }, { - 'src_names': 'hyam', - 'dst_name': 'hyam', - 'var_args': { - 'dimensions': ('level', ) - } - }, { - 'src_names': 'hybm', - 'dst_name': 'hybm', - 'var_args': { - 'dimensions': ('level', ) - } - }, { - 'src_names': 'ilev', - 'dst_name': 'ilev' - }] - - var_copiers = [VariableCopier(**kwargs) for kwargs in var_opts] - - extract_data(infile, time_index, dim_copiers, var_copiers, - outname_template)
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/reduce_output_start_end.html b/pr-preview/pr-63/_modules/jobs/tools/reduce_output_start_end.html deleted file mode 100644 index e569447d..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/reduce_output_start_end.html +++ /dev/null @@ -1,501 +0,0 @@ - - - - - - jobs.tools.reduce_output_start_end — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
-
    -
  • - - -
  • -
  • -
-
-
-
-
- -

Source code for jobs.tools.reduce_output_start_end

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-Script used by `reduce_output` job
-
-Author: Michael Jaehn (jae), Empa, Switzerland
-"""
-
-from __future__ import print_function
-
-import sys
-import numpy as np
-import netCDF4 as nc
-from datetime import datetime
-from datetime import timedelta
-import glob
-import os
-import shutil
-import csv
-
-import helper
-
-import logging
-
-logging.basicConfig(level=logging.DEBUG)
-
-
-def get_attrs(v):
-    return dict((k, v.getncattr(k)) for k in v.ncattrs())
-
-
-def str2char(s):
-    return np.array(list(s), 'c')
-
-
-def search_met(infile, fname_met):
-    """
-    Checks which file contains the meteorology data
-    """
-    time = None
-    tocheck = []
-    print(infile)
-    for f in infile:
-        basename = os.path.split(f)[1]
-        print(basename)
-        timestr = basename.split('lffd', 1)[1][:10]
-        mytime = datetime.strptime(timestr, '%Y%m%d%H')
-        if time is None:
-            time = mytime
-        if mytime == time:
-            tocheck.append(f)
-
-    for f in tocheck:
-        with nc.Dataset(f, 'r') as inf:
-            for var in ['T', 'P', 'PS', 'QV']:
-                if var in inf.variables:
-                    basename = os.path.split(f)[1]
-                    fileending = basename.split('lffd', 1)[1][10:-3]
-                    fname_met[var] = fileending
-
-    return fname_met
-
-
-def append_variable(nc, name, values, attrs=None):
-    """\
-    Append variable (name, values) to netCDF file.
-    """
-
-    from six import string_types
-
-    if attrs is None:
-        attrs = {}
-
-    var = nc.createVariable(name,
-                            values.dtype, ('time', 'rlat', 'rlon'),
-                            zlib=True)
-    var[0] = values
-
-    # add or update attributes
-    for key, value in attrs.items():
-        if isinstance(value, string_types):
-            var.setncattr(key, str2char(value))
-        else:
-            var.setncattr(key, value)
-
-
-def reduce_output(infile, cfiles, h, nout_levels, output_path, fname_met, lsd,
-                  convert):
-    dtime = infile.split('lffd', 1)[1][0:10]
-    """Get path and filename for output file"""
-    path, output_filename = os.path.split(infile)
-    outfile = os.path.join(output_path, output_filename)
-    with nc.Dataset(infile, 'r') as inf, \
-         nc.Dataset(outfile, 'w') as outf:
-        # Copy global attributes all at once via dictionary
-        outf.setncatts(inf.__dict__)
-        # Copy dimensions
-        for name, dimension in inf.dimensions.items():
-            outf.createDimension(
-                name,
-                (len(dimension) if not dimension.isunlimited() else None))
-
-        # Get level information
-        level = len(inf.dimensions['level'])
-        level1 = len(inf.dimensions['level1'])
-
-        # Create new dimension level2
-        if nout_levels == -1:
-            nout_levels = level
-        else:
-            outf.createDimension('level2', nout_levels)
-
-        # Copy variables
-        for varname in inf.variables.keys():
-            logging.info('%s: %s' % (output_filename, varname))
-            var = inf.variables[varname]
-            attrs = get_attrs(var)
-            if len(var.dimensions) == 4:
-                if var.dimensions[1] == 'level':
-                    var_dimensions = list(var.dimensions)
-                    var_dimensions[1] = 'level' + '2' * (nout_levels != level)
-                elif var.dimensions[1] == 'level1':
-                    var_dimensions = list(var.dimensions)
-                    var_dimensions[1] = 'level' + '2' * (
-                        nout_levels != level) + '1' * (nout_levels == level)
-                else:
-                    var_dimensions = var.dimensions
-            else:
-                var_dimensions = var.dimensions
-
-            if len(var.dimensions) > 2:
-                if (varname in lsd):
-                    if '_FillValue' in var.ncattrs():
-                        fill_value = inf[varname].getncattr('_FillValue')
-                        outf.createVariable(
-                            varname,
-                            var.dtype,
-                            var_dimensions,
-                            zlib=True,
-                            fill_value=fill_value,
-                            least_significant_digit=lsd[varname])
-                    else:
-                        outf.createVariable(
-                            varname,
-                            var.dtype,
-                            var_dimensions,
-                            zlib=True,
-                            least_significant_digit=lsd[varname])
-                else:
-                    if '_FillValue' in var.ncattrs():
-                        fill_value = inf[varname].getncattr('_FillValue')
-                        outf.createVariable(varname,
-                                            var.dtype,
-                                            var_dimensions,
-                                            zlib=True,
-                                            fill_value=fill_value)
-                    else:
-                        outf.createVariable(varname,
-                                            var.dtype,
-                                            var_dimensions,
-                                            zlib=True)
-            else:
-                outf.createVariable(varname,
-                                    var.dtype,
-                                    var_dimensions,
-                                    zlib=True)
-
-            for attr in var.ncattrs():
-                if attr != '_FillValue':
-                    outf[varname].setncattr(attr, inf[varname].getncattr(attr))
-
-            gas = None
-            if varname != 'rotated_pole':
-                # Check for 3D data and extract only lower_levels
-                if 'level1' in var.dimensions and \
-                    len(var.dimensions) == 4:
-                    lstart = -nout_levels - (nout_levels == level)
-                elif 'level' in var.dimensions and \
-                    len(var.dimensions) == 4:
-                    lstart = -nout_levels
-                else:
-                    outf[varname][:] = inf[varname][:]
-
-            if (varname.startswith('CO2_') or varname.startswith('CO_') or
-                varname.startswith('CH4_') or varname.startswith('C14_') or
-                varname.startswith('NOX_') or varname.startswith('NO2_')) and \
-                len(var.dimensions) == 4:
-                outvar = outf.variables[varname]
-                gas = varname.split('_')[0]
-                if gas == 'NOX':
-                    attrs['standard_name'] = attrs['standard_name'].replace(
-                        'NOX', 'NO2')
-                    gas = 'NO2'
-                field = inf[varname][:, lstart:, :, :]
-                unit = attrs['units']
-
-                if convert:
-                    outvar.units = helper.common_unit(gas)
-                    if gas == 'C14':
-                        outf[varname][:] = helper.convert_unit(
-                            field, unit, outvar.units, 45.993e-3)
-                    else:
-                        outf[varname][:] = helper.convert_unit(
-                            field, unit, outvar.units, gas)
-                else:
-                    outvar.units = unit
-                    outf[varname][:] = field
-
-                attrs['standard_name'] = attrs['standard_name'].replace(
-                    '%s_mass_fraction' % gas, 'X%s' % gas)
-                attrs['units'] = outvar.units
-                attrs2 = attrs.copy()
-                attrs2['standard_name'] = attrs2['standard_name'].replace(
-                    'X%s' % gas, 'Y%s' % gas)
-            elif varname != 'rotated_pole' and len(var.dimensions) == 4 and \
-            ('level1' in var.dimensions or 'level' in var.dimensions):
-                outf[varname][:] = inf[varname][:, lstart:, :, :]
-
-            if gas:
-                fname_met_base = os.path.split(
-                    infile)[0] + '/' + os.path.split(infile)[1][:14]
-                with nc.Dataset(fname_met_base+fname_met['QV']+'.nc', 'r') as inf_qv, \
-                     nc.Dataset(fname_met_base+fname_met['T']+'.nc', 'r') as inf_t, \
-                     nc.Dataset(fname_met_base+fname_met['PS']+'.nc', 'r') as inf_ps, \
-                     nc.Dataset(fname_met_base+fname_met['P']+'.nc', 'r') as inf_p:
-                    qv = np.array(inf_qv.variables['QV'][0])
-                    t = np.array(inf_t.variables['T'][0])
-                    ps = np.array(inf_ps.variables['PS'][0])
-                    p = np.array(inf_p.variables['P'][0])
-
-                    xm = np.array(inf.variables[varname][0])
-                    mair = helper.calculate_mair(p, ps, h)
-
-                    # Column-averaged dry-air mole fraction
-                    column = helper.calculate_xgas(xm, mair, gas, qv)
-                    column = column.astype('f4')
-                    logging.info('%s: X%s' % (output_filename, varname))
-                    append_variable(outf, 'X%s' % varname, column, attrs=attrs)
-
-                    # Column-averaged moist-air mole fraction
-                    column2 = helper.calculate_xgas(xm, mair, gas, 0.0)
-                    column2 = column2.astype('f4')
-                    logging.info('%s: Y%s' % (output_filename, varname))
-                    append_variable(outf,
-                                    'Y%s' % varname,
-                                    column2,
-                                    attrs=attrs2)
-
-    return fname_met
-
-
-
[docs]def main(indir, outdir, strdate_start, strdate_end, nout_levels, csvfile, - convert_gas): - """ - Script to reduce output. - - Output: TODO - - Parameters (TODO) - ---------- - opath : str - Output path where the processed data is going to be written - """ - """Get list of constant files""" - cfiles = [] - read_cfile = False - for infile in sorted(glob.glob(os.path.join(indir, "lffd*[0-9]c*.nc"))): - cfiles.append(infile) - if not read_cfile: - # Read the first constant file and store height value - logging.info(infile) - with nc.Dataset(infile) as inf: - h = np.array(inf.variables['HHL'][0]) - read_cfile = True - - if not read_cfile: - logging.error('Constant file could not be read') - """Get list of files""" - infiles = sorted(glob.glob(os.path.join(indir, "lffd*.nc"))) - """Remove constant files from file list""" - for cfile in cfiles: - if cfile in infiles: - infiles.remove(cfile) - - date_start = datetime.strptime(strdate_start, '%Y%m%d%H') - date_end = datetime.strptime(strdate_end, '%Y%m%d%H') - """Only take relevant date period into account""" - for infile in list(infiles): - basename = os.path.split(infile)[1] - timestr = basename.split('lffd', 1)[1][:10] - mytime = datetime.strptime(timestr, '%Y%m%d%H') - if mytime < date_start or mytime > date_end: - infiles.remove(infile) - """Initialize dict to remember file name for meteo variables""" - fname_met = { - 'T': None, - 'P': None, - 'PS': None, - 'QV': None, - } - fname_met = search_met(infiles, fname_met) - """Translate csv file to dict""" - variables = helper.find_variables_file(csvfile) - lsd = variables['lsd'].to_dict() - """Loop over all input files and apply output reduction""" - for infile in infiles: - fname_met = reduce_output(infile, cfiles, h, int(nout_levels), outdir, - fname_met, lsd, convert_gas == 'True')
- - -if __name__ == '__main__': - indir = sys.argv[1] - outdir = sys.argv[2] - strdate_start = sys.argv[3] - strdate_end = sys.argv[4] - nout_levels = sys.argv[5] - csvfile = sys.argv[6] - convert_gas = sys.argv[7] - main(indir, outdir, strdate_start, strdate_end, nout_levels, csvfile, - convert_gas) -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/string2char.html b/pr-preview/pr-63/_modules/jobs/tools/string2char.html deleted file mode 100644 index ef061182..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/string2char.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - jobs.tools.string2char — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.tools.string2char

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""\
-Convert string to char for attributes globally and for variables.
-"""
-
-from __future__ import print_function
-
-import sys
-import numpy as np
-import netCDF4
-
-if (sys.version_info.major) >= 3:
-    basestring = (str, bytes)
-
-
-def string2char(nc, name, value):
-    if isinstance(value, basestring):
-        value = np.array(list(value), 'c')
-        nc.setncattr(name, value)
-
-
-
[docs]def main(filename): - """Convert the variable names of a netcdf-file from strings to a - ``np.array`` of chars. - - Parameters - ---------- - filename : str - Path to the netcdf-file - """ - with netCDF4.Dataset(filename, 'a') as nc: - for name in nc.ncattrs(): - value = nc.getncattr(name) - string2char(nc, name, value) - - for v in nc.variables: - var = nc.variables[v] - for name in var.ncattrs(): - value = var.getncattr(name) - string2char(var, name, value)
- - -if __name__ == '__main__': - main(sys.argv[1]) -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/vprmsplit.html b/pr-preview/pr-63/_modules/jobs/tools/vprmsplit.html deleted file mode 100644 index 514a6ea2..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/vprmsplit.html +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - jobs.tools.vprmsplit — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.tools.vprmsplit

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-Script to extract VPRM emissions for a single day
-and to convert the output into an int2lm compatible format.
-
-Authors: Dominik Brunner (brd), Empa, Switzerland
-         Michael Jaehn (jae), Empa, Switzerland
-
-History:
-    brd, 23 Jul 2013: first implementation
-    brd, 20 Aug 2014: modified to handle files with gpp and ra provided
-                      separately
-    brd, 12 Jul 2015: corrected for grid coordinate shift by +0.5 grid cells
-                      (since cell coordinates are given for lower left corner)
-                      and added option to specify CO2 name
-    brd, 15 Jan 2017: slightly adapted for hypatia and project SmartCarb
-    jae, 17 Aug 2018: translated to Python
-
-TODOs:
-    - use logging
-"""
-
-from __future__ import print_function
-
-import sys
-import numpy as np
-from netCDF4 import Dataset
-from datetime import datetime
-from datetime import timedelta
-import logging
-
-
-
[docs]def main(year, ipath, opath): - """ - Script to extract VPRM emissions for a single day - and to convert the output into an int2lm compatible format. - - Output: - The script generates individual 1-hour emission files for the specified - year:: - - gpp_yyyymmddhh.nc - ra_yyyymmddhh.nc - - Parameters - ---------- - year : str - Year (YYYY) of data to be processed - The original VPRM input file (e.g., VPRM_ECMWF_*_2017.nc for 2017 - fluxes) needs to be present in the input directory 'ipath' - ipath : str - Input path where the VPRM input file is located - opath : str - Output path where the processed data is going to be written - """ - m_co2 = 44.01 - - filename_gee = ''.join([ipath, '/VPRM_ECMWF_GEE_', year[:4], '.nc']) - filename_resp = ''.join([ipath, '/VPRM_ECMWF_RESP_', year[:4], '.nc']) - - print('Opening VPRM GEE file', filename_gee) - ifile_gee = Dataset(filename_gee, mode='r') - print('Opening VPRM RESP file', filename_resp) - ifile_resp = Dataset(filename_resp, mode='r') - - lat = ifile_gee.variables['lat'][:] - lon = ifile_gee.variables['lon'][:] - hours = ifile_gee.variables['time'][:] - gpp = ifile_gee.variables['GEE'][:] - resp = ifile_resp.variables['RESP'][:] - ifile_gee.close() - ifile_resp.close() - - # Get grid spacing of VPRM grid - dx = lat[1] - lat[0] - dy = lon[1] - lon[0] - - # Change fluxes from umol m-2 s-1 to kg m-2 s-1 for GPP - gpp *= 1e-9 * m_co2 - - # Switch the sign and avoid negative values - gpp *= -1.0 - gpp[gpp <= 0.0] = 0.0 - - # Change fluxes from umol m-2 s-1 to kg m-2 s-1 for RESP - resp *= 1e-9 * m_co2 - - print(hours) - for ti, hour in enumerate(hours): - - begin_of_year_dt = datetime.strptime(year[:4] + '0101', '%Y%m%d') - curdate_dt = begin_of_year_dt + timedelta(hours=int(hour)) - curdate_str = datetime.strftime(curdate_dt, '%Y%m%d%H') - print(curdate_dt) - - ofile_gpp = Dataset(opath + '/gpp_' + curdate_str + '.nc', mode='w') - - olat = ofile_gpp.createDimension('lat', len(lat)) - olon = ofile_gpp.createDimension('lon', len(lon)) - otime = ofile_gpp.createDimension('time', 1) - - olat = ofile_gpp.createVariable('lat', np.float64, ('lat', )) - olon = ofile_gpp.createVariable('lon', np.float64, ('lon', )) - otime = ofile_gpp.createVariable('time', np.float64, ('time', )) - otime.units = ''.join(['seconds since ', year, '-01-01 00:00:00']) - otime.calendar = 'proleptic_gregorian' - - ogpp = ofile_gpp.createVariable('CO2_GPP_F', - np.float32, ('time', 'lat', 'lon'), - fill_value=-999.99) - ogpp.units = 'kg m-2 s-1' - ogpp.long_name = 'surface upward mass flux of GPP CO2' - ogpp.standard_name = 'surface_upward_mass_flux_of_gpp_carbon_dioxide' - - olat[:] = lat + dx / 2. - olon[:] = lon + dy / 2. - otime[:] = int((curdate_dt - begin_of_year_dt).total_seconds()) - ogpp[:] = gpp[ti, :] - - ofile_gpp.close() - - ofile_resp = Dataset(opath + '/ra_' + curdate_str + '.nc', mode='w') - - olat = ofile_resp.createDimension('lat', len(lat)) - olon = ofile_resp.createDimension('lon', len(lon)) - otime = ofile_resp.createDimension('time', 1) - - olat = ofile_resp.createVariable('lat', np.float64, ('lat', )) - olon = ofile_resp.createVariable('lon', np.float64, ('lon', )) - otime = ofile_resp.createVariable('time', np.float64, ('time', )) - otime.units = ''.join(['seconds since ', year, '-01-01 00:00:00']) - otime.calendar = 'proleptic_gregorian' - - oresp = ofile_resp.createVariable('CO2_RA_F', - np.float32, ('time', 'lat', 'lon'), - fill_value=-999.99) - oresp.units = 'kg m-2 s-1' - oresp.long_name = 'surface upward mass flux of respiration CO2' - oresp.standard_name = 'surface_upward_mass_flux_of_respiration_carbon_dioxide' - - olat[:] = lat + dx / 2. - olon[:] = lon + dy / 2. - otime[:] = int((curdate_dt - begin_of_year_dt).total_seconds()) - oresp[:] = resp[ti, :] - - ofile_resp.close()
- - -if __name__ == '__main__': - - year = sys.argv[1] - ipath = sys.argv[2] - opath = sys.argv[3] - main(year, ipath, opath) -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/write_cosmo_input_ghg.html b/pr-preview/pr-63/_modules/jobs/tools/write_cosmo_input_ghg.html deleted file mode 100644 index efdd7483..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/write_cosmo_input_ghg.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - jobs.tools.write_cosmo_input_ghg — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
-
    -
  • - - -
  • -
  • -
-
-
-
-
- -

Source code for jobs.tools.write_cosmo_input_ghg

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import csv
-import sys
-from .. import tools
-
-STR2INT = {
-    'ytype_adv': {
-        'off': 0,
-        'on': 1
-    },
-    'ytype_diff': {
-        'off': 0,
-        'on': 1
-    },
-    'ytype_turbmix': {
-        'off': 0,
-        '1D': 1,
-        '3D': 2
-    },
-    'ytype_passconv': {
-        'off': 0,
-        'on': 1
-    },
-    'ytype_ini': {
-        'zero': 0,
-        'file': 1,
-        'user': 2
-    },
-    'ytype_lbc': {
-        'zero': 0,
-        'file': 1,
-        'constant': 2,
-        'zero_gradient': 3,
-        'user': 4
-    },
-    'ytype_bbc': {
-        'zero_flux': 0,
-        'zero_value': 1,
-        'surface_value': 2
-    },
-    'ytype_relax': {
-        'off': 0,
-        'full': 1,
-        'inflow': 2
-    },
-    'ytype_damp': {
-        'off': 0,
-        'on': 1
-    },
-    'ytype_clip': {
-        'off': 0,
-        'on': 1
-    }
-}
-
-# Read initial conditions from file (= 1) in case of spinup simluation
-STR2INT_recycling = STR2INT.copy()
-STR2INT_recycling["ytype_ini"] = {'zero': 1, 'file': 1, 'user': 2}
-
-
-def group2text(group, recycling=False):
-
-    lines = ['&TRACER']
-    for key, value in group.items():
-
-        if key == '' or value == '':
-            continue
-
-        if key in STR2INT:
-            if recycling:
-                value = STR2INT_recycling[key][value]
-            else:
-                value = STR2INT[key][value]
-            key = 'i%s' % key[1:]
-
-        if key[0] == 'y':
-            value = "'%s'" % value
-
-        if key == 'ycatl' or key == 'ytpl' or key == 'yvpl':
-            value = value.replace('\'\'', '\'')
-        lines.append('  %s = %s,' % (key, value))
-    lines.append('/\n')
-
-    return '\n'.join(lines)
-
-
-
[docs]def main(csv_filename, namelist_filename, cfg=None): - """Convert a table (``.csv`` file) to namelist file (``INPUT_GHG``) - read by **COSMO**. - - Parameters - ---------- - csv_filename : str - Path to the source csv-file - namelist_filename : str - Path to the namelist file that will be created - cfg : Config - Object holding all user-configuration parameters as attributes. - """ - - with open(csv_filename, 'r') as csv_file: - reader = csv.DictReader(csv_file, delimiter=',') - reader = [r for r in reader if r[''] != '#'] - - with open(namelist_filename, 'a') as nml_file: - for group in reader: - if hasattr(cfg, 'spinup') and not cfg.first_one: - nml_file.write(group2text(group, recycling=True)) - else: - nml_file.write(group2text(group))
- - -if __name__ == '__main__': - input_filename = sys.argv[1] # csv file with tracers - output_filename = sys.argv[2] # filename (INPUT_TRCR) read by COSMO - main(input_filename, output_filename) -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/tools/write_int2lm_input_art.html b/pr-preview/pr-63/_modules/jobs/tools/write_int2lm_input_art.html deleted file mode 100644 index c6034bc6..00000000 --- a/pr-preview/pr-63/_modules/jobs/tools/write_int2lm_input_art.html +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - jobs.tools.write_int2lm_input_art — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
-
    -
  • - - -
  • -
  • -
-
-
-
-
- -

Source code for jobs.tools.write_int2lm_input_art

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from __future__ import print_function
-
-import argparse
-import csv
-import sys
-
-
-def art_control(nart_ds, nart_trcr, hstart=0):
-    lines = [
-        "&ARTCONTROL",
-        "  nart_ds = %d," % nart_ds,  # number of dataset groups
-        "  nart_trcr = %d," % nart_trcr,  # number of tracers groups
-        "  hstart = %d," % hstart,
-        "/"
-    ]
-    return '\n'.join(lines)
-
-
-def make_group(keys, values, group):
-    lines = ['&%s' % group]
-    for key, value in zip(keys, values):
-        if value:
-            if key == 'yvarlist':
-                value = ','.join('"%s"' % v.strip() for v in value.split(","))
-                lines.append('  %s = %s,' % (key, value))
-            elif key[0] == 'y':
-                lines.append('  %s = "%s",' % (key, value))
-            else:
-                lines.append('  %s = %s,' % (key, value))
-    lines.append('/\n')
-    return '\n'.join(lines)
-
-
-def read_file(filename):
-    with open(filename, 'r') as csv_file:
-        lines = [
-            line[1:] for line in csv.reader(csv_file)
-            if not line[0].startswith('#')
-        ]
-
-    return lines[0], lines[1:]
-
-
-
[docs]def main(trcr_filename, set_filename, nml_filename, hstart=0): - """Write the INPUT_ART namelist file for int2lm from ``.csv`` files - - Parameters - ---------- - trcr_filename : str - csv file with tracer definitions - set_filename : str - csv file with tracer datasets - nml_filename : str - output filename (INPUT_ART) - hstart : int - meteorology spin up in hours - """ - # art tracers - if trcr_filename is None: - tracer_values = [] - n_tracers = 0 - else: - tracer_keys, tracer_values = read_file(trcr_filename) - n_tracers = len(tracer_values) - - # art datasets - if set_filename is None: - set_values = [] - n_sets = 0 - else: - set_keys, set_values = read_file(set_filename) - n_sets = len(set_values) - - # write namelist file - with open(nml_filename, 'w') as nml: - - nml.write(art_control(n_sets, n_tracers, hstart)) - nml.write('\n') - - for values in tracer_values: - text = make_group(tracer_keys, values, 'ARTTRACER') - nml.write(text) - nml.write('\n') - - for values in set_values: - text = make_group(set_keys, values, 'ARTDATASET') - nml.write(text) - nml.write('\n')
- - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Write INPUT_ART for int2lm.') - - parser.add_argument('-t', - dest='trcr_filename', - default=None, - type=str, - help='filename of csv file with tracers') - parser.add_argument('-d', - dest='datasets_filename', - default=None, - type=str, - help='filename of csv file with datasets') - parser.add_argument('-o', - dest='nml_filename', - default='INPUT_ART', - type=str, - help='output filename (INPUT_ART)') - parser.add_argument('-m', - dest='meteo_spinup', - default=0, - type=float, - help='meteorology spin up') - - args = parser.parse_args() - main(args.trcr_filename, args.datasets_filename, args.nml_filename, - args.meteo_spinup) -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/jobs/verify_chain.html b/pr-preview/pr-63/_modules/jobs/verify_chain.html deleted file mode 100644 index 1d2eef2e..00000000 --- a/pr-preview/pr-63/_modules/jobs/verify_chain.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - jobs.verify_chain — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for jobs.verify_chain

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-import netCDF4 as nc
-
-from . import tools
-
-BASIC_PYTHON_JOB = True
-
-
-def comp_data(dataset1, dataset2, variables):
-    """Use tools.helper.datasets_equal to compare the datasets.
-    """
-    tools.helper.datasets_equal(dataset1, dataset2, variables, verbose=True)
-
-
-
[docs]def main(cfg): - """Compare outputs of the chain to a reference. - - Looks for the reference-file in ``cfg.verify_chain['reference_dir']``. - - Looks for the output file in ``cfg.verify_chain['output_dir']`` (if not ``None``), else it - goes to the output directory created by the **COSMO**-job. - - In the dict ``cfg.verify_chain['values_to_check']``, the user specifies the names of the - files to be compared as keys, and the variables to compare as a list. - - To compare the temperatures of the last output of the example case, the - following variables should be added to the ``config.yaml`` file: :: - - verify_chain['reference_dir'] = os.path.join(input_root, "reference_output") - verify_chain['output_dir'] = None - verify_chain['values_to_check'] = {("reference_lffd2015010200.nc","lffd2015010200.nc"): - ['T']} - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes - """ - tools.change_logfile(cfg.logfile) - logging.info("Started verification") - for (ref_file, - run_file), variables in cfg.verify_chain['values_to_check'].items(): - logging.info("Comparing " + str(variables)) - - # reference file location - ref_file_path = os.path.join(cfg.verify_chain['reference_dir'], - ref_file) - - # run data location - if cfg.verify_chain['output_dir'] is None: - # Standard output location - run_file_path = os.path.join( - cfg.output_root, cfg.startdate_sim_yyyymmddhh + "_" + - cfg.enddate_sim_yyyymmddhh, "cosmo_output", run_file) - else: - # User-provided output location - run_file_path = os.path.join(cfg.verify_chain['output_dir'], - run_file) - - logging.info("Output file: " + str(run_file_path)) - logging.info("Reference file: " + str(ref_file_path)) - - # compare data - with nc.Dataset(ref_file_path) as ref_data, nc.Dataset( - run_file_path) as run_data: - comp_data(ref_data, run_data, variables) - - logging.info("Finished verification")
-
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_modules/run_chain.html b/pr-preview/pr-63/_modules/run_chain.html deleted file mode 100644 index b64c89e1..00000000 --- a/pr-preview/pr-63/_modules/run_chain.html +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - run_chain — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

Source code for run_chain

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from datetime import datetime, timedelta
-import pytz
-import logging
-import shutil
-import argparse
-
-import jobs
-from jobs import tools
-from config import Config
-
-
-def parse_arguments():
-    """Parse command line arguments for the Processing Chain script.
-
-    Parses and retrieves command line arguments, allowing users to specify
-    run identifiers, jobs to execute, and various options to control the
-    execution of the Processing Chain.
-
-    Returns
-    -------
-    argparse.Namespace
-        A namespace object containing parsed command line arguments.
-    """
-    parser = argparse.ArgumentParser(description="Run the Processing Chain.")
-
-    parser.add_argument("casenames",
-                        nargs='+',
-                        help="List of identifiers for the runs. "
-                        "The config-files for each run is assumed "
-                        "to be in cases/<casename>/. The runs are executed "
-                        "sequentially in the order they're given here.")
-
-    jobs_help = ("List of job names to be executed. A job is a .py "
-                 "file in jobs/ with a main()-function which "
-                 "handles one aspect of the Processing Chain, for "
-                 "example copying meteo-input data or launching a "
-                 "job for int2lm. "
-                 "Jobs are executed in the order in which they are "
-                 "given here. "
-                 "If no jobs are given, default jobs will be executed"
-                 "as defined in config/workflows.yaml.")
-    parser.add_argument("-j",
-                        "--jobs",
-                        nargs='*',
-                        dest="job_list",
-                        help=jobs_help,
-                        default=None)
-
-    chunks_help = ("List of chunks to be executed. A chunk is time"
-                   "frame within the total simulation period."
-                   "It has the format `YYYYMMDDHH_YYYYMMDDHH`."
-                   "If no chunks are given, all chunks within the"
-                   "simulation period will be executed.")
-    parser.add_argument("-c",
-                        "--chunks",
-                        nargs='*',
-                        dest="chunk_list",
-                        help=chunks_help,
-                        default=None)
-
-    sync_help = ("Force synchronous execution.")
-    parser.add_argument("-s",
-                        "--force-sync",
-                        action='store_true',
-                        help=sync_help)
-
-    no_logging_help = ("Disable logging for chain_status.log.")
-    parser.add_argument("--no-logging",
-                        action='store_false',
-                        dest="enable_logging",
-                        default=True,
-                        help=no_logging_help)
-
-    force_help = ("Force the processing chain to redo all specified jobs,"
-                  " even if they have been started already or were finished"
-                  " previously. WARNING: Only logfiles get deleted,"
-                  " other effects of a given job (copied files etc.)"
-                  " are simply overwritten. This may cause errors"
-                  " or unexpected behavior.")
-    parser.add_argument("-f", "--force", action='store_true', help=force_help)
-
-    resume_help = (
-        "Resume the Processing Chain by restarting the last unfinished job."
-        " WARNING: Only the logfile gets deleted,"
-        " other effects of a given job (copied files etc.)"
-        " are simply overwritten. This may cause errors."
-        " or unexpected behavior.")
-    parser.add_argument("-r",
-                        "--resume",
-                        help=resume_help,
-                        dest="resume",
-                        action='store_true')
-
-    args = parser.parse_args()
-
-    return args
-
-
-
[docs]def run_chunk(cfg, force, resume): - """Run a chunk of the processing chain, managing job execution and logging. - - This function sets up and manages the execution of a Processing Chain, handling - job execution, logging, and various configuration settings. - - Parameters - ---------- - cfg : Config - Object holding user-defined configuration parameters as attributes. - force : bool - If True, it will force the execution of jobs regardless of their completion status. - resume : bool - If True, it will resume the last unfinished job. - - Raises - ------ - RuntimeError - If an error or timeout occurs during job execution. - - Notes - ----- - - This function sets various configuration values based on the provided parameters. - - It checks for job completion status and resumes or forces execution accordingly. - - Job log files are managed, and errors or timeouts are handled with notifications. - """ - # Set forecast time - cfg.forecasttime = (cfg.enddate_sim - - cfg.startdate_sim).total_seconds() / 3600 - - # Logging - cfg.chain_root = cfg.work_root / cfg.casename / cfg.chunk_id - cfg.log_working_dir = cfg.chain_root / 'checkpoints' / 'working' - cfg.log_finished_dir = cfg.chain_root / 'checkpoints' / 'finished' - - # Create working directories - tools.create_dir(cfg.chain_root, "chain_root") - tools.create_dir(cfg.log_working_dir, "log_working") - tools.create_dir(cfg.log_finished_dir, "log_finished") - - # Config variables for spinup and restart runs - cfg.cosmo_restart_in = '' - cfg.cosmo_restart_out = '' - if hasattr(cfg, 'spinup'): - if cfg.chunk_id_prev: - cfg.chain_root_prev = cfg.work_root / cfg.casename / cfg.chunk_id_prev - cfg.last_cosmo_output = cfg.chain_root_prev / 'cosmo' / 'output' - elif 'restart' in cfg.workflow['features']: - if cfg.chunk_id_prev: - cfg.chain_root_prev = cfg.work_root / cfg.casename / cfg.chunk_id_prev - cfg.cosmo_restart_in = cfg.chain_root_prev / 'cosmo' / 'restart' - cfg.cosmo_restart_out = cfg.chain_root / 'cosmo' / 'restart' - - if not cfg.force_sync: - # Empty curent job ids - cfg.job_ids['current'] = {} - - # Submit current chunk - for job_name in cfg.jobs: - if (cfg.log_finished_dir / job_name).exists() and not force: - # Skip job if already finished - print(f' └── Skipping "{job_name}" job') - skip = True - else: - print(f' └── Submitting "{job_name}" job') - - # Logfile settings - cfg.logfile = cfg.log_working_dir / job_name - cfg.logfile_finish = cfg.log_finished_dir / job_name - - # Submit the job - job = getattr(jobs, job_name) - if hasattr(job, 'BASIC_PYTHON_JOB') and job.BASIC_PYTHON_JOB: - cfg.submit_basic_python(job_name) - else: - job.main(cfg) - - # Wait for previous chunk jobs, monitor them and cycle info - cfg.cycle() - - else: # For nested run_chain.py - for job_name in cfg.jobs: - print(f' └── Process "{job_name}" for chunk "{cfg.chunk_id}"') - try: - # Change the log file - cfg.logfile = cfg.log_working_dir / job_name - cfg.logfile_finish = cfg.log_finished_dir / job_name - - # Launch the job - to_call = getattr(jobs, job_name) - to_call.main(cfg) - - shutil.copy(cfg.logfile, cfg.logfile_finish) - - exitcode = 0 - except Exception: - exitcode = 1 - subject = "ERROR or TIMEOUT in job '%s' for chunk '%s'" % ( - job_name, cfg.chunk_id) - logging.exception(subject) - if cfg.user_mail: - message = tools.prepare_message(cfg.log_working_dir / - job_name) - logging.info('Sending log file to %s' % cfg.user_mail) - tools.send_mail(cfg.user_mail, subject, message) - - if exitcode != 0 or not (cfg.log_finished_dir / job_name).exists(): - subject = "ERROR or TIMEOUT in job '%s' for chunk '%s'" % ( - job_name, cfg.chunk_id) - if cfg.user_mail: - message = tools.prepare_message(cfg.log_working_dir / - job_name) - logging.info('Sending log file to %s' % cfg.user_mail) - tools.send_mail(cfg.user_mail, subject, message) - raise RuntimeError(subject)
- - -
[docs]def restart_runs(cfg, force, resume): - """Start subchains in specified intervals and manage restarts. - - This function slices the total runtime of the processing chain according to the - `cfg.restart_step_hours` configuration. It calls `run_chunk()` for each - specified interval. - - Parameters - ---------- - cfg : Config - Object holding all user-configuration parameters as attributes. - force : bool - If True, it will force the execution of jobs regardless of their completion status. - resume : bool - If True, it will resume the last unfinished job. - - Notes - ----- - - The function iterates over specified intervals, calling `run_chunk()` for each. - - It manages restart settings and logging for each subchain. - """ - - for chunk_id in cfg.chunks: - cfg.chunk_id = chunk_id - cfg.get_previous_chunk_id(cfg.chunk_id) - cfg.startdate_sim_yyyymmddhh = cfg.chunk_id[0:10] - cfg.enddate_sim_yyyymmddhh = cfg.chunk_id[-10:] - cfg.startdate_sim = datetime.strptime( - cfg.startdate_sim_yyyymmddhh, "%Y%m%d%H").replace(tzinfo=pytz.UTC) - cfg.enddate_sim = datetime.strptime( - cfg.enddate_sim_yyyymmddhh, "%Y%m%d%H").replace(tzinfo=pytz.UTC) - - if 'spinup' in cfg.workflow['features'] and hasattr(cfg, 'spinup'): - if cfg.startdate_sim == cfg.startdate: - cfg.first_one = True - cfg.second_one = False - cfg.lrestart = '.FALSE.' - elif cfg.startdate_sim == cfg.startdate + timedelta( - hours=cfg.restart_step_hours): - cfg.first_one = False - cfg.second_one = True - cfg.lrestart = '.TRUE.' - else: - cfg.first_one = False - cfg.second_one = False - cfg.lrestart = '.TRUE.' - else: - # Set restart variable (only takes effect for ICON) - cfg.lrestart = ".FALSE." if cfg.startdate_sim == cfg.startdate else ".TRUE." - - print(f'└── Starting chunk "{cfg.chunk_id}"') - - run_chunk(cfg=cfg, force=force, resume=resume)
- - -def main(): - """Main script for running a processing chain. - - This script handles the execution of a processing chain for one or more - specified cases. It loads model configurations, prepares the environment, - and starts the chain based on the provided settings. - - Parameters - ---------- - None (Command-line arguments are parsed internally) - - Notes - ----- - - This script uses command-line arguments to specify cases and job lists. - - It loads model configurations, converts paths to absolute, sets restart - settings, and starts the chain. - - Depending on the model's features, it may run with or without restarts - or utilize spin-up restarts. - """ - args = parse_arguments() - - for casename in args.casenames: - # Load configs - cfg = Config(casename) - - # Convert relative to absolute paths - cfg.convert_paths_to_absolute() - - # Set restart step in hours - cfg.set_restart_step_hours() - - # Duplicate variables in the form of <dict>_<value> for better - # access within namelist template. - # E.g.: cfg.meteo['dir'] -> cfg.meteo_dir - cfg.create_vars_from_dicts() - - # Check if jobs are set or if default ones are used - if args.job_list is None: - cfg.jobs = cfg.workflow['jobs'] - else: - cfg.jobs = args.job_list - - # Check sync is forced - if args.force_sync: - cfg.force_sync = True - else: - cfg.force_sync = False - - # Check constraint - if cfg.constraint and cfg.machine == 'daint': - assert cfg.constraint in ['gpu', 'mc'], ("Unknown constraint, use" - "gpu or mc") - - # Get complete chunk list - cfg.get_chunk_list() - - # Print config before chain starts - cfg.print_config() - - # Get custom chunks if specified - cfg.chunks = args.chunk_list if args.chunk_list else cfg.chunk_list - - tools.create_dir(cfg.case_root, "case_root") - - print("╔════════════════════════════════════════╗") - print("║ Starting Processing Chain ║") - print("╠════════════════════════════════════════╣") - print(f"║ Case: {casename: <27} ║") - print(f"║ Workflow: {cfg.workflow_name: <27} ║") - print("╚════════════════════════════════════════╝") - - # Check for restart compatibility and spinup - if 'restart' in cfg.workflow['features']: - restart_runs(cfg=cfg, force=args.force, resume=args.resume) - else: - print("No restarts are used.") - cfg.startdate_sim = cfg.startdate - cfg.enddate_sim = cfg.enddate - run_chunk(cfg=cfg, force=args.force, resume=args.resume) - - print("╔════════════════════════════════════════╗") - print("║ Processing Chain Completed ║") - print("╚════════════════════════════════════════╝") - - -if __name__ == '__main__': - main() -
- -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/_sources/code-structure.rst.txt b/pr-preview/pr-63/_sources/code-structure.rst.txt deleted file mode 100644 index 9a7ee7ab..00000000 --- a/pr-preview/pr-63/_sources/code-structure.rst.txt +++ /dev/null @@ -1,55 +0,0 @@ -.. _code-structure-section: - -Code Structure --------------- - -The Processing Chain code is structured as follows: - -.. code-block:: bash - - $ tree -L 3 -F --dirsfirst - . - ├── cases/ # folder where all cases are stored - │ ├── cosmo-ghg-spinup-test/ # COSMO-GHG test case with spinup restart - │ │ ├── config.yaml # case configuration file - │ │ ├── *.cfg # templates for namelists & batch jobs - │ │ └── *.csv # CSV files with tracer information - │ ├── cosmo-ghg-test/ # COSMO-GHG testcase with standard restart - │ │ ├── config.yaml - │ │ ├── *.cfg - │ │ └── *.csv - │ ├── icon-art-global-test/ # ICON-ART test case (global domain) - │ │ ├── config.yaml - │ │ ├── icon_runjob.cfg # template for ICON-ART runjob - │ │ ├── *.sh # pre-processing scripts - │ │ └── mypartab - │ ├── icon-art-oem-test/ # ICON-ART test case with online emissions - │ │ ├── config.yaml - │ │ └── *.cfg - │ └── icon-test/ # ICON test case - │ ├── config.yaml - │ └── *.cfg - ├── docs/ # folder for Sphinx documentation - │ ├── _static/ # folder for static assets - │ │ ├── custom.css # custom CSS styles - │ │ └── *.png|ico # additional image assets - │ ├── tables/ # folder for tables used in documentation - │ │ └── *.csv # CSV files containing table data - │ ├── conf.py # configuration file for the Sphinx builder - │ └── *.rst # documentation files (reStructuredText) - ├── env/ - │ └── environment.yml # conda environment file - ├── ext/ # folder for other code (spack, models, etc.) - ├── jenkins/ # automated Jenkins testing - │ ├── scripts/ - │ │ └── *.sh # individual Shell scripts for testing - │ └── Jenkinsfile # text file containing the Jenkins pipeline - ├── jobs/ - │ ├── tools/ - │ │ └── *.py # tool scripts - │ └── *.py # job scripts - ├── LICENSE # license file - ├── README.md # README file - ├── config.py # file containing the Config class - ├── run_chain.py # main script - └── workflows.yaml # file to store workflows with job dependencies diff --git a/pr-preview/pr-63/_sources/config.rst.txt b/pr-preview/pr-63/_sources/config.rst.txt deleted file mode 100644 index f38ef329..00000000 --- a/pr-preview/pr-63/_sources/config.rst.txt +++ /dev/null @@ -1,190 +0,0 @@ -.. _config-section: - -The Processing Chain uses cases to describe a simulation. A case is a -subdirectory in ``cases/``, containing a ``config.yaml`` and several -`namelist` (e.g., ``int2lm_INPUT.cfg``) and `runscripts` (e.g., -``icon_runjob.cfg``) :ref:`templates`, -which define the simulation. - -.. _config.yaml: - -Configuration File ------------------- - -The case-dependent configuration file ``/config.yaml`` contains most -of the information that the :ref:`jobs` need to prepare -and run the simulation, for example the location of the input data. -This configuration file is loaded in ``run_chain.py`` as an instance -of the ``Config()`` class in ``config.py``. - -Configuration Variables -~~~~~~~~~~~~~~~~~~~~~~~ - -This is a non-exhaustive list containing the most important configuration variables: - -+------------------------+-------------------------------------------------------------------------+ -| Variable | Description | -+========================+=========================================================================+ -|| ``case_path`` || The path to the case directory under ``cases/`` for the specified | -|| || casename. | -+------------------------+-------------------------------------------------------------------------+ -| ``casename`` | The name of the case. Derived from the folder name under ``case_path``. | -+------------------------+-------------------------------------------------------------------------+ -|| ``chain_src_dir`` || The source directory for the processing chain, typically the current | -|| || working directory. | -+------------------------+-------------------------------------------------------------------------+ -| ``compute_account`` | The compute account to be used based on user information. | -+------------------------+-------------------------------------------------------------------------+ -| ``constraint`` | The computational constraint (``gpu`` or ``mc``). | -+------------------------+-------------------------------------------------------------------------+ -|| ``email`` || The user's email address, initially set to None and updated using the | -|| || set_email method. | -+------------------------+-------------------------------------------------------------------------+ -|| ``enddate`` || The end date of the simulation in ISO 8601 format | -|| || (``YYYY-MM-DDTHH:mm:ssZ``). | -+------------------------+-------------------------------------------------------------------------+ -| ``jobs`` | List of job-names to be executed. | -+------------------------+-------------------------------------------------------------------------+ -| ``log_finished_dir`` | The directory for finished log files. | -+------------------------+-------------------------------------------------------------------------+ -| ``log_working_dir`` | The directory for working log files. | -+------------------------+-------------------------------------------------------------------------+ -| ``ntasks_per_node`` | The number of tasks per node, based on the node type. | -+------------------------+-------------------------------------------------------------------------+ -| ``restart_step`` | The restart step in ISO 8601 format. | -+------------------------+-------------------------------------------------------------------------+ -| ``restart_step_hours`` | The restart step in hours, derived from the ``restart_step`` attribute. | -+------------------------+-------------------------------------------------------------------------+ -| ``run_on`` | The architecture the model runs on (``cpu`` or ``gpu``). | -+------------------------+-------------------------------------------------------------------------+ -| ``spinup`` | Spin-up duration in hours. Activates spinup behavior if set. | -+------------------------+-------------------------------------------------------------------------+ -|| ``startdate`` || The start date of the simulation in ISO 8601 format | -|| || (``YYYY-MM-DDTHH:mm:ssZ``). | -+------------------------+-------------------------------------------------------------------------+ -| ``user_mail`` | The user's email address, determined based on system configuration. | -+------------------------+-------------------------------------------------------------------------+ -|| ``user_name`` || Your email address to receive notifications. Either provide it | -|| || directly here or in ``~/.forward``. | -+------------------------+-------------------------------------------------------------------------+ -| ``workflow`` | The name of the workflow from ``workflows.yaml`` or a self-defined one. | -+------------------------+-------------------------------------------------------------------------+ -|| ``work_root`` || The working directory where all output is stored. Should be somewhere | -|| || on ``$SCRATCH$``. By default, it is set to ``/work``. | -+------------------------+-------------------------------------------------------------------------+ - - -Variables to Set in ``config.yaml`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Here are two examples of which general variables should be set by the user in the -case configuration file. - -Header of ``config.yaml`` for the ``cosmo-ghg-spinup-test`` case -================================================================ - -.. code-block:: yaml - - workflow: cosmo-ghg - constraint: gpu - ntasks_per_node: 12 - restart_step: PT6H - spinup: 3 - startdate: 2015-01-01T00:00:00Z - enddate: 2015-01-01T18:00:00Z - -Header of ``config.yaml`` for the ``icon-art-oem-test`` case -============================================================ - -.. code-block:: yaml - - workflow: icon-art-oem - constraint: gpu - run_on: cpu - compute_queue: normal - ntasks_per_node: 12 - restart_step: PT6H - startdate: 2018-01-01T00:00:00Z - enddate: 2018-01-01T12:00:00Z - - eccodes_dir: ./input/eccodes_definitions - iconremap_bin: iconremap - iconsub_bin: iconsub - latbc_filename: ifs__lbc.nc - inidata_prefix: ifs_init_ - inidata_nameformat: '%Y%m%d%H' - inidata_filename_suffix: .nc - output_filename: icon-art-oem-test - filename_format: _DOM_ - lateral_boundary_grid_order: lateral_boundary - art_input_folder: ./input/icon-art-oem/ART - -Further variables -================= - -Furthermore, there are additional variables to set that are tied to the individual jobs. -These config variables themselves are dictionaries. Let's have a look at and example -for the the ``cfg.meteo`` variable: - -.. code-block:: yaml - - meteo: - dir: ./input/cosmo-ghg/meteo - prefix: laf - nameformat: laf%Y%m%d%H - inc: 1 - -These config variables can be accessed via ``cfg.meteo['dir']``, ``cfg.meteo['prefix']``, etc. -as they are Python dictionaries. - -.. hint:: - In :ref:`namelist and runscript template` files - (see next section), this accessing does not work because of how the ``.format()`` - method is implemented in Python. For that reason, the Processing Chain automatically - creates new variables in the form of ``cfg.meteo_dir``, ``cfg.meteo_prefix``, etc. - at the start to make them accessible for namelist and runjob templates. - -List of dictionary variables -**************************** - -The following is a list of dictionary variables that exist for the Processing Chain. -For the individual elements of those variables, please refer to the ``config.yaml`` -files within the test cases. - -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| Dictionary variable | Used in job | -+=======================+=====================================================================================================================================+ -| ``meteo`` | ``prepare_cosmo``, ``prepare_icon``, ``icontools``, ``int2lm``, ``icon`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``icontools_runjobs`` | ``icontools`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``input_files`` | ``prepare_icon`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``chem`` | ``prepare_icon`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``era5`` | ``prepare_icon`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``cams`` | ``prepare_cosmo`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``emissions`` | ``emissions`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``vprm`` | ``biofluxes`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``oem`` | ``oem``, ``cosmo`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``online_vprm`` | ``online_vprm`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``int2lm`` | ``prepare_cosmo``, ``emissions``, ``biofluxes``, ``octe``, ``int2lm``, ``post_int2lm``, ``cosmo``, ``post_cosmo`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``post_int2lm`` | ``post_int2lm`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``cosmo`` | ``reduce_output``, ``oem``, ``photo_rate``, ``octe``, ``check_output``, ``post_cosmo``, ``cosmo``, ``obs_nudging``, ``online_vprm`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``reduce_output`` | ``reduce_output`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``post_cosmo`` | ``post_cosmo`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``verify_chain`` | ``verify_chain`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| ``icon`` | ``oem``, ``prepare_icon``, ``icon`` | -+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/pr-preview/pr-63/_sources/environment.rst.txt b/pr-preview/pr-63/_sources/environment.rst.txt deleted file mode 100644 index 58707f7a..00000000 --- a/pr-preview/pr-63/_sources/environment.rst.txt +++ /dev/null @@ -1,62 +0,0 @@ -.. _environment-section: - -Conda Environment -================= - -The following steps allow you to create and use your own virtual environment to run the Processing Chain. We recommend using a conda environment for the usage of the provided scripts. Please follow the instructions for the installation. The following steps only need to be performed once. - -1. Install Miniconda -~~~~~~~~~~~~~~~~~~~~ - -Install Miniconda as user-specific Miniconda, e.g., in your ``$HOME`` directory, which is the default location. - -.. note:: - Only conda itself should be installed in your ``$HOME``. All environments should be stored in your ``$PROJECT`` directory; otherwise, you risk filling up your ``$HOME`` directory. See below for instructions. - -To install the latest Miniconda, type: - -.. code-block:: bash - - wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh - bash Miniconda3-latest-Linux-x86_64.sh - -Further details on Miniconda can be found on the `Miniconda documentation page `_. - -2. Create the Conda Environment -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Create a conda environment ``proc-chain`` and install the requirements: - -.. code-block:: bash - - conda env create --prefix $PROJECT/envs/proc-chain -f env/environment.yml - -To be able to activate your conda environment by simply using ``conda activate proc-chain`` instead of the full path, add the following to your ``.bashrc``: - -.. code-block:: bash - - export CONDA_ENVS_PATH=$PROJECT/envs - -Activate the environment (use "source activate" in case "conda activate" does not work): - -.. code-block:: bash - - conda activate proc-chain - -If you already have the environment but want to update it: - -.. code-block:: bash - - conda env update --file env/environment.yml --prune - -3. Store user-specific data -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To register your email address and standard project account, store them in these files within your home directory: - -.. code-block:: bash - - echo > ~/.acct - echo > ~/.forward - -These settings are optional. The Processing Chain will first check the content of those files. If desired, the corresponding variables can be overridden by setting the ``compute_account`` and ``user_mail`` variables in the ``config.yaml`` file. diff --git a/pr-preview/pr-63/_sources/features.rst.txt b/pr-preview/pr-63/_sources/features.rst.txt deleted file mode 100644 index c0f14d0a..00000000 --- a/pr-preview/pr-63/_sources/features.rst.txt +++ /dev/null @@ -1,13 +0,0 @@ -.. _features-section: - -Feature Overview -================ - -- Asynchronous submission of compute jobs to the HPC queue -- Intuitive definition of job dependencies -- Automatic cycling over time periods including folder structure creation -- Various jobs for pre- and post-processing steps -- Using model built-in restarts or custom spinup -- Nested runs possible -- Easy creation of own cases and workflows -- Various examples for COSMO and ICON workflows available \ No newline at end of file diff --git a/pr-preview/pr-63/_sources/functions.rst.txt b/pr-preview/pr-63/_sources/functions.rst.txt deleted file mode 100644 index 4305a932..00000000 --- a/pr-preview/pr-63/_sources/functions.rst.txt +++ /dev/null @@ -1,155 +0,0 @@ -.. _functions-section: - -Jobs ----- - -* :func:`jobs.biofluxes.main` -* :func:`jobs.check_output.main` -* :func:`jobs.cosmo.main` -* :func:`jobs.emissions.main` -* :func:`jobs.icon.main` -* :func:`jobs.icontools.main` -* :func:`jobs.int2lm.main` -* :func:`jobs.obs_nudging.main` -* :func:`jobs.octe.main` -* :func:`jobs.oem.main` -* :func:`jobs.online_vprm.main` -* :func:`jobs.photo_rate.main` -* :func:`jobs.post_cosmo.main` -* :func:`jobs.post_int2lm.main` -* :func:`jobs.prepare_cosmo.main` -* :func:`jobs.prepare_icon.main` -* :func:`jobs.reduce_output.main` -* :func:`jobs.verify_chain.main` - -------------------------------------------- - -.. autofunction:: jobs.biofluxes.main - -------------------------------------------- - -.. autofunction:: jobs.check_output.main - -------------------------------------------- - -.. autofunction:: jobs.cosmo.main - -------------------------------------------- - -.. autofunction:: jobs.emissions.main - -------------------------------------------- - -.. autofunction:: jobs.icon.main - -------------------------------------------- - -.. autofunction:: jobs.icontools.main - -------------------------------------------- - -.. autofunction:: jobs.int2lm.main - -------------------------------------------- - -.. autofunction:: jobs.obs_nudging.main - -------------------------------------------- - -.. autofunction:: jobs.octe.main - -------------------------------------------- - -.. autofunction:: jobs.oem.main - -------------------------------------------- - -.. autofunction:: jobs.online_vprm.main - -------------------------------------------- - -.. autofunction:: jobs.photo_rate.main - -------------------------------------------- - -.. autofunction:: jobs.post_cosmo.main - -------------------------------------------- - -.. autofunction:: jobs.post_int2lm.main - -------------------------------------------- - -.. autofunction:: jobs.prepare_cosmo.main - -------------------------------------------- - -.. autofunction:: jobs.prepare_icon.main - -------------------------------------------- - -.. autofunction:: jobs.reduce_output.main - -------------------------------------------- - -.. autofunction:: jobs.verify_chain.main - - -Tools ------ - -The tools are a collection of functions used by the jobs. Most of those -functions are well documented and listed here. For others, one may take -a look into ``jobs/tools`` directly. - -* :func:`jobs.tools.cams4int2cosmo.main` -* :func:`jobs.tools.check_model.check_model` -* :func:`jobs.tools.comp_nc.datasets_equal` -* :func:`jobs.tools.ctnoaa4int2cosmo.main` -* :func:`jobs.tools.mozart2int2lm.main` -* :func:`jobs.tools.reduce_output_start_end.main` -* :func:`jobs.tools.string2char.main` -* :func:`jobs.tools.vprmsplit.main` -* :func:`jobs.tools.write_cosmo_input_ghg.main` -* :func:`jobs.tools.write_int2lm_input_art.main` - - -------------------------------------------- - -.. autofunction:: jobs.tools.cams4int2cosmo.main - -------------------------------------------- - -.. autofunction:: jobs.tools.check_model.check_model - -------------------------------------------- - -.. autofunction:: jobs.tools.comp_nc.datasets_equal - -------------------------------------------- - -.. autofunction:: jobs.tools.ctnoaa4int2cosmo.main - -------------------------------------------- - -.. autofunction:: jobs.tools.mozart2int2lm.main - -------------------------------------------- - -.. autofunction:: jobs.tools.reduce_output_start_end.main - -------------------------------------------- - -.. autofunction:: jobs.tools.string2char.main - -------------------------------------------- - -.. autofunction:: jobs.tools.vprmsplit.main - -------------------------------------------- - -.. autofunction:: jobs.tools.write_cosmo_input_ghg.main - -------------------------------------------- - -.. autofunction:: jobs.tools.write_int2lm_input_art.main diff --git a/pr-preview/pr-63/_sources/howtorun.rst.txt b/pr-preview/pr-63/_sources/howtorun.rst.txt deleted file mode 100644 index 9d074ee7..00000000 --- a/pr-preview/pr-63/_sources/howtorun.rst.txt +++ /dev/null @@ -1,245 +0,0 @@ -.. _howtorun-section: - -How to Run -========== - -The Python file ``run_chain.py`` in the root directory is the main script of the -Processing Chain. -It reads the user's input from the command line and from the ``config.yaml`` file of the -respective case. -Then it will start the Processing Chain. - -Starting the Chain ------------------- - -The chain has to be run with the following command: - -.. code-block:: bash - - $ ./run_chain.py - -Here, ```` is the name of a directory in the ``cases/``-directory where -there is a ``config.yaml``-file specifying the configuration, as well as templates -for the necessary namelist files for **int2lm**, **COSMO** or **ICON**. It may also -contain additional runscripts to be submitted via ``sbatch``. - -.. hint:: - Technically, you can run several cases (instead of a single case) in one command, - which is useful for nested runs, for example. This can be achieved by running - ``./run_chain.py ``. With that, the full chain is executed for - ``case1`` first, and afterwards for ``case2``. - -There are several optional arguments available to change the behavior of the chain: - -.. code-block:: bash - - $ ./run_chain.py -h - -* ``-h``, ``--help`` - Show this help message and exit. -* ``-j [JOB_LIST ...]``, ``--jobs [JOB_LIST ...]`` - List of job names to be executed. - A job is a ``.py`` file in i``jobs/`` with a ``main()`` function, which - handles one aspect of the Processing Chain, for - example copying ``meteo`` input data or launching a - job for ``int2lm``. Jobs are executed in the order - in which they are given here. If no jobs are - given, default jobs will be executed as defined - in ``config/models.yaml``. -* ``-f``, ``--force`` - Force the Processing Chain to redo all specified - jobs, even if they have been started already or - were finished previously. WARNING: Only logfiles - get deleted, other effects of a given job - (copied files etc.) are simply overwritten. This - may cause errors or unexpected behavior. -* ``-r``, ``--resume`` - Resume the Processing Chain by restarting the - last unfinished job. WARNING: Only the logfile - gets deleted, other effects of a given job - (copied files etc.) are simply overwritten. This - may cause errors or unexpected behavior. - -What it Does ------------- - -The script ``run_chain.py`` reads the command line arguments and the config file -from the specified case. -It then calls the function :func:`run_chain.restart_runs`, which divides the -simulation time according to the specified restart steps. Then it calls -:func:`run_chain.run_chunk` for each part (chunk) of the simulation workflow. -This function sets up the directory structure of the chain and then submits the -specified :ref:`jobs` via ``sbatch`` to the Slurm workload manager, -taking job dependencies into account. - -Test Cases ----------- - -The following test cases are available: - -* ``cosmo-ghg-spinup-test`` -* ``cosmo-ghg-test`` -* ``icon-test`` -* ``icon-art-oem-test`` -* ``icon-art-global-test`` - -To be able to run these test cases, it is necessary to provide the input data, -to setup spack and to compile the models and tools. All this is automized via -the script:: - - $ ./jenkins/scripts/jenkins.sh - -This will run all the individual scripts in ``jenkins/scripts/``, which -can also be launched separately if desired. - -These cases undergo regulary testing to ensure that the Processing Chain runs -correctly. A corresponding Jenkins plan is launched on a weekly basis and -when triggered within a GitHub pull request. - -Directory Structure -------------------- - -The directory structure generated by the Processing Chain for a ``cosmo-ghg`` -run looks like this: - -.. code-block:: bash - - cfg.work_root/cfg.casename/ - └── cfg.chain_root/ - ├── checkpoints/ - │ ├── cfg.log_working_dir/ - │ ├── cfg.log_finished_dir/ - ├── cfg.cosmo_base/ - │ ├── cfg.cosmo_work/ - │ ├── cfg.cosmo_output/ - │ ├── cfg.cosmo_restart_out/ - └── cfg.int2lm_base/ - ├── cfg.int2lm_input/ - ├── cfg.int2lm_work/ - └── cfg.int2lm_output/ - -As one can see, it creates working directories for both the ``int2lm`` preprocessor -and ``cosmo``. Additionally, and this is always the case, the ``checkpoints`` -directory holds all the job logfiles. Whenever a job has successfully finished, -the logfile is copied from the ``working`` to the ``finished`` sub-directory. - -Running the ``cosmo-ghg-test`` case therefore produces the following -directories and files (showing four levels of directories deep): - -.. code-block:: bash - - work/cosmo-ghg-test - ├── 2015010100_2015010106/ - │ ├── checkpoints/ - │ │ ├── finished/ - │ │ │ ├── biofluxes - │ │ │ ├── cosmo - │ │ │ ├── emissions - │ │ │ ├── int2lm - │ │ │ ├── oem - │ │ │ ├── online_vprm - │ │ │ ├── post_cosmo - │ │ │ ├── post_int2lm - │ │ │ └── prepare_cosmo - │ │ └── working/ - │ │ ├── biofluxes - │ │ ├── cosmo - │ │ ├── emissions - │ │ ├── int2lm - │ │ ├── oem - │ │ ├── online_vprm - │ │ ├── post_cosmo - │ │ ├── post_int2lm - │ │ └── prepare_cosmo - │ ├── cosmo/ - │ │ ├── input/ - │ │ │ ├── oem/ - │ │ │ └── vprm/ - │ │ ├── output/ - │ │ │ └── lffd*.nc - │ │ ├── restart/ - │ │ │ └── lrff00060000o.nc - │ │ └── run/ - │ │ ├── cosmo-ghg - │ │ ├── INPUT_* - │ │ ├── post_cosmo.job - │ │ ├── run.job - │ │ └── YU* - │ └── int2lm/ - │ ├── input/ - │ │ ├── emissions - │ │ ├── extpar - │ │ ├── icbc - │ │ ├── meteo - │ │ └── vprm - │ ├── output/ - │ │ ├── laf*.nc - │ │ └── lbfd*.nc - │ └── run/ - │ ├── INPUT - │ ├── INPUT_ART - │ ├── int2lm - │ ├── OUTPUT - │ ├── run.job - │ └── YU* - └── 2015010106_2015010112/ - ├── checkpoints/ - │ ├── finished/ - │ │ ├── biofluxes - │ │ ├── cosmo - │ │ ├── emissions - │ │ ├── int2lm - │ │ ├── oem - │ │ ├── online_vprm - │ │ ├── post_cosmo - │ │ ├── post_int2lm - │ │ └── prepare_cosmo - │ └── working/ - │ ├── biofluxes - │ ├── cosmo - │ ├── emissions - │ ├── int2lm - │ ├── oem - │ ├── online_vprm - │ ├── post_cosmo - │ ├── post_int2lm - │ └── prepare_cosmo - ├── cosmo/ - │ ├── input/ - │ │ ├── oem - │ │ └── vprm - │ ├── output/ - │ │ └── lffd*.nc - │ ├── restart/ - │ │ └── lrff00060000o.nc - │ └── run/ - │ ├── cosmo-ghg - │ ├── INPUT_* - │ ├── post_cosmo.job - │ ├── run.job - │ └── YU* - └── int2lm/ - ├── input/ - │ ├── emissions - │ ├── extpar - │ ├── icbc - │ ├── meteo - │ └── vprm - ├── output/ - │ ├── laf*.nc - │ └── lbfd*.nc - └── run/ - ├── INPUT - ├── INPUT_ART - ├── int2lm - ├── OUTPUT - ├── run.job - └── YU* - -------------------------------------------- - -.. autofunction:: run_chain.run_chunk - -------------------------------------------- - -.. autofunction:: run_chain.restart_runs diff --git a/pr-preview/pr-63/_sources/index.rst.txt b/pr-preview/pr-63/_sources/index.rst.txt deleted file mode 100644 index 169bf730..00000000 --- a/pr-preview/pr-63/_sources/index.rst.txt +++ /dev/null @@ -1,50 +0,0 @@ -.. Processing Chain documentation master file, created by - sphinx-quickstart on Thu Sep 27 14:11:04 2018. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Processing Chain -================ - -The Processing Chain is a Python-based workflow tool designed to streamline -weather and climate simulations. -It facilitates the preparation of essential input data, submission of compute -jobs to the queue on CSCS HPC systems, and the implementation of post-processing -steps. -In addition to supporting standard versions of the COSMO and ICON models, -it is equipped to handle various model variants, notably COSMO-GHG -(Greenhouse Gas Extension) and ICON-ART (Aerosols and Reactive Trace Gases) - -The Processing Chain can be easily customized to meet your specific requirements. -This includes defining custom workflows, creating your own simulation cases, -and integrating new jobs and auxiliary scripts. - -.. toctree:: - :maxdepth: 2 - :caption: Getting Started - - features - environment - howtorun - -.. toctree:: - :maxdepth: 2 - :caption: Configuration - - code-structure - config - namelists - - -.. toctree:: - :maxdepth: 2 - :caption: Jobs & Workflows - - jobs - -.. toctree:: - :maxdepth: 2 - :caption: API - - functions - diff --git a/pr-preview/pr-63/_sources/jobs.rst.txt b/pr-preview/pr-63/_sources/jobs.rst.txt deleted file mode 100644 index 96cae42b..00000000 --- a/pr-preview/pr-63/_sources/jobs.rst.txt +++ /dev/null @@ -1,79 +0,0 @@ -.. _jobs-section: - -Overview --------- - -Jobs have to be part of the respective workflow. They are submitted via ``sbatch`` -to the Slurm workload manager. - -The order of job submission is based on the list given in ``workflows.yaml`` -(or in ``config.yaml`` in case a custom, user-defined workflow is used.) - -Let's have a look at the ``icon-art`` example: - -.. code-block:: yaml - - icon-art: - features: - - restart - jobs: - - prepare_icon - - icontools - - prepare_art - - icon - -This workflow consists of four jobs: ``prepare_icon``, ``icontools``, -``prepare_art`` and ``icon``. - -These jobs will be submitted, however, they are not starting at the same time, -because some of them depend on others: - -.. code-block:: yaml - - dependencies: - icontools: - current: - - prepare_icon - prepare_art: - current: - - icontools - icon: - current: - - prepare_icon - - icontools - - prepare_art - previous: - - icon - -Since ``icontools`` depends on ``prepare_icon``, and ``prepare_art`` depends -on ``icontools``, the order of execution is ``prepare_icon`` --> ``icontools`` ---> ``prepare_art``. Note that if we had another job in there without dependencies, -it would run in parallel to the others. - -Since ``icon`` depends on all other jobs, it will be executed last. Note that -these dependencies are all listed under the ``current`` keyword, targeting -the current chunk. For ``icon``, there is an additional ``previous`` keyword. -This means that an ``icon`` simulation will always wait until the simulation -from the last chunk is finished (because the restart file has to be available). - -Another effect of this workflow definition is that the ``prepare_icon``, -``icontools`` and ``prepare_art`` jobs will also be launched for the next chunk, -as they are not dependent on their previous ones. - -.. figure:: _static/processing_chain_workflow_icon_art.png - :alt: Flowchart for the ``icon-art`` workflow. - - Flowchart for the ``icon-art`` workflow. - - -Adding New Jobs ---------------- - -Adding a new job to the chain is simple: - -1. In the directory ``jobs/``, create a file called ``.py`` containing - a function called ``main`` which takes the same arguments as every other job. - Make sure the function is documented with a docstring. -2. Import it in ``jobs/__init__.py`` to make it accessible to ``run_chain.py``. -3. Add the job to your workflow. - diff --git a/pr-preview/pr-63/_sources/namelists.rst.txt b/pr-preview/pr-63/_sources/namelists.rst.txt deleted file mode 100644 index 20da47ca..00000000 --- a/pr-preview/pr-63/_sources/namelists.rst.txt +++ /dev/null @@ -1,34 +0,0 @@ -.. _namelists-section: - -Namelist and Runscript Templates --------------------------------- - -The namelists and run jobs for **int2lm** and **COSMO**, as well as for **icontools** and **ICON** are dynamically generated -using templates located in the ``cases/`` directory. These templates are essentially -text files containing "normal" namelist parameters alongside Python variables enclosed in curly braces. - -During runtime, these template files are read by their respective jobs. -The resulting strings are formatted through Python's ``.format()`` function, facilitating the -substitution of Python variables with their corresponding value. -Subsequently, the formatted strings are then saved as the actual namelist and run scripts in the -run directory of their respective jobs. - -.. code-block:: - - cases/example/example_namelist.cfg -> [read file] -> - "namelist_var = '{cfg.prefix}{cfg.suffix}'" -> ["".format(cfg)] -> - "namelist_var = 'pref_suff.nc'" -> [write to disk] -> - int2lm/run/example_namelist - -A special case is ``INPUT_ART`` for **int2lm** and ``INPUT_GHG`` for **COSMO** . These namelists are -generated by :func:`jobs.tools.write_int2lm_input_art.main` and :func:`jobs.tools.write_cosmo_input_ghg.main` -from ``.csv``-files containing all necessary information. - ----------------------------------------------------- - -.. autofunction:: jobs.tools.write_int2lm_input_art.main - ----------------------------------------------------- - -.. autofunction:: jobs.tools.write_cosmo_input_ghg.main - diff --git a/pr-preview/pr-63/_static/_sphinx_javascript_frameworks_compat.js b/pr-preview/pr-63/_static/_sphinx_javascript_frameworks_compat.js deleted file mode 100644 index 81415803..00000000 --- a/pr-preview/pr-63/_static/_sphinx_javascript_frameworks_compat.js +++ /dev/null @@ -1,123 +0,0 @@ -/* Compatability shim for jQuery and underscores.js. - * - * Copyright Sphinx contributors - * Released under the two clause BSD licence - */ - -/** - * small helper function to urldecode strings - * - * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL - */ -jQuery.urldecode = function(x) { - if (!x) { - return x - } - return decodeURIComponent(x.replace(/\+/g, ' ')); -}; - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s === 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node, addItems) { - if (node.nodeType === 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && - !jQuery(node.parentNode).hasClass(className) && - !jQuery(node.parentNode).hasClass("nohighlight")) { - var span; - var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.className = className; - } - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - if (isInSVG) { - var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - var bbox = node.parentElement.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute('class', className); - addItems.push({ - "parent": node.parentNode, - "target": rect}); - } - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this, addItems); - }); - } - } - var addItems = []; - var result = this.each(function() { - highlight(this, addItems); - }); - for (var i = 0; i < addItems.length; ++i) { - jQuery(addItems[i].parent).before(addItems[i].target); - } - return result; -}; - -/* - * backward compatibility for jQuery.browser - * This will be supported until firefox bug is fixed. - */ -if (!jQuery.browser) { - jQuery.uaMatch = function(ua) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || - /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - jQuery.browser = {}; - jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; -} diff --git a/pr-preview/pr-63/_static/basic.css b/pr-preview/pr-63/_static/basic.css deleted file mode 100644 index cfc60b86..00000000 --- a/pr-preview/pr-63/_static/basic.css +++ /dev/null @@ -1,921 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -div.section::after { - display: block; - content: ''; - clear: left; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox form.search { - overflow: hidden; -} - -div.sphinxsidebar #searchbox input[type="text"] { - float: left; - width: 80%; - padding: 0.25em; - box-sizing: border-box; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - float: left; - width: 20%; - border-left: none; - padding: 0.25em; - box-sizing: border-box; -} - - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li p.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; - margin-left: auto; - margin-right: auto; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable ul { - margin-top: 0; - margin-bottom: 0; - list-style-type: none; -} - -table.indextable > tbody > tr > td > ul { - padding-left: 0em; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- domain module index --------------------------------------------------- */ - -table.modindextable td { - padding: 2px; - border-collapse: collapse; -} - -/* -- general body styles --------------------------------------------------- */ - -div.body { - min-width: 360px; - max-width: 800px; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, figure.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, figure.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, figure.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -img.align-default, figure.align-default, .figure.align-default { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-default { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar, -aside.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px; - background-color: #ffe; - width: 40%; - float: right; - clear: right; - overflow-x: auto; -} - -p.sidebar-title { - font-weight: bold; -} - -nav.contents, -aside.topic, -div.admonition, div.topic, blockquote { - clear: left; -} - -/* -- topics ---------------------------------------------------------------- */ - -nav.contents, -aside.topic, -div.topic { - border: 1px solid #ccc; - padding: 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- content of sidebars/topics/admonitions -------------------------------- */ - -div.sidebar > :last-child, -aside.sidebar > :last-child, -nav.contents > :last-child, -aside.topic > :last-child, -div.topic > :last-child, -div.admonition > :last-child { - margin-bottom: 0; -} - -div.sidebar::after, -aside.sidebar::after, -nav.contents::after, -aside.topic::after, -div.topic::after, -div.admonition::after, -blockquote::after { - display: block; - content: ''; - clear: both; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - margin-top: 10px; - margin-bottom: 10px; - border: 0; - border-collapse: collapse; -} - -table.align-center { - margin-left: auto; - margin-right: auto; -} - -table.align-default { - margin-left: auto; - margin-right: auto; -} - -table caption span.caption-number { - font-style: italic; -} - -table caption span.caption-text { -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -th > :first-child, -td > :first-child { - margin-top: 0px; -} - -th > :last-child, -td > :last-child { - margin-bottom: 0px; -} - -/* -- figures --------------------------------------------------------------- */ - -div.figure, figure { - margin: 0.5em; - padding: 0.5em; -} - -div.figure p.caption, figcaption { - padding: 0.3em; -} - -div.figure p.caption span.caption-number, -figcaption span.caption-number { - font-style: italic; -} - -div.figure p.caption span.caption-text, -figcaption span.caption-text { -} - -/* -- field list styles ----------------------------------------------------- */ - -table.field-list td, table.field-list th { - border: 0 !important; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.field-name { - -moz-hyphens: manual; - -ms-hyphens: manual; - -webkit-hyphens: manual; - hyphens: manual; -} - -/* -- hlist styles ---------------------------------------------------------- */ - -table.hlist { - margin: 1em 0; -} - -table.hlist td { - vertical-align: top; -} - -/* -- object description styles --------------------------------------------- */ - -.sig { - font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; -} - -.sig-name, code.descname { - background-color: transparent; - font-weight: bold; -} - -.sig-name { - font-size: 1.1em; -} - -code.descname { - font-size: 1.2em; -} - -.sig-prename, code.descclassname { - background-color: transparent; -} - -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - -.sig-param.n { - font-style: italic; -} - -/* C++ specific styling */ - -.sig-inline.c-texpr, -.sig-inline.cpp-texpr { - font-family: unset; -} - -.sig.c .k, .sig.c .kt, -.sig.cpp .k, .sig.cpp .kt { - color: #0033B3; -} - -.sig.c .m, -.sig.cpp .m { - color: #1750EB; -} - -.sig.c .s, .sig.c .sc, -.sig.cpp .s, .sig.cpp .sc { - color: #067D17; -} - - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -:not(li) > ol > li:first-child > :first-child, -:not(li) > ul > li:first-child > :first-child { - margin-top: 0px; -} - -:not(li) > ol > li:last-child > :last-child, -:not(li) > ul > li:last-child > :last-child { - margin-bottom: 0px; -} - -ol.simple ol p, -ol.simple ul p, -ul.simple ol p, -ul.simple ul p { - margin-top: 0; -} - -ol.simple > li:not(:first-child) > p, -ul.simple > li:not(:first-child) > p { - margin-top: 0; -} - -ol.simple p, -ul.simple p { - margin-bottom: 0; -} - -aside.footnote > span, -div.citation > span { - float: left; -} -aside.footnote > span:last-of-type, -div.citation > span:last-of-type { - padding-right: 0.5em; -} -aside.footnote > p { - margin-left: 2em; -} -div.citation > p { - margin-left: 4em; -} -aside.footnote > p:last-of-type, -div.citation > p:last-of-type { - margin-bottom: 0em; -} -aside.footnote > p:last-of-type:after, -div.citation > p:last-of-type:after { - content: ""; - clear: both; -} - -dl.field-list { - display: grid; - grid-template-columns: fit-content(30%) auto; -} - -dl.field-list > dt { - font-weight: bold; - word-break: break-word; - padding-left: 0.5em; - padding-right: 5px; -} - -dl.field-list > dd { - padding-left: 0.5em; - margin-top: 0em; - margin-left: 0em; - margin-bottom: 0em; -} - -dl { - margin-bottom: 15px; -} - -dd > :first-child { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -.sig dd { - margin-top: 0px; - margin-bottom: 0px; -} - -.sig dl { - margin-top: 0px; - margin-bottom: 0px; -} - -dl > dd:last-child, -dl > dd:last-child > :last-child { - margin-bottom: 0; -} - -dt:target, span.highlighted { - background-color: #fbe54e; -} - -rect.highlighted { - fill: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -.classifier:before { - font-style: normal; - margin: 0 0.5em; - content: ":"; - display: inline-block; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -.translated { - background-color: rgba(207, 255, 207, 0.2) -} - -.untranslated { - background-color: rgba(255, 207, 207, 0.2) -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -pre, div[class*="highlight-"] { - clear: both; -} - -span.pre { - -moz-hyphens: none; - -ms-hyphens: none; - -webkit-hyphens: none; - hyphens: none; - white-space: nowrap; -} - -div[class*="highlight-"] { - margin: 1em 0; -} - -td.linenos pre { - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - display: block; -} - -table.highlighttable tbody { - display: block; -} - -table.highlighttable tr { - display: flex; -} - -table.highlighttable td { - margin: 0; - padding: 0; -} - -table.highlighttable td.linenos { - padding-right: 0.5em; -} - -table.highlighttable td.code { - flex: 1; - overflow: hidden; -} - -.highlight .hll { - display: block; -} - -div.highlight pre, -table.highlighttable pre { - margin: 0; -} - -div.code-block-caption + div { - margin-top: 0; -} - -div.code-block-caption { - margin-top: 1em; - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -table.highlighttable td.linenos, -span.linenos, -div.highlight span.gp { /* gp: Generic.Prompt */ - user-select: none; - -webkit-user-select: text; /* Safari fallback only */ - -webkit-user-select: none; /* Chrome/Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* IE10+ */ -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - margin: 1em 0; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; -} - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -span.eqno a.headerlink { - position: absolute; - z-index: 1; -} - -div.math:hover a.headerlink { - visibility: visible; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/pr-preview/pr-63/_static/check-solid.svg b/pr-preview/pr-63/_static/check-solid.svg deleted file mode 100644 index 92fad4b5..00000000 --- a/pr-preview/pr-63/_static/check-solid.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pr-preview/pr-63/_static/clipboard.min.js b/pr-preview/pr-63/_static/clipboard.min.js deleted file mode 100644 index 54b3c463..00000000 --- a/pr-preview/pr-63/_static/clipboard.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * clipboard.js v2.0.8 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 - - - - diff --git a/pr-preview/pr-63/_static/copybutton.css b/pr-preview/pr-63/_static/copybutton.css deleted file mode 100644 index f1916ec7..00000000 --- a/pr-preview/pr-63/_static/copybutton.css +++ /dev/null @@ -1,94 +0,0 @@ -/* Copy buttons */ -button.copybtn { - position: absolute; - display: flex; - top: .3em; - right: .3em; - width: 1.7em; - height: 1.7em; - opacity: 0; - transition: opacity 0.3s, border .3s, background-color .3s; - user-select: none; - padding: 0; - border: none; - outline: none; - border-radius: 0.4em; - /* The colors that GitHub uses */ - border: #1b1f2426 1px solid; - background-color: #f6f8fa; - color: #57606a; -} - -button.copybtn.success { - border-color: #22863a; - color: #22863a; -} - -button.copybtn svg { - stroke: currentColor; - width: 1.5em; - height: 1.5em; - padding: 0.1em; -} - -div.highlight { - position: relative; -} - -/* Show the copybutton */ -.highlight:hover button.copybtn, button.copybtn.success { - opacity: 1; -} - -.highlight button.copybtn:hover { - background-color: rgb(235, 235, 235); -} - -.highlight button.copybtn:active { - background-color: rgb(187, 187, 187); -} - -/** - * A minimal CSS-only tooltip copied from: - * https://codepen.io/mildrenben/pen/rVBrpK - * - * To use, write HTML like the following: - * - *

Short

- */ - .o-tooltip--left { - position: relative; - } - - .o-tooltip--left:after { - opacity: 0; - visibility: hidden; - position: absolute; - content: attr(data-tooltip); - padding: .2em; - font-size: .8em; - left: -.2em; - background: grey; - color: white; - white-space: nowrap; - z-index: 2; - border-radius: 2px; - transform: translateX(-102%) translateY(0); - transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); -} - -.o-tooltip--left:hover:after { - display: block; - opacity: 1; - visibility: visible; - transform: translateX(-100%) translateY(0); - transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); - transition-delay: .5s; -} - -/* By default the copy button shouldn't show up when printing a page */ -@media print { - button.copybtn { - display: none; - } -} diff --git a/pr-preview/pr-63/_static/copybutton.js b/pr-preview/pr-63/_static/copybutton.js deleted file mode 100644 index 863baa29..00000000 --- a/pr-preview/pr-63/_static/copybutton.js +++ /dev/null @@ -1,248 +0,0 @@ -// Localization support -const messages = { - 'en': { - 'copy': 'Copy', - 'copy_to_clipboard': 'Copy to clipboard', - 'copy_success': 'Copied!', - 'copy_failure': 'Failed to copy', - }, - 'es' : { - 'copy': 'Copiar', - 'copy_to_clipboard': 'Copiar al portapapeles', - 'copy_success': '¡Copiado!', - 'copy_failure': 'Error al copiar', - }, - 'de' : { - 'copy': 'Kopieren', - 'copy_to_clipboard': 'In die Zwischenablage kopieren', - 'copy_success': 'Kopiert!', - 'copy_failure': 'Fehler beim Kopieren', - }, - 'fr' : { - 'copy': 'Copier', - 'copy_to_clipboard': 'Copier dans le presse-papier', - 'copy_success': 'Copié !', - 'copy_failure': 'Échec de la copie', - }, - 'ru': { - 'copy': 'Скопировать', - 'copy_to_clipboard': 'Скопировать в буфер', - 'copy_success': 'Скопировано!', - 'copy_failure': 'Не удалось скопировать', - }, - 'zh-CN': { - 'copy': '复制', - 'copy_to_clipboard': '复制到剪贴板', - 'copy_success': '复制成功!', - 'copy_failure': '复制失败', - }, - 'it' : { - 'copy': 'Copiare', - 'copy_to_clipboard': 'Copiato negli appunti', - 'copy_success': 'Copiato!', - 'copy_failure': 'Errore durante la copia', - } -} - -let locale = 'en' -if( document.documentElement.lang !== undefined - && messages[document.documentElement.lang] !== undefined ) { - locale = document.documentElement.lang -} - -let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; -if (doc_url_root == '#') { - doc_url_root = ''; -} - -/** - * SVG files for our copy buttons - */ -let iconCheck = ` - ${messages[locale]['copy_success']} - - -` - -// If the user specified their own SVG use that, otherwise use the default -let iconCopy = ``; -if (!iconCopy) { - iconCopy = ` - ${messages[locale]['copy_to_clipboard']} - - - -` -} - -/** - * Set up copy/paste for code blocks - */ - -const runWhenDOMLoaded = cb => { - if (document.readyState != 'loading') { - cb() - } else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', cb) - } else { - document.attachEvent('onreadystatechange', function() { - if (document.readyState == 'complete') cb() - }) - } -} - -const codeCellId = index => `codecell${index}` - -// Clears selected text since ClipboardJS will select the text when copying -const clearSelection = () => { - if (window.getSelection) { - window.getSelection().removeAllRanges() - } else if (document.selection) { - document.selection.empty() - } -} - -// Changes tooltip text for a moment, then changes it back -// We want the timeout of our `success` class to be a bit shorter than the -// tooltip and icon change, so that we can hide the icon before changing back. -var timeoutIcon = 2000; -var timeoutSuccessClass = 1500; - -const temporarilyChangeTooltip = (el, oldText, newText) => { - el.setAttribute('data-tooltip', newText) - el.classList.add('success') - // Remove success a little bit sooner than we change the tooltip - // So that we can use CSS to hide the copybutton first - setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) - setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) -} - -// Changes the copy button icon for two seconds, then changes it back -const temporarilyChangeIcon = (el) => { - el.innerHTML = iconCheck; - setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) -} - -const addCopyButtonToCodeCells = () => { - // If ClipboardJS hasn't loaded, wait a bit and try again. This - // happens because we load ClipboardJS asynchronously. - if (window.ClipboardJS === undefined) { - setTimeout(addCopyButtonToCodeCells, 250) - return - } - - // Add copybuttons to all of our code cells - const COPYBUTTON_SELECTOR = 'div.highlight pre'; - const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) - codeCells.forEach((codeCell, index) => { - const id = codeCellId(index) - codeCell.setAttribute('id', id) - - const clipboardButton = id => - `` - codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) - }) - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -/** - * Removes excluded text from a Node. - * - * @param {Node} target Node to filter. - * @param {string} exclude CSS selector of nodes to exclude. - * @returns {DOMString} Text from `target` with text removed. - */ -function filterText(target, exclude) { - const clone = target.cloneNode(true); // clone as to not modify the live DOM - if (exclude) { - // remove excluded nodes - clone.querySelectorAll(exclude).forEach(node => node.remove()); - } - return clone.innerText; -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} - - -var copyTargetText = (trigger) => { - var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); - - // get filtered text - let exclude = '.linenos'; - - let text = filterText(target, exclude); - return formatCopyText(text, '\\$ ', true, true, true, true, '', '') -} - - // Initialize with a callback so we can modify the text before copy - const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) - - // Update UI with error/success messages - clipboard.on('success', event => { - clearSelection() - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) - temporarilyChangeIcon(event.trigger) - }) - - clipboard.on('error', event => { - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) - }) -} - -runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/pr-preview/pr-63/_static/copybutton_funcs.js b/pr-preview/pr-63/_static/copybutton_funcs.js deleted file mode 100644 index dbe1aaad..00000000 --- a/pr-preview/pr-63/_static/copybutton_funcs.js +++ /dev/null @@ -1,73 +0,0 @@ -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -/** - * Removes excluded text from a Node. - * - * @param {Node} target Node to filter. - * @param {string} exclude CSS selector of nodes to exclude. - * @returns {DOMString} Text from `target` with text removed. - */ -export function filterText(target, exclude) { - const clone = target.cloneNode(true); // clone as to not modify the live DOM - if (exclude) { - // remove excluded nodes - clone.querySelectorAll(exclude).forEach(node => node.remove()); - } - return clone.innerText; -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} diff --git a/pr-preview/pr-63/_static/css/badge_only.css b/pr-preview/pr-63/_static/css/badge_only.css deleted file mode 100644 index c718cee4..00000000 --- a/pr-preview/pr-63/_static/css/badge_only.css +++ /dev/null @@ -1 +0,0 @@ -.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Bold.woff b/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Bold.woff deleted file mode 100644 index 6cb60000..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Bold.woff and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Bold.woff2 b/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Bold.woff2 deleted file mode 100644 index 7059e231..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Bold.woff2 and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Regular.woff b/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Regular.woff deleted file mode 100644 index f815f63f..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Regular.woff and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Regular.woff2 b/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Regular.woff2 deleted file mode 100644 index f2c76e5b..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/Roboto-Slab-Regular.woff2 and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.eot b/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca9..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.svg b/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.svg deleted file mode 100644 index 855c845e..00000000 --- a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.ttf b/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2f..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.woff b/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a4..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.woff2 b/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc60..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/lato-bold-italic.woff b/pr-preview/pr-63/_static/css/fonts/lato-bold-italic.woff deleted file mode 100644 index 88ad05b9..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/lato-bold-italic.woff and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/lato-bold-italic.woff2 b/pr-preview/pr-63/_static/css/fonts/lato-bold-italic.woff2 deleted file mode 100644 index c4e3d804..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/lato-bold-italic.woff2 and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/lato-bold.woff b/pr-preview/pr-63/_static/css/fonts/lato-bold.woff deleted file mode 100644 index c6dff51f..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/lato-bold.woff and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/lato-bold.woff2 b/pr-preview/pr-63/_static/css/fonts/lato-bold.woff2 deleted file mode 100644 index bb195043..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/lato-bold.woff2 and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/lato-normal-italic.woff b/pr-preview/pr-63/_static/css/fonts/lato-normal-italic.woff deleted file mode 100644 index 76114bc0..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/lato-normal-italic.woff and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/lato-normal-italic.woff2 b/pr-preview/pr-63/_static/css/fonts/lato-normal-italic.woff2 deleted file mode 100644 index 3404f37e..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/lato-normal-italic.woff2 and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/lato-normal.woff b/pr-preview/pr-63/_static/css/fonts/lato-normal.woff deleted file mode 100644 index ae1307ff..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/lato-normal.woff and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/fonts/lato-normal.woff2 b/pr-preview/pr-63/_static/css/fonts/lato-normal.woff2 deleted file mode 100644 index 3bf98433..00000000 Binary files a/pr-preview/pr-63/_static/css/fonts/lato-normal.woff2 and /dev/null differ diff --git a/pr-preview/pr-63/_static/css/theme.css b/pr-preview/pr-63/_static/css/theme.css deleted file mode 100644 index 19a446a0..00000000 --- a/pr-preview/pr-63/_static/css/theme.css +++ /dev/null @@ -1,4 +0,0 @@ -html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/pr-preview/pr-63/_static/custom.css b/pr-preview/pr-63/_static/custom.css deleted file mode 100644 index 59b5412a..00000000 --- a/pr-preview/pr-63/_static/custom.css +++ /dev/null @@ -1,3 +0,0 @@ -.wy-table-responsive table td { - white-space: normal; -} diff --git a/pr-preview/pr-63/_static/doctools.js b/pr-preview/pr-63/_static/doctools.js deleted file mode 100644 index d06a71d7..00000000 --- a/pr-preview/pr-63/_static/doctools.js +++ /dev/null @@ -1,156 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ -"use strict"; - -const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ - "TEXTAREA", - "INPUT", - "SELECT", - "BUTTON", -]); - -const _ready = (callback) => { - if (document.readyState !== "loading") { - callback(); - } else { - document.addEventListener("DOMContentLoaded", callback); - } -}; - -/** - * Small JavaScript module for the documentation. - */ -const Documentation = { - init: () => { - Documentation.initDomainIndexTable(); - Documentation.initOnKeyListeners(); - }, - - /** - * i18n support - */ - TRANSLATIONS: {}, - PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), - LOCALE: "unknown", - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext: (string) => { - const translated = Documentation.TRANSLATIONS[string]; - switch (typeof translated) { - case "undefined": - return string; // no translation - case "string": - return translated; // translation exists - default: - return translated[0]; // (singular, plural) translation tuple exists - } - }, - - ngettext: (singular, plural, n) => { - const translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated !== "undefined") - return translated[Documentation.PLURAL_EXPR(n)]; - return n === 1 ? singular : plural; - }, - - addTranslations: (catalog) => { - Object.assign(Documentation.TRANSLATIONS, catalog.messages); - Documentation.PLURAL_EXPR = new Function( - "n", - `return (${catalog.plural_expr})` - ); - Documentation.LOCALE = catalog.locale; - }, - - /** - * helper function to focus on search bar - */ - focusSearchBar: () => { - document.querySelectorAll("input[name=q]")[0]?.focus(); - }, - - /** - * Initialise the domain index toggle buttons - */ - initDomainIndexTable: () => { - const toggler = (el) => { - const idNumber = el.id.substr(7); - const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); - if (el.src.substr(-9) === "minus.png") { - el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; - toggledRows.forEach((el) => (el.style.display = "none")); - } else { - el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; - toggledRows.forEach((el) => (el.style.display = "")); - } - }; - - const togglerElements = document.querySelectorAll("img.toggler"); - togglerElements.forEach((el) => - el.addEventListener("click", (event) => toggler(event.currentTarget)) - ); - togglerElements.forEach((el) => (el.style.display = "")); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); - }, - - initOnKeyListeners: () => { - // only install a listener if it is really needed - if ( - !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && - !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS - ) - return; - - document.addEventListener("keydown", (event) => { - // bail for input elements - if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; - // bail with special keys - if (event.altKey || event.ctrlKey || event.metaKey) return; - - if (!event.shiftKey) { - switch (event.key) { - case "ArrowLeft": - if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; - - const prevLink = document.querySelector('link[rel="prev"]'); - if (prevLink && prevLink.href) { - window.location.href = prevLink.href; - event.preventDefault(); - } - break; - case "ArrowRight": - if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; - - const nextLink = document.querySelector('link[rel="next"]'); - if (nextLink && nextLink.href) { - window.location.href = nextLink.href; - event.preventDefault(); - } - break; - } - } - - // some keyboard layouts may need Shift to get / - switch (event.key) { - case "/": - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; - Documentation.focusSearchBar(); - event.preventDefault(); - } - }); - }, -}; - -// quick alias for translations -const _ = Documentation.gettext; - -_ready(Documentation.init); diff --git a/pr-preview/pr-63/_static/documentation_options.js b/pr-preview/pr-63/_static/documentation_options.js deleted file mode 100644 index 4b43a2ed..00000000 --- a/pr-preview/pr-63/_static/documentation_options.js +++ /dev/null @@ -1,14 +0,0 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: 'v3.1', - LANGUAGE: 'en', - COLLAPSE_INDEX: false, - BUILDER: 'html', - FILE_SUFFIX: '.html', - LINK_SUFFIX: '.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt', - NAVIGATION_WITH_KEYS: false, - SHOW_SEARCH_SUMMARY: true, - ENABLE_SEARCH_SHORTCUTS: true, -}; \ No newline at end of file diff --git a/pr-preview/pr-63/_static/file.png b/pr-preview/pr-63/_static/file.png deleted file mode 100644 index a858a410..00000000 Binary files a/pr-preview/pr-63/_static/file.png and /dev/null differ diff --git a/pr-preview/pr-63/_static/jquery.js b/pr-preview/pr-63/_static/jquery.js deleted file mode 100644 index c4c6022f..00000000 --- a/pr-preview/pr-63/_static/jquery.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/pr-preview/pr-63/_static/js/html5shiv.min.js b/pr-preview/pr-63/_static/js/html5shiv.min.js deleted file mode 100644 index cd1c674f..00000000 --- a/pr-preview/pr-63/_static/js/html5shiv.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/** -* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed -*/ -!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/pr-preview/pr-63/_static/js/theme.js b/pr-preview/pr-63/_static/js/theme.js deleted file mode 100644 index 1fddb6ee..00000000 --- a/pr-preview/pr-63/_static/js/theme.js +++ /dev/null @@ -1 +0,0 @@ -!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 - var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 - var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 - var s_v = "^(" + C + ")?" + v; // vowel in stem - - this.stemWord = function (w) { - var stem; - var suffix; - var firstch; - var origword = w; - - if (w.length < 3) - return w; - - var re; - var re2; - var re3; - var re4; - - firstch = w.substr(0,1); - if (firstch == "y") - w = firstch.toUpperCase() + w.substr(1); - - // Step 1a - re = /^(.+?)(ss|i)es$/; - re2 = /^(.+?)([^s])s$/; - - if (re.test(w)) - w = w.replace(re,"$1$2"); - else if (re2.test(w)) - w = w.replace(re2,"$1$2"); - - // Step 1b - re = /^(.+?)eed$/; - re2 = /^(.+?)(ed|ing)$/; - if (re.test(w)) { - var fp = re.exec(w); - re = new RegExp(mgr0); - if (re.test(fp[1])) { - re = /.$/; - w = w.replace(re,""); - } - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1]; - re2 = new RegExp(s_v); - if (re2.test(stem)) { - w = stem; - re2 = /(at|bl|iz)$/; - re3 = new RegExp("([^aeiouylsz])\\1$"); - re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re2.test(w)) - w = w + "e"; - else if (re3.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - else if (re4.test(w)) - w = w + "e"; - } - } - - // Step 1c - re = /^(.+?)y$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(s_v); - if (re.test(stem)) - w = stem + "i"; - } - - // Step 2 - re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step2list[suffix]; - } - - // Step 3 - re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step3list[suffix]; - } - - // Step 4 - re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; - re2 = /^(.+?)(s|t)(ion)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - if (re.test(stem)) - w = stem; - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1] + fp[2]; - re2 = new RegExp(mgr1); - if (re2.test(stem)) - w = stem; - } - - // Step 5 - re = /^(.+?)e$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - re2 = new RegExp(meq1); - re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) - w = stem; - } - re = /ll$/; - re2 = new RegExp(mgr1); - if (re.test(w) && re2.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - - // and turn initial Y back to y - if (firstch == "y") - w = firstch.toLowerCase() + w.substr(1); - return w; - } -} - diff --git a/pr-preview/pr-63/_static/minus.png b/pr-preview/pr-63/_static/minus.png deleted file mode 100644 index d96755fd..00000000 Binary files a/pr-preview/pr-63/_static/minus.png and /dev/null differ diff --git a/pr-preview/pr-63/_static/plus.png b/pr-preview/pr-63/_static/plus.png deleted file mode 100644 index 7107cec9..00000000 Binary files a/pr-preview/pr-63/_static/plus.png and /dev/null differ diff --git a/pr-preview/pr-63/_static/processing-chain-favicon.ico b/pr-preview/pr-63/_static/processing-chain-favicon.ico deleted file mode 100644 index 95d31d5d..00000000 Binary files a/pr-preview/pr-63/_static/processing-chain-favicon.ico and /dev/null differ diff --git a/pr-preview/pr-63/_static/processing-chain-logo-notext.png b/pr-preview/pr-63/_static/processing-chain-logo-notext.png deleted file mode 100644 index 9f870bf7..00000000 Binary files a/pr-preview/pr-63/_static/processing-chain-logo-notext.png and /dev/null differ diff --git a/pr-preview/pr-63/_static/processing-chain-logo-small.png b/pr-preview/pr-63/_static/processing-chain-logo-small.png deleted file mode 100644 index dc81a858..00000000 Binary files a/pr-preview/pr-63/_static/processing-chain-logo-small.png and /dev/null differ diff --git a/pr-preview/pr-63/_static/processing-chain-logo.png b/pr-preview/pr-63/_static/processing-chain-logo.png deleted file mode 100644 index c7e2dc93..00000000 Binary files a/pr-preview/pr-63/_static/processing-chain-logo.png and /dev/null differ diff --git a/pr-preview/pr-63/_static/processing_chain_workflow_icon_art.png b/pr-preview/pr-63/_static/processing_chain_workflow_icon_art.png deleted file mode 100644 index 4a5164d0..00000000 Binary files a/pr-preview/pr-63/_static/processing_chain_workflow_icon_art.png and /dev/null differ diff --git a/pr-preview/pr-63/_static/pygments.css b/pr-preview/pr-63/_static/pygments.css deleted file mode 100644 index 0d49244e..00000000 --- a/pr-preview/pr-63/_static/pygments.css +++ /dev/null @@ -1,75 +0,0 @@ -pre { line-height: 125%; } -td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } -span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } -td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } -span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } -.highlight .hll { background-color: #ffffcc } -.highlight { background: #eeffcc; } -.highlight .c { color: #408090; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ -.highlight .k { color: #007020; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ -.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #007020 } /* Comment.Preproc */ -.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ -.highlight .gd { color: #A00000 } /* Generic.Deleted */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ -.highlight .gr { color: #FF0000 } /* Generic.Error */ -.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #333333 } /* Generic.Output */ -.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ -.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ -.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { color: #007020 } /* Keyword.Pseudo */ -.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #902000 } /* Keyword.Type */ -.highlight .m { color: #208050 } /* Literal.Number */ -.highlight .s { color: #4070a0 } /* Literal.String */ -.highlight .na { color: #4070a0 } /* Name.Attribute */ -.highlight .nb { color: #007020 } /* Name.Builtin */ -.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ -.highlight .no { color: #60add5 } /* Name.Constant */ -.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ -.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #007020 } /* Name.Exception */ -.highlight .nf { color: #06287e } /* Name.Function */ -.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ -.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ -.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #bb60d5 } /* Name.Variable */ -.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mb { color: #208050 } /* Literal.Number.Bin */ -.highlight .mf { color: #208050 } /* Literal.Number.Float */ -.highlight .mh { color: #208050 } /* Literal.Number.Hex */ -.highlight .mi { color: #208050 } /* Literal.Number.Integer */ -.highlight .mo { color: #208050 } /* Literal.Number.Oct */ -.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ -.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ -.highlight .sc { color: #4070a0 } /* Literal.String.Char */ -.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ -.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ -.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ -.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ -.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ -.highlight .sx { color: #c65d09 } /* Literal.String.Other */ -.highlight .sr { color: #235388 } /* Literal.String.Regex */ -.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ -.highlight .ss { color: #517918 } /* Literal.String.Symbol */ -.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #06287e } /* Name.Function.Magic */ -.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ -.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ -.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ -.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ -.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/pr-preview/pr-63/_static/searchtools.js b/pr-preview/pr-63/_static/searchtools.js deleted file mode 100644 index 97d56a74..00000000 --- a/pr-preview/pr-63/_static/searchtools.js +++ /dev/null @@ -1,566 +0,0 @@ -/* - * searchtools.js - * ~~~~~~~~~~~~~~~~ - * - * Sphinx JavaScript utilities for the full-text search. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ -"use strict"; - -/** - * Simple result scoring code. - */ -if (typeof Scorer === "undefined") { - var Scorer = { - // Implement the following function to further tweak the score for each result - // The function takes a result array [docname, title, anchor, descr, score, filename] - // and returns the new score. - /* - score: result => { - const [docname, title, anchor, descr, score, filename] = result - return score - }, - */ - - // query matches the full name of an object - objNameMatch: 11, - // or matches in the last dotted part of the object name - objPartialMatch: 6, - // Additive scores depending on the priority of the object - objPrio: { - 0: 15, // used to be importantResults - 1: 5, // used to be objectResults - 2: -5, // used to be unimportantResults - }, - // Used when the priority is not in the mapping. - objPrioDefault: 0, - - // query found in title - title: 15, - partialTitle: 7, - // query found in terms - term: 5, - partialTerm: 2, - }; -} - -const _removeChildren = (element) => { - while (element && element.lastChild) element.removeChild(element.lastChild); -}; - -/** - * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping - */ -const _escapeRegExp = (string) => - string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string - -const _displayItem = (item, searchTerms) => { - const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; - const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; - const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; - const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; - const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; - - const [docName, title, anchor, descr, score, _filename] = item; - - let listItem = document.createElement("li"); - let requestUrl; - let linkUrl; - if (docBuilder === "dirhtml") { - // dirhtml builder - let dirname = docName + "/"; - if (dirname.match(/\/index\/$/)) - dirname = dirname.substring(0, dirname.length - 6); - else if (dirname === "index/") dirname = ""; - requestUrl = docUrlRoot + dirname; - linkUrl = requestUrl; - } else { - // normal html builders - requestUrl = docUrlRoot + docName + docFileSuffix; - linkUrl = docName + docLinkSuffix; - } - let linkEl = listItem.appendChild(document.createElement("a")); - linkEl.href = linkUrl + anchor; - linkEl.dataset.score = score; - linkEl.innerHTML = title; - if (descr) - listItem.appendChild(document.createElement("span")).innerHTML = - " (" + descr + ")"; - else if (showSearchSummary) - fetch(requestUrl) - .then((responseData) => responseData.text()) - .then((data) => { - if (data) - listItem.appendChild( - Search.makeSearchSummary(data, searchTerms) - ); - }); - Search.output.appendChild(listItem); -}; -const _finishSearch = (resultCount) => { - Search.stopPulse(); - Search.title.innerText = _("Search Results"); - if (!resultCount) - Search.status.innerText = Documentation.gettext( - "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." - ); - else - Search.status.innerText = _( - `Search finished, found ${resultCount} page(s) matching the search query.` - ); -}; -const _displayNextItem = ( - results, - resultCount, - searchTerms -) => { - // results left, load the summary and display it - // this is intended to be dynamic (don't sub resultsCount) - if (results.length) { - _displayItem(results.pop(), searchTerms); - setTimeout( - () => _displayNextItem(results, resultCount, searchTerms), - 5 - ); - } - // search finished, update title and status message - else _finishSearch(resultCount); -}; - -/** - * Default splitQuery function. Can be overridden in ``sphinx.search`` with a - * custom function per language. - * - * The regular expression works by splitting the string on consecutive characters - * that are not Unicode letters, numbers, underscores, or emoji characters. - * This is the same as ``\W+`` in Python, preserving the surrogate pair area. - */ -if (typeof splitQuery === "undefined") { - var splitQuery = (query) => query - .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) - .filter(term => term) // remove remaining empty strings -} - -/** - * Search Module - */ -const Search = { - _index: null, - _queued_query: null, - _pulse_status: -1, - - htmlToText: (htmlString) => { - const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); - htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); - const docContent = htmlElement.querySelector('[role="main"]'); - if (docContent !== undefined) return docContent.textContent; - console.warn( - "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." - ); - return ""; - }, - - init: () => { - const query = new URLSearchParams(window.location.search).get("q"); - document - .querySelectorAll('input[name="q"]') - .forEach((el) => (el.value = query)); - if (query) Search.performSearch(query); - }, - - loadIndex: (url) => - (document.body.appendChild(document.createElement("script")).src = url), - - setIndex: (index) => { - Search._index = index; - if (Search._queued_query !== null) { - const query = Search._queued_query; - Search._queued_query = null; - Search.query(query); - } - }, - - hasIndex: () => Search._index !== null, - - deferQuery: (query) => (Search._queued_query = query), - - stopPulse: () => (Search._pulse_status = -1), - - startPulse: () => { - if (Search._pulse_status >= 0) return; - - const pulse = () => { - Search._pulse_status = (Search._pulse_status + 1) % 4; - Search.dots.innerText = ".".repeat(Search._pulse_status); - if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); - }; - pulse(); - }, - - /** - * perform a search for something (or wait until index is loaded) - */ - performSearch: (query) => { - // create the required interface elements - const searchText = document.createElement("h2"); - searchText.textContent = _("Searching"); - const searchSummary = document.createElement("p"); - searchSummary.classList.add("search-summary"); - searchSummary.innerText = ""; - const searchList = document.createElement("ul"); - searchList.classList.add("search"); - - const out = document.getElementById("search-results"); - Search.title = out.appendChild(searchText); - Search.dots = Search.title.appendChild(document.createElement("span")); - Search.status = out.appendChild(searchSummary); - Search.output = out.appendChild(searchList); - - const searchProgress = document.getElementById("search-progress"); - // Some themes don't use the search progress node - if (searchProgress) { - searchProgress.innerText = _("Preparing search..."); - } - Search.startPulse(); - - // index already loaded, the browser was quick! - if (Search.hasIndex()) Search.query(query); - else Search.deferQuery(query); - }, - - /** - * execute search (requires search index to be loaded) - */ - query: (query) => { - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const titles = Search._index.titles; - const allTitles = Search._index.alltitles; - const indexEntries = Search._index.indexentries; - - // stem the search terms and add them to the correct list - const stemmer = new Stemmer(); - const searchTerms = new Set(); - const excludedTerms = new Set(); - const highlightTerms = new Set(); - const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); - splitQuery(query.trim()).forEach((queryTerm) => { - const queryTermLower = queryTerm.toLowerCase(); - - // maybe skip this "word" - // stopwords array is from language_data.js - if ( - stopwords.indexOf(queryTermLower) !== -1 || - queryTerm.match(/^\d+$/) - ) - return; - - // stem the word - let word = stemmer.stemWord(queryTermLower); - // select the correct list - if (word[0] === "-") excludedTerms.add(word.substr(1)); - else { - searchTerms.add(word); - highlightTerms.add(queryTermLower); - } - }); - - if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js - localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) - } - - // console.debug("SEARCH: searching for:"); - // console.info("required: ", [...searchTerms]); - // console.info("excluded: ", [...excludedTerms]); - - // array of [docname, title, anchor, descr, score, filename] - let results = []; - _removeChildren(document.getElementById("search-progress")); - - const queryLower = query.toLowerCase(); - for (const [title, foundTitles] of Object.entries(allTitles)) { - if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { - for (const [file, id] of foundTitles) { - let score = Math.round(100 * queryLower.length / title.length) - results.push([ - docNames[file], - titles[file] !== title ? `${titles[file]} > ${title}` : title, - id !== null ? "#" + id : "", - null, - score, - filenames[file], - ]); - } - } - } - - // search for explicit entries in index directives - for (const [entry, foundEntries] of Object.entries(indexEntries)) { - if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { - for (const [file, id] of foundEntries) { - let score = Math.round(100 * queryLower.length / entry.length) - results.push([ - docNames[file], - titles[file], - id ? "#" + id : "", - null, - score, - filenames[file], - ]); - } - } - } - - // lookup as object - objectTerms.forEach((term) => - results.push(...Search.performObjectSearch(term, objectTerms)) - ); - - // lookup as search terms in fulltext - results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); - - // let the scorer override scores with a custom scoring function - if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); - - // now sort the results by score (in opposite order of appearance, since the - // display function below uses pop() to retrieve items) and then - // alphabetically - results.sort((a, b) => { - const leftScore = a[4]; - const rightScore = b[4]; - if (leftScore === rightScore) { - // same score: sort alphabetically - const leftTitle = a[1].toLowerCase(); - const rightTitle = b[1].toLowerCase(); - if (leftTitle === rightTitle) return 0; - return leftTitle > rightTitle ? -1 : 1; // inverted is intentional - } - return leftScore > rightScore ? 1 : -1; - }); - - // remove duplicate search results - // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept - let seen = new Set(); - results = results.reverse().reduce((acc, result) => { - let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); - if (!seen.has(resultStr)) { - acc.push(result); - seen.add(resultStr); - } - return acc; - }, []); - - results = results.reverse(); - - // for debugging - //Search.lastresults = results.slice(); // a copy - // console.info("search results:", Search.lastresults); - - // print the results - _displayNextItem(results, results.length, searchTerms); - }, - - /** - * search for object names - */ - performObjectSearch: (object, objectTerms) => { - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const objects = Search._index.objects; - const objNames = Search._index.objnames; - const titles = Search._index.titles; - - const results = []; - - const objectSearchCallback = (prefix, match) => { - const name = match[4] - const fullname = (prefix ? prefix + "." : "") + name; - const fullnameLower = fullname.toLowerCase(); - if (fullnameLower.indexOf(object) < 0) return; - - let score = 0; - const parts = fullnameLower.split("."); - - // check for different match types: exact matches of full name or - // "last name" (i.e. last dotted part) - if (fullnameLower === object || parts.slice(-1)[0] === object) - score += Scorer.objNameMatch; - else if (parts.slice(-1)[0].indexOf(object) > -1) - score += Scorer.objPartialMatch; // matches in last name - - const objName = objNames[match[1]][2]; - const title = titles[match[0]]; - - // If more than one term searched for, we require other words to be - // found in the name/title/description - const otherTerms = new Set(objectTerms); - otherTerms.delete(object); - if (otherTerms.size > 0) { - const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); - if ( - [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) - ) - return; - } - - let anchor = match[3]; - if (anchor === "") anchor = fullname; - else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; - - const descr = objName + _(", in ") + title; - - // add custom score for some objects according to scorer - if (Scorer.objPrio.hasOwnProperty(match[2])) - score += Scorer.objPrio[match[2]]; - else score += Scorer.objPrioDefault; - - results.push([ - docNames[match[0]], - fullname, - "#" + anchor, - descr, - score, - filenames[match[0]], - ]); - }; - Object.keys(objects).forEach((prefix) => - objects[prefix].forEach((array) => - objectSearchCallback(prefix, array) - ) - ); - return results; - }, - - /** - * search for full-text terms in the index - */ - performTermsSearch: (searchTerms, excludedTerms) => { - // prepare search - const terms = Search._index.terms; - const titleTerms = Search._index.titleterms; - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const titles = Search._index.titles; - - const scoreMap = new Map(); - const fileMap = new Map(); - - // perform the search on the required terms - searchTerms.forEach((word) => { - const files = []; - const arr = [ - { files: terms[word], score: Scorer.term }, - { files: titleTerms[word], score: Scorer.title }, - ]; - // add support for partial matches - if (word.length > 2) { - const escapedWord = _escapeRegExp(word); - Object.keys(terms).forEach((term) => { - if (term.match(escapedWord) && !terms[word]) - arr.push({ files: terms[term], score: Scorer.partialTerm }); - }); - Object.keys(titleTerms).forEach((term) => { - if (term.match(escapedWord) && !titleTerms[word]) - arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); - }); - } - - // no match but word was a required one - if (arr.every((record) => record.files === undefined)) return; - - // found search word in contents - arr.forEach((record) => { - if (record.files === undefined) return; - - let recordFiles = record.files; - if (recordFiles.length === undefined) recordFiles = [recordFiles]; - files.push(...recordFiles); - - // set score for the word in each file - recordFiles.forEach((file) => { - if (!scoreMap.has(file)) scoreMap.set(file, {}); - scoreMap.get(file)[word] = record.score; - }); - }); - - // create the mapping - files.forEach((file) => { - if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) - fileMap.get(file).push(word); - else fileMap.set(file, [word]); - }); - }); - - // now check if the files don't contain excluded terms - const results = []; - for (const [file, wordList] of fileMap) { - // check if all requirements are matched - - // as search terms with length < 3 are discarded - const filteredTermCount = [...searchTerms].filter( - (term) => term.length > 2 - ).length; - if ( - wordList.length !== searchTerms.size && - wordList.length !== filteredTermCount - ) - continue; - - // ensure that none of the excluded terms is in the search result - if ( - [...excludedTerms].some( - (term) => - terms[term] === file || - titleTerms[term] === file || - (terms[term] || []).includes(file) || - (titleTerms[term] || []).includes(file) - ) - ) - break; - - // select one (max) score for the file. - const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); - // add result to the result list - results.push([ - docNames[file], - titles[file], - "", - null, - score, - filenames[file], - ]); - } - return results; - }, - - /** - * helper function to return a node containing the - * search summary for a given text. keywords is a list - * of stemmed words. - */ - makeSearchSummary: (htmlText, keywords) => { - const text = Search.htmlToText(htmlText); - if (text === "") return null; - - const textLower = text.toLowerCase(); - const actualStartPosition = [...keywords] - .map((k) => textLower.indexOf(k.toLowerCase())) - .filter((i) => i > -1) - .slice(-1)[0]; - const startWithContext = Math.max(actualStartPosition - 120, 0); - - const top = startWithContext === 0 ? "" : "..."; - const tail = startWithContext + 240 < text.length ? "..." : ""; - - let summary = document.createElement("p"); - summary.classList.add("context"); - summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; - - return summary; - }, -}; - -_ready(Search.init); diff --git a/pr-preview/pr-63/_static/sphinx_highlight.js b/pr-preview/pr-63/_static/sphinx_highlight.js deleted file mode 100644 index aae669d7..00000000 --- a/pr-preview/pr-63/_static/sphinx_highlight.js +++ /dev/null @@ -1,144 +0,0 @@ -/* Highlighting utilities for Sphinx HTML documentation. */ -"use strict"; - -const SPHINX_HIGHLIGHT_ENABLED = true - -/** - * highlight a given string on a node by wrapping it in - * span elements with the given class name. - */ -const _highlight = (node, addItems, text, className) => { - if (node.nodeType === Node.TEXT_NODE) { - const val = node.nodeValue; - const parent = node.parentNode; - const pos = val.toLowerCase().indexOf(text); - if ( - pos >= 0 && - !parent.classList.contains(className) && - !parent.classList.contains("nohighlight") - ) { - let span; - - const closestNode = parent.closest("body, svg, foreignObject"); - const isInSVG = closestNode && closestNode.matches("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.classList.add(className); - } - - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - parent.insertBefore( - span, - parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling - ) - ); - node.nodeValue = val.substr(0, pos); - - if (isInSVG) { - const rect = document.createElementNS( - "http://www.w3.org/2000/svg", - "rect" - ); - const bbox = parent.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute("class", className); - addItems.push({ parent: parent, target: rect }); - } - } - } else if (node.matches && !node.matches("button, select, textarea")) { - node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); - } -}; -const _highlightText = (thisNode, text, className) => { - let addItems = []; - _highlight(thisNode, addItems, text, className); - addItems.forEach((obj) => - obj.parent.insertAdjacentElement("beforebegin", obj.target) - ); -}; - -/** - * Small JavaScript module for the documentation. - */ -const SphinxHighlight = { - - /** - * highlight the search words provided in localstorage in the text - */ - highlightSearchWords: () => { - if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight - - // get and clear terms from localstorage - const url = new URL(window.location); - const highlight = - localStorage.getItem("sphinx_highlight_terms") - || url.searchParams.get("highlight") - || ""; - localStorage.removeItem("sphinx_highlight_terms") - url.searchParams.delete("highlight"); - window.history.replaceState({}, "", url); - - // get individual terms from highlight string - const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); - if (terms.length === 0) return; // nothing to do - - // There should never be more than one element matching "div.body" - const divBody = document.querySelectorAll("div.body"); - const body = divBody.length ? divBody[0] : document.querySelector("body"); - window.setTimeout(() => { - terms.forEach((term) => _highlightText(body, term, "highlighted")); - }, 10); - - const searchBox = document.getElementById("searchbox"); - if (searchBox === null) return; - searchBox.appendChild( - document - .createRange() - .createContextualFragment( - '" - ) - ); - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords: () => { - document - .querySelectorAll("#searchbox .highlight-link") - .forEach((el) => el.remove()); - document - .querySelectorAll("span.highlighted") - .forEach((el) => el.classList.remove("highlighted")); - localStorage.removeItem("sphinx_highlight_terms") - }, - - initEscapeListener: () => { - // only install a listener if it is really needed - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; - - document.addEventListener("keydown", (event) => { - // bail for input elements - if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; - // bail with special keys - if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; - if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { - SphinxHighlight.hideSearchWords(); - event.preventDefault(); - } - }); - }, -}; - -_ready(SphinxHighlight.highlightSearchWords); -_ready(SphinxHighlight.initEscapeListener); diff --git a/pr-preview/pr-63/code-structure.html b/pr-preview/pr-63/code-structure.html deleted file mode 100644 index ac0688ce..00000000 --- a/pr-preview/pr-63/code-structure.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - Code Structure — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Code Structure

-

The Processing Chain code is structured as follows:

-
$ tree -L 3 -F --dirsfirst
-.
-├── cases/                      # folder where all cases are stored
-│   ├── cosmo-ghg-spinup-test/  # COSMO-GHG test case with spinup restart
-│      ├── config.yaml         # case configuration file
-│      ├── *.cfg               # templates for namelists & batch jobs
-│      └── *.csv               # CSV files with tracer information
-│   ├── cosmo-ghg-test/         # COSMO-GHG testcase with standard restart
-│      ├── config.yaml
-│      ├── *.cfg
-│      └── *.csv
-│   ├── icon-art-global-test/   # ICON-ART test case (global domain)
-│      ├── config.yaml
-│      ├── icon_runjob.cfg     # template for ICON-ART runjob
-│      ├── *.sh                # pre-processing scripts
-│      └── mypartab
-│   ├── icon-art-oem-test/      # ICON-ART test case with online emissions
-│      ├── config.yaml
-│      └── *.cfg
-│   └── icon-test/              # ICON test case
-│       ├── config.yaml
-│       └── *.cfg
-├── docs/                       # folder for Sphinx documentation
-│   ├── _static/                # folder for static assets
-│      ├── custom.css          # custom CSS styles
-│      └── *.png|ico           # additional image assets
-│   ├── tables/                 # folder for tables used in documentation
-│      └── *.csv               # CSV files containing table data
-│   ├── conf.py                 # configuration file for the Sphinx builder
-│   └── *.rst                   # documentation files (reStructuredText)
-├── env/
-│   └── environment.yml         # conda environment file
-├── ext/                        # folder for other code (spack, models, etc.)
-├── jenkins/                    # automated Jenkins testing
-│   ├── scripts/
-│      └── *.sh                # individual Shell scripts for testing
-│   └── Jenkinsfile             # text file containing the Jenkins pipeline
-├── jobs/
-│   ├── tools/
-│      └── *.py                # tool scripts
-│   └── *.py                    # job scripts
-├── LICENSE                     # license file
-├── README.md                   # README file
-├── config.py                   # file containing the Config class
-├── run_chain.py                # main script
-└── workflows.yaml              # file to store workflows with job dependencies
-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/config.html b/pr-preview/pr-63/config.html deleted file mode 100644 index 78e49e57..00000000 --- a/pr-preview/pr-63/config.html +++ /dev/null @@ -1,459 +0,0 @@ - - - - - - - Configuration File — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -

The Processing Chain uses cases to describe a simulation. A case is a -subdirectory in cases/, containing a config.yaml and several -namelist (e.g., int2lm_INPUT.cfg) and runscripts (e.g., -icon_runjob.cfg) templates, -which define the simulation.

-
-

Configuration File

-

The case-dependent configuration file <casename>/config.yaml contains most -of the information that the jobs need to prepare -and run the simulation, for example the location of the input data. -This configuration file is loaded in run_chain.py as an instance -of the Config() class in config.py.

-
-

Configuration Variables

-

This is a non-exhaustive list containing the most important configuration variables:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Variable

Description

-
case_path
-

-
-
-
The path to the case directory under cases/ for the specified
-
casename.
-
-

casename

The name of the case. Derived from the folder name under case_path.

-
chain_src_dir
-

-
-
-
The source directory for the processing chain, typically the current
-
working directory.
-
-

compute_account

The compute account to be used based on user information.

constraint

The computational constraint (gpu or mc).

-
email
-

-
-
-
The user’s email address, initially set to None and updated using the
-
set_email method.
-
-
-
enddate
-

-
-
-
The end date of the simulation in ISO 8601 format
-
(YYYY-MM-DDTHH:mm:ssZ).
-
-

jobs

List of job-names to be executed.

log_finished_dir

The directory for finished log files.

log_working_dir

The directory for working log files.

ntasks_per_node

The number of tasks per node, based on the node type.

restart_step

The restart step in ISO 8601 format.

restart_step_hours

The restart step in hours, derived from the restart_step attribute.

run_on

The architecture the model runs on (cpu or gpu).

spinup

Spin-up duration in hours. Activates spinup behavior if set.

-
startdate
-

-
-
-
The start date of the simulation in ISO 8601 format
-
(YYYY-MM-DDTHH:mm:ssZ).
-
-

user_mail

The user’s email address, determined based on system configuration.

-
user_name
-

-
-
-
Your email address to receive notifications. Either provide it
-
directly here or in ~/.forward.
-
-

workflow

The name of the workflow from workflows.yaml or a self-defined one.

-
work_root
-

-
-
-
The working directory where all output is stored. Should be somewhere
-
on $SCRATCH$. By default, it is set to <chain_src_dir>/work.
-
-
-
-
-

Variables to Set in config.yaml

-

Here are two examples of which general variables should be set by the user in the -case configuration file.

-
-

Header of config.yaml for the cosmo-ghg-spinup-test case

-
workflow: cosmo-ghg
-constraint: gpu
-ntasks_per_node: 12
-restart_step: PT6H
-spinup: 3
-startdate: 2015-01-01T00:00:00Z
-enddate: 2015-01-01T18:00:00Z
-
-
-
-
-

Header of config.yaml for the icon-art-oem-test case

-
workflow: icon-art-oem
-constraint: gpu
-run_on: cpu
-compute_queue: normal
-ntasks_per_node: 12
-restart_step: PT6H
-startdate: 2018-01-01T00:00:00Z
-enddate: 2018-01-01T12:00:00Z
-
-eccodes_dir: ./input/eccodes_definitions
-iconremap_bin: iconremap
-iconsub_bin: iconsub
-latbc_filename: ifs_<y><m><d><h>_lbc.nc
-inidata_prefix: ifs_init_
-inidata_nameformat: '%Y%m%d%H'
-inidata_filename_suffix: .nc
-output_filename: icon-art-oem-test
-filename_format: <output_filename>_DOM<physdom>_<ddhhmmss>
-lateral_boundary_grid_order: lateral_boundary
-art_input_folder: ./input/icon-art-oem/ART
-
-
-
-
-

Further variables

-

Furthermore, there are additional variables to set that are tied to the individual jobs. -These config variables themselves are dictionaries. Let’s have a look at and example -for the the cfg.meteo variable:

-
meteo:
-    dir: ./input/cosmo-ghg/meteo
-    prefix: laf
-    nameformat: laf%Y%m%d%H
-    inc: 1
-
-
-

These config variables can be accessed via cfg.meteo['dir'], cfg.meteo['prefix'], etc. -as they are Python dictionaries.

-
-

Hint

-

In namelist and runscript template files -(see next section), this accessing does not work because of how the .format() -method is implemented in Python. For that reason, the Processing Chain automatically -creates new variables in the form of cfg.meteo_dir, cfg.meteo_prefix, etc. -at the start to make them accessible for namelist and runjob templates.

-
-
-

List of dictionary variables

-

The following is a list of dictionary variables that exist for the Processing Chain. -For the individual elements of those variables, please refer to the config.yaml -files within the test cases.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Dictionary variable

Used in job

meteo

prepare_cosmo, prepare_icon, icontools, int2lm, icon

icontools_runjobs

icontools

input_files

prepare_icon

chem

prepare_icon

era5

prepare_icon

cams

prepare_cosmo

emissions

emissions

vprm

biofluxes

oem

oem, cosmo

online_vprm

online_vprm

int2lm

prepare_cosmo, emissions, biofluxes, octe, int2lm, post_int2lm, cosmo, post_cosmo

post_int2lm

post_int2lm

cosmo

reduce_output, oem, photo_rate, octe, check_output, post_cosmo, cosmo, obs_nudging, online_vprm

reduce_output

reduce_output

post_cosmo

post_cosmo

verify_chain

verify_chain

icon

oem, prepare_icon, icon

-
-
-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/environment.html b/pr-preview/pr-63/environment.html deleted file mode 100644 index 132c3256..00000000 --- a/pr-preview/pr-63/environment.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - - Conda Environment — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Conda Environment

-

The following steps allow you to create and use your own virtual environment to run the Processing Chain. We recommend using a conda environment for the usage of the provided scripts. Please follow the instructions for the installation. The following steps only need to be performed once.

-
-

1. Install Miniconda

-

Install Miniconda as user-specific Miniconda, e.g., in your $HOME directory, which is the default location.

-
-

Note

-

Only conda itself should be installed in your $HOME. All environments should be stored in your $PROJECT directory; otherwise, you risk filling up your $HOME directory. See below for instructions.

-
-

To install the latest Miniconda, type:

-
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
-bash Miniconda3-latest-Linux-x86_64.sh
-
-
-

Further details on Miniconda can be found on the Miniconda documentation page.

-
-
-

2. Create the Conda Environment

-

Create a conda environment proc-chain and install the requirements:

-
conda env create --prefix $PROJECT/envs/proc-chain -f env/environment.yml
-
-
-

To be able to activate your conda environment by simply using conda activate proc-chain instead of the full path, add the following to your .bashrc:

-
export CONDA_ENVS_PATH=$PROJECT/envs
-
-
-

Activate the environment (use “source activate” in case “conda activate” does not work):

-
conda activate proc-chain
-
-
-

If you already have the environment but want to update it:

-
conda env update --file env/environment.yml --prune
-
-
-
-
-

3. Store user-specific data

-

To register your email address and standard project account, store them in these files within your home directory:

-
echo <your_account_id> > ~/.acct
-echo <your_email_address> > ~/.forward
-
-
-

These settings are optional. The Processing Chain will first check the content of those files. If desired, the corresponding variables can be overridden by setting the compute_account and user_mail variables in the config.yaml file.

-
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/features.html b/pr-preview/pr-63/features.html deleted file mode 100644 index f4373e66..00000000 --- a/pr-preview/pr-63/features.html +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - - Feature Overview — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Feature Overview

-
    -
  • Asynchronous submission of compute jobs to the HPC queue

  • -
  • Intuitive definition of job dependencies

  • -
  • Automatic cycling over time periods including folder structure creation

  • -
  • Various jobs for pre- and post-processing steps

  • -
  • Using model built-in restarts or custom spinup

  • -
  • Nested runs possible

  • -
  • Easy creation of own cases and workflows

  • -
  • Various examples for COSMO and ICON workflows available

  • -
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/functions.html b/pr-preview/pr-63/functions.html deleted file mode 100644 index 0aad3a8d..00000000 --- a/pr-preview/pr-63/functions.html +++ /dev/null @@ -1,803 +0,0 @@ - - - - - - - Jobs — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Jobs

- -
-
-
-jobs.biofluxes.main(cfg)[source]
-

Prepare biofluxes files for COSMO simulations.

-

Copies biofluxes files from the project folder (cfg.vprm['dir']) -to the int2lm input folder on scratch (cfg.int2lm_input/vprm).

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.check_output.main(cfg)[source]
-

Check output variables for physical reasonability and create plots.

-

This function checks the output variables to ensure they are in a physically -reasonable range. It stores the time series of the minimum, maximum, mean, and -standard deviation of the variables as a pandas object into a pickle file.

-

It also creates per-variable plots from the stored time series data.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.cosmo.main(cfg)[source]
-

Setup the namelists for a COSMO run and submit the job to the queue.

-

Create necessary directory structure to run COSMO (run, output, and -restart directories, defined in cfg.cosmo_run, cfg.cosmo_output, -and cfg.cosmo_restart_out).

-

Copy the COSMO-executable from -cfg.cosmo['binary_file'] to cfg.cosmo_run/cfg.cosmo['execname'].

-

Convert the tracer csv file to a COSMO namelist file.

-

Format the COSMO namelist templates using the information in cfg.

-

Format the runscript template and submit the job.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.emissions.main(cfg)[source]
-

Copy emission files to the int2lm input directory.

-

Necessary for both COSMO and COSMOART simulations.

-

Copy emission files from project folder (cfg.emissions['dir']) to -int2lm input folder on scratch (cfg.int2lm_input/emissions).

-

For COSMO simulations, converts the netCDF-variable-names -from string to char (necessary for int2lm).

-

If there are multiple emission-datasets (cfg.emissions[‘dir’] is a list of -paths), they are copied as follows:

-
cfg.emissions['dir'][0]/cfg.emissions['gridname'][0]YYYYMMDD.nc -> int2lm_input/emissions/emis_YYYYMMDD.nc
-cfg.emissions['dir'][1]/cfg.emissions['gridname'][1]YYYYMMDD.nc -> int2lm_input/emissions2/emis_YYYYMMDD.nc
-cfg.emissions['dir'][2]/cfg.emissions['gridname'][2]YYYYMMDD.nc -> int2lm_input/emissions3/emis_YYYYMMDD.nc
-
-
-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.icon.main(cfg)[source]
-

Setup the namelists for an ICON run and submit the job to -the queue.

-

Copy the ICON-executable from -cfg.icon_binary_file to cfg.icon_work/icon.exe.

-

Format the ICON-namelist-templates: -icon_master.namelist.cfg, icon_NAMELIST_NWP.cfg, -using the information in cfg.

-

Format the runscript-template and submit the job.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.icontools.main(cfg)[source]
-
    -
  • Add GEOSP to all meteo files

  • -
  • Submit the runscript for the DWD ICON tools to remap the meteorological files.

  • -
  • All runscripts specified in cfg.icontools_runjobs are submitted.

  • -
  • The meteorological files are read from the original input directory -(cfg.input_root_meteo), and the remapped meteorological files are saved -in the input folder on scratch (cfg.icon_input/icbc).

  • -
-
- -
-
-
-jobs.int2lm.main(cfg)[source]
-

Setup the namelist for int2lm and submit the job to the queue.

-

Necessary for both COSMO and COSMOART simulations.

-

Decide if the soil model should be TERRA or TERRA multi-layer depending on -startdate of the simulation.

-

Create necessary directory structure to run int2lm (run and output -directories, defined in cfg.int2lm and cfg.int2lm['output']).

-

Copy the int2lm-executable from cfg.int2lm['binary_file'] to -cfg.int2lm['work']/int2lm.

-

Copy the extpar-file cfg.int2lm['extpar_file'] to -cfg.int2lm_run/work.

-

COSMOART: Copy the libgrib_api files to -cfg.int2lm['work']/libgrib_api.

-

COSMO: Convert the tracer-csv-files into an int2lm-namelist file.

-

Format the int2lm-namelist-template using the information in cfg.

-

Format the runscript-template and submit the job.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.obs_nudging.main(cfg)[source]
-

Copy and rename the obs_nudging files to the COSMO input directory.

-

In the folder cfg.obs_nudging_dir, the files are saved in the format -{prefix}-YYYYMMDD000000-YYYYMMDD000000. COSMO expects files in the -format {prefix}x, where x is [nothing], .2, .3, .4, .... This -job handles this filename-change and copies them to the COSMO input -folder on scratch (cfg.cosmo_input/obs_nudging).

-

Missing observation files are ignored.

-

Also copies the blacklist-file blklsttmp.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.octe.main(cfg)[source]
-

Copy necessary input files for COSMO and perturb BG.

-

Copies the NetCDF-files found at cfg.octe_maps and cfg.octe_lambdas to -the COSMO input-directory.

-

Perturbs the background tracer field. To do that, it reads the lambda-value -from the cfg.octe_lambdas (last value along the nparam-dimension) and -scales the BG-field produced by int2lm, creating a new variable for each -ensemble.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.oem.main(cfg)[source]
-

Copy emission and profile files to the cosmo or icon input -directory.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
Raises:
-

RuntimeError – If an error occurs during the process.

-
-
-
- -
-
-
-jobs.online_vprm.main(cfg)[source]
-

Copy MODIS surface reflectance data and vegetation class fraction file -to the cosmo input directory.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.photo_rate.main(cfg)[source]
-

Copy photolysis-rate file to the COSMOART input directory.

-

Only necessary for COSMOART simulations.

-

Copy the photolysis-rate file from the project (cfg.photo_rate_file) to -the COSMOART input folder on scratch (cfg.cosmo_input/art_photolysis).

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.post_cosmo.main(cfg)[source]
-

Copy the output of a COSMO-run to a user-defined position.

-

Write a runscript to copy all files (COSMO settings & output, -int2lm settings, logfiles) from cfg.cosmo_run, -cfg.cosmo_output, cfg.int2lm_run, cfg.log_finished_dir to -cfg.output_root/.... -If the job reduce_output has been run before post_cosmo, a -directory cfg.cosmo_output_reduced is created. In this case, -cfg.cosmo_output_reduced is copied instead of cfg.cosmo_output.

-

Submit the job to the xfer-queue.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.post_int2lm.main(cfg)[source]
-

Combine multiple int2lm tracer-output files into a single one for -COSMO.

-

Only necessary for COSMO simulations.

-

int2lm puts tracers into different netCDF files. Combine the files -specified in cfg.post_int2lm_species into a single netCDF file for -COSMO.

-

If cfg.spinup and cfg.post_int2lm_species_spinup are present, -also read in the specified variables and take them as an input for -COSMO.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
-
- -
-
-
-jobs.prepare_cosmo.main(cfg)[source]
-

COSMO Data Preparation

-

This function prepares input data for COSMO simulations by creating necessary directories, -copying meteorological files, and handling specific data processing.

-
    -
  • Copy meteorological files to int2lm input.

  • -
  • Create the necessary directory cfg.int2lm_input/meteo.

  • -
  • Copy meteorological files from the project directory (cfg.meteo['dir']/cfg.meteo['prefix']YYYYMMDDHH) -to the int2lm input folder on scratch (cfg.int2lm_input/meteo).

  • -
  • For nested runs (meteorological files are COSMO output: cfg.meteo['prefix'] == 'lffd'), -also copy the *c.nc-file with constant parameters.

  • -
-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
Raises:
-

RuntimeError – If any subprocess returns a non-zero exit code during execution.

-
-
-
- -
-
-
-jobs.prepare_icon.main(cfg)[source]
-

ICON Data Preparation

-

This function prepares input data for ICON simulations by creating necessary directories, -copying meteorological files, and handling specific data processing.

-
    -
  • Create working directories and copy input files

  • -
-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes.

-
-
Raises:
-

RuntimeError – If any subprocess returns a non-zero exit code during execution.

-
-
-
- -
-
-
-jobs.reduce_output.main(cfg)[source]
-

Calculates 2D column data and writes them into a new netCDF file. -Only a fixed number of levels from COSMO output are considered. -Those files are written into a new directory cosmo_output_reduced.

-

The number of levels is set by the configuration variable -cfg.reduce_output['output_levels'] (default = all levels).

-

Important: If several GRIBOUT sections are used to split the output -data, then this code only works in case of the following: -The tracers, for which the column-averaged dry-air (X) and -moist-air (Y) mole fractions are calculated, have to be

-
-
    -
  1. saved in a separate output file and

  2. -
  3. the output file appears alphabetically after the meteorological -variables.

  4. -
-
-

For example, use a GRIBOUT section suffix _met for standard COSMO -output, and _trc for tracers.

-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes

-
-
-
- -
-
-
-jobs.verify_chain.main(cfg)[source]
-

Compare outputs of the chain to a reference.

-

Looks for the reference-file in cfg.verify_chain['reference_dir'].

-

Looks for the output file in cfg.verify_chain['output_dir'] (if not None), else it -goes to the output directory created by the COSMO-job.

-

In the dict cfg.verify_chain['values_to_check'], the user specifies the names of the -files to be compared as keys, and the variables to compare as a list.

-

To compare the temperatures of the last output of the example case, the -following variables should be added to the config.yaml file:

-
verify_chain['reference_dir'] = os.path.join(input_root, "reference_output")
-verify_chain['output_dir'] = None
-verify_chain['values_to_check'] = {("reference_lffd2015010200.nc","lffd2015010200.nc"):
-      ['T']}
-
-
-
-
Parameters:
-

cfg (Config) – Object holding all user-configuration parameters as attributes

-
-
-
- -
-
-

Tools

-

The tools are a collection of functions used by the jobs. Most of those -functions are well documented and listed here. For others, one may take -a look into jobs/tools directly.

- -
-
-
-jobs.tools.cams4int2cosmo.main(date, inpath, outpath, param)[source]
-

Prepare CAMS CO2, CO and NOx boundary conditions for -int2lm/int2cosmo for the project SMARTCARB.

-

The CAMS data consists of

- -

The data sets are retrieved as individual 3-hourly files from the MARS -archive at ECMWF with names:

-
cams_0001_2015010500.nc   # for NO and NO2
-sfc_0001_2015010500.nc    # for log of surface pressure
-cams_gf39_2015010500.nc   # for CO and CO2
-sfc_gf39_2015010500.nc    # for log of surface pressure
-
-
-

The path to the directory of the CAMS data can optionally be supplied, -otherwise the script should be invoked in the directory of the CAMS data.

-

The script generates 8 individual 3-hourly IC/BC files:

-
cams_nox_yyyymmddhh.nc
-cams_co2_yyyymmddhh.nc
-
-
-

Usage:

-
python cams4int2cosmo.py date [-i inpath -o outpath]
-
-
-

Output:

-
-

cams_NOX_YYYYMMDD00.nc to cams_NOX_YYYYMMDD21.nc -cams_CO2_YYYYMMDD00.nc to cams_CO2_YYYYMMDD21.nc

-
-
-
Parameters:
-
    -
  • date (str) – date in format YYYYMMDD

  • -
  • inpath (str) – path of original CAMS files (default is current path)

  • -
  • outpath (str) – path where output files should be generated (default is current path)

  • -
  • param (dict) –

  • -
-
-
-
- -
-
-
-jobs.tools.check_model.check_model(cfg, model='COSMO')[source]
-

Check that the model specified in cfg matched the prescribed model.

-

Check that cfg.workflow_name == model. If not, raises a value-error. -Ignores capitalization of the strings

-
-
Parameters:
-
    -
  • cfg (Config) – Object holding all user-configuration parameters as attributes.

  • -
  • model (str) – Prescribed model

  • -
-
-
-
- -
-
-
-jobs.tools.comp_nc.datasets_equal(dataset1, dataset2, variables, verbose=True)[source]
-

Compare the contents of dataset1 and dataset2

-

Compare with numpy.isclose whether the two datasets are equal. No check for -equality (of the values or bitwise of the files) is performed, as numerical -errors can produce slightly different files for essentially identical -computations. Rather, the values are compared to absolute and relative -tolerances, check np.isclose documentation for more detail.

-

If variables is not empty, only the provided variables are compared.

-
-
Parameters:
-
    -
  • dataset1 (netCDF4.Dataset) –

  • -
  • dataset2 (netCDF4.Dataset) –

  • -
  • variables (list of str) – List of the variables to be compared. If it is empty, all variables -are compared.

  • -
  • verbose (bool) – If True, results will be printed to stdout.

  • -
-
-
Returns:
-

True if the datasets, or if provided the selected variables, are equal, -False otherwise.

-
-
Return type:
-

bool

-
-
-
- -
-
-
-jobs.tools.ctnoaa4int2cosmo.main(date, indir, outdir, param)[source]
-

Process all CarbonTracker files of a single date to a format -compatible with int2lm

-
-
Parameters:
-
    -
  • date (str) – date in format YYYYMMDD.

  • -
  • indir (str) – directory of original CarbonTracker files (default is current path).

  • -
  • outdir (str) – utput directory of processed files (default is indir/processed).

  • -
  • param (dict) – dictionary of the parameters

  • -
-
-
-
- -
-
-
-jobs.tools.mozart2int2lm.main(_, infile, outdir, params)[source]
-

Extract each timeslice from infile into seperate file in outdir.

-

Copies dimensions, renaming ‘lev’ -> ‘level’.

-

Copies, renames and combines variables (see source code for specifics).

-

Transforms ‘lon’ to [-180, 180) range.

-
-
Parameters:
-
    -
  • _ – Ignored

  • -
  • infile (str) – Path to file to extract from

  • -
  • outdir (str) – Path to the directory where the output files are written to

  • -
  • params (dict) – Only entry: ‘suffix’ -Processed files are stored as outdir/{suffix}_YYYYMMDDHH.nc

  • -
-
-
-
- -
-
-
-jobs.tools.reduce_output_start_end.main(indir, outdir, strdate_start, strdate_end, nout_levels, csvfile, convert_gas)[source]
-

Script to reduce output.

-

Output: TODO

-
-

Parameters (TODO)

-
-
opathstr

Output path where the processed data is going to be written

-
-
-
-
- -
-
-
-jobs.tools.string2char.main(filename)[source]
-

Convert the variable names of a netcdf-file from strings to a -np.array of chars.

-
-
Parameters:
-

filename (str) – Path to the netcdf-file

-
-
-
- -
-
-
-jobs.tools.vprmsplit.main(year, ipath, opath)[source]
-

Script to extract VPRM emissions for a single day -and to convert the output into an int2lm compatible format.

-

Output: -The script generates individual 1-hour emission files for the specified -year:

-
gpp_yyyymmddhh.nc
-ra_yyyymmddhh.nc
-
-
-
-
Parameters:
-
    -
  • year (str) – Year (YYYY) of data to be processed -The original VPRM input file (e.g., VPRM_ECMWF_*_2017.nc for 2017 -fluxes) needs to be present in the input directory ‘ipath’

  • -
  • ipath (str) – Input path where the VPRM input file is located

  • -
  • opath (str) – Output path where the processed data is going to be written

  • -
-
-
-
- -
-
-
-jobs.tools.write_cosmo_input_ghg.main(csv_filename, namelist_filename, cfg=None)[source]
-

Convert a table (.csv file) to namelist file (INPUT_GHG) -read by COSMO.

-
-
Parameters:
-
    -
  • csv_filename (str) – Path to the source csv-file

  • -
  • namelist_filename (str) – Path to the namelist file that will be created

  • -
  • cfg (Config) – Object holding all user-configuration parameters as attributes.

  • -
-
-
-
- -
-
-
-jobs.tools.write_int2lm_input_art.main(trcr_filename, set_filename, nml_filename, hstart=0)[source]
-

Write the INPUT_ART namelist file for int2lm from .csv files

-
-
Parameters:
-
    -
  • trcr_filename (str) – csv file with tracer definitions

  • -
  • set_filename (str) – csv file with tracer datasets

  • -
  • nml_filename (str) – output filename (INPUT_ART)

  • -
  • hstart (int) – meteorology spin up in hours

  • -
-
-
-
- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/genindex.html b/pr-preview/pr-63/genindex.html deleted file mode 100644 index fa16c53f..00000000 --- a/pr-preview/pr-63/genindex.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - Index — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/howtorun.html b/pr-preview/pr-63/howtorun.html deleted file mode 100644 index fb864f67..00000000 --- a/pr-preview/pr-63/howtorun.html +++ /dev/null @@ -1,473 +0,0 @@ - - - - - - - How to Run — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

How to Run

-

The Python file run_chain.py in the root directory is the main script of the -Processing Chain. -It reads the user’s input from the command line and from the config.yaml file of the -respective case. -Then it will start the Processing Chain.

-
-

Starting the Chain

-

The chain has to be run with the following command:

-
$ ./run_chain.py <casename>
-
-
-

Here, <casename> is the name of a directory in the cases/-directory where -there is a config.yaml-file specifying the configuration, as well as templates -for the necessary namelist files for int2lm, COSMO or ICON. It may also -contain additional runscripts to be submitted via sbatch.

-
-

Hint

-

Technically, you can run several cases (instead of a single case) in one command, -which is useful for nested runs, for example. This can be achieved by running -./run_chain.py <case1> <case2>. With that, the full chain is executed for -case1 first, and afterwards for case2.

-
-

There are several optional arguments available to change the behavior of the chain:

-
$ ./run_chain.py -h
-
-
-
    -
  • -
    -h, --help

    Show this help message and exit.

    -
    -
    -
  • -
  • -
    -j [JOB_LIST ...], --jobs [JOB_LIST ...]

    List of job names to be executed. -A job is a .py file in i``jobs/`` with a main() function, which -handles one aspect of the Processing Chain, for -example copying meteo input data or launching a -job for int2lm. Jobs are executed in the order -in which they are given here. If no jobs are -given, default jobs will be executed as defined -in config/models.yaml.

    -
    -
    -
  • -
  • -
    -f, --force

    Force the Processing Chain to redo all specified -jobs, even if they have been started already or -were finished previously. WARNING: Only logfiles -get deleted, other effects of a given job -(copied files etc.) are simply overwritten. This -may cause errors or unexpected behavior.

    -
    -
    -
  • -
  • -
    -r, --resume

    Resume the Processing Chain by restarting the -last unfinished job. WARNING: Only the logfile -gets deleted, other effects of a given job -(copied files etc.) are simply overwritten. This -may cause errors or unexpected behavior.

    -
    -
    -
  • -
-
-
-

What it Does

-

The script run_chain.py reads the command line arguments and the config file -from the specified case. -It then calls the function run_chain.restart_runs(), which divides the -simulation time according to the specified restart steps. Then it calls -run_chain.run_chunk() for each part (chunk) of the simulation workflow. -This function sets up the directory structure of the chain and then submits the -specified jobs via sbatch to the Slurm workload manager, -taking job dependencies into account.

-
-
-

Test Cases

-

The following test cases are available:

-
    -
  • cosmo-ghg-spinup-test

  • -
  • cosmo-ghg-test

  • -
  • icon-test

  • -
  • icon-art-oem-test

  • -
  • icon-art-global-test

  • -
-

To be able to run these test cases, it is necessary to provide the input data, -to setup spack and to compile the models and tools. All this is automized via -the script:

-
$ ./jenkins/scripts/jenkins.sh
-
-
-

This will run all the individual scripts in jenkins/scripts/, which -can also be launched separately if desired.

-

These cases undergo regulary testing to ensure that the Processing Chain runs -correctly. A corresponding Jenkins plan is launched on a weekly basis and -when triggered within a GitHub pull request.

-
-
-

Directory Structure

-

The directory structure generated by the Processing Chain for a cosmo-ghg -run looks like this:

-
cfg.work_root/cfg.casename/
-└── cfg.chain_root/
-    ├── checkpoints/
-       ├── cfg.log_working_dir/
-       ├── cfg.log_finished_dir/
-    ├── cfg.cosmo_base/
-       ├── cfg.cosmo_work/
-       ├── cfg.cosmo_output/
-       ├── cfg.cosmo_restart_out/
-    └── cfg.int2lm_base/
-        ├── cfg.int2lm_input/
-        ├── cfg.int2lm_work/
-        └── cfg.int2lm_output/
-
-
-

As one can see, it creates working directories for both the int2lm preprocessor -and cosmo. Additionally, and this is always the case, the checkpoints -directory holds all the job logfiles. Whenever a job has successfully finished, -the logfile is copied from the working to the finished sub-directory.

-

Running the cosmo-ghg-test case therefore produces the following -directories and files (showing four levels of directories deep):

-
work/cosmo-ghg-test
-├── 2015010100_2015010106/
-│   ├── checkpoints/
-│      ├── finished/
-│         ├── biofluxes
-│         ├── cosmo
-│         ├── emissions
-│         ├── int2lm
-│         ├── oem
-│         ├── online_vprm
-│         ├── post_cosmo
-│         ├── post_int2lm
-│         └── prepare_cosmo
-│      └── working/
-│          ├── biofluxes
-│          ├── cosmo
-│          ├── emissions
-│          ├── int2lm
-│          ├── oem
-│          ├── online_vprm
-│          ├── post_cosmo
-│          ├── post_int2lm
-│          └── prepare_cosmo
-│   ├── cosmo/
-│      ├── input/
-│         ├── oem/
-│         └── vprm/
-│      ├── output/
-│         └── lffd*.nc
-│      ├── restart/
-│         └── lrff00060000o.nc
-│      └── run/
-│          ├── cosmo-ghg
-│          ├── INPUT_*
-│          ├── post_cosmo.job
-│          ├── run.job
-│          └── YU*
-│   └── int2lm/
-│       ├── input/
-│          ├── emissions
-│          ├── extpar
-│          ├── icbc
-│          ├── meteo
-│          └── vprm
-│       ├── output/
-│          ├── laf*.nc
-│          └── lbfd*.nc
-│       └── run/
-│           ├── INPUT
-│           ├── INPUT_ART
-│           ├── int2lm
-│           ├── OUTPUT
-│           ├── run.job
-│           └── YU*
-└── 2015010106_2015010112/
-        ├── checkpoints/
-           ├── finished/
-              ├── biofluxes
-              ├── cosmo
-              ├── emissions
-              ├── int2lm
-              ├── oem
-              ├── online_vprm
-              ├── post_cosmo
-              ├── post_int2lm
-              └── prepare_cosmo
-           └── working/
-               ├── biofluxes
-               ├── cosmo
-               ├── emissions
-               ├── int2lm
-               ├── oem
-               ├── online_vprm
-               ├── post_cosmo
-               ├── post_int2lm
-               └── prepare_cosmo
-        ├── cosmo/
-           ├── input/
-              ├── oem
-              └── vprm
-           ├── output/
-              └── lffd*.nc
-           ├── restart/
-              └── lrff00060000o.nc
-           └── run/
-               ├── cosmo-ghg
-               ├── INPUT_*
-               ├── post_cosmo.job
-               ├── run.job
-               └── YU*
-        └── int2lm/
-                ├── input/
-                   ├── emissions
-                   ├── extpar
-                   ├── icbc
-                   ├── meteo
-                   └── vprm
-                ├── output/
-                   ├── laf*.nc
-                   └── lbfd*.nc
-                └── run/
-                        ├── INPUT
-                        ├── INPUT_ART
-                        ├── int2lm
-                        ├── OUTPUT
-                        ├── run.job
-                        └── YU*
-
-
-
-
-
-run_chain.run_chunk(cfg, force, resume)[source]
-

Run a chunk of the processing chain, managing job execution and logging.

-

This function sets up and manages the execution of a Processing Chain, handling -job execution, logging, and various configuration settings.

-
-
Parameters:
-
    -
  • cfg (Config) – Object holding user-defined configuration parameters as attributes.

  • -
  • force (bool) – If True, it will force the execution of jobs regardless of their completion status.

  • -
  • resume (bool) – If True, it will resume the last unfinished job.

  • -
-
-
Raises:
-

RuntimeError – If an error or timeout occurs during job execution.

-
-
-

Notes

-
    -
  • This function sets various configuration values based on the provided parameters.

  • -
  • It checks for job completion status and resumes or forces execution accordingly.

  • -
  • Job log files are managed, and errors or timeouts are handled with notifications.

  • -
-
- -
-
-
-run_chain.restart_runs(cfg, force, resume)[source]
-

Start subchains in specified intervals and manage restarts.

-

This function slices the total runtime of the processing chain according to the -cfg.restart_step_hours configuration. It calls run_chunk() for each -specified interval.

-
-
Parameters:
-
    -
  • cfg (Config) – Object holding all user-configuration parameters as attributes.

  • -
  • force (bool) – If True, it will force the execution of jobs regardless of their completion status.

  • -
  • resume (bool) – If True, it will resume the last unfinished job.

  • -
-
-
-

Notes

-
    -
  • The function iterates over specified intervals, calling run_chunk() for each.

  • -
  • It manages restart settings and logging for each subchain.

  • -
-
- -
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/index.html b/pr-preview/pr-63/index.html deleted file mode 100644 index 007c45b7..00000000 --- a/pr-preview/pr-63/index.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - Processing Chain — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Processing Chain

-

The Processing Chain is a Python-based workflow tool designed to streamline -weather and climate simulations. -It facilitates the preparation of essential input data, submission of compute -jobs to the queue on CSCS HPC systems, and the implementation of post-processing -steps. -In addition to supporting standard versions of the COSMO and ICON models, -it is equipped to handle various model variants, notably COSMO-GHG -(Greenhouse Gas Extension) and ICON-ART (Aerosols and Reactive Trace Gases)

-

The Processing Chain can be easily customized to meet your specific requirements. -This includes defining custom workflows, creating your own simulation cases, -and integrating new jobs and auxiliary scripts.

- - -
-

Jobs & Workflows

- -
- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/jobs.html b/pr-preview/pr-63/jobs.html deleted file mode 100644 index 32d361bc..00000000 --- a/pr-preview/pr-63/jobs.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - - Overview — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Overview

-

Jobs have to be part of the respective workflow. They are submitted via sbatch -to the Slurm workload manager.

-

The order of job submission is based on the list given in workflows.yaml -(or in config.yaml in case a custom, user-defined workflow is used.)

-

Let’s have a look at the icon-art example:

-
icon-art:
-   features:
-      - restart
-   jobs:
-      - prepare_icon
-      - icontools
-      - prepare_art
-      - icon
-
-
-

This workflow consists of four jobs: prepare_icon, icontools, -prepare_art and icon.

-

These jobs will be submitted, however, they are not starting at the same time, -because some of them depend on others:

-
dependencies:
-   icontools:
-      current:
-        - prepare_icon
-   prepare_art:
-      current:
-        - icontools
-   icon:
-      current:
-        - prepare_icon
-        - icontools
-        - prepare_art
-      previous:
-        - icon
-
-
-

Since icontools depends on prepare_icon, and prepare_art depends -on icontools, the order of execution is prepare_icon –> icontools -–> prepare_art. Note that if we had another job in there without dependencies, -it would run in parallel to the others.

-

Since icon depends on all other jobs, it will be executed last. Note that -these dependencies are all listed under the current keyword, targeting -the current chunk. For icon, there is an additional previous keyword. -This means that an icon simulation will always wait until the simulation -from the last chunk is finished (because the restart file has to be available).

-

Another effect of this workflow definition is that the prepare_icon, -icontools and prepare_art jobs will also be launched for the next chunk, -as they are not dependent on their previous ones.

-
-Flowchart for the ``icon-art`` workflow. -
-

Flowchart for the icon-art workflow.

-
-
-
-
-

Adding New Jobs

-

Adding a new job to the chain is simple:

-
    -
  1. In the directory jobs/, create a file called <jobname>.py containing -a function called main which takes the same arguments as every other job. -Make sure the function is documented with a docstring.

  2. -
  3. Import it in jobs/__init__.py to make it accessible to run_chain.py.

  4. -
  5. Add the job to your workflow.

  6. -
-
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/namelists.html b/pr-preview/pr-63/namelists.html deleted file mode 100644 index 31e70269..00000000 --- a/pr-preview/pr-63/namelists.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - Namelist and Runscript Templates — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
- -
-
-
-
- -
-

Namelist and Runscript Templates

-

The namelists and run jobs for int2lm and COSMO, as well as for icontools and ICON are dynamically generated -using templates located in the cases/<casename> directory. These templates are essentially -text files containing “normal” namelist parameters alongside Python variables enclosed in curly braces.

-

During runtime, these template files are read by their respective jobs. -The resulting strings are formatted through Python’s .format() function, facilitating the -substitution of Python variables with their corresponding value. -Subsequently, the formatted strings are then saved as the actual namelist and run scripts in the -run directory of their respective jobs.

-
cases/example/example_namelist.cfg -> [read file] ->
-"namelist_var = '{cfg.prefix}{cfg.suffix}'" -> ["".format(cfg)] ->
-"namelist_var = 'pref_suff.nc'" -> [write to disk] ->
-int2lm/run/example_namelist
-
-
-

A special case is INPUT_ART for int2lm and INPUT_GHG for COSMO . These namelists are -generated by jobs.tools.write_int2lm_input_art.main() and jobs.tools.write_cosmo_input_ghg.main() -from .csv-files containing all necessary information.

-
-
-
-jobs.tools.write_int2lm_input_art.main(trcr_filename, set_filename, nml_filename, hstart=0)[source]
-

Write the INPUT_ART namelist file for int2lm from .csv files

-
-
Parameters:
-
    -
  • trcr_filename (str) – csv file with tracer definitions

  • -
  • set_filename (str) – csv file with tracer datasets

  • -
  • nml_filename (str) – output filename (INPUT_ART)

  • -
  • hstart (int) – meteorology spin up in hours

  • -
-
-
-
- -
-
-
-jobs.tools.write_cosmo_input_ghg.main(csv_filename, namelist_filename, cfg=None)[source]
-

Convert a table (.csv file) to namelist file (INPUT_GHG) -read by COSMO.

-
-
Parameters:
-
    -
  • csv_filename (str) – Path to the source csv-file

  • -
  • namelist_filename (str) – Path to the namelist file that will be created

  • -
  • cfg (Config) – Object holding all user-configuration parameters as attributes.

  • -
-
-
-
- -
- - -
-
- -
-
-
-
- - - - \ No newline at end of file diff --git a/pr-preview/pr-63/objects.inv b/pr-preview/pr-63/objects.inv deleted file mode 100644 index 4070e7ad..00000000 Binary files a/pr-preview/pr-63/objects.inv and /dev/null differ diff --git a/pr-preview/pr-63/search.html b/pr-preview/pr-63/search.html deleted file mode 100644 index e3bcd2c1..00000000 --- a/pr-preview/pr-63/search.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Search — Processing Chain v3.1 documentation - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
-
    -
  • - -
  • -
  • -
-
-
-
-
- - - - -
- -
- -
-
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/pr-preview/pr-63/searchindex.js b/pr-preview/pr-63/searchindex.js deleted file mode 100644 index c92b2210..00000000 --- a/pr-preview/pr-63/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({"docnames": ["code-structure", "config", "environment", "features", "functions", "howtorun", "index", "jobs", "namelists"], "filenames": ["code-structure.rst", "config.rst", "environment.rst", "features.rst", "functions.rst", "howtorun.rst", "index.rst", "jobs.rst", "namelists.rst"], "titles": ["Code Structure", "Configuration File", "Conda Environment", "Feature Overview", "Jobs", "How to Run", "Processing Chain", "Overview", "Namelist and Runscript Templates"], "terms": {"The": [0, 1, 2, 4, 5, 6, 7, 8], "process": [0, 1, 2, 3, 4, 5], "chain": [0, 1, 2, 4, 7], "i": [0, 1, 2, 4, 5, 6, 7, 8], "follow": [0, 1, 2, 4, 5], "tree": 0, "l": 0, "3": [0, 1, 4, 6], "f": [0, 2, 5], "dirsfirst": 0, "case": [0, 2, 3, 4, 6, 7, 8], "folder": [0, 1, 3, 4], "where": [0, 1, 4, 5], "all": [0, 1, 2, 4, 5, 7, 8], "ar": [0, 1, 2, 4, 5, 7, 8], "store": [0, 1, 4, 6], "cosmo": [0, 3, 4, 5, 6, 8], "ghg": [0, 5, 6], "spinup": [0, 3, 4, 5], "test": [0, 6], "restart": [0, 1, 3, 4, 5, 7], "config": [0, 2, 4, 5, 6, 7, 8], "yaml": [0, 2, 4, 5, 6, 7], "configur": [0, 4, 5, 8], "file": [0, 2, 4, 5, 6, 7, 8], "cfg": [0, 1, 4, 5, 8], "templat": [0, 1, 4, 5, 6], "namelist": [0, 1, 4, 5, 6], "batch": 0, "job": [0, 1, 3, 5, 8], "csv": [0, 4, 8], "tracer": [0, 4, 8], "inform": [0, 1, 4, 8], "testcas": 0, "standard": [0, 2, 4, 6], "icon": [0, 3, 4, 5, 6, 7, 8], "art": [0, 5, 6, 7], "global": [0, 5], "domain": 0, "icon_runjob": [0, 1], "runjob": [0, 1], "sh": [0, 2, 5], "pre": [0, 3], "script": [0, 2, 4, 5, 6, 8], "mypartab": 0, "oem": [0, 4, 5, 6], "onlin": 0, "emiss": [0, 1, 4, 5, 6], "doc": 0, "sphinx": 0, "document": [0, 2, 4, 7], "_static": 0, "static": 0, "asset": 0, "custom": [0, 3, 6, 7], "css": 0, "style": 0, "png": 0, "ico": 0, "addit": [0, 1, 5, 6, 7], "imag": 0, "tabl": [0, 4, 8], "us": [0, 1, 2, 3, 4, 5, 7, 8], "contain": [0, 1, 5, 7, 8], "data": [0, 1, 4, 5, 6], "conf": 0, "py": [0, 1, 4, 5, 7], "builder": 0, "rst": 0, "restructuredtext": 0, "env": [0, 2], "environ": [0, 6], "yml": [0, 2], "conda": [0, 6], "ext": 0, "other": [0, 4, 5, 7], "spack": [0, 5], "model": [0, 1, 3, 4, 5, 6], "etc": [0, 1, 5], "jenkin": [0, 5], "autom": [0, 5], "individu": [0, 1, 4, 5], "shell": 0, "jenkinsfil": 0, "text": [0, 8], "pipelin": 0, "tool": [0, 5, 6, 8], "licens": 0, "readm": 0, "md": 0, "class": [0, 1, 4], "run_chain": [0, 1, 5, 7], "main": [0, 4, 5, 6, 7, 8], "workflow": [0, 1, 3, 5, 7], "depend": [0, 1, 3, 4, 5, 7], "describ": 1, "simul": [1, 4, 5, 6, 7], "A": [1, 5, 8], "subdirectori": 1, "sever": [1, 4, 5], "e": [1, 2, 4], "g": [1, 2, 4], "int2lm_input": [1, 4, 5], "runscript": [1, 4, 5, 6], "which": [1, 2, 4, 5, 7], "defin": [1, 4, 5, 6, 7], "casenam": [1, 5, 8], "most": [1, 4], "need": [1, 2, 4], "prepar": [1, 4, 6], "run": [1, 2, 3, 4, 6, 7, 8], "exampl": [1, 3, 4, 5, 7, 8], "locat": [1, 2, 4, 8], "input": [1, 4, 5, 6], "thi": [1, 4, 5, 6, 7], "load": 1, "an": [1, 4, 5, 7], "instanc": 1, "non": [1, 4], "exhaust": 1, "import": [1, 4, 7], "descript": 1, "case_path": 1, "path": [1, 2, 4, 8], "directori": [1, 2, 4, 6, 7, 8], "under": [1, 7], "specifi": [1, 4, 5], "name": [1, 4, 5], "deriv": 1, "from": [1, 4, 5, 7, 8], "chain_src_dir": 1, "sourc": [1, 2, 4, 5, 8], "typic": 1, "current": [1, 4, 7], "work": [1, 2, 4, 5], "compute_account": [1, 2], "comput": [1, 3, 4, 6], "account": [1, 2, 5], "base": [1, 5, 6, 7], "user": [1, 4, 5, 6, 7, 8], "constraint": 1, "gpu": 1, "mc": [1, 4], "email": [1, 2], "": [1, 5, 7, 8], "address": [1, 2], "initi": 1, "none": [1, 4, 8], "updat": [1, 2], "set_email": 1, "method": 1, "enddat": 1, "end": 1, "date": [1, 4], "iso": 1, "8601": 1, "format": [1, 4, 8], "yyyi": [1, 4], "mm": 1, "ddthh": 1, "ssz": 1, "execut": [1, 4, 5, 7], "log_finished_dir": [1, 4, 5], "finish": [1, 5, 7], "log": [1, 4, 5], "log_working_dir": [1, 5], "ntasks_per_nod": 1, "number": [1, 4], "task": 1, "per": [1, 4], "node": 1, "type": [1, 2, 4], "restart_step": 1, "step": [1, 2, 3, 5, 6], "restart_step_hour": [1, 5], "hour": [1, 4, 8], "attribut": [1, 4, 5, 8], "run_on": 1, "architectur": 1, "cpu": 1, "spin": [1, 4, 8], "up": [1, 2, 4, 5, 8], "durat": 1, "activ": [1, 2], "behavior": [1, 5], "startdat": [1, 4], "start": [1, 7], "user_mail": [1, 2], "determin": 1, "system": [1, 6], "user_nam": 1, "your": [1, 2, 6, 7], "receiv": 1, "notif": [1, 5], "either": 1, "provid": [1, 2, 4, 5], "directli": [1, 4], "here": [1, 4, 5], "forward": [1, 2], "self": 1, "one": [1, 4, 5], "work_root": [1, 5], "output": [1, 4, 5, 8], "should": [1, 2, 4], "somewher": 1, "scratch": [1, 4], "By": 1, "default": [1, 2, 4, 5], "two": [1, 4], "gener": [1, 4, 5, 8], "12": 1, "pt6h": 1, "2015": 1, "01": 1, "01t00": 1, "00": 1, "00z": 1, "01t18": 1, "compute_queu": 1, "normal": [1, 8], "2018": 1, "01t12": 1, "eccodes_dir": 1, "eccodes_definit": 1, "iconremap_bin": 1, "iconremap": 1, "iconsub_bin": 1, "iconsub": 1, "latbc_filenam": 1, "ifs_": 1, "y": [1, 4], "m": 1, "d": 1, "h": [1, 5], "_lbc": 1, "nc": [1, 4, 5, 8], "inidata_prefix": 1, "ifs_init_": 1, "inidata_nameformat": 1, "inidata_filename_suffix": 1, "output_filenam": 1, "filename_format": 1, "_dom": 1, "physdom": 1, "_": [1, 4], "ddhhmmss": 1, "lateral_boundary_grid_ord": 1, "lateral_boundari": 1, "art_input_fold": 1, "furthermor": 1, "ti": 1, "These": [1, 2, 5, 7, 8], "themselv": 1, "let": [1, 7], "have": [1, 2, 4, 5, 7], "look": [1, 4, 5, 7], "meteo": [1, 4, 5], "dir": [1, 4], "prefix": [1, 2, 4, 8], "laf": [1, 5], "nameformat": 1, "inc": 1, "1": [1, 4, 6], "can": [1, 2, 4, 5, 6], "access": [1, 7], "via": [1, 5, 7], "thei": [1, 4, 5, 7], "python": [1, 4, 5, 6, 8], "In": [1, 4, 6, 7], "see": [1, 2, 4, 5], "next": [1, 7], "section": [1, 4], "doe": [1, 2, 6], "becaus": [1, 7], "how": [1, 6], "implement": [1, 6], "For": [1, 4, 7], "reason": [1, 4], "automat": [1, 3], "creat": [1, 4, 5, 6, 7, 8], "new": [1, 4, 6], "form": 1, "meteo_dir": 1, "meteo_prefix": 1, "make": [1, 7], "them": [1, 2, 4, 7], "exist": 1, "element": 1, "those": [1, 2, 4], "pleas": [1, 2], "refer": [1, 4], "within": [1, 2, 5], "prepare_cosmo": [1, 4, 5, 6], "prepare_icon": [1, 4, 6, 7], "icontool": [1, 4, 6, 7, 8], "int2lm": [1, 4, 5, 6, 8], "icontools_runjob": [1, 4], "input_fil": 1, "chem": 1, "era5": 1, "cam": [1, 4], "vprm": [1, 4, 5], "bioflux": [1, 4, 5, 6], "online_vprm": [1, 4, 5, 6], "oct": [1, 4, 6], "post_int2lm": [1, 4, 5, 6], "post_cosmo": [1, 4, 5, 6], "reduce_output": [1, 4, 6], "photo_r": [1, 4, 6], "check_output": [1, 4, 6], "obs_nudg": [1, 4, 6], "verify_chain": [1, 4, 6], "allow": 2, "you": [2, 5], "own": [2, 3, 6], "virtual": 2, "we": [2, 7], "recommend": 2, "usag": [2, 4], "instruct": 2, "onli": [2, 4, 5], "perform": [2, 4], "onc": 2, "home": 2, "itself": 2, "project": [2, 4], "otherwis": [2, 4], "risk": 2, "fill": 2, "below": 2, "To": [2, 4, 5], "latest": 2, "wget": 2, "http": [2, 4], "repo": 2, "anaconda": 2, "com": 2, "miniconda3": 2, "linux": 2, "x86_64": 2, "bash": 2, "further": 2, "detail": [2, 4], "found": [2, 4], "page": 2, "proc": 2, "requir": [2, 6], "abl": [2, 5], "simpli": [2, 5], "instead": [2, 4, 5], "full": [2, 5], "add": [2, 4, 7], "bashrc": 2, "export": 2, "conda_envs_path": 2, "If": [2, 4, 5], "alreadi": [2, 5], "want": 2, "prune": 2, "regist": 2, "echo": 2, "your_account_id": 2, "acct": 2, "your_email_address": 2, "set": [2, 4, 5, 6], "option": [2, 4, 5], "first": [2, 5], "check": [2, 4, 5], "content": [2, 4], "desir": [2, 5], "correspond": [2, 5, 8], "variabl": [2, 4, 6, 8], "overridden": 2, "asynchron": 3, "submiss": [3, 6, 7], "hpc": [3, 6], "queue": [3, 4, 6], "intuit": 3, "definit": [3, 4, 7, 8], "cycl": 3, "over": [3, 5], "time": [3, 4, 5, 7], "period": 3, "includ": [3, 6], "structur": [3, 4, 6], "creation": 3, "variou": [3, 5, 6], "post": [3, 6], "built": 3, "nest": [3, 4, 5], "possibl": 3, "easi": 3, "avail": [3, 5, 7], "copi": [4, 5], "object": [4, 5, 8], "hold": [4, 5, 8], "physic": 4, "plot": 4, "function": [4, 5, 7, 8], "ensur": [4, 5], "rang": 4, "It": [4, 5, 6], "seri": 4, "minimum": 4, "maximum": 4, "mean": [4, 7], "deviat": 4, "panda": 4, "pickl": 4, "also": [4, 5, 7], "setup": [4, 5], "submit": [4, 5, 7], "necessari": [4, 5, 8], "cosmo_run": 4, "cosmo_output": [4, 5], "cosmo_restart_out": [4, 5], "binary_fil": 4, "execnam": 4, "convert": [4, 8], "both": [4, 5], "cosmoart": 4, "netcdf": 4, "string": [4, 8], "char": 4, "multipl": 4, "dataset": [4, 8], "list": [4, 5, 7], "0": [4, 8], "gridnam": 4, "yyyymmdd": 4, "emis_yyyymmdd": 4, "emissions2": 4, "2": [4, 6], "emissions3": 4, "icon_binary_fil": 4, "icon_work": 4, "ex": 4, "icon_mast": 4, "icon_namelist_nwp": 4, "geosp": 4, "dwd": 4, "remap": 4, "meteorolog": 4, "read": [4, 5, 8], "origin": 4, "input_root_meteo": 4, "save": [4, 8], "icon_input": 4, "icbc": [4, 5], "decid": 4, "soil": 4, "terra": 4, "multi": 4, "layer": 4, "extpar": [4, 5], "extpar_fil": 4, "int2lm_run": 4, "libgrib_api": 4, "renam": 4, "obs_nudging_dir": 4, "yyyymmdd000000": 4, "expect": 4, "x": 4, "noth": 4, "4": 4, "handl": [4, 5, 6], "filenam": [4, 8], "chang": [4, 5], "cosmo_input": 4, "miss": 4, "observ": 4, "ignor": 4, "blacklist": 4, "blklsttmp": 4, "perturb": 4, "bg": 4, "octe_map": 4, "octe_lambda": 4, "background": 4, "field": 4, "do": 4, "lambda": 4, "valu": [4, 5, 8], "last": [4, 5, 7], "along": 4, "nparam": 4, "dimens": 4, "scale": 4, "produc": [4, 5], "each": [4, 5], "ensembl": 4, "profil": 4, "rais": [4, 5], "runtimeerror": [4, 5], "error": [4, 5], "occur": [4, 5], "dure": [4, 5, 8], "modi": 4, "surfac": 4, "reflect": 4, "veget": 4, "fraction": 4, "photolysi": 4, "rate": 4, "photo_rate_fil": 4, "art_photolysi": 4, "posit": 4, "write": [4, 8], "logfil": [4, 5], "output_root": 4, "ha": [4, 5, 7], "been": [4, 5], "befor": 4, "cosmo_output_reduc": 4, "xfer": 4, "combin": 4, "singl": [4, 5], "put": 4, "differ": 4, "post_int2lm_speci": 4, "post_int2lm_species_spinup": 4, "present": 4, "take": [4, 5, 7], "specif": [4, 6], "yyyymmddhh": 4, "lffd": [4, 5], "c": 4, "constant": 4, "ani": 4, "subprocess": 4, "return": 4, "zero": 4, "exit": [4, 5], "code": [4, 6], "calcul": 4, "2d": 4, "column": 4, "fix": 4, "level": [4, 5], "consid": 4, "written": 4, "output_level": 4, "gribout": 4, "split": 4, "averag": 4, "dry": 4, "air": 4, "moist": 4, "mole": 4, "separ": [4, 5], "appear": 4, "alphabet": 4, "after": 4, "suffix": [4, 8], "_met": 4, "_trc": 4, "compar": 4, "reference_dir": 4, "output_dir": 4, "els": 4, "goe": 4, "dict": 4, "values_to_check": 4, "kei": 4, "temperatur": 4, "ad": [4, 6], "o": 4, "join": 4, "input_root": 4, "reference_output": 4, "reference_lffd2015010200": 4, "lffd2015010200": 4, "t": 4, "collect": 4, "well": [4, 5, 8], "mai": [4, 5], "cams4int2cosmo": [4, 6], "check_model": [4, 6], "comp_nc": [4, 6], "datasets_equ": [4, 6], "ctnoaa4int2cosmo": [4, 6], "mozart2int2lm": [4, 6], "reduce_output_start_end": [4, 6], "string2char": [4, 6], "vprmsplit": [4, 6], "write_cosmo_input_ghg": [4, 6, 8], "write_int2lm_input_art": [4, 6, 8], "inpath": 4, "outpath": 4, "param": 4, "co2": 4, "co": 4, "nox": 4, "boundari": 4, "condit": 4, "int2cosmo": 4, "smartcarb": 4, "consist": [4, 7], "experi": 4, "gf39": 4, "rd": 4, "approx": 4, "15": 4, "km": 4, "resolut": 4, "137": 4, "atmospher": 4, "copernicu": 4, "eu": 4, "NO": 4, "no2": 4, "oper": 4, "product": 4, "exp": 4, "0001": 4, "60": 4, "retriev": 4, "hourli": 4, "mar": 4, "archiv": 4, "ecmwf": 4, "cams_0001_2015010500": 4, "sfc_0001_2015010500": 4, "pressur": 4, "cams_gf39_2015010500": 4, "sfc_gf39_2015010500": 4, "suppli": 4, "invok": 4, "8": 4, "ic": 4, "bc": 4, "cams_nox_yyyymmddhh": 4, "cams_co2_yyyymmddhh": 4, "cams_nox_yyyymmdd00": 4, "cams_nox_yyyymmdd21": 4, "cams_co2_yyyymmdd00": 4, "cams_co2_yyyymmdd21": 4, "str": [4, 8], "match": 4, "prescrib": 4, "workflow_nam": 4, "capit": 4, "dataset1": 4, "dataset2": 4, "verbos": 4, "true": [4, 5], "numpi": 4, "isclos": 4, "whether": 4, "equal": 4, "No": 4, "bitwis": 4, "numer": 4, "slightli": 4, "essenti": [4, 6, 8], "ident": 4, "rather": 4, "absolut": 4, "rel": 4, "toler": 4, "np": 4, "more": 4, "empti": 4, "netcdf4": 4, "bool": [4, 5], "result": [4, 8], "print": 4, "stdout": 4, "select": 4, "fals": 4, "indir": 4, "outdir": 4, "carbontrack": 4, "compat": 4, "utput": 4, "dictionari": 4, "infil": 4, "extract": 4, "timeslic": 4, "seper": 4, "lev": 4, "transform": 4, "lon": 4, "180": 4, "entri": 4, "_yyyymmddhh": 4, "strdate_start": 4, "strdate_end": 4, "nout_level": 4, "csvfile": 4, "convert_ga": 4, "reduc": 4, "opath": 4, "go": 4, "arrai": 4, "year": 4, "ipath": 4, "dai": 4, "gpp_yyyymmddhh": 4, "ra_yyyymmddhh": 4, "vprm_ecmwf_": 4, "_2017": 4, "2017": 4, "flux": 4, "csv_filenam": [4, 8], "namelist_filenam": [4, 8], "input_ghg": [4, 8], "trcr_filenam": [4, 8], "set_filenam": [4, 8], "nml_filenam": [4, 8], "hstart": [4, 8], "input_art": [4, 5, 8], "int": [4, 8], "meteorologi": [4, 8], "root": 5, "command": 5, "line": 5, "respect": [5, 7, 8], "Then": 5, "sbatch": [5, 7], "technic": 5, "achiev": 5, "case1": 5, "case2": 5, "With": 5, "afterward": 5, "There": 5, "argument": [5, 7], "help": 5, "show": 5, "messag": 5, "j": 5, "job_list": 5, "aspect": 5, "launch": [5, 7], "order": [5, 7], "given": [5, 7], "forc": 5, "redo": 5, "even": 5, "were": 5, "previous": 5, "warn": 5, "get": 5, "delet": 5, "effect": [5, 7], "overwritten": 5, "caus": 5, "unexpect": 5, "r": 5, "resum": 5, "unfinish": 5, "call": [5, 7], "restart_run": 5, "divid": 5, "accord": 5, "run_chunk": 5, "part": [5, 7], "chunk": [5, 7], "slurm": [5, 7], "workload": [5, 7], "manag": [5, 7], "compil": 5, "undergo": 5, "regulari": 5, "correctli": 5, "plan": 5, "weekli": 5, "basi": 5, "when": 5, "trigger": 5, "github": 5, "pull": 5, "request": 5, "like": 5, "chain_root": 5, "checkpoint": 5, "cosmo_bas": 5, "cosmo_work": 5, "int2lm_bas": 5, "int2lm_work": 5, "int2lm_output": 5, "As": 5, "preprocessor": 5, "addition": 5, "alwai": [5, 7], "whenev": 5, "successfulli": 5, "sub": 5, "therefor": 5, "four": [5, 7], "deep": 5, "2015010100_2015010106": 5, "lrff00060000o": 5, "input_": 5, "yu": 5, "lbfd": 5, "2015010106_2015010112": 5, "paramet": [5, 8], "regardless": 5, "complet": 5, "statu": 5, "timeout": 5, "note": [5, 7], "accordingli": 5, "subchain": 5, "interv": 5, "slice": 5, "total": 5, "runtim": [5, 8], "iter": 5, "design": 6, "streamlin": 6, "weather": 6, "climat": 6, "facilit": [6, 8], "csc": 6, "support": 6, "version": 6, "equip": 6, "variant": 6, "notabl": 6, "greenhous": 6, "ga": 6, "extens": 6, "aerosol": 6, "reactiv": 6, "trace": 6, "gase": 6, "easili": 6, "meet": 6, "integr": 6, "auxiliari": 6, "featur": [6, 7], "overview": 6, "instal": 6, "miniconda": 6, "what": 6, "prepare_art": 7, "howev": 7, "same": 7, "some": 7, "previou": 7, "sinc": 7, "had": 7, "anoth": 7, "without": 7, "would": 7, "parallel": 7, "keyword": 7, "target": 7, "wait": 7, "until": 7, "ones": 7, "flowchart": 7, "simpl": 7, "jobnam": 7, "everi": 7, "sure": 7, "docstr": 7, "__init__": 7, "dynam": 8, "alongsid": 8, "enclos": 8, "curli": 8, "brace": 8, "through": 8, "substitut": 8, "subsequ": 8, "actual": 8, "example_namelist": 8, "namelist_var": 8, "pref_suff": 8, "disk": 8, "special": 8}, "objects": {"jobs.biofluxes": [[4, 0, 1, "", "main"]], "jobs.check_output": [[4, 0, 1, "", "main"]], "jobs.cosmo": [[4, 0, 1, "", "main"]], "jobs.emissions": [[4, 0, 1, "", "main"]], "jobs.icon": [[4, 0, 1, "", "main"]], "jobs.icontools": [[4, 0, 1, "", "main"]], "jobs.int2lm": [[4, 0, 1, "", "main"]], "jobs.obs_nudging": [[4, 0, 1, "", "main"]], "jobs.octe": [[4, 0, 1, "", "main"]], "jobs.oem": [[4, 0, 1, "", "main"]], "jobs.online_vprm": [[4, 0, 1, "", "main"]], "jobs.photo_rate": [[4, 0, 1, "", "main"]], "jobs.post_cosmo": [[4, 0, 1, "", "main"]], "jobs.post_int2lm": [[4, 0, 1, "", "main"]], "jobs.prepare_cosmo": [[4, 0, 1, "", "main"]], "jobs.prepare_icon": [[4, 0, 1, "", "main"]], "jobs.reduce_output": [[4, 0, 1, "", "main"]], "jobs.tools.cams4int2cosmo": [[4, 0, 1, "", "main"]], "jobs.tools.check_model": [[4, 0, 1, "", "check_model"]], "jobs.tools.comp_nc": [[4, 0, 1, "", "datasets_equal"]], "jobs.tools.ctnoaa4int2cosmo": [[4, 0, 1, "", "main"]], "jobs.tools.mozart2int2lm": [[4, 0, 1, "", "main"]], "jobs.tools.reduce_output_start_end": [[4, 0, 1, "", "main"]], "jobs.tools.string2char": [[4, 0, 1, "", "main"]], "jobs.tools.vprmsplit": [[4, 0, 1, "", "main"]], "jobs.tools.write_cosmo_input_ghg": [[8, 0, 1, "", "main"]], "jobs.tools.write_int2lm_input_art": [[8, 0, 1, "", "main"]], "jobs.verify_chain": [[4, 0, 1, "", "main"]], "run_chain": [[5, 0, 1, "", "restart_runs"], [5, 0, 1, "", "run_chunk"]]}, "objtypes": {"0": "py:function"}, "objnames": {"0": ["py", "function", "Python function"]}, "titleterms": {"code": 0, "structur": [0, 5], "configur": [1, 6], "file": 1, "variabl": 1, "set": 1, "config": 1, "yaml": 1, "header": 1, "cosmo": 1, "ghg": 1, "spinup": 1, "test": [1, 5], "case": [1, 5], "icon": 1, "art": 1, "oem": 1, "further": 1, "list": 1, "dictionari": 1, "conda": 2, "environ": 2, "1": 2, "instal": 2, "miniconda": 2, "2": 2, "creat": 2, "3": 2, "store": 2, "user": 2, "specif": 2, "data": 2, "featur": 3, "overview": [3, 7], "job": [4, 6, 7], "tool": 4, "paramet": 4, "todo": 4, "how": 5, "run": 5, "start": [5, 6], "chain": [5, 6], "what": 5, "doe": 5, "directori": 5, "process": 6, "get": 6, "workflow": 6, "api": 6, "ad": 7, "new": 7, "namelist": 8, "runscript": 8, "templat": 8}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.todo": 2, "sphinx.ext.viewcode": 1, "sphinx": 58}, "alltitles": {"Code Structure": [[0, "code-structure"]], "Configuration File": [[1, "configuration-file"]], "Configuration Variables": [[1, "configuration-variables"]], "Variables to Set in config.yaml": [[1, "variables-to-set-in-config-yaml"]], "Header of config.yaml for the cosmo-ghg-spinup-test case": [[1, "header-of-config-yaml-for-the-cosmo-ghg-spinup-test-case"]], "Header of config.yaml for the icon-art-oem-test case": [[1, "header-of-config-yaml-for-the-icon-art-oem-test-case"]], "Further variables": [[1, "further-variables"]], "List of dictionary variables": [[1, "list-of-dictionary-variables"]], "Conda Environment": [[2, "conda-environment"]], "1. Install Miniconda": [[2, "install-miniconda"]], "2. Create the Conda Environment": [[2, "create-the-conda-environment"]], "3. Store user-specific data": [[2, "store-user-specific-data"]], "Feature Overview": [[3, "feature-overview"]], "Jobs": [[4, "jobs"]], "Tools": [[4, "tools"]], "Parameters (TODO)": [[4, "parameters-todo"]], "How to Run": [[5, "how-to-run"]], "Starting the Chain": [[5, "starting-the-chain"]], "What it Does": [[5, "what-it-does"]], "Test Cases": [[5, "test-cases"]], "Directory Structure": [[5, "directory-structure"]], "Processing Chain": [[6, "processing-chain"]], "Getting Started": [[6, null]], "Configuration": [[6, null]], "Jobs & Workflows": [[6, null]], "API": [[6, null]], "Overview": [[7, "overview"]], "Adding New Jobs": [[7, "adding-new-jobs"]], "Namelist and Runscript Templates": [[8, "namelist-and-runscript-templates"]]}, "indexentries": {"check_model() (in module jobs.tools.check_model)": [[4, "jobs.tools.check_model.check_model"]], "datasets_equal() (in module jobs.tools.comp_nc)": [[4, "jobs.tools.comp_nc.datasets_equal"]], "main() (in module jobs.biofluxes)": [[4, "jobs.biofluxes.main"]], "main() (in module jobs.check_output)": [[4, "jobs.check_output.main"]], "main() (in module jobs.cosmo)": [[4, "jobs.cosmo.main"]], "main() (in module jobs.emissions)": [[4, "jobs.emissions.main"]], "main() (in module jobs.icon)": [[4, "jobs.icon.main"]], "main() (in module jobs.icontools)": [[4, "jobs.icontools.main"]], "main() (in module jobs.int2lm)": [[4, "jobs.int2lm.main"]], "main() (in module jobs.obs_nudging)": [[4, "jobs.obs_nudging.main"]], "main() (in module jobs.octe)": [[4, "jobs.octe.main"]], "main() (in module jobs.oem)": [[4, "jobs.oem.main"]], "main() (in module jobs.online_vprm)": [[4, "jobs.online_vprm.main"]], "main() (in module jobs.photo_rate)": [[4, "jobs.photo_rate.main"]], "main() (in module jobs.post_cosmo)": [[4, "jobs.post_cosmo.main"]], "main() (in module jobs.post_int2lm)": [[4, "jobs.post_int2lm.main"]], "main() (in module jobs.prepare_cosmo)": [[4, "jobs.prepare_cosmo.main"]], "main() (in module jobs.prepare_icon)": [[4, "jobs.prepare_icon.main"]], "main() (in module jobs.reduce_output)": [[4, "jobs.reduce_output.main"]], "main() (in module jobs.tools.cams4int2cosmo)": [[4, "jobs.tools.cams4int2cosmo.main"]], "main() (in module jobs.tools.ctnoaa4int2cosmo)": [[4, "jobs.tools.ctnoaa4int2cosmo.main"]], "main() (in module jobs.tools.mozart2int2lm)": [[4, "jobs.tools.mozart2int2lm.main"]], "main() (in module jobs.tools.reduce_output_start_end)": [[4, "jobs.tools.reduce_output_start_end.main"]], "main() (in module jobs.tools.string2char)": [[4, "jobs.tools.string2char.main"]], "main() (in module jobs.tools.vprmsplit)": [[4, "jobs.tools.vprmsplit.main"]], "main() (in module jobs.tools.write_cosmo_input_ghg)": [[4, "jobs.tools.write_cosmo_input_ghg.main"], [8, "jobs.tools.write_cosmo_input_ghg.main"]], "main() (in module jobs.tools.write_int2lm_input_art)": [[4, "jobs.tools.write_int2lm_input_art.main"], [8, "jobs.tools.write_int2lm_input_art.main"]], "main() (in module jobs.verify_chain)": [[4, "jobs.verify_chain.main"]], "restart_runs() (in module run_chain)": [[5, "run_chain.restart_runs"]], "run_chunk() (in module run_chain)": [[5, "run_chain.run_chunk"]]}}) \ No newline at end of file