# Path: idtxl/single_process_analysis.py
# class SingleProcessAnalysis(NetworkAnalysis):
#     def __init__(self):
#         super().__init__()
# 
# Path: idtxl/estimator.py
# def find_estimator(est):
#     """Return estimator class.
# 
#     Return an estimator class. If input is a class, check if it implements
#     methods 'estimate' and 'is_parallel' necessary for network analysis
#     (see abstract class 'Estimator' for documentation). If input is a string,
#     search for class with that name in IDTxl and return it.
# 
#     Args:
#         est : str | Class
#             name of an estimator class implemented in IDTxl or custom estimator
#             class
# 
#     Returns
#         Class
#             Estimator class
#     """
#     if inspect.isclass(est):
#         # Test if provided class implements the Estimator class. This
#         # constraint may be relaxed in the future.
#         if not np.issubclass_(est, Estimator):
#             raise RuntimeError('Provided class should implement abstract class'
#                                ' Estimator.')
#         return est
#     elif type(est) is str:
#         module_list = _package_contents()
#         estimator = None
#         for m in module_list:
#             try:
#                 module = importlib.import_module('.' + m, __package__)
#                 return getattr(module, est)
#             except AttributeError:
#                 pass
#         if not estimator:
#             raise RuntimeError('Estimator {0} not found.'.format(est))
#     else:
#         raise TypeError('Please provide an estimator class or the name of an '
#                         'estimator as string.')
# 
# Path: idtxl/results.py
# class ResultsMultivariatePID(ResultsNetworkAnalysis):
#     """Store results of Multivariate Partial Information Decomposition (PID)
# analysis.
# 
#     Provide a container for results of Multivariate Partial Information
#     Decomposition (PID) algorithms.
# 
#     Note that for convenience all dictionaries in this class can additionally
#     be accessed using dot-notation:
# 
#     >>> res_pid._single_target[2].source_1
# 
#     or
# 
#     >>> res_pid._single_target[2].['source_1'].
# 
#     Attributes:
#         settings : dict
#             settings used for estimation of information theoretic measures and
#             statistical testing
#         data_properties : dict
#             data properties, contains
# 
#                 - n_nodes : int - total number of nodes in the network
#                 - n_realisations : int - number of samples available for
#                   analysis given the settings (e.g., a high maximum lag used in
#                   network inference, results in fewer data points available for
#                   estimation)
#                 - normalised : bool - indicates if data were z-standardised
#                   before the estimation
# 
#         targets_analysed : list
#             list of analysed targets
#     """
# 
#     def __init__(self, n_nodes, n_realisations, normalised):
#         super().__init__(n_nodes, n_realisations, normalised)
# 
#     def get_single_target(self, target):
#         """Return results for a single target in the network.
# 
#         Results for single targets include for each target
# 
#         - source_i : tuple - source variable i
#         - selected_vars_sources : list of tuples - source variables used in PID
#           estimation
#         - avg : dict - avg pid {alpha -> float} where alpha is a redundancy
#           lattice node
#         - ptw : dict of dicts - ptw pid {rlz -> {alpha -> float} } where rlz is
#           a single realisation of the random variables and alpha is a redundancy
#           lattice node
#         - current_value : tuple - current value used for analysis, described by
#           target and sample index in the data
#         - [estimator-specific settings]
# 
#         Args:
#             target : int
#                 target id
# 
#         Returns:
#             dict
#                 Results for single target. Note that for convenience
#                 dictionary entries can either be accessed via keywords
#                 (result['selected_vars_sources']) or via dot-notation
#                 (result.selected_vars_sources).
#         """
#         return super(ResultsMultivariatePID,
#                      self).get_single_target(target, fdr=False)


