Determine whether multiple plot files need to be opened

    Args:
        config (configparser.ConfigParser): instance of a ConfigParser class that holds the users parameters

    Returns:
        boolean: boolean flag determining if multiple plot files need to be opened


Opens a visit database object

    Args:
        config (configparser.ConfigParser): instance of a ConfigParser class that holds the users parameters

    Raises:
        IOError: Could not open database!

    Returns:
        int: status code of opening the database


Close a VisIt database object

    Args:
		config (configparser.ConfigParser): instance of a ConfigParser class that holds the users parameters

    Raises:
        IOError: Could not close database!

    Returns:
        int: status code of closing database


    Select the plot function based on the scaling

    Args:
        scaling (str): "linear", "loglog", "loglinear", "linearlog"

    Returns:
        function: the plot function from pyplot


    Save the pyplot figure

    Args:
        path (str): absolute path to the output directory
        varname (str): name of the variable


Generates movie using ffmpeg from a series of images

    Args:
		config (configparser.ConfigParser): instance of a ConfigParser class that holds the users parameters
        plotvariable (str): name of the variable to be plotted

    Raises:
        OSError: ffmpeg failed. Could not make the movie.


Generates a single volume plot for a given variable

	Args:
		config (configparser.ConfigParser): instance of a ConfigParser class that holds the users parameters
		variableToPlot (str): name of the variable to be plotted
		setplotbounds (bool, optional): flag to specify whether bounds for the plotting variable should be specified. Defaults to False.
		plotbounds (list, optional): list of two values that specify the minimum and maximum value of the plot variable. Defaults to [0,1].

	Raises:
		RuntimeError: DrawPlots() failed. Aborting.


Common image quality assessment


For every test set


Initialize visdom
    Visdom: no tex-format syntax, but html-format syntax


trainning with a batch of data and logging & visdom


Validation -> get PSNR and SSIM or D_labmda D_s QNR


store generated images or not, and this takes lots of time!
    store = None, nothing would happen
    store = (this_psnr, highest_psnr, this_ssim, highest_ssim), if one
    this > high, 5 images would be stored
    or sotre = (this_D_lambda, highest_D_labmda, this_D_s, highest_D_s,
    this_qnr, highest_qnr)


Get abs path of images


Get names of images (without extension)


path is img key in lmdb


    read image by cv2/gdal or from lmdb
    return: Numpy float32, HWC, BGR, [0,1], where C could be 1, 3 or more


range transform and channels control


same as matlab rgb2ycbcr
    only_y: only return Y channel
    Input:
        uint8, [0, 255]
        float, [0, 1]


bgr version of rgb2ycbcr
    only_y: only return Y channel
    Input:
        uint8, [0, 255]
        float, [0, 1]


same as matlab ycbcr2rgb
    Input:
        uint8, [0, 255]
        float, [0, 1]


Crop HR to be multiple of scale


Input: CHW, B G R NIR, uint16
        norm_type: channels-wise, mM, dynamic_range
        Output: HWC, BGRNIR, float32 [0, 1]


Input: HWC, BGRNIR, float32 [0, 1]
        Channel-wise clip; range transform [0, 1]


imgs: torch.tensor, CHW, float, [0, 1]


A multi-thread tool for converting RGB images to gary/Y images.


Read img as array


Split dataset into train val test


generate LR image,
    size of img_HR should be multiple of scale


Saves training state during training,
        which will be used for resuming


Resume the optimizers and schedulers for training


Fisrt G, then R D; wrong, but not used anymore


First G R, then D; wrong, but not used anymore


        HRMS -> LRMS, fixed filter and downsampler
        HRMS -> PAN, fixed linear transform
        Ref: Remote Sensing Image Fusion via Sparse Representations
        Over Learned Dictionaries


Fixe R and train G D alternatively


r"""Applies spectral normalization to a parameter in the given module.

    .. math::
         \mathbf{W} &= \dfrac{\mathbf{W}}{\sigma(\mathbf{W})} \\
         \sigma(\mathbf{W}) &= \max_{\mathbf{h}: \mathbf{h} \ne 0} \dfrac{\|\mathbf{W} \mathbf{h}\|_2}{\|\mathbf{h}\|_2}

    Spectral normalization stabilizes the training of discriminators (critics)
    in Generaive Adversarial Networks (GANs) by rescaling the weight tensor
    with spectral norm :math:`\sigma` of the weight matrix calculated using
    power iteration method. If the dimension of the weight tensor is greater
    than 2, it is reshaped to 2D in power iteration method to get spectral
    norm. This is implemented via a hook that calculates spectral norm and
    rescales weight before every :meth:`~Module.forward` call.

    See `Spectral Normalization for Generative Adversarial Networks`_ .

    .. _`Spectral Normalization for Generative Adversarial Networks`: https://arxiv.org/abs/1802.05957

    Args:
        module (nn.Module): containing module
        name (str, optional): name of weight parameter
        n_power_iterations (int, optional): number of power iterations to
            calculate spectal norm
        eps (float, optional): epsilon for numerical stability in
            calculating norms
        dim (int, optional): dimension corresponding to number of outputs,
            the default is 0, except for modules that are instances of
            ConvTranspose1/2/3d, when it is 1

    Returns:
        The original module with the spectal norm hook

    Example::

        >>> m = spectral_norm(nn.Linear(20, 40))
        Linear (20 -> 40)
        >>> m.weight_u.size()
        torch.Size([20])


r"""Removes the spectral normalization reparameterization from a module.

    Args:
        module (nn.Module): containing module
        name (str, optional): name of weight parameter

    Example:
        >>> m = spectral_norm(nn.Linear(40, 10))
        >>> remove_spectral_norm(m)


    Conv layer with padding, normalization, activation
    mode: CNA --> Conv -> Norm -> Act
        NAC --> Norm -> Act --> Conv
        Identity Mappings in Deep Residual Networks, ECCV16


    Pixel shuffle layer
    (Real-Time Single Image and Video Super-Resolution
    Using an Efficient Sub-Pixel Convolutional
    Neural Network, CVPR17)


    Converts a torch Tensor into an image Numpy array
    Input: 4D(B,(8/4/3/1),H,W), 3D(C,H,W), or 2D(H,W), any range
    Output: 3D(H,W,C) or 2D(H,W), [0,255], (uint8 as default)


Generate a 2D convolutional window from a given GNyq
    GNyq: Nyquist frequency
    downscale: spatial size of PAN / spatial size of MS


SAM for 3D image, shape (H, W, C); uint or float[0, 1]


SCC for 2D (H, W)or 3D (H, W, C) image; uint or float[0, 1].
    The value is in [-1., 1.] due to the appearance of covariance.


Q-index for 2D (one-band) image, shape (H, W); uint or float [0, 1]
    This value is in [-1, 1] due to the appearance of covariance.


Q-index for 2D (H, W) or 3D (H, W, C) image; uint or float [0, 1]


SSIM for 2D (one-band) image, shape (H, W);
    uint8 if 225; uint16 if 2047
    The value could small than zero


ERGAS for 2D (H, W) or 3D (H, W, C) image; uint or float [0, 1].
    scale = spatial resolution ratio of PAN and MUL, default 4.


Spectral distortion, if not clipped, it could be very large.
    img_fake, generated HRMS
    img_lm, LRMS


Spatial distortion, if not clipped, it could be very large.
    img_fake, generated HRMS
    img_lm, LRMS
    pan_hp, HRPan


QNR - No reference IQA


dict to string for logger


