Python API Usage

The Analysis Runners module contains the Python API to analyze an algorithm using the Python API, programmatically from another program or script.

Each runner implements a complete analysis workflow for a set of databases, including:

  • Input validation

  • Algorithm selection

  • Execution

  • Result formatting

Each algorithm needs two arguments, the data needed to identify the ensembles, usually just a raster of activity, and the parameters for the algorithm.

See also

Check the detail of the arguments for the analyses in the docs Analysis Runners.

See also

Check the needed data and parameters for each algorithm in the Algorithms configuration file

Data examples

Each algorithm needs different data inputs. This inputs should be inside a python dictionary with specific names:

 1import numpy as np
 2
 3# Dummy data
 4neurons = 100
 5timepoints = 2000
 6behaviors = 2
 7stimuli = 4
 8neurons_sets = 5
 9
10# The binary activity raster
11neuronal_activity = np.random.rand(neurons, timepoints)
12neuronal_activity = (neuronal_activity > 0.9).astype(np.int_)
13
14# The continuous fluorescence raster
15dFFo = np.random.rand(neurons, timepoints)
16
17# The 2D coordinates
18coordinates = np.random.rand(2, timepoints) * 100
19
20# The binary stimuli matrix
21stims = np.random.rand(stimuli, timepoints)
22stims = (stims > 0.25).astype(np.int_)
23
24# The binary groups of neurons
25cells = np.random.rand(neurons_sets, neurons)
26cells = (cells > 0.9).astype(np.int_)
27
28# The continuous behavior matrix
29behavior = np.random.rand(behaviors, timepoints)
30
31data = {
32    "data_neuronal_activity":  neuronal_activity,
33    "data_dFFo":  dFFo,
34    "data_coordinates": coordinates,
35    "data_stims": stims,
36    "data_cells": cells,
37    "data_behavior": behavior,
38}

Those are the available names and variables, however most algorithms need only one.

Needed data for each algorithm

Algorithm

Data needed

SVD

data_neuronal_activity

PCA

data_neuronal_activity

ICA

data_neuronal_activity

X2P

data_neuronal_activity

SGC

data_dFFo

Example

data_dFFo and data_neuronal_activity

Note

The other variables are available for possible new algorithms.

Parameters examples

Each runner requires the parameter for the specific algorithm. You can check the parameters definitions in the config file.

Here is an example of the definition of the parameters dictionary for each algorithm.

Tip

The description of each parameter, the accepted values for each and other names is also in the Algorithms configuration file.

SVD

 1parameters_svd = {
 2    "pks": 3,
 3    "scut": 0.24,
 4    "hcut": 0.24,
 5    "state_cut": 6,
 6    "csi_start": 0.01,
 7    "csi_step": 0.01,
 8    "csi_end": 0.1,
 9    "tf_idf_norm": True,
10    "parallel_processing": False,
11    "fixed_ens_cant": 0,
12}

ICA

 1parameters_ica = {
 2    "threshold_method": "MarcenkoPastur",
 3    "permutations_percentile": 95.0,
 4    "number_of_permutations": 20,
 5    "min_ensembles_cant": 4,
 6    "max_ensembles_cant": 10,
 7    "patterns_method": "ICA",
 8    "number_of_iterations": 1000,
 9    "threshold_for_p_value": 1.90,
10}

X2P

 1parameters_x2p = {
 2    "NetworkBin": 1,
 3    "NetworkIterations": 1000,
 4    "NetworkSignificance": 0.05,
 5    "CoactiveNeuronsThreshold": 2,
 6    "ClusteringRangeStart": 3,
 7    "ClusteringRangeEnd": 10,
 8    "ClusteringFixed": 0,
 9    "EnsembleIterations": 3000,
10    "ParallelProcessing": False,
11}

PCA

 1parameters_pca = {
 2    "dc": 0.01,
 3    "npcs": 3,
 4    "minspk": 3,
 5    "nsur": 1000,
 6    "prct": 99.90,
 7    "cent_thr": 99.90,
 8    "inner_corr": 5.0,
 9    "minsize": 3,
10}

SGC

1parameters_sgc = {
2    "use_first_derivative": False,
3    "standard_deviations_threshold": 2,
4    "shuffling_rounds": 1000,
5    "coactivity_significance_level": 0.05,
6    "montecarlo_rounds": 5,
7    "montecarlo_steps": 10000,
8    "affinity_threshold": 0.2,
9}

Simple analysis script

In the following example I define a sample raster binary with 100 neurons and 2000 timepoints and analyze it using the SVD algorithm.

 1import numpy as np
 2from encore.runners.encore import run_svd
 3
 4# Dummy data for the analysis
 5neurons = 100
 6timepoints = 2000
 7raster = np.random.rand(neurons, timepoints)
 8raster = (raster > 0.9).astype(np.int_)
 9
10data = {
11    'data_neuronal_activity': raster
12}
13
14# Define algorithm parameters
15parameters = {
16    "pks": 3,
17    "scut": 0.24,
18    "hcut": 0.24,
19    "state_cut": 6,
20    "csi_start": 0.01,
21    "csi_step": 0.01,
22    "csi_end": 0.1,
23    "tf_idf_norm": True,
24    "parallel_processing": False,
25    "fixed_ens_cant": 0,
26}
27
28# Run analysis
29results = run_svd(data, parameters)

Analysis output

The output of every runner contains a dictionary like the following:

 1results = {
 2    "success": True, # Bool value indicating if the algorithm was executed successfully
 3    "algorithm_time": 95.47, # Float with the running time of the algorithm in seconds
 4    "engine_time": 11.42, # Float with the loading time for the MATLAB engine if used
 5
 6    "results": {
 7        # Probably the most important one, the minimal results of the algorithm
 8        "ensembles_cant": 8, # int, number of ensembles identified
 9        "neus_in_ens": np.ndarray,  # 2D binary numpy array showing what neurons belong to each ensemble
10                                    # with shape (N, E) for N neurons and E identified ensembles
11        "timecourse": np.ndarray,   # 2D binary array showing the activity of each ensemble in time
12                                    # with shape (T, E) for T timepoints and E ensembles.
13    },
14
15    "update_params": {
16        # Contains parameters updated by the algorithm, e.g. during automatic parameter estimation
17        # these keys and values varies from each algorithm and parameter selection.
18        "pks": 3,
19        "scut": 0.24,
20    },
21
22    "answer": {
23        # Contains internal variables produced by the algorithm, this depends on the algorithm
24        # This variable is saved when the runner is executed with the argument include_answer=True
25        "Pks_Frame": np.ndarray, #2D
26        "Pools_coords": np.ndarray, #3D
27        "num_state": 17,
28        "state_cut": 17,
29        # etc ...
30    }
31}

Important

The keys "success", "algorithm_time", "engine_time" and "results" are returned for every algorithm and have the same logic. The ones that change depending on the algorithm are "update_params" and "answer".

Saving results example

You can easily save the results of that analysis using the built in function save_data_to_hdf5_file, check Save data.

1from encore.data.save_data import save_data_to_hdf5_file
2
3result_path = folder_path / "svd_results.h5"
4save_data_to_hdf5_file(result_path, results)

Tip

Use a graphical HDF5 visualizer for a quick glance on the results.

Using a logger

You can track the progress of the function by passing a logger function, for example:

1def logger_adapter(message: str, level: str):
2    print(f"{level.upper()} - {message}")
3
4
5results = run_svd(data, parameters, logger=logger_adapter)