diff --git a/.github/workflows/run_unit_tests.yaml b/.github/workflows/run_unit_tests.yaml index c9a19cd..157ca3d 100644 --- a/.github/workflows/run_unit_tests.yaml +++ b/.github/workflows/run_unit_tests.yaml @@ -4,15 +4,15 @@ on: push: jobs: - build: + test-ubuntu: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.8", "3.9"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: 'pip' @@ -20,15 +20,19 @@ jobs: run: | sudo apt-get update sudo apt-get install -y build-essential octave - - name: Install dependencies + - name: Install pyspi dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install . - - name: Run pyspi calculator unit tests + - name: Run pyspi calculator/utils unit tests run: | pytest -v ./tests/test_calc.py + pytest -v ./tests/test_utils.py - name: Run pyspi SPI unit tests run: | pytest -v ./tests/test_SPIs.py + + + \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index d99eff5..81f1a87 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pyspi" -version = "0.4.2" +version = "1.0.0" authors = [ { name ="Oliver M. Cliff", email="oliver.m.cliff@gmail.com"}, ] diff --git a/pyspi/calculator.py b/pyspi/calculator.py index caf480b..9a7131b 100644 --- a/pyspi/calculator.py +++ b/pyspi/calculator.py @@ -8,7 +8,7 @@ # From this package from .data import Data -from .utils import convert_mdf_to_ddf +from .utils import convert_mdf_to_ddf, check_optional_deps class Calculator: @@ -31,15 +31,17 @@ class Calculator: labels (array_like, optional): Any set of strings by which you want to label the calculator. This can be useful later for classification purposes, defaults to None. subset (str, optional): - A pre-configured subset of SPIs to use. Options are "all", "fast", "sonnet", "octaveless", or "fabfour", defaults to "all". + A pre-configured subset of SPIs to use. Options are "all", "fast", "sonnet", or "fabfour", defaults to "all". configfile (str, optional): The location of the YAML configuration file for a user-defined subset. See :ref:`Using a reduced SPI set`, defaults to :code:`'/pyspi/config.yaml'` """ + _optional_dependencies = None def __init__( self, dataset=None, name=None, labels=None, subset="all", configfile=None ): self._spis = {} + self._excluded_spis = list() # Define configfile by subset if it was not specified if configfile is None: @@ -55,17 +57,20 @@ def __init__( configfile = ( os.path.dirname(os.path.abspath(__file__)) + "/fabfour_config.yaml" ) - elif subset == "octaveless": - configfile = ( - os.path.dirname(os.path.abspath(__file__)) + "/octaveless_config.yaml" - ) # If no configfile was provided but the subset was not one of the above (or the default 'all'), raise an error elif subset != "all": raise ValueError( - f"Subset '{subset}' does not exist. Try 'all' (default), 'fast', 'sonnet', 'octaveless', or 'fabfour'." + f"Subset '{subset}' does not exist. Try 'all' (default), 'fast', 'sonnet', or 'fabfour'." ) else: configfile = os.path.dirname(os.path.abspath(__file__)) + "/config.yaml" + + # add dependency checks here if the calculator is being instantiated for the first time + if not Calculator._optional_dependencies: + # check if optional dependencies exist + print("Checking if optional dependencies exist...") + Calculator._optional_dependencies = check_optional_deps() + self._load_yaml(configfile) duplicates = [ @@ -79,7 +84,38 @@ def __init__( self._name = name self._labels = labels - print("Number of SPIs: {}".format(len(self.spis))) + print(f"="*100) + print(f"Number of SPIs: {len(self.spis)}\n") + if len(self._excluded_spis) > 0: + missing_deps = [dep for dep, is_met in self._optional_dependencies.items() if not is_met] + print("**** SPI Initialisation Warning ****") + print("\nSome dependencies were not detected, which has led to the exclusion of certain SPIs:") + print("\nMissing Dependencies:") + + for dep in missing_deps: + print(f"- {dep}") + + print(f"\nAs a result, a total of {len(self._excluded_spis)} SPI(s) have been excluded:\n") + + dependency_groups = {} + for spi in self._excluded_spis: + for dep in spi[1]: + if dep not in dependency_groups: + dependency_groups[dep] = [] + dependency_groups[dep].append(spi[0]) + + for dep, spis in dependency_groups.items(): + print(f"\nDependency - {dep} - affects {len(spis)} SPI(s)") + print("Excluded SPIs:") + for spi in spis: + print(f" - {spi}") + + print(f"\n" + "="*100) + print("\nOPTIONS TO PROCEED:\n") + print(f" 1) Install the following dependencies to access all SPIs: [{', '.join(missing_deps)}]") + callable_name = "{Calculator/CalculatorFrame}" + print(f" 2) Continue with a reduced set of {self.n_spis} SPIs by calling {callable_name}.compute(). \n") + print(f"="*100 + "\n") if dataset is not None: self.load_dataset(dataset) @@ -180,10 +216,20 @@ def _load_yaml(self, document): print("*** Importing module {}".format(module_name)) module = importlib.import_module(module_name, __package__) for fcn in yf[module_name]: + deps = yf[module_name][fcn].get('dependencies') + if deps is not None: + all_deps_met = all(Calculator._optional_dependencies.get(dep, False) for dep in deps) + if not all_deps_met: + current_base_spi = yf[module_name][fcn] + print(f"Optional dependencies: {deps} not met. Skipping {len(current_base_spi.get('configs'))} SPI(s):") + for params in current_base_spi.get('configs'): + print(f"*SKIPPING SPI: {module_name}.{fcn}(x,y,{params})...") + self._excluded_spis.append([f"{fcn}(x,y,{params})", deps]) + continue try: - for params in yf[module_name][fcn]: + for params in yf[module_name][fcn].get('configs'): print( - f"[{self.n_spis}] Adding SPI {module_name}.{fcn}(x,y,{params})..." + f"[{self.n_spis}] Adding SPI {module_name}.{fcn}(x,y,{params})" ) spi = getattr(module, fcn)(**params) self._spis[spi.identifier] = spi diff --git a/pyspi/config.yaml b/pyspi/config.yaml index 8b17bc4..266c075 100644 --- a/pyspi/config.yaml +++ b/pyspi/config.yaml @@ -2,594 +2,926 @@ .statistics.basic: # Covariance Covariance: - - estimator: EmpiricalCovariance - - estimator: EllipticEnvelope - - estimator: GraphicalLasso - - estimator: GraphicalLassoCV - - estimator: LedoitWolf - - estimator: MinCovDet - - estimator: OAS - - estimator: ShrunkCovariance - - estimator: EmpiricalCovariance - squared: True - - estimator: EllipticEnvelope - squared: True - - estimator: GraphicalLasso - squared: True - - estimator: GraphicalLassoCV - squared: True - - estimator: LedoitWolf - squared: True - - estimator: MinCovDet - squared: True - - estimator: OAS - squared: True - - estimator: ShrunkCovariance - squared: True + labels: + - undirected + - linear + - signed + - multivariate + - contemporaneous + dependencies: + configs: + - estimator: EmpiricalCovariance + - estimator: EllipticEnvelope + - estimator: GraphicalLasso + - estimator: GraphicalLassoCV + - estimator: LedoitWolf + - estimator: MinCovDet + - estimator: OAS + - estimator: ShrunkCovariance + - estimator: EmpiricalCovariance + squared: True + - estimator: EllipticEnvelope + squared: True + - estimator: GraphicalLasso + squared: True + - estimator: GraphicalLassoCV + squared: True + - estimator: LedoitWolf + squared: True + - estimator: MinCovDet + squared: True + - estimator: OAS + squared: True + - estimator: ShrunkCovariance + squared: True # Precision Precision: - - estimator: EmpiricalCovariance - - estimator: EllipticEnvelope - - estimator: GraphicalLasso - - estimator: GraphicalLassoCV - - estimator: LedoitWolf - - estimator: MinCovDet - - estimator: OAS - - estimator: ShrunkCovariance - - estimator: EmpiricalCovariance - squared: True - - estimator: EllipticEnvelope - squared: True - - estimator: GraphicalLasso - squared: True - - estimator: GraphicalLassoCV - squared: True - - estimator: LedoitWolf - squared: True - - estimator: MinCovDet - squared: True - - estimator: OAS - squared: True - - estimator: ShrunkCovariance - squared: True + labels: + - undirected + - linear + - signed + - multivariate + - contemporaneous + dependencies: + configs: + - estimator: EmpiricalCovariance + - estimator: EllipticEnvelope + - estimator: GraphicalLasso + - estimator: GraphicalLassoCV + - estimator: LedoitWolf + - estimator: MinCovDet + - estimator: OAS + - estimator: ShrunkCovariance + - estimator: EmpiricalCovariance + squared: True + - estimator: EllipticEnvelope + squared: True + - estimator: GraphicalLasso + squared: True + - estimator: GraphicalLassoCV + squared: True + - estimator: LedoitWolf + squared: True + - estimator: MinCovDet + squared: True + - estimator: OAS + squared: True + - estimator: ShrunkCovariance + squared: True # Spearman's correlation coefficient SpearmanR: - - squared: True - - - squared: False + labels: + - undirected + - nonlinear + - signed + - bivariate + - contemporaneous + dependencies: + configs: + - squared: True + - squared: False # Kendall's rank correlation coefficient KendallTau: - - squared: True - - - squared: False + labels: + - undirected + - nonlinear + - signed + - bivariate + - contemporaneous + dependencies: + configs: + - squared: True + - squared: False # statistics based on cross-correlation (squared means we square the xcorr, not the output) CrossCorrelation: - - statistic: "max" + labels: + - undirected + - linear + - signed/unsigned + - bivariate + - time-dependent + dependencies: + configs: + - statistic: "max" - - statistic: "max" - squared: True + - statistic: "max" + squared: True - - statistic: "mean" + - statistic: "mean" - - statistic: "mean" - squared: True + - statistic: "mean" + squared: True - - statistic: "mean" - sigonly: False + - statistic: "mean" + sigonly: False - - statistic: "mean" - squared: True - sigonly: False + - statistic: "mean" + squared: True + sigonly: False .statistics.distance: PairwiseDistance: - - metric: "euclidean" - - metric: "cityblock" - - metric: "cosine" - - metric: "chebyshev" - - metric: "canberra" - - metric: "braycurtis" + labels: + - unsigned + - unordered + - nonlinear + - undirected + dependencies: + configs: + - metric: "euclidean" + - metric: "cityblock" + - metric: "cosine" + - metric: "chebyshev" + - metric: "canberra" + - metric: "braycurtis" # Distance correlation DistanceCorrelation: - - biased: False - - biased: True + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: + - biased: False + - biased: True # Multi-scale graph correlation MultiscaleGraphCorrelation: + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Hilbert-Schmidt independence criterion HilbertSchmidtIndependenceCriterion: - - biased: False - - biased: True + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: + - biased: False + - biased: True # Heller-Heller-Gorfine (HHG) test HellerHellerGorfine: + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Multi-scale graph correlation for time series CrossMultiscaleGraphCorrelation: - - max_lag: 1 - - max_lag: 10 + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - max_lag: 1 + - max_lag: 10 # Distance correlation for time series CrossDistanceCorrelation: - - max_lag: 1 - - max_lag: 10 + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - max_lag: 1 + - max_lag: 10 DynamicTimeWarping: - - global_constraint: null - - global_constraint: itakura - - global_constraint: sakoe_chiba + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - global_constraint: null + - global_constraint: itakura + - global_constraint: sakoe_chiba SoftDynamicTimeWarping: - - global_constraint: null - - global_constraint: itakura - - global_constraint: sakoe_chiba + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - global_constraint: null + - global_constraint: itakura + - global_constraint: sakoe_chiba LongestCommonSubsequence: - - global_constraint: null - - global_constraint: itakura - - global_constraint: sakoe_chiba + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - global_constraint: null + - global_constraint: itakura + - global_constraint: sakoe_chiba Barycenter: - - mode: euclidean - statistic: mean - - mode: euclidean - statistic: max - - mode: dtw - statistic: mean - - mode: dtw - statistic: max - - mode: sgddtw - statistic: mean - - mode: sgddtw - statistic: max - - mode: softdtw - statistic: mean - - mode: softdtw - statistic: max - - - mode: euclidean - statistic: mean - squared: True - - - mode: euclidean - statistic: max - squared: True - - - mode: dtw - statistic: mean - squared: True - - - mode: dtw - statistic: max - squared: True - - - mode: sgddtw - statistic: mean - squared: True - - - mode: sgddtw - statistic: max - squared: True - - - mode: softdtw - statistic: mean - squared: True - - - mode: softdtw - statistic: max - squared: True + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - mode: euclidean + statistic: mean + - mode: euclidean + statistic: max + - mode: dtw + statistic: mean + - mode: dtw + statistic: max + - mode: sgddtw + statistic: mean + - mode: sgddtw + statistic: max + - mode: softdtw + statistic: mean + - mode: softdtw + statistic: max + + - mode: euclidean + statistic: mean + squared: True + + - mode: euclidean + statistic: max + squared: True + + - mode: dtw + statistic: mean + squared: True + + - mode: dtw + statistic: max + squared: True + + - mode: sgddtw + statistic: mean + squared: True + + - mode: sgddtw + statistic: max + squared: True + + - mode: softdtw + statistic: mean + squared: True + + - mode: softdtw + statistic: max + squared: True .statistics.causal: # Additive noise model AdditiveNoiseModel: + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Conditional distribution similarity statistic ConditionalDistributionSimilarity: + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Regression error-based causal inference RegressionErrorCausalInference: + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Information-geometric conditional independence InformationGeometricConditionalIndependence: + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Convergent-cross mapping ConvergentCrossMapping: - - statistic: mean - - statistic: max - - statistic: diff - - statistic: mean - embedding_dimension: 1 - - statistic: max - embedding_dimension: 1 - - statistic: diff - embedding_dimension: 1 - - statistic: mean - embedding_dimension: 10 - - statistic: max - embedding_dimension: 10 - - statistic: diff - embedding_dimension: 10 + labels: + - directed + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - statistic: mean + - statistic: max + - statistic: diff + - statistic: mean + embedding_dimension: 1 + - statistic: max + embedding_dimension: 1 + - statistic: diff + embedding_dimension: 1 + - statistic: mean + embedding_dimension: 10 + - statistic: max + embedding_dimension: 10 + - statistic: diff + embedding_dimension: 10 # Information-theoretic statistics .statistics.infotheory: JointEntropy: # No theiler window yet - - estimator: gaussian - - - estimator: kozachenko - - - estimator: kernel + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + - java + configs: + - estimator: gaussian + - estimator: kozachenko + - estimator: kernel ConditionalEntropy: # No theiler window yet - - estimator: gaussian - - - estimator: kozachenko - - - estimator: kernel + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + - java + configs: + - estimator: gaussian + - estimator: kozachenko + - estimator: kernel CausalEntropy: # No theiler window yet - - estimator: gaussian - - - estimator: kozachenko - - - estimator: kernel + labels: + - directed + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: gaussian + - estimator: kozachenko + - estimator: kernel CrossmapEntropy: # No theiler window yet - - estimator: gaussian - history_length: 1 + labels: + - unsigned + - directed + - time-dependent + - bivariate + dependencies: + - java + configs: + - estimator: gaussian + history_length: 1 - - estimator: kozachenko - history_length: 1 + - estimator: kozachenko + history_length: 1 - - estimator: kernel - history_length: 1 + - estimator: kernel + history_length: 1 - - estimator: gaussian - history_length: 10 + - estimator: gaussian + history_length: 10 - - estimator: kozachenko - history_length: 10 + - estimator: kozachenko + history_length: 10 - - estimator: kernel - history_length: 10 + - estimator: kernel + history_length: 10 DirectedInfo: # No theiler window yet - - estimator: gaussian - - - estimator: kozachenko - - - estimator: kernel + labels: + - directed + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: gaussian + - estimator: kozachenko + - estimator: kernel StochasticInteraction: # No theiler window - - estimator: gaussian - - - estimator: kozachenko - - - estimator: kernel + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: gaussian + - estimator: kozachenko + - estimator: kernel # Mutual information MutualInfo: - - estimator: gaussian - - - estimator: kraskov - prop_k: 4 - - - estimator: kraskov - prop_k: 4 - dyn_corr_excl: AUTO - - - estimator: kernel - kernel_width: 0.25 + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + - java + configs: + - estimator: gaussian + + - estimator: kraskov + prop_k: 4 + + - estimator: kraskov + prop_k: 4 + dyn_corr_excl: AUTO + + - estimator: kernel + kernel_width: 0.25 # Mutual information TimeLaggedMutualInfo: - - estimator: gaussian - - - estimator: kraskov - prop_k: 4 - - - estimator: kraskov - prop_k: 4 - dyn_corr_excl: AUTO - - - estimator: kernel - kernel_width: 0.25 + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: gaussian + + - estimator: kraskov + prop_k: 4 + + - estimator: kraskov + prop_k: 4 + dyn_corr_excl: AUTO + + - estimator: kernel + kernel_width: 0.25 # Transfer entropy TransferEntropy: - # Kraskov estimator with auto-embedding on source/target and DCE - - estimator: kraskov - prop_k: 4 - auto_embed_method: MAX_CORR_AIS - k_search_max: 10 - tau_search_max: 4 - - - estimator: kraskov - prop_k: 4 - auto_embed_method: MAX_CORR_AIS - k_search_max: 10 - tau_search_max: 4 - dyn_corr_excl: AUTO - - # Kraskov estimator with auto-embedding on target-only, src history of 1, and DCE - - estimator: kraskov - prop_k: 4 - k_history: 2 - l_history: 1 - dyn_corr_excl: AUTO - - # Kraskov estimator with fixed embedding of 1 for source/target and DCE - - estimator: kraskov - prop_k: 4 - k_history: 1 - l_history: 1 - dyn_corr_excl: AUTO - - # Same as above with no DCE - - estimator: kraskov - prop_k: 4 - k_history: 1 - l_history: 1 - - # Currently the Kernel method has an overload issue with the AIS calculator.. - # Kernel estimator with auto-embedding on source/target and DCE - # - estimator: kernel - # auto_embed_method: MAX_CORR_AIS - # k_search_max: 4 - # kernel_width: 0.25 - - # Kernel estimator with no auto-embedding on source/target and DCE - - estimator: kernel - kernel_width: 0.25 - k_history: 1 - l_history: 1 - - # Gaussian estimator doesn't have DCE (aka Bartlett corrections) yet - - estimator: gaussian - auto_embed_method: MAX_CORR_AIS - k_search_max: 10 - tau_search_max: 2 - - - estimator: gaussian - k_history: 1 - l_history: 1 - - - estimator: symbolic - k_history: 1 - l_history: 1 - - - estimator: symbolic - k_history: 10 - l_history: 1 + labels: + - directed + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + # Kraskov estimator with auto-embedding on source/target and DCE + - estimator: kraskov + prop_k: 4 + auto_embed_method: MAX_CORR_AIS + k_search_max: 10 + tau_search_max: 4 + + - estimator: kraskov + prop_k: 4 + auto_embed_method: MAX_CORR_AIS + k_search_max: 10 + tau_search_max: 4 + dyn_corr_excl: AUTO + + # Kraskov estimator with auto-embedding on target-only, src history of 1, and DCE + - estimator: kraskov + prop_k: 4 + k_history: 2 + l_history: 1 + dyn_corr_excl: AUTO + + # Kraskov estimator with fixed embedding of 1 for source/target and DCE + - estimator: kraskov + prop_k: 4 + k_history: 1 + l_history: 1 + dyn_corr_excl: AUTO + + # Same as above with no DCE + - estimator: kraskov + prop_k: 4 + k_history: 1 + l_history: 1 + + # Currently the Kernel method has an overload issue with the AIS calculator.. + # Kernel estimator with auto-embedding on source/target and DCE + # - estimator: kernel + # auto_embed_method: MAX_CORR_AIS + # k_search_max: 4 + # kernel_width: 0.25 + + # Kernel estimator with no auto-embedding on source/target and DCE + - estimator: kernel + kernel_width: 0.25 + k_history: 1 + l_history: 1 + + # Gaussian estimator doesn't have DCE (aka Bartlett corrections) yet + - estimator: gaussian + auto_embed_method: MAX_CORR_AIS + k_search_max: 10 + tau_search_max: 2 + + - estimator: gaussian + k_history: 1 + l_history: 1 + + - estimator: symbolic + k_history: 1 + l_history: 1 + + - estimator: symbolic + k_history: 10 + l_history: 1 IntegratedInformation: - - phitype: "star" + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - octave + configs: + - phitype: "star" - - phitype: "star" - normalization: 1 + - phitype: "star" + normalization: 1 - - phitype: "Geo" + - phitype: "Geo" - - phitype: "Geo" - normalization: 1 + - phitype: "Geo" + normalization: 1 # statistics that analyse in the frequency-domain (see Schoegl and Supp, 2006) .statistics.spectral: CoherencePhase: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max CoherenceMagnitude: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max # Coherence (ordinal or squared? imaginary components of the coherence) ImaginaryCoherence: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max PhaseSlopeIndex: - - fmin: 0 - fmax: 0.5 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 + labels: + - directed + - linear/nonlinear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fmin: 0 + fmax: 0.5 + + - fmin: 0 + fmax: 0.25 + + - fmin: 0.25 + fmax: 0.5 PhaseLockingValue: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max PhaseLagIndex: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max WeightedPhaseLagIndex: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max DebiasedSquaredPhaseLagIndex: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max DebiasedSquaredWeightedPhaseLagIndex: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max PairwisePhaseConsistency: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max DirectedTransferFunction: - - fs: 1 + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max # partial_coherence: # - fs: 1 @@ -612,352 +944,439 @@ # statistic: max DirectedCoherence: - - fs: 1 + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max PartialDirectedCoherence: - - fs: 1 + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max GeneralizedPartialDirectedCoherence: - - fs: 1 + labels: + - unsigned + - directed + - linear + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max DirectDirectedTransferFunction: - - fs: 1 + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max GroupDelay: - - fmin: 0 - fmax: 0.5 - statistic: delay - - - fmin: 0 - fmax: 0.25 - statistic: delay - - - fmin: 0.25 - fmax: 0.5 - statistic: delay + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fmin: 0 + fmax: 0.5 + statistic: delay + + - fmin: 0 + fmax: 0.25 + statistic: delay + + - fmin: 0.25 + fmax: 0.5 + statistic: delay SpectralGrangerCausality: # Non-parametric Granger causality (no VAR model) - - method: nonparametric - fmin: 0 - fmax: 0.5 - statistic: mean - - - method: nonparametric - fmin: 0 - fmax: 0.25 - statistic: mean - - - method: nonparametric - fmin: 0.25 - fmax: 0.5 - statistic: mean - - - method: nonparametric - fmin: 0 - fmax: 0.5 - statistic: max - - - method: nonparametric - fmin: 0 - fmax: 0.25 - statistic: max - - - method: nonparametric - fmin: 0.25 - fmax: 0.5 - statistic: max - - # Parametric Granger causality (VAR model with inferred or predefined order) - - # AR order optimised by BIC - - method: parametric - fmin: 0 - fmax: 0.5 - statistic: mean - - - method: parametric - fmin: 0 - fmax: 0.25 - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - method: parametric - statistic: mean - - # AR order 1 - - fs: 1 - order: 1 - method: parametric - statistic: mean - - - fmin: 0 - fmax: 0.25 - order: 1 - method: parametric - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - order: 1 - method: parametric - statistic: mean - - # AR order 20 - - fs: 1 - order: 20 - method: parametric - statistic: mean - - - fmin: 0 - fmax: 0.25 - order: 20 - method: parametric - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - order: 20 - method: parametric - statistic: mean - - # AR order optimised by BIC - - fs: 1 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - method: parametric - statistic: max - - # AR order 1 - - fs: 1 - order: 1 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - order: 1 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - order: 1 - method: parametric - statistic: max - - # AR order 20 - - fs: 1 - order: 20 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - order: 20 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - order: 20 - method: parametric - statistic: max + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - method: nonparametric + fmin: 0 + fmax: 0.5 + statistic: mean + + - method: nonparametric + fmin: 0 + fmax: 0.25 + statistic: mean + + - method: nonparametric + fmin: 0.25 + fmax: 0.5 + statistic: mean + + - method: nonparametric + fmin: 0 + fmax: 0.5 + statistic: max + + - method: nonparametric + fmin: 0 + fmax: 0.25 + statistic: max + + - method: nonparametric + fmin: 0.25 + fmax: 0.5 + statistic: max + + # Parametric Granger causality (VAR model with inferred or predefined order) + + # AR order optimised by BIC + - method: parametric + fmin: 0 + fmax: 0.5 + statistic: mean + + - method: parametric + fmin: 0 + fmax: 0.25 + statistic: mean + + - fmin: 0.25 + fmax: 0.5 + method: parametric + statistic: mean + + # AR order 1 + - fs: 1 + order: 1 + method: parametric + statistic: mean + + - fmin: 0 + fmax: 0.25 + order: 1 + method: parametric + statistic: mean + + - fmin: 0.25 + fmax: 0.5 + order: 1 + method: parametric + statistic: mean + + # AR order 20 + - fs: 1 + order: 20 + method: parametric + statistic: mean + + - fmin: 0 + fmax: 0.25 + order: 20 + method: parametric + statistic: mean + + - fmin: 0.25 + fmax: 0.5 + order: 20 + method: parametric + statistic: mean + + # AR order optimised by BIC + - fs: 1 + method: parametric + statistic: max + + - fmin: 0 + fmax: 0.25 + method: parametric + statistic: max + + - fmin: 0.25 + fmax: 0.5 + method: parametric + statistic: max + + # AR order 1 + - fs: 1 + order: 1 + method: parametric + statistic: max + + - fmin: 0 + fmax: 0.25 + order: 1 + method: parametric + statistic: max + + - fmin: 0.25 + fmax: 0.5 + order: 1 + method: parametric + statistic: max + + # AR order 20 + - fs: 1 + order: 20 + method: parametric + statistic: max + + - fmin: 0 + fmax: 0.25 + order: 20 + method: parametric + statistic: max + + - fmin: 0.25 + fmax: 0.5 + order: 20 + method: parametric + statistic: max # statistics that analyse in the wavelet-domain (only Mortlet wavelet's at the moment) .statistics.wavelet: PhaseSlopeIndex: - - fs: 1 + labels: + - undirected + - unsigned + - time/frequency dependent + - bivariate + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fmin: 0 - fmax: 0.5 - statistic: max + - fmin: 0 + fmax: 0.5 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max .statistics.misc: LinearModel: - - model: Ridge - - model: Lasso - - model: SGDRegressor - - model: ElasticNet - - model: BayesianRidge + labels: + - directed + - linear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: + - model: Ridge + - model: Lasso + - model: SGDRegressor + - model: ElasticNet + - model: BayesianRidge GPModel: - - kernel: DotProduct - - kernel: RBF + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: + - kernel: DotProduct + - kernel: RBF # Cointegration Cointegration: - - method: johansen - statistic: max_eig_stat - det_order: 0 # Constant trend - k_ar_diff: 10 - - - method: johansen - statistic: trace_stat - det_order: 0 - k_ar_diff: 10 - - - method: johansen - statistic: max_eig_stat - det_order: 0 # Constant trend - k_ar_diff: 1 - - - method: johansen - statistic: trace_stat - det_order: 0 - k_ar_diff: 1 - - - method: johansen - statistic: max_eig_stat - det_order: 1 # Linear trend - k_ar_diff: 10 - - - method: johansen - statistic: trace_stat - det_order: 1 - k_ar_diff: 10 - - - method: johansen - statistic: max_eig_stat - det_order: 1 - k_ar_diff: 1 - - - method: johansen - statistic: trace_stat - det_order: 1 - k_ar_diff: 1 - - - method: aeg - statistic: tstat - autolag: aic - maxlag: 10 - trend: c - - - method: aeg - statistic: tstat - autolag: aic - maxlag: 10 - trend: ct - - - method: aeg - statistic: tstat - autolag: bic - maxlag: 10 - trend: ct + labels: + - undirected + - linear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - method: johansen + statistic: max_eig_stat + det_order: 0 # Constant trend + k_ar_diff: 10 + + - method: johansen + statistic: trace_stat + det_order: 0 + k_ar_diff: 10 + + - method: johansen + statistic: max_eig_stat + det_order: 0 # Constant trend + k_ar_diff: 1 + + - method: johansen + statistic: trace_stat + det_order: 0 + k_ar_diff: 1 + + - method: johansen + statistic: max_eig_stat + det_order: 1 # Linear trend + k_ar_diff: 10 + + - method: johansen + statistic: trace_stat + det_order: 1 + k_ar_diff: 10 + + - method: johansen + statistic: max_eig_stat + det_order: 1 + k_ar_diff: 1 + + - method: johansen + statistic: trace_stat + det_order: 1 + k_ar_diff: 1 + + - method: aeg + statistic: tstat + autolag: aic + maxlag: 10 + trend: c + + - method: aeg + statistic: tstat + autolag: aic + maxlag: 10 + trend: ct + + - method: aeg + statistic: tstat + autolag: bic + maxlag: 10 + trend: ct # Power envelope correlation PowerEnvelopeCorrelation: - - orth: False - log: False - absolute: False - - - orth: True - log: False - absolute: False - - - orth: False - log: True - absolute: False - - - orth: True - log: True - absolute: False - - - orth: True - log: False - absolute: True - - - orth: True - log: True - absolute: True + labels: + - undirected + - linear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - orth: False + log: False + absolute: False + + - orth: True + log: False + absolute: False + + - orth: False + log: True + absolute: False + + - orth: True + log: True + absolute: False + + - orth: True + log: False + absolute: True + + - orth: True + log: True + absolute: True diff --git a/pyspi/fabfour_config.yaml b/pyspi/fabfour_config.yaml index 7e84b1b..e0c8b00 100644 --- a/pyspi/fabfour_config.yaml +++ b/pyspi/fabfour_config.yaml @@ -2,20 +2,53 @@ .statistics.basic: # Covariance Covariance: - - estimator: EmpiricalCovariance + labels: + - undirected + - nonlinear + - unisgned + - bivariate + - contemporaneous + dependencies: + configs: + - estimator: EmpiricalCovariance # Spearman's correlation coefficient SpearmanR: - - squared: True + labels: + - undirected + - nonlinear + - signed + - bivariate + - contemporaneous + dependencies: + configs: + - squared: True # Directed information with a Gaussian density estimator .statistics.infotheory: DirectedInfo: - - estimator: gaussian + labels: + - directed + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: gaussian # Power envelope correlation .statistics.misc: PowerEnvelopeCorrelation: - - orth: False - log: False - absolute: False \ No newline at end of file + labels: + - undirected + - linear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - orth: False + log: False + absolute: False diff --git a/pyspi/fast_config.yaml b/pyspi/fast_config.yaml index 44ea3ed..e421604 100644 --- a/pyspi/fast_config.yaml +++ b/pyspi/fast_config.yaml @@ -2,411 +2,657 @@ .statistics.basic: # Covariance Covariance: - - estimator: EmpiricalCovariance - - estimator: GraphicalLasso - - estimator: GraphicalLassoCV - - estimator: LedoitWolf - - estimator: OAS - - estimator: ShrunkCovariance - - estimator: EmpiricalCovariance - squared: True - - estimator: GraphicalLasso - squared: True - - estimator: LedoitWolf - squared: True - - estimator: OAS - squared: True - - estimator: ShrunkCovariance - squared: True + labels: + - undirected + - linear + - signed + - multivariate + - contemporaneous + dependencies: + configs: + - estimator: EmpiricalCovariance + - estimator: GraphicalLasso + - estimator: GraphicalLassoCV + - estimator: LedoitWolf + - estimator: OAS + - estimator: ShrunkCovariance + - estimator: EmpiricalCovariance + squared: True + - estimator: GraphicalLasso + squared: True + - estimator: LedoitWolf + squared: True + - estimator: OAS + squared: True + - estimator: ShrunkCovariance + squared: True # Precision Precision: - - estimator: EmpiricalCovariance - - estimator: GraphicalLasso - - estimator: LedoitWolf - - estimator: OAS - - estimator: ShrunkCovariance - - estimator: EmpiricalCovariance - squared: True - - estimator: GraphicalLasso - squared: True - - estimator: LedoitWolf - squared: True - - estimator: OAS - squared: True - - estimator: ShrunkCovariance - squared: True + labels: + - undirected + - linear + - signed + - multivariate + - contemporaneous + dependencies: + configs: + - estimator: EmpiricalCovariance + - estimator: GraphicalLasso + - estimator: LedoitWolf + - estimator: OAS + - estimator: ShrunkCovariance + - estimator: EmpiricalCovariance + squared: True + - estimator: GraphicalLasso + squared: True + - estimator: LedoitWolf + squared: True + - estimator: OAS + squared: True + - estimator: ShrunkCovariance + squared: True # Spearman's correlation coefficient SpearmanR: - - squared: True - - - squared: False + labels: + - undirected + - nonlinear + - signed + - bivariate + - contemporaneous + dependencies: + configs: + - squared: True + - squared: False # Kendall's rank correlation coefficient KendallTau: - - squared: True - - - squared: False + labels: + - undirected + - nonlinear + - signed + - bivariate + - contemporaneous + dependencies: + configs: + - squared: True + - squared: False # statistics based on cross-correlation (squared means we square the xcorr, not the output) CrossCorrelation: - - statistic: "max" + labels: + - undirected + - linear + - signed/unsigned + - bivariate + - time-dependent + dependencies: + configs: + - statistic: "max" - - statistic: "max" - squared: True + - statistic: "max" + squared: True - - statistic: "mean" + - statistic: "mean" - - statistic: "mean" - squared: True + - statistic: "mean" + squared: True - - statistic: "mean" - sigonly: False + - statistic: "mean" + sigonly: False - - statistic: "mean" - squared: True - sigonly: False + - statistic: "mean" + squared: True + sigonly: False .statistics.distance: PairwiseDistance: - - metric: "euclidean" - - metric: "cityblock" - - metric: "cosine" - - metric: "chebyshev" - - metric: "canberra" - - metric: "braycurtis" + labels: + - unsigned + - unordered + - nonlinear + - undirected + dependencies: + configs: + - metric: "euclidean" + - metric: "cityblock" + - metric: "cosine" + - metric: "chebyshev" + - metric: "canberra" + - metric: "braycurtis" # Distance correlation DistanceCorrelation: - - biased: False - - biased: True + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: + - biased: False + - biased: True # Hilbert-Schmidt independence criterion HilbertSchmidtIndependenceCriterion: - - biased: False - - biased: True + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: + - biased: False + - biased: True Barycenter: - - mode: euclidean - statistic: mean - - mode: euclidean - statistic: max - - - mode: euclidean - statistic: mean - squared: True - - - mode: euclidean - statistic: max - squared: True + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - mode: euclidean + statistic: mean + - mode: euclidean + statistic: max + + - mode: euclidean + statistic: mean + squared: True + + - mode: euclidean + statistic: max + squared: True .statistics.causal: # Additive noise model AdditiveNoiseModel: + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Conditional distribution similarity statistic ConditionalDistributionSimilarity: + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Regression error-based causal inference RegressionErrorCausalInference: + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Information-geometric conditional independence InformationGeometricConditionalIndependence: + labels: + - directed + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Information-theoretic statistics .statistics.infotheory: JointEntropy: # No theiler window yet - - estimator: gaussian - - - estimator: kozachenko - - - estimator: kernel + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + - java + configs: + - estimator: gaussian + - estimator: kozachenko + - estimator: kernel ConditionalEntropy: # No theiler window yet + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + - java + configs: - estimator: gaussian - - estimator: kernel CrossmapEntropy: # No theiler window yet - - estimator: gaussian - history_length: 1 + labels: + - unsigned + - directed + - time-dependent + - bivariate + dependencies: + - java + configs: + - estimator: gaussian + history_length: 1 - - estimator: kozachenko - history_length: 1 + - estimator: kozachenko + history_length: 1 - - estimator: kernel - history_length: 1 + - estimator: kernel + history_length: 1 - - estimator: gaussian - history_length: 10 + - estimator: gaussian + history_length: 10 - - estimator: kozachenko - history_length: 10 + - estimator: kozachenko + history_length: 10 - - estimator: kernel - history_length: 10 + - estimator: kernel + history_length: 10 StochasticInteraction: # No theiler window - - estimator: gaussian - - - estimator: kozachenko - - - estimator: kernel + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: gaussian + - estimator: kozachenko + - estimator: kernel # Mutual information MutualInfo: - - estimator: gaussian - - - estimator: kraskov - prop_k: 4 - - - estimator: kraskov - prop_k: 4 - dyn_corr_excl: AUTO - - - estimator: kernel - kernel_width: 0.25 + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + - java + configs: + - estimator: gaussian + + - estimator: kraskov + prop_k: 4 + + - estimator: kraskov + prop_k: 4 + dyn_corr_excl: AUTO + + - estimator: kernel + kernel_width: 0.25 # Mutual information TimeLaggedMutualInfo: - - estimator: gaussian - - - estimator: kraskov - prop_k: 4 - - - estimator: kraskov - prop_k: 4 - dyn_corr_excl: AUTO - - - estimator: kernel - kernel_width: 0.25 + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: gaussian + + - estimator: kraskov + prop_k: 4 + + - estimator: kraskov + prop_k: 4 + dyn_corr_excl: AUTO + + - estimator: kernel + kernel_width: 0.25 # Transfer entropy TransferEntropy: # Kraskov estimator with fixed embedding of 1 for source/target and DCE - - estimator: kraskov - prop_k: 4 - k_history: 1 - l_history: 1 - dyn_corr_excl: AUTO - - - estimator: gaussian - k_history: 1 - l_history: 1 + labels: + - directed + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: kraskov + prop_k: 4 + k_history: 1 + l_history: 1 + dyn_corr_excl: AUTO + + - estimator: gaussian + k_history: 1 + l_history: 1 # statistics that analyse in the frequency-domain (see Schoegl and Supp, 2006) .statistics.spectral: CoherencePhase: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max CoherenceMagnitude: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max # Coherence (ordinal or squared? imaginary components of the coherence) ImaginaryCoherence: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max PhaseSlopeIndex: - - fmin: 0 - fmax: 0.5 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 + labels: + - directed + - linear/nonlinear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fmin: 0 + fmax: 0.5 + + - fmin: 0 + fmax: 0.25 + + - fmin: 0.25 + fmax: 0.5 PhaseLockingValue: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max PhaseLagIndex: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max WeightedPhaseLagIndex: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max DebiasedSquaredPhaseLagIndex: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max DebiasedSquaredWeightedPhaseLagIndex: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max PairwisePhaseConsistency: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max DirectedTransferFunction: - - fs: 1 + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max # partial_coherence: # - fs: 1 @@ -429,234 +675,282 @@ # statistic: max DirectedCoherence: - - fs: 1 + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max PartialDirectedCoherence: - - fs: 1 + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max GeneralizedPartialDirectedCoherence: - - fs: 1 + labels: + - unsigned + - directed + - linear + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max DirectDirectedTransferFunction: - - fs: 1 + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fs: 1 - statistic: max + - fs: 1 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max GroupDelay: - - fmin: 0 - fmax: 0.5 - statistic: delay - - - fmin: 0 - fmax: 0.25 - statistic: delay - - - fmin: 0.25 - fmax: 0.5 - statistic: delay + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fmin: 0 + fmax: 0.5 + statistic: delay + + - fmin: 0 + fmax: 0.25 + statistic: delay + + - fmin: 0.25 + fmax: 0.5 + statistic: delay SpectralGrangerCausality: # Non-parametric Granger causality (no VAR model) - - method: nonparametric - fmin: 0 - fmax: 0.5 - statistic: mean - - - method: nonparametric - fmin: 0 - fmax: 0.25 - statistic: mean - - - method: nonparametric - fmin: 0.25 - fmax: 0.5 - statistic: mean - - - method: nonparametric - fmin: 0 - fmax: 0.5 - statistic: max - - - method: nonparametric - fmin: 0 - fmax: 0.25 - statistic: max - - - method: nonparametric - fmin: 0.25 - fmax: 0.5 - statistic: max - - # Parametric Granger causality (VAR model with inferred or predefined order) - - # AR order optimised by BIC - - method: parametric - fmin: 0 - fmax: 0.5 - statistic: mean - - - method: parametric - fmin: 0 - fmax: 0.25 - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - method: parametric - statistic: mean - - # AR order 1 - - fs: 1 - order: 1 - method: parametric - statistic: mean - - - fmin: 0 - fmax: 0.25 - order: 1 - method: parametric - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - order: 1 - method: parametric - statistic: mean - - # AR order 20 - - fs: 1 - order: 20 - method: parametric - statistic: mean - - - fmin: 0 - fmax: 0.25 - order: 20 - method: parametric - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - order: 20 - method: parametric - statistic: mean - - # AR order optimised by BIC - - fs: 1 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - method: parametric - statistic: max - - # AR order 1 - - fs: 1 - order: 1 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - order: 1 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - order: 1 - method: parametric - statistic: max - - # AR order 20 - - fs: 1 - order: 20 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - order: 20 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - order: 20 - method: parametric - statistic: max + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - method: nonparametric + fmin: 0 + fmax: 0.5 + statistic: mean + + - method: nonparametric + fmin: 0 + fmax: 0.25 + statistic: mean + + - method: nonparametric + fmin: 0.25 + fmax: 0.5 + statistic: mean + + - method: nonparametric + fmin: 0 + fmax: 0.5 + statistic: max + + - method: nonparametric + fmin: 0 + fmax: 0.25 + statistic: max + + - method: nonparametric + fmin: 0.25 + fmax: 0.5 + statistic: max + + # Parametric Granger causality (VAR model with inferred or predefined order) + + # AR order optimised by BIC + - method: parametric + fmin: 0 + fmax: 0.5 + statistic: mean + + - method: parametric + fmin: 0 + fmax: 0.25 + statistic: mean + + - fmin: 0.25 + fmax: 0.5 + method: parametric + statistic: mean + + # AR order 1 + - fs: 1 + order: 1 + method: parametric + statistic: mean + + - fmin: 0 + fmax: 0.25 + order: 1 + method: parametric + statistic: mean + + - fmin: 0.25 + fmax: 0.5 + order: 1 + method: parametric + statistic: mean + + # AR order 20 + - fs: 1 + order: 20 + method: parametric + statistic: mean + + - fmin: 0 + fmax: 0.25 + order: 20 + method: parametric + statistic: mean + + - fmin: 0.25 + fmax: 0.5 + order: 20 + method: parametric + statistic: mean + + # AR order optimised by BIC + - fs: 1 + method: parametric + statistic: max + + - fmin: 0 + fmax: 0.25 + method: parametric + statistic: max + + - fmin: 0.25 + fmax: 0.5 + method: parametric + statistic: max + + # AR order 1 + - fs: 1 + order: 1 + method: parametric + statistic: max + + - fmin: 0 + fmax: 0.25 + order: 1 + method: parametric + statistic: max + + - fmin: 0.25 + fmax: 0.5 + order: 1 + method: parametric + statistic: max + + # AR order 20 + - fs: 1 + order: 20 + method: parametric + statistic: max + + - fmin: 0 + fmax: 0.25 + order: 20 + method: parametric + statistic: max + + - fmin: 0.25 + fmax: 0.5 + order: 20 + method: parametric + statistic: max # statistics that analyse in the wavlet-domain (only Mortlet wavelet's at the moment) .statistics.wavelet: @@ -842,116 +1136,147 @@ # statistic: max PhaseSlopeIndex: - - fs: 1 + labels: + - undirected + - unsigned + - time/frequency dependent + - bivariate + dependencies: + configs: + - fs: 1 - - fmin: 0 - fmax: 0.25 + - fmin: 0 + fmax: 0.25 - - fmin: 0.25 - fmax: 0.5 + - fmin: 0.25 + fmax: 0.5 - - fmin: 0 - fmax: 0.5 - statistic: max + - fmin: 0 + fmax: 0.5 + statistic: max - - fmin: 0 - fmax: 0.25 - statistic: max + - fmin: 0 + fmax: 0.25 + statistic: max - - fmin: 0.25 - fmax: 0.5 - statistic: max + - fmin: 0.25 + fmax: 0.5 + statistic: max .statistics.misc: LinearModel: - - model: Ridge - - model: Lasso - - model: SGDRegressor - - model: ElasticNet - - model: BayesianRidge + labels: + - directed + - linear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: + - model: Ridge + - model: Lasso + - model: SGDRegressor + - model: ElasticNet + - model: BayesianRidge # Cointegration Cointegration: - - method: johansen - statistic: max_eig_stat - det_order: 0 # Constant trend - k_ar_diff: 10 - - - method: johansen - statistic: trace_stat - det_order: 0 - k_ar_diff: 10 - - - method: johansen - statistic: max_eig_stat - det_order: 0 # Constant trend - k_ar_diff: 1 - - - method: johansen - statistic: trace_stat - det_order: 0 - k_ar_diff: 1 - - - method: johansen - statistic: max_eig_stat - det_order: 1 # Linear trend - k_ar_diff: 10 - - - method: johansen - statistic: trace_stat - det_order: 1 - k_ar_diff: 10 - - - method: johansen - statistic: max_eig_stat - det_order: 1 - k_ar_diff: 1 - - - method: johansen - statistic: trace_stat - det_order: 1 - k_ar_diff: 1 - - - method: aeg - statistic: tstat - autolag: aic - maxlag: 10 - trend: c - - - method: aeg - statistic: tstat - autolag: aic - maxlag: 10 - trend: ct - - - method: aeg - statistic: tstat - autolag: bic - maxlag: 10 - trend: ct + labels: + - undirected + - linear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - method: johansen + statistic: max_eig_stat + det_order: 0 # Constant trend + k_ar_diff: 10 + + - method: johansen + statistic: trace_stat + det_order: 0 + k_ar_diff: 10 + + - method: johansen + statistic: max_eig_stat + det_order: 0 # Constant trend + k_ar_diff: 1 + + - method: johansen + statistic: trace_stat + det_order: 0 + k_ar_diff: 1 + + - method: johansen + statistic: max_eig_stat + det_order: 1 # Linear trend + k_ar_diff: 10 + + - method: johansen + statistic: trace_stat + det_order: 1 + k_ar_diff: 10 + + - method: johansen + statistic: max_eig_stat + det_order: 1 + k_ar_diff: 1 + + - method: johansen + statistic: trace_stat + det_order: 1 + k_ar_diff: 1 + + - method: aeg + statistic: tstat + autolag: aic + maxlag: 10 + trend: c + + - method: aeg + statistic: tstat + autolag: aic + maxlag: 10 + trend: ct + + - method: aeg + statistic: tstat + autolag: bic + maxlag: 10 + trend: ct # Power envelope correlation PowerEnvelopeCorrelation: - - orth: False - log: False - absolute: False - - - orth: True - log: False - absolute: False - - - orth: False - log: True - absolute: False - - - orth: True - log: True - absolute: False - - - orth: True - log: False - absolute: True - - - orth: True - log: True - absolute: True + labels: + - undirected + - linear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - orth: False + log: False + absolute: False + + - orth: True + log: False + absolute: False + + - orth: False + log: True + absolute: False + + - orth: True + log: True + absolute: False + + - orth: True + log: False + absolute: True + + - orth: True + log: True + absolute: True diff --git a/pyspi/octaveless_config.yaml b/pyspi/octaveless_config.yaml deleted file mode 100644 index 695e63b..0000000 --- a/pyspi/octaveless_config.yaml +++ /dev/null @@ -1,963 +0,0 @@ -# Basic statistics -.statistics.basic: - # Covariance - Covariance: - - estimator: EmpiricalCovariance - - estimator: EllipticEnvelope - - estimator: GraphicalLasso - - estimator: GraphicalLassoCV - - estimator: LedoitWolf - - estimator: MinCovDet - - estimator: OAS - - estimator: ShrunkCovariance - - estimator: EmpiricalCovariance - squared: True - - estimator: EllipticEnvelope - squared: True - - estimator: GraphicalLasso - squared: True - - estimator: GraphicalLassoCV - squared: True - - estimator: LedoitWolf - squared: True - - estimator: MinCovDet - squared: True - - estimator: OAS - squared: True - - estimator: ShrunkCovariance - squared: True - - # Precision - Precision: - - estimator: EmpiricalCovariance - - estimator: EllipticEnvelope - - estimator: GraphicalLasso - - estimator: GraphicalLassoCV - - estimator: LedoitWolf - - estimator: MinCovDet - - estimator: OAS - - estimator: ShrunkCovariance - - estimator: EmpiricalCovariance - squared: True - - estimator: EllipticEnvelope - squared: True - - estimator: GraphicalLasso - squared: True - - estimator: GraphicalLassoCV - squared: True - - estimator: LedoitWolf - squared: True - - estimator: MinCovDet - squared: True - - estimator: OAS - squared: True - - estimator: ShrunkCovariance - squared: True - - # Spearman's correlation coefficient - SpearmanR: - - squared: True - - - squared: False - - # Kendall's rank correlation coefficient - KendallTau: - - squared: True - - - squared: False - - # statistics based on cross-correlation (squared means we square the xcorr, not the output) - CrossCorrelation: - - statistic: "max" - - - statistic: "max" - squared: True - - - statistic: "mean" - - - statistic: "mean" - squared: True - - - statistic: "mean" - sigonly: False - - - statistic: "mean" - squared: True - sigonly: False - -.statistics.distance: - PairwiseDistance: - - metric: "euclidean" - - metric: "cityblock" - - metric: "cosine" - - metric: "chebyshev" - - metric: "canberra" - - metric: "braycurtis" - - # Distance correlation - DistanceCorrelation: - - biased: False - - biased: True - - # Multi-scale graph correlation - MultiscaleGraphCorrelation: - - # Hilbert-Schmidt independence criterion - HilbertSchmidtIndependenceCriterion: - - biased: False - - biased: True - - # Heller-Heller-Gorfine (HHG) test - HellerHellerGorfine: - - # Multi-scale graph correlation for time series - CrossMultiscaleGraphCorrelation: - - max_lag: 1 - - max_lag: 10 - - # Distance correlation for time series - CrossDistanceCorrelation: - - max_lag: 1 - - max_lag: 10 - - DynamicTimeWarping: - - global_constraint: null - - global_constraint: itakura - - global_constraint: sakoe_chiba - - SoftDynamicTimeWarping: - - global_constraint: null - - global_constraint: itakura - - global_constraint: sakoe_chiba - - LongestCommonSubsequence: - - global_constraint: null - - global_constraint: itakura - - global_constraint: sakoe_chiba - - Barycenter: - - mode: euclidean - statistic: mean - - mode: euclidean - statistic: max - - mode: dtw - statistic: mean - - mode: dtw - statistic: max - - mode: sgddtw - statistic: mean - - mode: sgddtw - statistic: max - - mode: softdtw - statistic: mean - - mode: softdtw - statistic: max - - - mode: euclidean - statistic: mean - squared: True - - - mode: euclidean - statistic: max - squared: True - - - mode: dtw - statistic: mean - squared: True - - - mode: dtw - statistic: max - squared: True - - - mode: sgddtw - statistic: mean - squared: True - - - mode: sgddtw - statistic: max - squared: True - - - mode: softdtw - statistic: mean - squared: True - - - mode: softdtw - statistic: max - squared: True - -.statistics.causal: - # Additive noise model - AdditiveNoiseModel: - - # Conditional distribution similarity statistic - ConditionalDistributionSimilarity: - - # Regression error-based causal inference - RegressionErrorCausalInference: - - # Information-geometric conditional independence - InformationGeometricConditionalIndependence: - - # Convergent-cross mapping - ConvergentCrossMapping: - - statistic: mean - - statistic: max - - statistic: diff - - statistic: mean - embedding_dimension: 1 - - statistic: max - embedding_dimension: 1 - - statistic: diff - embedding_dimension: 1 - - statistic: mean - embedding_dimension: 10 - - statistic: max - embedding_dimension: 10 - - statistic: diff - embedding_dimension: 10 - -# Information-theoretic statistics -# .statistics.infotheory: -# JointEntropy: # No theiler window yet -# - estimator: gaussian - -# - estimator: kozachenko - -# - estimator: kernel - -# ConditionalEntropy: # No theiler window yet -# - estimator: gaussian - -# - estimator: kozachenko - -# - estimator: kernel - -# CausalEntropy: # No theiler window yet -# - estimator: gaussian - -# - estimator: kozachenko - -# - estimator: kernel - -# CrossmapEntropy: # No theiler window yet -# - estimator: gaussian -# history_length: 1 - -# - estimator: kozachenko -# history_length: 1 - -# - estimator: kernel -# history_length: 1 - -# - estimator: gaussian -# history_length: 10 - -# - estimator: kozachenko -# history_length: 10 - -# - estimator: kernel -# history_length: 10 - -# DirectedInfo: # No theiler window yet -# - estimator: gaussian - -# - estimator: kozachenko - -# - estimator: kernel - -# StochasticInteraction: # No theiler window -# - estimator: gaussian - -# - estimator: kozachenko - -# - estimator: kernel - -# # Mutual information -# MutualInfo: -# - estimator: gaussian - -# - estimator: kraskov -# prop_k: 4 - -# - estimator: kraskov -# prop_k: 4 -# dyn_corr_excl: AUTO - -# - estimator: kernel -# kernel_width: 0.25 - -# # Mutual information -# TimeLaggedMutualInfo: -# - estimator: gaussian - -# - estimator: kraskov -# prop_k: 4 - -# - estimator: kraskov -# prop_k: 4 -# dyn_corr_excl: AUTO - -# - estimator: kernel -# kernel_width: 0.25 - -# # Transfer entropy -# TransferEntropy: -# # Kraskov estimator with auto-embedding on source/target and DCE -# - estimator: kraskov -# prop_k: 4 -# auto_embed_method: MAX_CORR_AIS -# k_search_max: 10 -# tau_search_max: 4 - -# - estimator: kraskov -# prop_k: 4 -# auto_embed_method: MAX_CORR_AIS -# k_search_max: 10 -# tau_search_max: 4 -# dyn_corr_excl: AUTO - -# # Kraskov estimator with auto-embedding on target-only, src history of 1, and DCE -# - estimator: kraskov -# prop_k: 4 -# k_history: 2 -# l_history: 1 -# dyn_corr_excl: AUTO - -# # Kraskov estimator with fixed embedding of 1 for source/target and DCE -# - estimator: kraskov -# prop_k: 4 -# k_history: 1 -# l_history: 1 -# dyn_corr_excl: AUTO - -# # Same as above with no DCE -# - estimator: kraskov -# prop_k: 4 -# k_history: 1 -# l_history: 1 - -# # Currently the Kernel method has an overload issue with the AIS calculator.. -# # Kernel estimator with auto-embedding on source/target and DCE -# # - estimator: kernel -# # auto_embed_method: MAX_CORR_AIS -# # k_search_max: 4 -# # kernel_width: 0.25 - -# # Kernel estimator with no auto-embedding on source/target and DCE -# - estimator: kernel -# kernel_width: 0.25 -# k_history: 1 -# l_history: 1 - -# # Gaussian estimator doesn't have DCE (aka Bartlett corrections) yet -# - estimator: gaussian -# auto_embed_method: MAX_CORR_AIS -# k_search_max: 10 -# tau_search_max: 2 - -# - estimator: gaussian -# k_history: 1 -# l_history: 1 - -# - estimator: symbolic -# k_history: 1 -# l_history: 1 - -# - estimator: symbolic -# k_history: 10 -# l_history: 1 - -# IntegratedInformation: -# - phitype: "star" - -# - phitype: "star" -# normalization: 1 - -# - phitype: "Geo" - -# - phitype: "Geo" -# normalization: 1 - -# statistics that analyse in the frequency-domain (see Schoegl and Supp, 2006) -.statistics.spectral: - CoherencePhase: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - CoherenceMagnitude: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - # Coherence (ordinal or squared? imaginary components of the coherence) - ImaginaryCoherence: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - PhaseSlopeIndex: - - fmin: 0 - fmax: 0.5 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - PhaseLockingValue: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - PhaseLagIndex: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - WeightedPhaseLagIndex: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - DebiasedSquaredPhaseLagIndex: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - DebiasedSquaredWeightedPhaseLagIndex: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - PairwisePhaseConsistency: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - DirectedTransferFunction: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - # partial_coherence: - # - fs: 1 - - # - fmin: 0 - # fmax: 0.25 - - # - fmin: 0.25 - # fmax: 0.5 - - # - fs: 1 - # statistic: max - - # - fmin: 0 - # fmax: 0.25 - # statistic: max - - # - fmin: 0.25 - # fmax: 0.5 - # statistic: max - - DirectedCoherence: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - PartialDirectedCoherence: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - GeneralizedPartialDirectedCoherence: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - DirectDirectedTransferFunction: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fs: 1 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - - GroupDelay: - - fmin: 0 - fmax: 0.5 - statistic: delay - - - fmin: 0 - fmax: 0.25 - statistic: delay - - - fmin: 0.25 - fmax: 0.5 - statistic: delay - - SpectralGrangerCausality: - # Non-parametric Granger causality (no VAR model) - - method: nonparametric - fmin: 0 - fmax: 0.5 - statistic: mean - - - method: nonparametric - fmin: 0 - fmax: 0.25 - statistic: mean - - - method: nonparametric - fmin: 0.25 - fmax: 0.5 - statistic: mean - - - method: nonparametric - fmin: 0 - fmax: 0.5 - statistic: max - - - method: nonparametric - fmin: 0 - fmax: 0.25 - statistic: max - - - method: nonparametric - fmin: 0.25 - fmax: 0.5 - statistic: max - - # Parametric Granger causality (VAR model with inferred or predefined order) - - # AR order optimised by BIC - - method: parametric - fmin: 0 - fmax: 0.5 - statistic: mean - - - method: parametric - fmin: 0 - fmax: 0.25 - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - method: parametric - statistic: mean - - # AR order 1 - - fs: 1 - order: 1 - method: parametric - statistic: mean - - - fmin: 0 - fmax: 0.25 - order: 1 - method: parametric - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - order: 1 - method: parametric - statistic: mean - - # AR order 20 - - fs: 1 - order: 20 - method: parametric - statistic: mean - - - fmin: 0 - fmax: 0.25 - order: 20 - method: parametric - statistic: mean - - - fmin: 0.25 - fmax: 0.5 - order: 20 - method: parametric - statistic: mean - - # AR order optimised by BIC - - fs: 1 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - method: parametric - statistic: max - - # AR order 1 - - fs: 1 - order: 1 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - order: 1 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - order: 1 - method: parametric - statistic: max - - # AR order 20 - - fs: 1 - order: 20 - method: parametric - statistic: max - - - fmin: 0 - fmax: 0.25 - order: 20 - method: parametric - statistic: max - - - fmin: 0.25 - fmax: 0.5 - order: 20 - method: parametric - statistic: max - -# statistics that analyse in the wavelet-domain (only Mortlet wavelet's at the moment) -.statistics.wavelet: - PhaseSlopeIndex: - - fs: 1 - - - fmin: 0 - fmax: 0.25 - - - fmin: 0.25 - fmax: 0.5 - - - fmin: 0 - fmax: 0.5 - statistic: max - - - fmin: 0 - fmax: 0.25 - statistic: max - - - fmin: 0.25 - fmax: 0.5 - statistic: max - -.statistics.misc: - LinearModel: - - model: Ridge - - model: Lasso - - model: SGDRegressor - - model: ElasticNet - - model: BayesianRidge - - GPModel: - - kernel: DotProduct - - kernel: RBF - - # Cointegration - Cointegration: - - method: johansen - statistic: max_eig_stat - det_order: 0 # Constant trend - k_ar_diff: 10 - - - method: johansen - statistic: trace_stat - det_order: 0 - k_ar_diff: 10 - - - method: johansen - statistic: max_eig_stat - det_order: 0 # Constant trend - k_ar_diff: 1 - - - method: johansen - statistic: trace_stat - det_order: 0 - k_ar_diff: 1 - - - method: johansen - statistic: max_eig_stat - det_order: 1 # Linear trend - k_ar_diff: 10 - - - method: johansen - statistic: trace_stat - det_order: 1 - k_ar_diff: 10 - - - method: johansen - statistic: max_eig_stat - det_order: 1 - k_ar_diff: 1 - - - method: johansen - statistic: trace_stat - det_order: 1 - k_ar_diff: 1 - - - method: aeg - statistic: tstat - autolag: aic - maxlag: 10 - trend: c - - - method: aeg - statistic: tstat - autolag: aic - maxlag: 10 - trend: ct - - - method: aeg - statistic: tstat - autolag: bic - maxlag: 10 - trend: ct - - # Power envelope correlation - PowerEnvelopeCorrelation: - - orth: False - log: False - absolute: False - - - orth: True - log: False - absolute: False - - - orth: False - log: True - absolute: False - - - orth: True - log: True - absolute: False - - - orth: True - log: False - absolute: True - - - orth: True - log: True - absolute: True diff --git a/pyspi/sonnet_config.yaml b/pyspi/sonnet_config.yaml index 47b3b27..8dba3dd 100644 --- a/pyspi/sonnet_config.yaml +++ b/pyspi/sonnet_config.yaml @@ -2,78 +2,194 @@ .statistics.basic: # Covariance Covariance: - - estimator: EmpiricalCovariance + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: + - estimator: EmpiricalCovariance .statistics.distance: DynamicTimeWarping: - - global_constraint: itakura + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - global_constraint: itakura Barycenter: - - mode: dtw - statistic: mean + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - mode: dtw + statistic: mean .statistics.causal: # Additive noise model AdditiveNoiseModel: + labels: + - directed, + - nonlinear + - unsigned + - bivariate + - contemporaneous + dependencies: + configs: # Information-theoretic statistics .statistics.infotheory: DirectedInfo: # No theiler window yet - - estimator: gaussian + labels: + - directed + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: gaussian # Transfer entropy TransferEntropy: - - estimator: kraskov - prop_k: 4 - auto_embed_method: MAX_CORR_AIS - k_search_max: 10 - tau_search_max: 4 - dyn_corr_excl: AUTO + labels: + - directed + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - java + configs: + - estimator: kraskov + prop_k: 4 + auto_embed_method: MAX_CORR_AIS + k_search_max: 10 + tau_search_max: 4 + dyn_corr_excl: AUTO # Integrated information IntegratedInformation: - - phitype: 'star' + labels: + - undirected + - nonlinear + - unsigned + - bivariate + - time-dependent + dependencies: + - octave + configs: + - phitype: 'star' # statistics that analyse in the frequency-domain (see Schoegl and Supp, 2006) .statistics.spectral: CoherenceMagnitude: - - fs: 1 + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 PhaseSlopeIndex: - - fmin: 0 - fmax: 0.5 + labels: + - directed + - linear/nonlinear + - unsigned + - bivariate + - frequency-dependent + - time-frequency dependent + dependencies: + configs: + - fmin: 0 + fmax: 0.5 PhaseLagIndex: - - - fs: 1 - statistic: max + labels: + - undirected + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - fs: 1 + statistic: max SpectralGrangerCausality: # Non-parametric Granger causality (no VAR model) - - method: nonparametric - fmin: 0 - fmax: 0.5 - statistic: mean + labels: + - directed + - linear + - unsigned + - bivariate + - frequency-dependent + dependencies: + configs: + - method: nonparametric + fmin: 0 + fmax: 0.5 + statistic: mean # statistics that analyse in the wavlet-domain (only Mortlet wavelet's at the moment) .statistics.wavelet: PhaseSlopeIndex: - - fs: 1 + labels: + - directed + - linear/nonlinear + - unsigned + - bivariate + - frequency-dependent + - time-frequency dependent + dependencies: + configs: + - fs: 1 .statistics.misc: # Cointegration Cointegration: - - method: aeg - statistic: tstat - autolag: aic - maxlag: 10 - trend: ct + labels: + - undirected + - linear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - method: aeg + statistic: tstat + autolag: aic + maxlag: 10 + trend: ct # Power envelope correlation PowerEnvelopeCorrelation: - - orth: False - log: False - absolute: False \ No newline at end of file + labels: + - undirected, + - linear + - unsigned + - bivariate + - time-dependent + dependencies: + configs: + - orth: False + log: False + absolute: False diff --git a/pyspi/statistics/infotheory.py b/pyspi/statistics/infotheory.py index c41e327..1bd797e 100644 --- a/pyspi/statistics/infotheory.py +++ b/pyspi/statistics/infotheory.py @@ -1,7 +1,10 @@ import jpype as jp import numpy as np from pyspi import utils -from oct2py import octave, Struct +try: + from oct2py import octave, Struct +except Exception: + pass import copy import os import logging @@ -11,13 +14,13 @@ """ Contains relevant dependence statistics from the information theory community. """ -if not jp.isJVMStarted(): - jarloc = ( - os.path.dirname(os.path.abspath(__file__)) + "/../lib/jidt/infodynamics.jar" - ) - # Change to debug info - logging.debug(f"Starting JVM with java class {jarloc}.") - jp.startJVM(jp.getDefaultJVMPath(), "-ea", "-Djava.class.path=" + jarloc) +# if not jp.isJVMStarted(): +# jarloc = ( +# os.path.dirname(os.path.abspath(__file__)) + "/../lib/jidt/infodynamics.jar" +# ) +# # Change to debug info +# logging.debug(f"Starting JVM with java class {jarloc}.") +# jp.startJVM(jp.getDefaultJVMPath(), "-ea", "-Djava.class.path=" + jarloc) class JIDTBase(Unsigned): diff --git a/pyspi/utils.py b/pyspi/utils.py index 0baebd8..00482e9 100644 --- a/pyspi/utils.py +++ b/pyspi/utils.py @@ -3,6 +3,8 @@ from scipy.stats import zscore import warnings import pandas as pd +import os +import yaml def _contains_nan(a, nan_policy='propagate'): policies = ['propagate', 'raise', 'omit'] @@ -94,7 +96,7 @@ def standardise(a, dimension=0, df=1): numpy array standardised data """ - # Avoid division by standard devitation if the process is constant. + # Avoid division by standard deviation if the process is constant. a_sd = a.std(axis=dimension, ddof=df) if np.isclose(a_sd, 0): @@ -104,4 +106,82 @@ def standardise(a, dimension=0, df=1): def convert_mdf_to_ddf(df): ddf = pd.pivot_table(data=df.stack(dropna=False).reset_index(),index='Dataset',columns=['SPI-1', 'SPI-2'],dropna=False).T.droplevel(0) - return ddf \ No newline at end of file + return ddf + +def is_jpype_jvm_available(): + """Check whether a JVM is accessible via Jpype""" + try: + import jpype as jp + if not jp.isJVMStarted(): + jarloc = (os.path.dirname(os.path.abspath(__file__)) + "/lib/jidt/infodynamics.jar") + # if JVM not started, start a session + print(f"Starting JVM with java class {jarloc}.") + jp.startJVM(jp.getDefaultJVMPath(), "-ea", "-Djava.class.path=" + jarloc) + return True + except Exception as e: + print(f"Jpype JVM not available: {e}") + return False + +def is_octave_available(): + """Check whether octave is available""" + try: + from oct2py import Oct2Py + oc = Oct2Py() + oc.exit() + return True + except Exception as e: + print(f"Octave not available: {e}") + return False + +def check_optional_deps(): + """Bundle all of the optional + dependency checks together.""" + isAvailable = {} + isAvailable['octave'] = is_octave_available() + isAvailable['java'] = is_jpype_jvm_available() + + return isAvailable + +def filter_spis(configfile, keywords, name="filtered_config"): + """Filter a YAML using a list of keywords, and save the reduced + set as a new YAML with a user-specified name in the current + directory.""" + + # check that keywords is a list + if not isinstance(keywords, list): + raise TypeError("Keywords must be passed as a list.") + # load in the original YAML + with open(configfile) as f: + yf = yaml.load(f, Loader=yaml.FullLoader) + + # new dictonary to be converted to final YAML + filtered_subset = {} + spis_found = 0 + + for module in yf: + module_spis = {} + for spi in yf[module]: + spi_labels = yf[module][spi].get('labels') + if all(keyword in spi_labels for keyword in keywords): + module_spis[spi] = yf[module][spi] + spis_found += len(yf[module][spi].get('configs')) + if module_spis: + filtered_subset[module] = module_spis + + # check that > 0 SPIs found + if spis_found == 0: + raise ValueError(f"0 SPIs were found with the specific keywords: {keywords}.") + + # write to YAML + with open(f"pyspi/{name}.yaml", "w") as outfile: + yaml.dump(filtered_subset, outfile, default_flow_style=False, sort_keys=False) + + # output relevant information + # output relevant information + print(f"""\nOperation Summary: +----------------- +- Total SPIs Matched: {spis_found} SPI(s) were found with the specific keywords: {keywords}. +- New File Created: A YAML file named `{name}.yaml` has been saved in the current directory: `pyspi/{name}.yaml' +- Next Steps: To utilise the filtered set of SPIs, please initialise a new Calculator instance with the following command: +`Calculator(configfile='pyspi/{name}.yaml')` +""") diff --git a/setup.py b/setup.py index dd94a76..a90a720 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,6 @@ 'sonnet_config.yaml', 'fast_config.yaml', 'fabfour_config.yaml', - 'octaveless_config.yaml', 'lib/jidt/infodynamics.jar', 'lib/PhiToolbox/Phi/phi_comp.m', 'lib/PhiToolbox/Phi/phi_star_Gauss.m', @@ -62,7 +61,7 @@ 'data/standard_normal.npy', 'data/cml7.npy']}, include_package_data=True, - version='0.4.2', + version='1.0.0', description='Library for pairwise analysis of time series data.', author='Oliver M. Cliff', author_email='oliver.m.cliff@gmail.com', diff --git a/tests/test_SPIs.py b/tests/test_SPIs.py index 61b50bd..d3412bd 100644 --- a/tests/test_SPIs.py +++ b/tests/test_SPIs.py @@ -4,9 +4,6 @@ import pyspi import numpy as np - - - ############# Fixtures and helper functions ######### def load_benchmark_tables(): @@ -103,7 +100,3 @@ def test_mpi(est, est_ob, mpi_benchmark, mpi_new, spi_warning_logger): num_iteractions /= 2 spi_warning_logger(est, module_name, max_z, int(num_exceed), int(num_iteractions)) - - - - diff --git a/tests/test_calc.py b/tests/test_calc.py index 47a35bc..4a202a8 100644 --- a/tests/test_calc.py +++ b/tests/test_calc.py @@ -1,37 +1,51 @@ -from pyspi.calculator import Calculator, Data +from pyspi.calculator import Calculator, Data, CalculatorFrame from pyspi.data import load_dataset import numpy as np import os -import yaml import pytest ############################# Test Calculator Object ######################## -def test_whether_calculator_instatiates(): +def test_whether_calculator_instantiates(): """Basic test to check whether or not the calculator will instantiate.""" calc = Calculator() assert isinstance(calc, Calculator), "Calculator failed to instantiate." -def test_default_calculator_instantiates_with_correct_num_spis(): - """Test whether the default calculator instantiates with the full SPI set""" +def test_whether_calculator_computes(): + # check whether the calculator runs + data = np.random.randn(3, 100) + calc = Calculator(dataset=data) + calc.compute() + +def test_whether_calc_instantiates_without_octave(): + # set octave to false to emulate a system without octave (i.e., fails the check) + Calculator._optional_dependencies['octave'] = False + calc = Calculator() + is_initialised = isinstance(calc, Calculator) + Calculator._optional_dependencies = {} + assert is_initialised, "Calculator failed to instantiate without Octave." + +def test_whether_calc_instantiates_without_java(): + # set java to false and all other deps to true + Calculator._optional_dependencies['java'] = False + Calculator._optional_dependencies['octave'] = True calc = Calculator() - n_spis_actual = calc.n_spis - # get expected number of spis based on yaml - with open('pyspi/config.yaml', 'rb') as y: - yaml_file = yaml.full_load(y) - count = 0 - for module in yaml_file.keys(): - for base_spi in yaml_file[module].keys(): - if yaml_file[module][base_spi] == None: - count += 1 - else: - count += len(yaml_file[module][base_spi]) - assert count == n_spis_actual, f"Number of SPIs loaded from the calculator ({n_spis_actual}) does not matched expected amount {count}" + is_initialised = isinstance(calc, Calculator) + Calculator._optional_dependencies = {} + assert is_initialised, "Calculator failed to instantiate without Java." + +def test_whether_calc_instantiates_wo_optional_deps(): + # set all optional deps to false + Calculator._optional_dependencies['java'] = False + Calculator._optional_dependencies['octave'] = False + calc = Calculator() + is_initialised = isinstance(calc, Calculator) + Calculator._optional_dependencies = {} + assert is_initialised, "Calculator failed to instantiate without optional dependencies." @pytest.mark.parametrize("subset", [ 'fabfour', 'fast', - 'sonnet', - 'octaveless' + 'sonnet' ]) def test_whether_calculator_instantiates_with_subsets(subset): """Test whether the calculator instantiates with each of the available subsets""" @@ -112,11 +126,10 @@ def test_data_object_process_and_observations(shape, n_procs_expected, n_obs_exp @pytest.mark.parametrize("yaml_filename", [ 'fabfour_config', - 'fast_config', - 'octaveless_config', + 'fast_config', 'sonnet_config']) def test_whether_config_files_exist(yaml_filename): - """Check whether the config, fabfour, fast, octaveless, sonnet_config files exist""" + """Check whether the config, fabfour, fast, sonnet_config files exist""" expected_file = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'pyspi', f'{yaml_filename}.yaml')) assert os.path.isfile(expected_file), f"{yaml_filename}.yaml file was not found." @@ -243,3 +256,44 @@ def test_load_invalid_dataset(): with pytest.raises(NameError) as excinfo: dataset = load_dataset(name="test") assert "Unknown dataset: test" in str(excinfo.value), "Did not get expected error when loading invalid dataset." + +def test_calculator_frame_normal_operation(): + """Test whether the calculator frame instantiates as expected.""" + datasets = [np.random.randn(3, 100) for _ in range(3)] + dataset_names = ['d1', 'd2', 'd3'] + dataset_labels = ['label1', 'label2', 'label3'] + + # create calculator frame + calc_frame = CalculatorFrame(name="MyCalcFrame", datasets=[Data(data=data, dim_order='ps') for data in datasets], + names=dataset_names, labels=dataset_labels, subset='fabfour') + assert(isinstance(calc_frame, CalculatorFrame)), "CalculatorFrame failed to instantiate." + + # check the properties of the frame + # check expected number of calcs in frame - 3 for 3 datasets + num_calcs_in_frame = calc_frame.n_calculators + assert num_calcs_in_frame == 3, f"Unexpected number ({num_calcs_in_frame}) of calculators in the frame. Expected 3." + + # get the frame name + assert calc_frame.name == "MyCalcFrame", "Calculator frame has unexpected name." + + # ensure dataset names, labels passed along to inidividual calculators + for (index, calc) in enumerate(calc_frame.calculators[0]): + assert calc.name == dataset_names[index], "Indiviudal calculator has unexpected name." + assert calc.labels == dataset_labels[index], "Indiviudal calculator has unexpected label." + + # check that compute runs + calc_frame.compute() + + +def test_correlation_frame_normal_operation(): + """Test whether the correlation frame instantiates as expected.""" + datasets = [np.random.randn(3, 100) for _ in range(3)] + dataset_names = ['d1', 'd2', 'd3'] + dataset_labels = ['label1', 'label2', 'label3'] + calc_frame = CalculatorFrame(name="MyCalcFrame", datasets=[Data(data=data, dim_order='ps') for data in datasets], + names=dataset_names, labels=dataset_labels, subset='fabfour') + + calc_frame.compute() + cf = calc_frame.get_correlation_df() + + assert not(cf[0].empty), "Correlation frame is empty." diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..ff30cb5 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,61 @@ +from pyspi.utils import filter_spis +import pytest +import yaml + +def test_filter_spis_invalid_keywords(): + """Pass in a dataype other than a list for the keywords""" + with pytest.raises(TypeError) as excinfo: + filter_spis("pyspi/config.yaml", "linear") + assert "Keywords must be passed as a list" in str(excinfo.value), "Keywords must be passed as list error not shown." + +def test_filter_spis_with_invalid_config(): + """Pass in an invalid/missing config file""" + with pytest.raises(FileNotFoundError): + filter_spis("invalid_config.yaml", ["test"]) + +def test_filter_spis_no_matches(): + """Pass in keywords that return no spis and check for ValuError""" + mock_yaml_content = { + "module1": { + "spi1": {"labels": ["keyword1", "keyword2"], "configs": [1, 2]}, + "spi2": {"labels": ["keyword1"], "configs": [3]} + } + } + keywords = ["random_keyword"] + + # create temporary YAML to load into the function + with open("pyspi/mock_config2.yaml", "w") as f: + yaml.dump(mock_yaml_content, f) + + with pytest.raises(ValueError) as excinfo: + filter_spis("pyspi/mock_config2.yaml", keywords, name="mock_filtered_config") + assert "0 SPIs were found" in str(excinfo.value), "Incorrect error message returned when no keywords match found." + +def test_filter_spis_normal_operation(): + """Test whether the filter spis function works as expected""" + # create some mock content to filter + mock_yaml_content = { + "module1": { + "spi1": {"labels": ["keyword1", "keyword2"], "configs": [1, 2]}, + "spi2": {"labels": ["keyword1"], "configs": [3]} + } + } + keywords = ["keyword1", "keyword2"] + expected_output_yaml = { + "module1": { + "spi1": {"labels": ["keyword1", "keyword2"], "configs": [1,2]} + } + } + + # create temporary YAML to load into the function + with open("pyspi/mock_config.yaml", "w") as f: + yaml.dump(mock_yaml_content, f) + + + filter_spis("pyspi/mock_config.yaml", keywords, name="mock_filtered_config") + + # load in the output + with open("pyspi/mock_filtered_config.yaml", "r") as f: + actual_output = yaml.load(f, Loader=yaml.FullLoader) + + assert actual_output == expected_output_yaml, "Expected filtered YAML does not match actual filtered YAML."