Check resume states and pretrain_model paths


        Determines the type of event so that the correct modules can be
        executed accordingly. Currently neutrino and cosmic ray events are
        supported, but others can be added in the future.

        Parameters
        ----------
        event: event

        station: station

        mode: string
            specifies which criteria the decision to flag the event as cosmic ray
            or neutrino should be based on. Currently only supports 'forced',
            which automatically flags the event to a specified type. Add new
            modes to use different criteria
        forced_event_type: string
            if the mode is set to forced, this is the type the event will be set to.
            Currently supported options are neutrino and cosmic_ray


        Parameters
        ----------
        evt: Event
            The event to run the module on
        station: Station
            The station to run the module on
        det: Detector
            The detector description
        channels_to_use: list of int (default: [0, 1, 2, 3])
            List with the IDs of channels to use for reconstruction
        cosmic_ray: Bool (default: False)
            Flag to mark event as cosmic ray


    Numerically compute the covariance matrix from a chi^2 or -logLikelihood function.

    Parameters
    ----------
    function: function-like
      The function may accept only a vector argument and has to return a scalar.
    vmin: array of floats
      Position of the minimum.
    up: float
      Threshold value to pass when climbing uphill.
      up = 1   for a chi^2 function
      up = 0.5 for a -logLikelihood function
    fast: boolean
      If true invert hesse matrix at the minimum, use this if computing function is expensive.

    Examples
    --------
    >>> cov = ((2.0,0.2),(0.2,2.0))
    >>> invcov = np.linalg.inv(cov)
    >>> xs = np.array((1.0,-1.0))
    >>> def ChiSquare(pars, grad = None): return np.dot(xs-pars,np.dot(invcov,xs-pars))
    >>> def NegLogLike(pars, grad = None): return 0.5*ChiSquare(pars)
    >>> covariance(ChiSquare, xs, 1.0)
    array([[ 2. ,  0.2],
           [ 0.2,  2. ]])
    >>> covariance(ChiSquare, xs, 1.0, fast=True)
    array([[ 2. ,  0.2],
           [ 0.2,  2. ]])
    >>> covariance(NegLogLike, xs, 0.5)
    array([[ 2. ,  0.2],
           [ 0.2,  2. ]])
    >>> covariance(NegLogLike, xs, 0.5, fast=True)
    array([[ 2. ,  0.2],
           [ 0.2,  2. ]])

    Notes
    -----
    The algorithm is slow (it needs many function evaluations), but robust.
    The covariance matrix is derived by explicitly following the chi^2
    or -logLikelihood function uphill until it crosses the 1-sigma contour.

    The fast alternative is to invert the hessian matrix at the minimum.

    Author: Hans Dembinski <hans.dembinski@kit.edu>


        Defines number of samples to cut the data to and how many samples before maximum in trace

        Parameters
        ----------
        number_of_samples: int
            Number of samples desired in signal
        offset: int
            (roughly) How many samples before pulse


        Run method for the channelLengthAdjuster

        Parameters
        ----------
        evt: Event object
            The event containing the station whose channels should be cut
        station: Station object
            The station whose channels should be cut
        det: Detector object
            The detector description. It is not actually needed and just
            kept as a parameter to comply with the module template
        channel_ids: List of ints
            Can be used to specify, which channels shall be cut. If it is None,
            all channels are cut.


        Add noise to given event.

        Parameters
        ----------

        event

        station

        detector

        amplitude: float or dict of floats
            desired voltage of noise as V_rms for the specified bandwidth
            a dict can be used to specify a different amplitude per channel, the key is the channel_id
        min_freq: float
            Minimum frequency of passband for noise generation
        max_freq: float
            Maximum frequency of passband for noise generation
            If the maximum frequency is above the Nquist frequencey (0.5 * sampling rate), the Nquist frequency is used
        type: string
            perfect_white: flat frequency spectrum
            rayleigh: Amplitude of each frequency bin is drawn from a Rayleigh distribution
        excluded_channels: list of ints
            the channels ids of channels where no noise will be added, default is that no channel is excluded
        bandwidth: float or None (default)
            if this parameter is specified, the amplitude is interpreted as the amplitude for the bandwidth specified here
            Otherwise the amplitude is interpreted for the bandwidth of min(max_freq, 0.5 * sampling rate) - min_freq
            If `bandwidth` is larger then (min(max_freq, 0.5 * sampling rate) - min_freq) it has the same effect as `None`


        Parameters
        ----------
        evt, station, det
            Event, Station, Detector
        window: list or None
            [time_window_start, time_window_end] in which the signal should be kept (in units of time)
        window_function: string
            select window function
            * rectangular
            * hanning
        around_pulse: float or None
            if not None: specifies time interval around 'signal_time',
            if this option is set, 'window' is ignored
        window_width: float
            if around_pulse is set, defines the time width of the trace where the filter is 1.
        window_rise_time: float
            if window_function is not rectangular, defines the rise time where the filter goes from 0 to 1.


        Parameters
        ----------
        evt: Event
            Event to run the module on
        station: Station
            Station to run the module on
        det: Detector
            The detector description
        channels_to_use: List of int (default: [0, 1, 2, 3])
            List of channel IDs for which the template correlation shall be calculated
        cosmic_ray: bool
            Switch for cosmic ray and neutrino analysis. Default is neutrino templates.
        n_templates: int
            default is 1: use just on standard template for all channels
            if n_templates is larger than one multiple templates are used and the
            average cross correlation for all templates is calculated. The set
            of templates contains several coreas input pulses and different
            incoming directions. The index first loops first over 6 different
            coreas pulses with different frequency content
            and then over azimuth angles of 0, 22.5 and 45 degree
            and then over zenith angles of 60, 50 and 70 degree


        Setup method for the module

        Parameters
        ----------
        electric_field_template: NuRadioReco.framework.base_trace.BaseTrace object (or child of BaseTrace class)
            An electric field waveform to be used as a template. It will be folded with the antenna and amplifier
            response to get a voltage template, which is then used to estimate timing differences between channels.
        medium: NuRadioMC.utilities.medium.Medium object
            The index of refraction profile of the ice.
        use_sim: Boolean (default: False)
            If true, the simulated vertex is used, otherwise it is assumed that the vertex is stored on either the
            vertex_2D_fit (for the neutrino2DVertexReconstructor) or the nu_vertex station parameter


        Run the module on a station

        Parameters
        ----------
        event: NuRadioReco.framework.event.Event object
            The event the module should be run on
        station: NuRadioReco.framework.station.Station object
            The station the module should be run on
        det: NuRadioReco.detector.detector.Detector object of child object
            The detector description
        channel_ids: array of int
            IDs of the channels the module should be run on
        passband: array of float
            Lower and upper bound of the bandpass filter that is applied to the
            channel waveforms when determining correlation to the template. Can
            be used to filter out frequencies that are dominated by noise.


        Check if the detector system triggers on a given channel.
        Passes the signal through the tunnel diode. Then compares the maximum
        and minimum values to a tunnel diode noise signal. Triggers if one of
        the maximum or minimum values exceed the noise mean +/- the noise rms
        times the power threshold.

        Parameters
        ----------
        channel : Channel
            `Channel` object on which to test the trigger condition.

        Returns
        -------
        boolean
            Whether or not the antenna triggers on `channel`.


        run method, selects CoREAS simulations that have any signal in
        desired frequency_window.
        Crude approximation with n_std sigma * noise

        Parameters
        ----------
        evt: Event
        sim_station: sim_station
            CoREAS simulated efields
        det: Detector
        frequency_window: list
            [lower, upper] frequencies that will be used for analysis
        n_std: int
            number of std deviations needed, can make cut stricter, if needed

        Returns
        -------
        selected_sim: bool
            if True then simulation has signal in desired range


        General settings for vertex reconstruction

        Parameters
        ----------
        station_id: integer
            ID of the station to be used for the reconstruction
        channel_ids: array of integers
            IDs of the channels to be used for the reconstruction
        detector: Detector or GenericDetector
            Detector description for the detector used in the reconstruction
        template: BaseTrace object or object of child class
            An electric field to be used to calculate the template which are correlated
            with the channel traces in order to determine the timing difference between
            channels
        distances_2d: array of float
            A list of horizontal distances from the center of the station at which the first
            rough scan to determine the search volume is done. The minimum and maximum of this
            list is later also used as the minimum and maximum distance for the finer search
        azimuths_2d: array of float
            Array of azimuths to be used in the first scan to determine the search volume
        z_coordinates_2d: array of float
            Array of the z coordinates relative to the surface to be used in the first scan
            to determine the search volume. The maximum depth is also used as the maximum
            depth for the finer search
        distance_step_3d: float
            Step size for the horizontal distances used in the finer scan
        widths_3d: array of float
            List of distances to the left and right of the line determined in the first rough
            scan on which the finer scan should be performed
        z_step_3d: float
            Step size for the depts used in the finer scan
        passband: array of float
            Lower and upper bounds off the bandpass filter that is applied to the channel
            waveform and the template before the correlations are determined. This filter
            does not affect the voltages stored in the channels.
        min_antenna_distance: float
            Minimum distance two antennas need to have to be used as a pair in the reconstruction
        debug_folder: string
            Path to the folder in which debug plots should be saved if the debug=True option
            is picked in the run() method.


        General settings for vertex reconstruction

        Parameters
        ----------
        station_id: integer
            ID of the station to be used for the reconstruction
        channel_ids: array of integers
            IDs of the channels to be used for the reconstruction
        detector: Detector or GenericDetector
            Detector description for the detector used in the reconstruction
        passband: array of float or None
            Passband of the filter that should be applied to channel traces before
            calculating the correlation. If None is passed, no filter is applied
        template: array of float or none
            Waveform template with which the channel waveforms are correlated to determine
            the timing differences. If None is passed, the channels are correlated directly
            with each other
        output_path: string or None
            Location where plots of the reconstruction are saved. If None is passed, no plots are
            created.


        Execute the 2D vertex reconstruction

        Parameters
        ----------
        station: Station
            The station for which the vertex shall be reconstructed
        max_distance: number
            Maximum distance up to which the vertex position shall be searched
        z_width: number
            Vertical size of the search area. If direction_guess is specified, a
            stripe of z_width to each side of the initial direction will be searched.
            If direction_guess is not specified, z_width is the maximum depth up
            to which the vertex will be searched.
        grid_spacing: number
            Distance between two points of the grid on which the vertex is searched
        direction_guess: number, defaults to None
            Zenith for an initial guess of the vertex direction. If specified,
            a strip if width 2*z_width around the guessed direction will be searched
        debug: boolean
            If True, debug plots will be produced
        use_dnr: boolean
            If True, DnR pulses are included in the reconstruction by correlating
            the channel waveforms with themselves.


        Calculate the most likely ray type (direct, reflected
        or refracted) of the signal that reached the detector.
        This is done by taking the reconstructed vertex position,
        calculating the expected time offset between channels and
        checking for which ray type scenario the correlation
        between channels is largest.

        Parameters
        ----------
        station: station object
            The station on which this reconstruction was run
        ch1: channel object
            The channel for which the ray type shall be determined


        Define settings for the reconstruction.

        Parameters
        ----------
        electric_field_template: NuRadioReco.framework.base_trace.BaseTrace object
            BaseTrace (or child class) object containing an electric field template
            that is used to determine the position of the radio pulse in the channel
            waveforms.
        passband: list of floats or None
            Lower and upper bound of the filter that should be applied to the channel
            waveforms and the IFT model. If None is passed, no filter is applied
        filter_type: string
            Name of the filter type to be used. Has to be implemented in the NuRadioReco.utilities.
            signal_processing.get_filter_response function. Only used if passband is not None
        amp_dct: dictionary
            Dictionary containing the prior settings for the electric field spectrum
        pulse_time_prior: float
            Expected pulse time relative to the trace start time. Note that this is the time of the
            electric field pulse, not the voltage pulse
        pulse_time_uncertainty: float
            Uncertainty on the pulse time
        n_iterations: integer
            Number of times the IFT minimizer iterates. More iterations lead to better results, but
            increase run time.
        n_samples: integer
            Number of prior samples the IFT minimizer uses to find the maximum prior. Also the number of
            samples used to estimate uncertainties
        polarization: string
            Polarization of the reconstructed radio signal. If set to "theta" or "phi", only that
            component of the electric field is reconstructed. If set to "pol", both components
            are reconstructed.
        relative_tolerance: float
            Relative improvement for the minimizer in a cycle for the optimization to finish.
        convergence_level: integer
            Number of cycles the relative improvement of the minimizer has to be below relative_tolerance
            for the optimization to finish.
        energy_fluence_passbands: list of floats
            List of passbands for which the energy fluence is calculated
        slope_passbands: list of floats
            List of passbands to calculate the ratio of the energy fluences in different passbands.
        phase_slope: string
            Specifies the sign of the slope of the linear function describing the phase of the electric field.
            Options are "negative", "positive" and "both". If "both" is selected, positive and negative slopes
            are used and the best fit is selected.
        debug: bool
            If true, debug plots are drawn.


        Plots samples from the prior distribution of the electric field.

        Parameters
        ----------
        event: NuRadioReco.framework.event.Event object
        station: NuRadioReco.framework.station.Station object
        detector: NuRadioReco.detector.detector.Detector object or child object
        channel_ids: list of floats
            IDs of the channels to use for the electric field reconstruction


        Run the electric field reconstruction

        Parameters
        ----------
        event: NuRadioReco.framework.event.Event object
        station: NuRadioReco.framework.station.Station object
        detector: NuRadioReco.detector.detector.Detector object or child object
        channel_ids: list of integers
            IDs of the channels to be used for the electric field reconstruction
        efield_scaling: boolean
            If true, a small variation in the amplitude between channels is included
            in the IFT model.
        use_sim: boolean
            If true, the simChannels are used to identify the position of the radio pulse.


    Performs forward FFT with correct normalization that conserves the power.

    Parameters
    ----------
    trace: np.array
        time trace to be transformed into frequency space
    sampling_rate: float
        sampling rate of the trace

    Returns
    -------
    spec: np.array
        Frequency spectrum


    Performs backward FFT with correct normalization that conserves the power.

    Parameters
    ----------
    spectrum: complex np array
        the frequency spectrum
    sampling_rate: float
        sampling rate of the spectrum
    n: int
        the number of sample in the time domain (relevant if time trace has an odd number of samples)

    Returns
    -------
    trace: np.array
        Time series/trace


    Read in a pickle file and return the result
    This utility is supposed to provide compatibility for pickles created with
    different python versions. If a simple pickle.load fails, it will try to
    load the file with a specific encoding.

    Parameters
    ----------
    filename: string
        Name of the pickle file to be opened
    encoding: string
        Encoding to be used if the first attempt to open the pickle fails


        registers modules applied to this event

        Parameters
        ----------
        instance: module instance
            the instance of the module that should be registered
        name: module name
            the name of the module
        kwargs:
            the key word arguments of the run method


        Adds a radio shower to the event

        Parameters
        ----------
        shower: RadioShower object
            The shower to be added to the event


        Add a simulated shower to the event

        Parameters
        ----------
        sim_shower: RadioShower object
            The shower to be added to the event


        Checks if station has a trigger with a certain name.
        WARNING: This function does not check if the trigger has triggered.

        Parameters
        ----------
        trigger_name: string
            the name of the trigger

        Returns bool


    helper function to linearly interpolate between two complex numbers

    Parameters
    ----------
    x: float
        the requested position
    x0, y0: float, complex float
        the first data point
    x1, y1: float, complex float
        the second data point
    interpolation_method: string
        specifies if interpolation is in

        * complex (default) i.e. real and imaginary part
        * magnitude and phase

    Returns
    -------
    y: complex float
        the interpolated value


    reads in WIPLD data

    Parameters
    ----------
    ad1: string
        path to ad1 file
    ra1: string
        path to radiation pattern file
    orientation: string
        path to orientation file
    gen_num: int
        which antenna (one or two) to pull from
    s_parameters: list of 2 ints
        determines which s-parametr to extract (ex: [1,2] extracts S_12 parameter).

    Returns
    -------
    all parameters of the files


    preprocesses WIPLD file

    this function implements the older insufficient calculation of the vector effective length. This VEL only
    relates the incident electric field to the open circuit voltage and not the voltage in a 50 Ohm system.

    Parameters
    ----------
    path: string
        path to folder containing ad1, ra1, and orientation files.
    gen_num: int
        which antenna (one or two) to pull from
    s_parameters: list of 2 ints
        determines which s-parametr to extract (ex: [1,2] extracts S_12 parameter).

    Returns
    -------
    orientation theta: float
        orientation of the antenna, as a zenith angle (0deg is the zenith, 180deg is straight down); for LPDA: outward along boresight; for dipoles: upward along axis of azimuthal symmetry
    orientation phi: float
        orientation of the antenna, as an azimuth angle (counting from East counterclockwise); for LPDA: outward along boresight; for dipoles: upward along axis of azimuthal symmetry
    rotation theta: float
        rotation of the antenna, is perpendicular to 'orientation', for LPDAs: vector perpendicular to the plane containing the the tines
    rotation phi: float
        rotation of the antenna, is perpendicular to 'orientation', for LPDAs: vector perpendicular to the plane containing the the tines
    ff2: array of floats
        array of frequencies
    theta: float
        zenith angle of inicdent electric field
    phi: float
        azimuth angle of incident electric field
    H_phi: float
        the complex realized vector effective length of the ePhi polarization component
    H_theta: float
        the complex realized vector effective length of the eTheta polarization component


    Helper function that parses the ARAsim ASCII files containig antenna responses

    Parameters
    ----------
    ara: string
        path to the file

    Returns
    -------
    ff: array of floats
        frequencies
    thetas: array of floats
        zenith angle of inicdent electric field
    phis: array of floats
        azimuth angle of inicdent electric field
    gains: array of floats
        corresponding linear gain values
    phases: array of floats
        corresponding phases


    preprocess an antenna pattern in the ARASim ASCII file format.

    The vector effective length is calculated and
    the output is saved to the NuRadioReco pickle format.

    Parameters
    ----------
    path: string
        the path to the file


    Helper function that parses the HFSS files containig antenna responses

    Parameters
    ----------
    hfss: string
        path to the file

    Returns
    -------
    ff: array of floats
        frequencies
    thetas: array of floats
        zenith angle of inicdent electric field
    phis: array of floats
        azimuth angle of inicdent electric field
    magnitudes_theta: array of floats
        corresponding logarithmic magnitude values theta component
    magnitudes_phi: array of floats
        corresponding logarithmic magnitude values phi component
    phases_phi: array of floats
        corresponding phases phi component
    phases_theta: array of floats
        corresponding phases theta component


    preprocess an antenna pattern in the HFSS file format. The realized vector effective length is calculated and the output is saved in the NuRadioReco pickle format.

    The vector effective length calculation still needs to be verified.

    The frequencies, theta, phi, magnitude theta, magnitude phi, phase theta and phase phi are read from the csv file and than ordered according to the NuRadioReco format.

    Parameters
    ----------
    path: string
        the path to the file


    preprocess an antenna pattern in the XFDTD file format. The realized vector effective length is calculated and
    the output is saved to the NuRadioReco pickle format.

    Parameters
    ----------
    path: string
        the path to the file


        transform zenith and azimuth angle in NuRadio coordinate system to the WIPLD coordinate system.
        In addition the orientation of the antenna as deployed in the field is taken into account.

        Parameters
        ----------


        Adds an entry to the list of event-specific changes to the detector
        description.

        Parameters
        ----------
        properties: dictionary
            Dictionary of the properties that should be changed, with keys being
            any of the property names in the detector description and values the
            values that these properties should be changed to
        station_id: integer
            ID of the station whose properties should be changed
        run_number: integer
            Run number of the event for which the changes are valid
        event_id: integer
            Event ID of the event for which the changes are valid


    Default file was imported from:
    https://github.com/bhokansonfasig/pyrex/tree/master/pyrex/custom/ara/data

    Parameters
    ----------
    path: string
        Path to the file containing the system response