import numpy as np
from .single_process_analysis import SingleProcessAnalysis
from .estimator import find_estimator
from .results import ResultsMultivariatePID
            >>>                                              sources=[1, 2, 3])

        Args: settings : dict parameters for estimator use and statistics:

                - pid_estimator : str - estimator to be used for PID estimation
                  (for estimator settings see the documentation in the
                  estimators_pid modules)
                - lags_pid : list of ints [optional] - lags in samples between
                  sources and target (default=[1, 1, ..., 1])
                - verbose : bool [optional] - toggle console output
                  (default=True)

            data : Data instance
                raw data for analysis
            target : int
                index of target processes
            sources : list of ints
                indices of the multiple source processes for the target

        Returns: ResultsMultivariatePID instance results of
            network inference, see documentation of
            ResultsPID()
        """
        # Check input and initialise values for analysis.
        self._initialise(settings, data, target, sources)

        # Estimate PID and significance.
        self._calculate_pid(data)

        # Add analyis info.

# Path: idtxl/single_process_analysis.py
# class SingleProcessAnalysis(NetworkAnalysis):
#     def __init__(self):
#         super().__init__()
# 
# Path: idtxl/estimator.py
# def find_estimator(est):
#     """Return estimator class.
# 
#     Return an estimator class. If input is a class, check if it implements
#     methods 'estimate' and 'is_parallel' necessary for network analysis
#     (see abstract class 'Estimator' for documentation). If input is a string,
#     search for class with that name in IDTxl and return it.
# 
#     Args:
#         est : str | Class
#             name of an estimator class implemented in IDTxl or custom estimator
#             class
# 
#     Returns
#         Class
#             Estimator class
#     """
#     if inspect.isclass(est):
#         # Test if provided class implements the Estimator class. This
#         # constraint may be relaxed in the future.
#         if not np.issubclass_(est, Estimator):
#             raise RuntimeError('Provided class should implement abstract class'
#                                ' Estimator.')
#         return est
#     elif type(est) is str:
#         module_list = _package_contents()
#         estimator = None
#         for m in module_list:
#             try:
#                 module = importlib.import_module('.' + m, __package__)
#                 return getattr(module, est)
#             except AttributeError:
#                 pass
#         if not estimator:
#             raise RuntimeError('Estimator {0} not found.'.format(est))
#     else:
#         raise TypeError('Please provide an estimator class or the name of an '
#                         'estimator as string.')
# 
# Path: idtxl/results.py
# class ResultsMultivariatePID(ResultsNetworkAnalysis):
#     """Store results of Multivariate Partial Information Decomposition (PID)
# analysis.
# 
#     Provide a container for results of Multivariate Partial Information
#     Decomposition (PID) algorithms.
# 
#     Note that for convenience all dictionaries in this class can additionally
#     be accessed using dot-notation:
# 
#     >>> res_pid._single_target[2].source_1
# 
#     or
# 
#     >>> res_pid._single_target[2].['source_1'].
# 
#     Attributes:
#         settings : dict
#             settings used for estimation of information theoretic measures and
#             statistical testing
#         data_properties : dict
#             data properties, contains
# 
#                 - n_nodes : int - total number of nodes in the network
#                 - n_realisations : int - number of samples available for
#                   analysis given the settings (e.g., a high maximum lag used in
#                   network inference, results in fewer data points available for
#                   estimation)
#                 - normalised : bool - indicates if data were z-standardised
#                   before the estimation
# 
#         targets_analysed : list
#             list of analysed targets
#     """
# 
#     def __init__(self, n_nodes, n_realisations, normalised):
#         super().__init__(n_nodes, n_realisations, normalised)
# 
#     def get_single_target(self, target):
#         """Return results for a single target in the network.
# 
#         Results for single targets include for each target
# 
#         - source_i : tuple - source variable i
#         - selected_vars_sources : list of tuples - source variables used in PID
#           estimation
#         - avg : dict - avg pid {alpha -> float} where alpha is a redundancy
#           lattice node
#         - ptw : dict of dicts - ptw pid {rlz -> {alpha -> float} } where rlz is
#           a single realisation of the random variables and alpha is a redundancy
#           lattice node
#         - current_value : tuple - current value used for analysis, described by
#           target and sample index in the data
#         - [estimator-specific settings]
# 
#         Args:
#             target : int
#                 target id
# 
#         Returns:
#             dict
#                 Results for single target. Note that for convenience
#                 dictionary entries can either be accessed via keywords
#                 (result['selected_vars_sources']) or via dot-notation
#                 (result.selected_vars_sources).
#         """
#         return super(ResultsMultivariatePID,
#                      self).get_single_target(target, fdr=False)


# Path: idtxl/multivariate_pid.py
import numpy as np
from .single_process_analysis import SingleProcessAnalysis
from .estimator import find_estimator
from .results import ResultsMultivariatePID

            >>>                                              sources=[1, 2, 3])

        Args: settings : dict parameters for estimator use and statistics:

                - pid_estimator : str - estimator to be used for PID estimation
                  (for estimator settings see the documentation in the
                  estimators_pid modules)
                - lags_pid : list of ints [optional] - lags in samples between
                  sources and target (default=[1, 1, ..., 1])
                - verbose : bool [optional] - toggle console output
                  (default=True)

            data : Data instance
                raw data for analysis
            target : int
                index of target processes
            sources : list of ints
                indices of the multiple source processes for the target

        Returns: ResultsMultivariatePID instance results of
            network inference, see documentation of
            ResultsPID()
        """
        # Check input and initialise values for analysis.
        self._initialise(settings, data, target, sources)

        # Estimate PID and significance.
        self._calculate_pid(data)

        # Add analyis info.

        results = ResultsMultivariatePID(