Runs a K-fold model.

    Splits the data into folds, and builds and evaluates a model for
    each fold.

    Parameters
    ----------
    model_params : ModelParams
        The dictionary of model parameters.
    samples : DataFrame
        A data frame containing the samples.
    X : dict
        The predictor data. The keys are the name of each source. Each
        value is an array of the predictors for that source. The first
        dimension is assumed to correspond to the rows of the samples
        data frame in length and order.
    y : Array
        The labels. A 1-dimensional array containing the label for each
        sample.

    Returns
    -------
    models : ModelList
        A list (length k) of the k-fold models. To save memory, the
        Keras components are removed from the models before they are
        returned.


Prepares data for LFMC model training or prediction.

    Prepares the data for an LFMC model test.
     - Only the inputs in the ``dataSources`` model parameter are
       processed
     - Extracts the auxiliary columns from the sample data
     - One-hot encodes any categorical auxiliary columns
     - Extracts a sub-series from each time series input based on the
       start and end model parameters.
     - Normalises the timeseries data using ``model_params`` settings
     - Augments the auxiliary data with the last item in each time
       series if required

    Parameters
    ----------
    model_params : ModelParams
        The dictionary of model parameters.
    samples : DataFrame or None, optional
        A data frame containing the samples. If None, the samples will
        be loaded from the file specified in the ``samplesFile`` model
        parameter. The default is None
    X : dict or None, optional
        The predictor data. The keys are the name of each source. Each
        value is an array of the predictors for that source. The first
        dimension is assumed to correspond to the rows of the samples
        data frame in length and order. Any keys not in ``dataSources``
        are ignored, as is any ``aux`` key (``aux`` is generated from
        the ``samples``). If a key for any of the ``dataSources`` is
        missing, that source is loaded from the file specified in the
        ``<source>Filename`` model parameter. If X is ``None`` or an
        empty dictionary then all ``dataSources`` sources are loaded
        from the source files. The default is {}.

    Returns
    -------
    X : dict
        A dictionary of the prepared data. Dictionary keys are the input
        names and values are numpy arrays of each input.


Creates a set of LFMC models.

    Creates a set of LFMC models. The number of models (or model runs)
    controlled by the modelRuns model parameter.

    If only a single run is requested, the model parameters are passed
    unchanged to either ``train_test_model`` (after splitting the data)
    or ``run_kfold_model``.

    If multiple runs are requested, the model parameters are modified
    to set a unique output directory for each run and to set the random
    seed (using the seedList). If required, the data is re-split
    between each run. After all runs are completed, aggregate
    evaluation statistics are created. If the same splits were used for
    each run, ensembles of equivalent models from all runs are created
    and evaluated.

    To save memory, the Keras components are removed from the models
    before they are returned. If the models need to be kept, ensure
    the ``saveModels`` model parameter is ``True``.

    Parameters
    ----------
    model_params : ModelParams
        The dictionary of model parameters.
    samples : DataFrame, optional
        A data frame containing the samples. If `None` the samples will
        be loaded from the source file. The default is None.
    X : dict, optional
        The predictor data. The keys are the name of each source. Each
        value is a DataFrame of the predictors for that source. If an
        empty dictionary or any sources are missing, these sources will
        be read from the source files. Any sources set to `None` will
        be skipped. The default is {}.
    y : pd.Series, optional
        The labels. A series containing the label for each sample.
        If `None` the labels will be extracted from the samples. The
        default is None.

    Returns
    -------
    LfmcModel or ModelList
        The trained and evaluated model or models.


Runs an LFMC experiment

    Parameters
    ----------
    experiment : dict
        A dictionary of experiment parameters.
    model_params : ModelParams
        The model parameter dictionary.
    samples : DataFrame, optional
        A data frame containing the samples. If `None` the samples will
        be loaded from the source file. The default is None.
    X : dict, optional
        The predictor data. The keys are the name of each source. Each
        value is a DataFrame of the predictors for that source. If an
        empty dictionary or any sources are missing, these sources will
        be read from the source files. Any sources set to `None` will
        be skipped. The default is {}.
    y : pd.Series, optional
        The labels. A series containing the label for each sample.
        If `None` the labels will be extracted from the samples. The
        default is None.

    Returns
    -------
    models : ModelList
        The results of each test in the experiment. Each element is
        either a Model (for single runs, without k-fold splits) or a
        ModelList (for multi-run tests, or tests using k-fold splits).


Reshape an array

    Reshape a two dimensional array of rows with flattened timeseries
    and channels to three dimensions.

    Parameters
    ----------
    X : np.array
        A two dimensional array. The first dimension is the row, the
        second the features ordered by date then band/channel - e.g.
        d1.b1 d1.b2 d1.b3 d2.b1 d2.b2 d2.b3 ...
    nchannels : int
        Number of channels.

    Returns
    -------
    np.array
        A 3 dimensional array where the first dimension are rows, the
        second time and the third the band or channel.


Gets the percentile bounds from an array

    Gets the percentile bounds for a 2-d or 3-d array. Dimensions are
    assumed to be [instances, time-steps, features], so for non-TS data
    of size n*m, reshape to (n, 1, m).

    Parameters
    ----------
    data : np.array
        Input dataset. Must have at least two dimensions.
    percentiles : int, tuple-like or list-like
        Percentiles for bounds. If int, this is assumed to be the lower
        percentile, and the upper percentile is 100 - lower percentile.
        If tuple-like, it should be the lower and upper percentiles. If
        list-like, should be a list in the format [`lower`, `upper`]
        where `lower` and `upper` are arrays of length `m` and specify
        the lower and upper percentiles for each feature. `Upper` is
        optional and is set to `100 - lower` if not provided.

    Returns
    -------
    np.array
        The bounds, calculated across the first two dimensions.


Saves the normalisation bounds.

    Save the normalisation bounds in CSV format to file
    ``<model_dir>/<input_name>_bounds.csv``

    Parameters
    ----------
    bounds : np.ndarray
        Two-dimensional array. First dimension is the lower and upper
        bounds, second dimension is the bounded channels or features.
    input_name : str
        Name of the input. Used for deriving the save file name.
    model_dir : str
        Name of the directory where the bounds are to be saved.

    Returns
    -------
    None.


Loads the normalisation bounds.

    Load the normalisation bounds from CSV file
    ``<model_dir>/<input_name>_bounds.csv``

    Parameters
    ----------
    input_name : str
        Name of the input. Used for deriving the save file name.
    model_dir : str
        Name of the directory where the bounds are saved.

    Returns
    -------
    bounds : np.ndarray
        Two-dimensional array. First dimension is the lower and upper
        bounds, second dimension is the bounded channels or features.


Normalises the data.

    Normalises and optionally clips an array. When using the minMax or
    standard methods, the data must be a 2-d or 3-d array (unused
    dimensions can be size 1) and data is normalised across the first 2
    dimensions. If clipping is requested, data is clipped before being
    normalised.

    Parameters
    ----------
    data : np.ndarray
        Array of the data to be normalised.
    method : str, optional
        Normalisation method to use. Currently implemented methods are:
          - minMax: Normalise so the lower percentile is 0 and the
            upper percentile is 1.
          - range: Normal across a set range, so lower range is 0 and
            upper range is 1.
          - standard: Normalise to mean=0, std_dev=1. If `mean` and `sd`
            parameters are provided, assume these values for input data
            mean and std_dev, else calculate these from the data.
          - FW_ratio: Convert the LFMC values to the fresh weight ratio
            (instead of dry weight ratio) and scale to range [-1, 1].
          - none: Default. No normalisation performed. Data is clipped
            if required, otherwise returned unchanged.
    percentiles : int or list-like, optional
        The percentile to use with the minMax method, If a single int
        value, this is treated as the lower percentile and the upper
        percentile is set to 100 - the value. Arrays of lower and upper
        percentiles can also be provided. See `percentiles_to_bounds`
        for details. The default is 0.
    data_range : tuple or list-like, optional
        Two values corresponding to the lower and upper bounds of the
        normalisation range. The values can be numbers or numpy arrays
        that can be broadcast to `data`. The default is [0, 10000].
    scaled_range : tuple or list-like, optional
        Two values corresponding to the lower and upper bounds of the
        output range. The values can be numbers or numpy arrays that
        can be broadcast to `data`. After normalising, the data is
        re-scaled to this range. The default is (0, 1).
    clip : bool, optional
        Indicates if the data should be clipped to ``range`` (``True``)
        or not (``False``). The default is False.
    input_name : str
        The name of the model input being processed. Required if either
        ``save_bounds`` or ``load_bounds`` are True. The default is
        None.
    model_dir : str
        The name of the model directory. Required if either
        ``save_bounds`` or ``load_bounds`` are True. The default is
        None.
    save_params : bool
        If ``True`` the bounds or mean/sd are saved. The ``input_name``
        and ``model_dir`` parameters must also be provided. The default
        is False.
    load_params : bool
        If ``True``: If the method is ``minMax``, the bounds are loaded
        from saved bounds, rather than computed from the data. If the
        method is ``standard`` the mean and sd are loaded from the
        saved bounds. The ``input_name`` and ``model_dir`` parameters
        must also be provided. The default is False.
    return_params : bool
        If ``True``, a dictionary of parameters is returned. This
        dictionary can be used to update the parameters used on this
        call to ``normalise`` to values that allow another set of data
        to be normalised or denormalised consistently with the current
        dataset. The default is False.
    mean : number or list-like, optional
        For the ``standard`` method. The mean of the denormalised data.
    sd : number or list-like, optional
        For the ``standard`` method. The standard deviation of the
        denormalised data.

    Returns
    -------
    np.ndarray
        The normalised data.


De-normalises the data.

    Converts normalised data back to de-normalised values. When using
    the minMax or standard methods, the data must be a 2-d or 3-d array
    (unused dimensions can be size 1) and data is de-normalised across
    the first 2 dimensions.

    Parameters
    ----------
    data : np.ndarray
        Array of the data to be normalised.
    method : str, optional
        Normalisation method to use. Currently implemented methods are:
          - minMax: Normalise so the lower percentile is 0 and the
            upper percentile is 1.
          - range: Normal across a set range, so lower range is 0 and
            upper range is 1.
          - FW_ratio: Convert the LFMC values from fresh weight ratios
            back to dry weight ratios.
          - none: Default. No normalisation performed. Data is clipped
            if required, otherwise returned unchanged.
    in_range : tuple or list-like, optional
        Two values corresponding to the lower and upper bounds of the
        normalisation range. The values can be numbers or numpy arrays
        that can be broadcast to `data`. The default is [0, 10000].
    out_range : tuple or list-like, optional
        Two values corresponding to the lower and upper bounds of the
        output range. The values can be numbers or numpy arrays that
        can be broadcast to `data`. After normalising, the data is
        re-scaled to this range. The default is (0, 1).
    mean : number or list-like, optional
        For the ``standard`` method. The mean of the denormalised data.
    sd : number or list-like, optional
        For the ``standard`` method. The standard deviation of the
        denormalised data.

    Returns
    -------
    np.ndarray
        The de-normalised data.


Creates the one-hot encoder

    Creates, fits and optionally saves a one-hot encoder. If
    ``fit_data`` is specified, this is used to fit the one-hot encoder.
    If ``fit_data`` is not specified, the ``onehot_data.json`` file in
    ``model_dir`` is loaded and used to create the one-hot encoding
    categories. If ``save`` is ``True``, ``fit_data`` is a DataFrame
    and ``model_dir`` is specified, ``save_onehot_enc`` is called to
    save the data required to re-create the one-hot encoder.

    Parameters
    ----------
    onehot_cols : list
        List of columns to one-hot encode.
    fit_data : pd.DataFrame or np.ndarray, optional
        The data to use to fit the encoder. The default is None.
    model_dir : str, optional
        If ``fit_data`` is none, the directory containing the saved
        one-hot encoder data. If ``save`` is ``True``, the directory
        where this data should be saved. The default is None.
    save : bool, optional
        Whether or not to save the one-hot encoder data. The default is
        False.

    Returns
    -------
    onehot_enc : sklearn.OneHotEncoder
        The fitted one-hot encoder.


Saves the model parameters

        Convert the model parameters dictionary to a JSON string and
        optionally save to a file.

        Parameters
        ----------
        file_stream : str or file handle, optional
            Either the name of the output file, or a file handle for
            the output file. If None, the converted JSON string is
            returned. The default is None.
        directory : str, optional
            If file_stream is str, the directory the output file is
            created in. It will be created if it doesn't exist. The
            default is ``self['modelDir']`` if this key exists, else
            None.

        Returns
        -------
        str
            The JSON representation of the model parameters. Only
            returned if no file stream parameter specified.


Prints a help message

        Prints the general help message if no key provided, or the help
        message for the specified key.

        Parameters
        ----------
        key : str, optional
            The key for which help is requested. If None, the general
            help message is displayed. The default is None.

        Returns
        -------
        None.


Sets parameters for a model block

        Creates a set of model parameters that will be used to build a
        block of layers. Currently supports (1D) convolutional blocks
        and dense (or fully-connected) blocks. Parameters for each
        layer are set to the defaults for the block type and then
        updated using ``block_params``, if this parameter is set.

        Parameters
        ----------
        block_name : str
            A name for the block.
        block_type : str
            Either "Conv" for a convolutional block, or "Dense" for a
            dense block.
        num_layers : int
            The number layers in the block.
        block_params : dict, optional
            A dictionary of parameters that override or add to the
            default parameter settings.

        Returns
        -------
        None.


 Adds an input to the model parameters.

        Parameters
        ----------
        name : str
            Input name.
        input_params : dict
            Dictionary of parameters. Valid keys are:
            'filename': Required.
                Full path name of the file containing the data for a
                list of file names.
            'channels': Required for time series inputs.
                Number of channels in the dataset.
            'includeChannels': Optional for time series inputs.
                A list of channels to include in the prepared data. By
                default, all channels are included.
            'normalise': Optional.
                A dictionary containing the method to use to normalise
                the data, plus any parameters required by this method.
            'start': Optional.
                Time series start. The offset from the start of the
                input time series.
            'end': Optional.
                Time series end. The offset from the end of the input
                time series. "None" means no end offset.
        data_type : str, optional
            Input type. Specify 'ts' (the default) if the input is a
            time series. This ensures a default value for all the time
            series input parameters (channels/start/end) is set. If any
            other value is specified, no defaults for these parameters
            are set, although they may be provided in the input_params.

        Returns
        -------
        None.


Merges fold predictions

    Merges the predictions from each fold to create a predictions file
    for the run. If results from intermediate epochs have been saved
    then the epoch predictions are also merged. Statistics for each
    merged set of predictions are saved.

    The merged predictions and stats are saved as ``models`` attributes
    *_predicts and *_stats. Any results for intermediate epochs are
    saved to the epoch_*_predicts and epoch_*_stats attrbiutes.

    Parameters
    ----------
    model_dir : str
        Name of directory containing the folds, and where the merged
        results will be written.
    models : ModelList
        The kfold models to merge. The model results should be stored
        in the ``*_predicts`` and ``*_stats`` attributes on each model.
    epochs : bool, optional
        Indicates if results were saved at intermediate epochs. If
        ``True``, the epoch results are also merged. The default is False.


 Create ensembles for all derived models.

    Create and evaluate ensembles of the individual run predictions for
    a test or model set. Ensembles can be created using all runs or for
    a selection of runs. They can be generated from the full models or
    for any saved epoch.

    Parameters
    ----------
    model_dir : str or None
        Directory containing the models if they are to be read from
        disk, also where the results are saved. If None, models must be
        a ModelList or a list of predictions, and ensembles will not be
        saved.
    models : ModelList, list or str, optional
      - If a ``ModelList``: List of the models to ensemble. The function
        assumes each model has test_stats and test_predicts attributes
        and adds attributes for the test and ensemble results.
      - If a ``str`` or ``list``: A directory or list of directories
        containing the models to ensemble. These are relative to
        ``model_dir`` and may contain wildchars. The directories or
        relevant epoch sub-directories) are assumed to contain a file
        called ``predictions.csv`` that holds the model predictions.
        Any directory without this file is silently ignored. The
        default is 'run*'.
      - If a ``list`` and ``model_dir`` is ``None``: A list of
        prediction dataframes to ensemble.
    epoch : str, optional
        Name of the epoch directory. Required when model evaluation at
        regular epochs is to be done. Ensembles are created using all
        runs that saved results at this epoch. If '', the results from
        the full model are used. The default is ''.
        Note: ``epoch`` is ignored if ``models`` is a ``ModelList``.
    classify: bool, optional
      - True: The labels and predictions are classes
      - False: The labels and predictions are numbers. The default is
        False.
    ensemble_name : str, optional
        Name of the ensemble. This is prefixed to the output file names
        (Note: For compatibility, if the default name is used it is
        not prefixed to the ensemble plots). The default is 'ensemble'.
    precision : int, optional
        The precision of the ensemble statistics. The default is 2.

    Returns
    -------
    ensembles : DataFrame
        A dataframe containing the ensemble predictions indexed by the
        sample ids. Columns are the checkpoint (derived) models.
    all_stats : DataFrame
        A dataframe containing the prediction statistics indexed by the
        checkpoint (derived) model. Columns are the statistic type.


 Generate sets of ensembles

    Can generate sets of ensembles of varying sizes for a test or model
    set, or a set of ensembles of fixed size for all tests in an
    experiment.

    Parameters
    ----------
    model_predicts : list
        Either a list of prediction data frames forming a model set
        Or a list of lists of prediction data frames forming an
        experiment (one list of prediction data frames for each test).
    ensemble_runs : int
        The number of ensembles (for each test) to create.
    ensemble_sizes : int or list
        Either the size of the ensembles or a list of ensemble sizes.
    classify: bool, optional
      - True: The labels and predictions are classes
      - False: The labels and predictions are numbers. The default is
        False.
    precision : int, optional
        The precision of the ensemble statistics. The default is 2.
    uncertainty : bool, optional
      - True: Return the standard deviations of the individual
        predictions as an uncertainty estimate
      - False: Do not return uncertainty estimates. The default False.
    random_seed : int, optional
        The random number generator seed. The default is 99.

    Returns
    -------
    preds : list
        a list of the predictions made by each ensemble. A list of
        lists if model_predicts is a list of data frames.
    std_devs : list
        The standard deviations of the individual predictions (the
        uncertainty estimate). Only returned if ``uncertainty`` is True.
    stats : list
        a list of the prediction statistics for each ensemble. A list
        of lists if model_predicts is a list of data frames.


Partitions a dataset by year

    Ensures temporal separation of the test and training samples. The
    main usage is to ensure all samples in the training
    set were collected before ``year``, and all samples in the test
    set were collected on or after ``year``. Each input index is a bool
    index listing the candidate samples. The function sets the index to
    `False` for samples that were not collected in the right years.

    NOTES:
      1. `train_adjust` and/or `test_adjust` can be used to adjust\
        the start/end of the training and/or test sets from the\
        beginning/end of the year.
      2. If `test_adjust` < `-train_adjust`, some samples may be in\
        both the training and test sets.
      3. If `train_adjust` is `"nonTest"`, the training and\
        date range is all dates outside the test date range.

    Parameters
    ----------
    sample_dates : pd.Series
        The sampling date for each sample.
    year : int
        The first year to include in the test set.
    train_index : np.array
        1-dimensional bool array the same length as sample_dates.
        Samples in the training set should be set to True, all others
        to False.
    test_index : np.array
        1-dimensional bool array the same length as sample_dates.
        Samples in the test set should be set to True, all others
        to False.
    num_years : int, optional
        The number of years to include in the test set. Samples
        collected in years later than `year + num_years` are discarded.
        Specify `None` or `0` to include all data from or after `year`
        in the test set.
    test_all_years : bool, optional
        If ``True``, the test index is returned unchanged (train_index
        is still updated). The default is False.
    train_adjust : int or str, optional
        If int: The number of days to adjust the end date of the
        training and validation sets. E.g. `90` will remove all samples
        within 90 days of the end of the training set. These samples
        are discarded (NOT added to the test set).
        If str: The only valid value is 'nonTest'. Only the samples
        that are in the test set are removed from the training and
        validation sets.
        The default is 0.
    test_adjust : int, optional
      - The number of days to adjust the start and end date of the test
        set. A postive number will shift the dates forward and a
        negative number will shift them backwards. E.g. setting
        `test_adjust` to `90`, `year` to `2014` and `num_year` to `1`
        will result in a test set containing samples from `01-Apr-2014`
        to `31-Mar-2015`. Samples in the adjustment period (e.g.
        `01-Jan-2014` to `31-Mar-2014`) are discarded (NOT added to the
        training or validation sets).
      - The default is 0.

    Returns
    -------
    train_index : np.array
        The updated training index with all samples for the test years
        set to False.
    test_index : np.array
        The updated test index with all samples for years other than
        the test years set to False.


Partitions a dataset by value

    Ensures separation by value of the test and training samples. Each
    input index is a bool index listing the candidate samples. The
    function sets the train index to `False` for samples that do not
    have a valid train value and test index to `False` for samples that
    do not have a valid test value.

    Parameters
    ----------
    part_data : pd.Series
        The column to use to partition the data.
    train_index : np.array
        1-dimensional bool array the same length as part_data.
        Samples in the training set should be set to True, all others
        to False.
    test_index : np.array
        1-dimensional bool array the same length as part_data.
        Samples in the test set should be set to True, all others
        to False.
    train_values : list
        The list of values to include in the training data. If ``None``
        (or anything other than a list), the train_index and val_indexes
        are returned unchanged
    test_values : list
        The list of values to include in the test data. Values may
        overlap with train_values. If ``None`` (or anything other than a
        list), the test_index is returned unchanged.

    Returns
    -------
    train_index : np.array
        The updated training index with all samples for the test years
        set to False.
    test_index : np.array
        The updated test index with all samples for years other than
        the test years set to False.


Splits samples randomly

    Randomly assigns numbers in range(0, num_samples) to the test and
    training sets in accordance with the required split
    sizes. Returns an index for each set that indicates which samples
    are in each set.

    Parameters
    ----------
    num_samples : int
        The number of samples.
    test_size : float or int
        The size of the test set. If int, the number of samples. If
        float, the proportion of samples.
    random_seed : int, optional
        The seed for the random number generator. The default is None.

    Returns
    -------
    train_index : array of bool
        An array of length num_samples. True if the sample should be
        included in the training set, false otherwise.
    test_index : array of bool
        An array of length num_samples. True if the sample should be
        included in the test set, false otherwise.


Creates a validation set from the training data.

    Parameters
    ----------
    num_samples : int
        Total number of samples (including test samples).
    val_size : int or float
        The number (int) or proportion of the training set (float) to
        allocate to the validation set.
    train_val_idx : np.array
        An array of length num_samples. True for samples in the
        training/validation set, False for samples in the test set.
    random_seed : int, optional
        The random seed. The default is None.

    Returns
    -------
    train_index : array of bool
        An array of length num_samples. True if the sample should be
        included in the training set, false otherwise.
    val_index : array of bool
        An array of length num_samples. True if the sample should be
        included in the validation set, false otherwise.


Splits sample sites randomly.

    Randomly assigns sites to the test, training and validation sets in
    accordance with the required split sizes. If stratified splitting
    is requested, sites are grouped according to the stratified column
    value and split so each group is evenly represented in each set.
    After the sites have been split, samples are assigned to the
    appropriate set based on their site.

    Parameters
    ----------
    data : DataFrame
        Data Frame of samples. Must have a column labelled with
        ``split_col``, and one labelled with ``stratify`` if specified.
    test_size : float or int
        The size of the test set. If int, the number of samples. If
        float, the proportion of samples.
    split_col : str, optional
        The name of the column containing the sample site. The default
        is 'Site'.
    stratify : str or None, optional
        The name of the column to use for stratified splitting. None
        for no stratified splits. The default is None.
    min_sites : int, optional
        The minimum number of sites in a stratified group. Groups with
        fewer sites are combined into a single group. The default is 6.
    random_seed : int, optional
        The seed for the random number generator. The default is None.

    Returns
    -------
    train_index : array of bool
        An array of length equal to rows in data. True if the sample
        should be included in the training set, false otherwise.
    test_index : array of bool
        An array of length equal to rows in data. True if the sample
        should be included in the test set, false otherwise.


Splits sample sites randomly.

    Splits the data into training and test sets by source.

    Parameters
    ----------
    data : DataFrame
        Data Frame of samples. Must have an index or column named
        ``Source``, which will be used to split the data.
    test_sources : list
        A list of sources to use for the test data.
    train_sources : list, optional
        A list of sources to use for the training data. If ``None``, all
        sources that are not test sources are used for training. The
        default is None.
    random_seed : int, optional
        The seed for the random number generator. The default is None.

    Returns
    -------
    train_index : array of bool
        An array of length equal to rows in data. True if the sample
        should be included in the training set, false otherwise.
    test_index : array of bool
        An array of length equal to rows in data. True if the sample
        should be included in the test set, false otherwise.


Creates k-fold splits

    Creates ``nFold`` splits of the "sites" by randomly assigning sites
    to a fold. Then, in turn, each fold is assigned to the test set and
    remaining folds assigned to the training set. (Validation data is
    randomly selected from training data, if required). If stratified
    splitting is requested, sites are grouped by the stratified column
    value and split so each group is evenly represented in each fold.
    After the sites have been split, samples are assigned to the
    appropriate set based on their site.

    Note that if split_col is set to the name of the data index (or
    "index" if unnamed), the folds will be random (stratified) splits
    of the samples, rather than the sites.

    Parameters
    ----------
    data : DataFrame
        Data Frame of samples. Must have a column labelled with
        ``split_col``, and one labelled with ``stratify`` if specified.
    n_folds : int
        The number of folds (``K``) to create.
    test_folds : int
        The number of folds required in each test set. If greater than
        1, all combinations of folds of the required size are generated
        for the test sets, with the remaining data in the train and
        validation sets. Consequntly, the number of train/test splits
        generated is ``<n_folds>C<test_folds>``.
    split_col : str, optional
        The name of the column to use for splitting. The default is
        'Site'. Use the index name for random splitting.
    stratify : str or None, optional
        The name of the column to use for stratified splitting. None
        for no stratified splits. The default is None.
    min_values : int, optional
        The minimum number of ``split_col`` values in a stratified
        group. Groups with fewer values are combined into one group.
        The default is 6.
    random_seed : int, optional
        The seed for the random number generator. The default is None.

    Returns
    -------
    train_index : list of bool arrays
        A list containing a bool array for each fold. The arrays are
        of length equal to rows in ``data``. Elements are True if the
        sample should be included in the training set for the fold,
        false otherwise.
    test_index : list of bool arrays
        A list containing a bool array for each fold. The arrays are
        of length equal to rows in ``data``. Elements are True if the
        sample should be included in the test set for the fold, false
        otherwise.


Splits data into train, test and validation sets

    Splits data into train, test and (optionally) validation sets using
    the index parameters.

    Parameters
    ----------
    data : array
        DESCRIPTION.
    train_index : array of bool
        Array values should be True for entries in the training set,
        False otherwise.
    test_index : array of bool
        Array values should be True for entries in the test set, False
        otherwise.
    val_index : array of bool, optional
        Array values should be True for entries in the validation set,
        False otherwise. If val_index is None, no validation set is
        created. The default is None.

    Returns
    -------
    train_data : array
        The training data.
    test_data : array
        The test data.
    val_data : array or None
        The validation data (if any).


Splits data into folds

    A generator that splits data into folds containing test, training
    and optionally validation sets. The samples are split into ``K``
    roughly equal parts (where ``K`` is the number of folds), then
    folds are formed by using each part in turn as the test set and the
    remaining parts as the training set. The validation set (if used)
    is randomly selected from the training set. The generator yields
    each fold in turn.

    The following model parameters determine how to split the data.

    valSize:
        If > 0, indicates if a validation set should be created.

    splitMethod:
      - random: samples are split randomly
      - byValue: sites are split into test and training sites, then all
        samples from the site are allocated to the respective set
      - NOTE: byYear cannot be used with k-fold splits

    splitFolds:
        The number of folds (``K``) required.

    valSize:
        The proportion or number of samples to allocate to validation
        sets.

    splitColumn:
        The column in the samples containing the site. Used for byValue
        splits.

    splitStratify:
        Indicates the column to use for stratified splitting, if this
        is needed. Stratified splitting groups the sites by value and
        ensures each split contains a roughly equal proportion of each
        group. If None, stratified splittig is not used. Used for
        byValue splits.

    randomSeed:
        The seed for the random number generator.

    Parameters
    ----------
    model_params : ModelParams
        The dictionary of model parameters, used as described above.
    samples : DataFrame
        A data frame containing the samples.
    X : dict
        The predictor data. The keys are the name of each source. Each
        value is an array of the predictors for that source. The first
        dimension is assumed to correspond to the rows of the samples
        data frame in length and order.
    y : Array
        The labels. A 1-dimensional array containing the label for each
        sample.

    Yields
    ------
    data : dict
        The split data with an item for each dataset. Keys are ``test``,
        ``val(idation)``, or ``train(ing)``. Values are dictionaries
        with two entries - ``X`` and ``y``. The ``X`` values are again
        dictionaries, with entries for each source. The lowest level
        values are numpy arrays containg the relevant data. ``val``
        entries are included even when no validation set is required.
        In this case, all lowest level values are ``None``.


Loads the folds for a run

        Creates a ModelList and loads the run results. Optionally
        loads any epoch results and/or populates the ModelList by
        loading any fold models for the run.

        Parameters
        ----------
        model_dir : str
            The name of the directory containing the model run.
        epoch : int
            The epoch to load. If ``None``, all epochs are loaded. If
            anything else and the directory ``epoch{epoch}`` exists in
            ``model_dir`` then that epoch is loaded as if it were the
            final epoch. Otherwise just the final epoch is loaded. The
            default is None.
        get_folds : bool
            If ``True`` then any folds for the run are loaded. If
            ``False`` then the folds are not loaded. The default is
            True.

        Returns
        -------
        ModelList or LfmcModel
            The loaded run - the model or a ModelList of folds.


Loads a set of models

        Creates a ModelList and populates it by loading all models in
        the model set (test or ensemble). If model_dir does not contain
        run directories, assumes the directory is for a single model
        and calls the load_model function to load it.

        Parameters
        ----------
        model_dir : str
            The name of the directory containing the models.
        num_runs : int, optional
            The number of models to load. If falsy (e.g. ``None``), all
            models are loaded. Ignored if model_dir is for a single
            run. The default is None.
        epoch : int
            The epoch to load. If ``None``, all epochs are loaded. If
            anything else and the directory ``epoch{epoch}`` exists in
            ``model_dir`` then that epoch is loaded as if it were the
            final epoch. Otherwise just the final epoch is loaded. The
            default is None.
        get_folds : bool
            If ``True`` then all folds of each run in the model_set are
            loaded. If ``False`` then the folds are not loaded. The
            default is True.

        Returns
        -------
        ModelList or LfmcModel
            The loaded models - the model or a ModelList of runs.


Loads an experiment

        Creates a ModelList and populates it by loading the completed
        tests in an experiment. If model_dir is not an experiment
        directory (does not contain a file called ``experiment.json``),
        assumes the directory is a test and calls the load_model_set
        class method to load it.

        Parameters
        ----------
        model_dir : str
            The name of the directory containing the experiment.
        experiment_only: bool
            True: model_dir must be an experiment directory.
            False: model_dir can be an experiment or test directory.
        num_tests : int, optional
            The number of tests to load. If falsy (e.g. ``None``), all
            tests are loaded. Ignored if ``model_dir`` contains a test
            instead of an experiment. The default is None.

        Returns
        -------
        ModelList
            The loaded experiment - a ModelList of tests.


Displays a list of dataframes.

    Parameters
    ----------
    frames : list
        The list of dataframes to display.
    captions : list, optional
        A list of captions for the dataframes. If any captions are
        provided there must be a caption for each dataframe. The
        default is None.
    precision : int, optional
        Precision for floating point numbers in the dataframes. The
        default is 3.
    separator : string, optional
        Dataframe separator. The default is "\xa0" * 10 (10 spaces).

    Returns
    -------
    string
        HTML to display the dataframes in a notebook.


    Takes a scalar and returns the css property 'font-weight: bold' if
    the value is less than the 'sigLevel' value, 'font-weight: normal'
    otherwise.


    Takes a series that includes a p-value and returns a series of css
    properties 'font-weight: bold' if the p-value is less than
    'sigLevel', 'font-weight: normal' otherwise.


Truncates a matplotlib colormap

    Parameters
    ----------
    cmap : colormap
        The input color map.
    minval : float, optional
        The lower bound for the output colormap. The default is 0.0.
    maxval : float, optional
        The upper bound for the output colormap. . The default is 1.0.
    n : int, optional
        Number of fixed points on the colormap. The default is -1 (use
        the number on the input colormap).

    Returns
    -------
    new_cmap : colormap
        The new colormap.


Plot results for all models

    Parameters
    ----------
    all_results : Data Frame
        A data frame contains the results to plot. The first column
        should be named ``y`` and contain the labels. The other columns
        should be named with the model name.
    all_stats : Data Frame
        A data frame containing the evaluation statistics for each
        model. The index should be the model names and the columns the
        statistic names.
    model_dir : str
        The name of the directory where the plots should be saved.

    Returns
    -------
    None.


Summarizes a set of model results.

    Parameters
    ----------
    model : string
        Specifies which derived model to use - e.g. 'base' for the base
        model, 'merge10' for the derived model formed by merging the
        last 10 checkpoints.
    tests : list
        A list of test names.
    ensembles : list
        A list of dataframes (one for each test) containing the model
        statistics generated by creating an ensemble containing all the
        runs in a test. If ``None`` ensembled results are not generated.
    means : list
        A list of dataframes (one for each test) containing the means
        of the model statistics.
    variances : list, optional
        A list of dataframes (one for each test) containing the
        variances of the model statistics. The default is None -
        variances are not displayed.
    std_devs : list, optional
        A list of dataframes (one for each test) containing the
        standard deviations of the model statistics. The default is
        None - standard deviations are not displayed.
    precision : int, optional
        The floating-point precision to use when displaying the
        dataframes. The default is 2.

    Returns
    -------
    None.


Displays the model bias and variance.

    Parameters
    ----------
    model : string
        Specifies which derived model to use - e.g. 'base' for the base
        model, 'merge10' for the derived model formed by merging the
        last 10 checkpoints.
    tests : list
        A list of test names.
    num_runs : int
        The number of runs in each test.
    source : list
        A list of dataframes containing the predictions for each test.
        A flat list of the runs for all tests, in test then run order
        (i.e. all runs for test 1, then all runs for test 2, etc.).
    all_tests : bool, optional
        If ``True``, the bias and variance is calculated across all
        runs for all tests, as well as the individual tests. The
        default is False.
    heading : str, optional
        Display heading. If None, ``Model: {model}`` is used. The
        default is None.
    precision : int, optional
        The floating-point precision to use when displaying the
        dataframe. The default is 3.

    Returns
    -------
    None.


Extracts time series data for a site

    Extracts time series data for all samples at a set of sites using a
    TimeseriesExtractor. Reports (prints) invalid samples and sites -
    those for which data cannot be extract (as well as returning a list
    of these).

    Parameters
    ----------
    extractor : TimeseriesExtractor
        The TimeseriesExtractor to extract data from.
    sites : DataFrame
        The sites to extract data for. Must have "Site", "Longitude" and
        "Latitude" columns.
    samples : DataFrame
        The samples to extract data for. Must have "ID" and
        "Sampling date" columns.
    earliest_sample_date : datetime
        The earliest date a sample can have to be valid. Samples with
        earlier dates will be returned as invalid_samples, but will not
        be otherwise reported
    tsOffset : int, optional
        The number of days prior to the sample's sampling date that the
        time series should end. The default is 1.
    tsLength : int, optional
        The length of the time series. The default is 365.
    tsFreq : int, optional
        The interval (in days) between timeseries entries. The default
        is 1.

    Returns
    -------
    ts_data : DataFrame
        The extracted timeseries data. Columns are the sample ID, then
        the stacked bands in date then bands order. There is a row for
        each valid sample.
    valid_data : list of bool
        A list with an entry for each sample indicating if data for the
        sample was successful extracted.
    invalid_samples : list of str
        A list of sample IDs for which data could not be extracted.
    invalid_sites : list of str
        A list of sites for which data could not be extracted.


Returns a numeric representation of a site or sample key

    Generates an integer key from a site or sample key. Assumes the key
    is a character followed by numbers between 1 and 999 separated by
    underscores. The leading character is ignored and the numeric parts
    processed from left to right.

    Example:
      - key: C13_1_4; generated key: 13001004
      - key: C6_1_13; generated key: 6001013
      - key: C6_1_5; generated key: 6001005

    These will be ordered as C6_1_5, C6_1_13, and C13_1_4 when sorted
    by the ``sortKey()`` value, a more natural ordering than the
    original alphanumeric sorting.

    Parameters
    ----------
    key : str
        Either a site (e.g. C6_1) or sample key (e.g. C6_1_13).

    Returns
    -------
    genKey : int
        A numeric representation of the key that can be used to sort
        keys into logical order.


 Extracts climate zone data

    Extract climate zone data from a raster file

    Parameters
    ----------
    koppen_file : str
        The name of the climate zone raster file. The file can be any
        format GDAL can read.
    legend_file : str
        The name of the file containing the climate zone codes. The
        file should be a csv file with headers, with the numeric codes
        in the first column and the alphabetic codes in the ``Code``
        column.
    data : pd.DataFrame
        Data Frame of sites.
    loc_columns : list, optional
        Column names of columns containing the site longitude and
        latitude. The default is ['longitude', 'latitude'].
    cz_columns : list, optional
        Names for the three climate zone columns. The default is
        ['Czone1', 'Czone2', 'Czone3'].
    nodata_value : str, optional
        Value to use if climate zone is invalid. The default is ''.
    append_to_data : bool, optional
        If True, climate zones are added to the ``data`` dataframe.
        If False, a list of the climate zones is returned. Has an entry
        for each row in ``data`` (site), which is a list of the three
        climate zone levels for the site. The default is True.

    Returns
    -------
    kop_values : list
        If ``append_to_data`` is False, a list of the climate zones. It
        has an entry for each row in ``data`` (site), which is a list
        of the three climate zone levels for the site.


Normalises DEM data

    Normalise the location and DEM data.

    Parameters
    ----------
    data : DataFrame
        A dataframe containing the data to be normalised.
    input_columns : list, optional
        The columns in ``data`` that represent the longitude, latitude,
        elevation, slope and aspect. The default is
        ``['longitude', 'latitude', 'elevation', 'slope', 'aspect']``.
    precision : int, optional
        The precision of the normalised data. The default is 5.

    Returns
    -------
    dem_norm : TYPE
        DESCRIPTION.


Imports an LFMC model class

    Parameters
    ----------
    model_class : str
        The name of the LFMC model class.

    Returns
    -------
    class
        The imported LFMC model class.


Evaluates a string as code

        If ``param`` is prefixed with ``starts_with`` or one of the
        elements in ``starts_with`` (if a list), it is assumed to be
        code and evaluated. Other strings are returned unchanged.

        If model parameters are set as keras classes or functions, they
        cannot be converted to JSON and stored. Setting the model
        parameter to a string of the function call allows the full set
        of model parameters to be stored as text, while allowing
        specification of any valid parameter.

        Note
        ----
        Currently only implemented for optimizer and kernel_regularizer
        keras parameters (regulariser and optimiser) model parameters.

        Parameters
        ----------
        param : str or object
            The string to evaluate. Not evaluated, if not a string.
        starts_with : str or list, optional
            Only evaluate strings prefixed by this string (if str), or
            by one of the strings in the list. The default is ['keras'].

        Returns
        -------
        object
            The results of evaluating ``param``. If ``param`` is not a
            string or does not start with ``starts_with``, ``param`` is
            returned unchanged.


Generates layers for a 1d-convolution block

        Layers generated are: Conv1D, BatchNormalization, Activation,
        Dropout and AveragePooling1D. Conv1d and Activation layers are
        always generated. Other layers are optional and only included
        if the relevant model_params and conv_params are set as below.

        Parameters
        ----------
        name : str
            The name of the block. Used to generate unique names for
            each layer.
        model_params : ModelParams
            Uses the following ModelParams values:
              - initialiser
              - regulariser
              - activation
              - dropoutRate (Dropout layer included if > 0)
        conv_params : dict
            The convolutional parameters for this block. Required keys:
              - filters
              - kernel
              - stride
              - bnorm (BatchNormalization layer included if True)
              - poolSize (AveragePooling1D layer included if > 0)

        Returns
        -------
        block : list of keras layers
            The keras layers that comprise the convolution block.


Generates layers for a fully-connected (dense) block

        Layers generated are: Dense, BatchNormalization, Activation,
        and Dropout. Dense and Activation layers are always generated.
        The other layers are optional and only included if the relevant
        model_params and conv_params are set as below.

        Parameters
        ----------
        name : str
            The name of the block. Used to generate unique names for each
            layer.
        model_params : ModelParams
            Uses the following ModelParams values:
                initialiser
                regulariser
                activation
                dropoutRate (Dropout layer included if > 0)
        fc_params : dict
            The fully-connected parameters for this block. Required keys
            are:
                units
                bnorm (BatchNormalization layer included if True)

        Returns
        -------
        block : list of keras layers
            The keras layers that comprise the fully-connected block.


Compiles the model

        Compiles the model using the optimizer, loss function and
        metrics from params.

        Returns
        -------
        None.


Trains the model

        Parameters
        ----------
        Xtrain : dict
            The training features. The dict keys are the sources and
            the values are arrays of the data for each source.
        ytrain : array
            The training labels.
        Xval : dict, optional
            The validation features in the same format as Xtrain. The
            default is None. Ignored if model params has valSize = 0.
        yval : TYPE, optional
            The validation labels. The default is None. Ignored if the
            model params has valSize = 0.

        Returns
        -------
        dict
            Dictionary of the training results, with keys:
            'minLoss' - the minimum loss from the training checkpoints
            'history' - the loss and metrics at all checkpoints
            'runTime' - the training time in seconds


Predicts labels from a model

        Parameters
        ----------
        X : dict
            The features to predict from.
        model_name : str, optional
            The name of the model to use for prediction. The 'base'
            model (i.e. fully-trained model) is used if no model
            specified. The default is 'base' (the fully trained model).
        ensemble : function, optional
            If the model is an ensemble, the function to use to combine
            the individual predictions. The default is np.mean.
        batch_size : int, optional
            keras.Model.predict batch_size parameter. The default is 1024.
        verbose : int, optional
            keras.Model.predict verbose parameter. The default is 0.

        Returns
        -------
        yhat : array
            The predicted labels.


Evaluates the model

        Evaluate the model using X as the test data and y as the labels
        for the test data.

        Parameters
        ----------
        X : dict
            The test data.
        y : array
            The test labels.
        model_name : str, optional
            Name of the model to use for the predictions. The default
            is 'base' (the fully trained model).
        ensemble : function, optional
            The function to use if the model is an ensemble. The
            default is np.mean.
        get_stats : bool, optional
            Flag indicating if prediction statistics should be
            calculated. The default is True.
        plot : bool, optional
            Flag indicating if a scatter plot of the results should be
            created. The default is True.
        fig_name : str, optional
            Name for the plot figure. If none, the model name is used.
            The default is None.

        Returns
        -------
        dict
            Dictionary of the evaluation results, with keys:
              - 'predict' - the predicted values
              - 'stats' - the evaluation statistics (bias, R, R2, RMSE,
                ubRMSE)
              - 'runTime' - the prediction time in seconds


Prints the model summary.

        Returns
        -------
        None.


Gets the number of model weights

        Calculates and returns the number of trainable and
        non-trainable weights in the model.

        Returns
        -------
        trainable : np.int32
            The number of trainable weights in the model.
        untrainable : np.int32
            The number of non-trainable weights in the model.


Saves model plot

        Calls the Keras plot_model utility to create an image of the
        model network.

        Parameters
        ----------
        file_name : str
            Name of the plot file (relative to self.model_dir).

        Returns
        -------
        None.


Loads the model

        Loads a saved model from disk. Run this method after creating
        the instance with no parameters.

        Parameters
        ----------
        model_dir : str
            The full path name of the directory storing the model.

        Returns
        -------
        None.


Saves the model history

        Saves the model plot, model parameters and training history
        Saves the model training history

        Returns
        -------
        None.


Loads a derived model

        Parameters
        ----------
        model_name : str
            The name of the derived model. This is assumed to be the
            filename (relative to the model directory), excluding the
            suffix, for a single model; or a directory containing the
            individual files for an ensemble.

        Returns
        -------
        None.


Saves models to disk

        Saves the specified model or models to disk. If neither
        ``model_name`` or ``model_list`` are specified, all models are
        saved.

        Parameters
        ----------
        model_name : str, optional
            Name of the model to save. The default is None.
        model_list : list, optional
            List of models to save. The default is [].

        Returns
        -------
        None.


Clears the model

        Removes as much of the model as possible, including:
          - model and derivedModel attributes
          - keras backend session
          - deallocate GPU and memory
          - runs garbage collection
          - delete all checkpoint files

        After running clear_model, the model instance still exists but
        no keras components will exist. As the checkpoint files are
        removed, no new derived models can be created. All other
        components are saved to disk and can be reloaded using the load
        and load_model methods.

        Returns
        -------
        None.


Creates a model by merging a set of models

        Create a model from a set of model checkpoints by averaging the
        equivalent weights from each model. A merged model is similar
        to an ensemble but usually slightly less accurate than an
        ensemble of the same set. The advantage is that it is much
        faster to predict from the merged model.

        Parameters
        ----------
        model_name : str
            A name for the merged model.
        models : list, optional
            The models to merge. See ``get_models model`` parameter for
            details of how this parameter is used. The default is None,
            meaning all checkpoints are merged.

        Returns
        -------
        None.


Creates a model by ensembling a set of models

        Create a model as an ensemble of checkpoints.

        Parameters
        ----------
        model_name : str
            A name for the ensemble model.
        models : list, optional
            The models to ensemble. See ``get_models model`` parameter
            for details of how this parameter is used. The default is
            None, meaning all checkpoints are ensembled.

        Returns
        -------
        None.


Creates a model using the best ``n`` checkpoints

        Create a model using the checkpoint(s) with the lowest loss.

        Parameters
        ----------
        model_name : str, optional
            A name for the model. If ``None``, a name is generated from
            the other parameters.
        n : int
            The number of checkpoints to use. If 1, then a model is
            created using a single checkpoint with the lowest loss. If
            > 1, create a model using the ``n`` checkpoints with the
            lowest loss. The default is 1.
        merge : bool, optional
            If n > 1, indicates whether to merge (True) or ensemble
            (False) the best ``n`` checkpoints. The default is True.

        Returns
        -------
        None.


Creates a plot of the training result at each epoch.

        Parameters
        ----------
        file_name : str, optional
            The file name for the plot, relative to the model directory.
            The `.png` extension is appended to the file name. If
            ``None`` the name ``training_{metric}.png`` is used. The
            default is None.
        metric : str, optional
            The name of the metric to plot. If ``None``, the checkpoint
            monitored metric is used, otherwise can be any metric
            included in the ``metrics`` model parameter. The default is
            None.
        rolling : int, optional
            The number of epochs to use to plot the rolling (moving)
            average. If 1 (or less), no rolling average is plotted. The
            default is 10.

        Returns
        -------
        None.


Builds the model.

        Build the model with layers and hyper-parameters as specified
        in params. The shape of the inputs are used to define the keras
        input layers.

        Parameters
        ----------
        inputs : dict
            Should contain a key for each input and values an array of
            the correct shape. The dimensions of the array are used to
            build the model layers.

        Returns
        -------
        None.