Time Travel Task Analyses

This notebook contains the analyses necessary to generate the results for the Time Travel Task. The time travel task outputs a binary format log file for space efficiency which first needs to be converted to the appropriate intermediate representations (the iPosition format for test results and an intermediate navigation format for study/test navigation results).

Note: Many of these processing steps can take quite a long time to run as they're processing several gigabytes of data. This issue is compounded if the data is being held on a server. If the intermediate data files have already been generated, it is advisable to skip the steps which regenerate them. These slow code blocks are marked with a note box.

Data Directories

In order to run most cells in this notebook, these data directories need to be defined (and filled with the appropriate data - see the Data Conversion section below to generate the data_output_directory contents).


In [1]:
data_directory = r'C:\Users\Kevin\Documents\GitHub\msl-iposition-pipeline\examples\saved_data\Paper Data (cleaned)'
data_output_directory = r'C:\Users\Kevin\Documents\GitHub\msl-iposition-pipeline\examples\saved_data\Paper Data (iPosition Format)'

generate_intermediate_files = False  # If True, the cells which generate intermediate files will run (they are very slow)
generate_embedded_animations = False  # If True, the embedded animations will be generated such that they are saved in the file

Data Conversion

First we'll process the data into the appropriate formats.


In [2]:
import cogrecon.core.data_flexing.time_travel_task.time_travel_task_to_iposition as ttt2i
Note: The next cell can take a significant amount of time to run and should only be run on an **empty** directory (otherwise it will append to the files in the directory).

To run the cell, set generate_intermediate_files to True (in [Data Directories](#Data-Directories)).

In [3]:
if 'generate_intermediate_files' in vars() and generate_intermediate_files:
    ttt2i.time_travel_task_to_iposition(data_directory, data_output_directory)

Test Intermediate Data

For test, there are several primary analyses to be run. First, a basic analysis for the purpose of determining the test-time performance in space or in time are performed. This can be done quite simply with the basic batch processing functions.

Note that these files contain all the output metrics necessary to perform the statistics on Space/Time Misplacement, Number of Incorrect Event Types, Miassignments in Space vs. Time, and Context Boundary Effects.


In [4]:
from cogrecon.core.batch_pipeline import batch_pipeline
from cogrecon.core.data_flexing.time_travel_task.time_travel_task_analytics import summarize_test_data
Note: The next cell can take a significant amount of time to run. If the intermediate data file (*time_travel_task_test_summary.csv* by default) already exists, consider skipping the next cell.

To run the cell, set generate_intermediate_files to True (in [Data Directories](#Data-Directories)).

In [5]:
if 'generate_intermediate_files' in vars() and generate_intermediate_files:
    summarize_test_data(search_directory=data_directory)  # For Time Travel Task specific analyses

Test Data Analyses

This subsection contains the analyses which generate basic statistics of interest for the following values:

  • Misplacement in Space
  • Misplacement in Time
  • Number of Events Incorrect
  • Misassignments in Space
  • Misassignments in Time
  • Context-Boundary Effects (in Time)
Note that this section requires the intermediate files (generated above) to execute.

In [6]:
# For Time vs. Space Reconstruction Analyses
if 'generate_intermediate_files' in vars() and generate_intermediate_files:
    batch_pipeline(str(data_output_directory), 'TimeTravelTask_SpaceOnly.csv', data_shape=(4, 10, 3),
                   collapse_trials=False, trial_by_trial_accuracy=False,
                   dimension=3, removal_dim_indicies=[2], actual_coordinate_prefixes=True)
    batch_pipeline(str(data_output_directory), 'TimeTravelTask_TimeOnly.csv', data_shape=(4, 10, 3),
                   collapse_trials=False, trial_by_trial_accuracy=False,
                   dimension=3, removal_dim_indicies=[0, 1], actual_coordinate_prefixes=True)
    batch_pipeline(str(data_output_directory), 'TimeTravelTask_CombinedSpaceAndTime.csv', data_shape=(4, 10, 3),
                   collapse_trials=False, trial_by_trial_accuracy=False,
                   dimension=3, actual_coordinate_prefixes=True)

Intermediate Files


In [7]:
test_summary_filename = 'time_travel_task_test_summary.csv'
test_cogrecon_space_only_filename = 'TimeTravelTask_SpaceOnly.csv'
test_cogrecon_time_only_filename = 'TimeTravelTask_TimeOnly.csv'

Visualization Helper Function


In [8]:
import pandas
import numpy as np
import matplotlib.pyplot as plt

import rpy2.robjects.packages as rpackages
from rpy2.robjects.vectors import StrVector
from rpy2.robjects import r, pandas2ri
import rpy2.robjects

pandas2ri.activate()
utils = rpackages.importr('utils')
utils.chooseCRANmirror(ind=1)
packnames = ['afex']
names_to_install = [x for x in packnames if not rpackages.isinstalled(x)]
if len(names_to_install) > 0:
    utils.install_packages(StrVector(names_to_install))
afex = rpackages.importr('afex')

def rANOVA(_data, column, significance_level=0.05, verbose=False):
    r_data = pandas2ri.py2ri(_data) # Convert the data
    ez = r.aov_ez('subID', column, r_data, within='trial') # Run the anova
    p_value = np.array(np.array(ez)[0])[-1][0] # Store the p-value
    print('_'*50)
    if p_value < significance_level: # Check for significance
        print("Significant (p={0}) change in {1} overall.\r\n".format(p_value, column))
        em = r.emmeans(ez, r.formula('~trial')) # Calculate the trial statistics
        forward_difference_anova_result = r.pairs(em) # Generate the Tukey corrected pairwise comparisons
        forward_difference_anova_summary = r.summary(forward_difference_anova_result) # Summarize the results
        adjacent_p_values = np.array(forward_difference_anova_summary)[5][[True, False, False, True, False, True]]
        for p, l in zip(adjacent_p_values, ['First vs. Second', 'Second vs. Third', 'Third vs. Fourth']):
            if p < significance_level:
                print("Significant (p={0}) change in {1}.".format(p, l))
            else:
                print("No Significant (p={0}) change in {1}.".format(p, l))
        if verbose:
            print(ez) # Print the basic anova result
            print(forward_difference_anova_summary) # Print the pairwise comparisons
    else:
        print("No Significant (p={0}) change in {1} overall.".format(p_value, column))
    print('_'*50)

In [9]:
import pandas
import numpy as np
import matplotlib.pyplot as plt

def visualize_columns(data, column_names, titles, ylabels, fig_size=(15, 5), separate_plots=True, legend_labels=None, subplot_shape=None, verbose_anova=False):
    # Extract the columns of interest
    trial_num = data['trial']
    columns = [data[c_name] for c_name in column_names]
    
    # Generate useful constants
    trials = list(set(trial_num))
    num_items = 10
    num_participants = len(trial_num)
    means = [[np.mean(column[trial_num == i]) for i in trials] for column in columns]
    std_errs = [[np.std(column[trial_num == i])/np.sqrt(num_participants) for i in trials] for column in columns]
    
    # Visualize each trial-over-trial mean in a subplot
    if separate_plots:
        if subplot_shape is None:
            f, axarr = plt.subplots(1, len(column_names))
        else:
            f, axarr = plt.subplots(*subplot_shape)
            axarr = [j for i in axarr for j in i]
        if len(column_names) == 1:
            axarr = [axarr]
        f.set_size_inches(fig_size)
        for ax, title, mean, std_err, ylabel in zip(axarr, titles, means, std_errs, ylabels):
            ax.errorbar(trials, mean, std_err)
            ax.set_title(title)
            ax.grid(True)
            ax.set_xlabel('Trials')
            ax.set_ylabel(ylabel)
            ax.xaxis.set_ticks(trials)
        plt.show()
    else:
        f = plt.figure()
        f.set_size_inches(fig_size)
        for idx, (title, mean, std_err, ylabel) in enumerate(zip(titles, means, std_errs, ylabels)):
            label = ''
            if legend_labels is not None:
                label = legend_labels[idx]
            plt.errorbar(trials, mean, std_err, label=label)
            plt.title(title)
            plt.grid(True)
            plt.xlabel('Trials')
            plt.ylabel(ylabel)
            plt.gca().xaxis.set_ticks(trials)
            plt.legend()
        plt.show()
    
    for column in column_names:
        rANOVA(data, column.replace(' ', '.'), verbose=verbose_anova)

Misplacement (in Space and Time) and Events


In [10]:
import pandas

In [11]:
# Load the data
data = pandas.read_csv(test_summary_filename)

columns =  ['space_misplacement', 'time_misplacement', 'event_type_correct_count']
titles = ['Space Misplacement', 'Time Misplacement', 'Event Type Correct']
ylabels = ['Misplacement (meters)', 'Misplacement (seconds)', 'Incorrect Events']
visualize_columns(data, columns, titles, ylabels)


__________________________________________________
Significant (p=1.63691801513e-09) change in space_misplacement overall.

Significant (p=0.00176252612195) change in First vs. Second.
Significant (p=0.00262516972853) change in Second vs. Third.
No Significant (p=0.988859577995) change in Third vs. Fourth.
__________________________________________________
__________________________________________________
Significant (p=7.64797273114e-19) change in time_misplacement overall.

Significant (p=0.0) change in First vs. Second.
Significant (p=0.0359419937541) change in Second vs. Third.
No Significant (p=0.101242727569) change in Third vs. Fourth.
__________________________________________________
__________________________________________________
Significant (p=1.71160205047e-17) change in event_type_correct_count overall.

Significant (p=1.32217111841e-05) change in First vs. Second.
Significant (p=0.000114630838888) change in Second vs. Third.
No Significant (p=0.307427235767) change in Third vs. Fourth.
__________________________________________________

Misassignments (in Space and Time)


In [12]:
# Load the data
data_time = pandas.read_csv(test_cogrecon_time_only_filename, skiprows=1)
data_space = pandas.read_csv(test_cogrecon_space_only_filename, skiprows=1)

visualize_columns(data_time, ['Accurate Misassignment'], ['Time Misassignment'], ['Number of Items'], verbose_anova=True)
visualize_columns(data_space, ['Accurate Misassignment'], ['Space Misassignment'], ['Number of Items'], verbose_anova=True)


__________________________________________________
Significant (p=1.19557816144e-06) change in Accurate.Misassignment overall.

No Significant (p=0.225202933101) change in First vs. Second.
No Significant (p=0.17643533459) change in Second vs. Third.
No Significant (p=0.347395629528) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: Accurate.Misassignment

  Effect           df  MSE         F ges p.value

1  trial 2.82, 118.30 3.03 11.97 *** .10  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast  estimate        SE  df t.ratio p.value

 X0 - X1  0.6976744 0.3635037 126   1.919  0.2252

 X0 - X2  1.4418605 0.3635037 126   3.967  0.0007

 X0 - X3  2.0465116 0.3635037 126   5.630  <.0001

 X1 - X2  0.7441860 0.3635037 126   2.047  0.1764

 X1 - X3  1.3488372 0.3635037 126   3.711  0.0017

 X2 - X3  0.6046512 0.3635037 126   1.663  0.3474



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=2.00144179543e-06) change in Accurate.Misassignment overall.

Significant (p=0.0110162792312) change in First vs. Second.
No Significant (p=0.262109863364) change in Second vs. Third.
No Significant (p=0.860591747484) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: Accurate.Misassignment

  Effect           df  MSE         F ges p.value

1  trial 2.40, 100.88 0.85 13.13 *** .11  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast  estimate        SE  df t.ratio p.value

 X0 - X1  0.5581395 0.1774742 126   3.145  0.0110

 X0 - X2  0.8837209 0.1774742 126   4.979  <.0001

 X0 - X3  1.0232558 0.1774742 126   5.766  <.0001

 X1 - X2  0.3255814 0.1774742 126   1.835  0.2621

 X1 - X3  0.4651163 0.1774742 126   2.621  0.0479

 X2 - X3  0.1395349 0.1774742 126   0.786  0.8606



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________

Context Boundary Effects (in Time)


In [13]:
# Load the data
data_time = pandas.read_csv(test_summary_filename)

columns = ['context_crossing_dist_exclude_wrong_color_pairs', 'context_noncrossing_dist_exclude_wrong_color_pairs']
titles = ['', 'Within vs. Across']
legend_labels = ['Across', 'Within']
ylabels = ['Normalized Distance (1 is perfect)', 'Normalized Distance (1 is perfect)']

visualize_columns(data_time, columns, titles, ylabels, separate_plots=False, legend_labels=legend_labels)


__________________________________________________
No Significant (p=0.479747100695) change in context_crossing_dist_exclude_wrong_color_pairs overall.
__________________________________________________
__________________________________________________
No Significant (p=0.214291908286) change in context_noncrossing_dist_exclude_wrong_color_pairs overall.
__________________________________________________

Effect of Context on Misassignment

The analysis of the effect of context on misassignment is not included in any of the packages directly. As a result, we need to do some custom computation to get out these numbers.

First, we need to read the data from the Accurate Misassignment Pairs column in the temporal only test output file. Because we're running this in one file, we can simply extract this from the output result rather than reading from file.


In [14]:
import ast
import pandas
import numpy as np
from cogrecon.core.batch_pipeline import get_header_labels

In [15]:
# Load the data
data = pandas.read_csv('TimeTravelTask_TimeOnly.csv', skiprows=1)
misassignment_pairs = [ast.literal_eval(row) for row in data['Accurate Misassignment Pairs']]

Next we'll process the list, counting the number of within vs. across context pairs.


In [16]:
# The pairs which share a context (note that order doesn't matter for this)
within_key = [[0, 1], [1, 0], [2, 3], [3, 2], [4, 5], [5, 4], [6, 7], [7, 6]]
# The items to exclude because they had no contextual information
# thus if they were given temporal information, they would not be a valid misassignment
exclusion_items = [8, 9]

within_list = []
across_list = []
totals_list = []
for i, a in enumerate(misassignment_pairs):
    totals_list.append(len(a))
    within_list.append(0)
    across_list.append(0)
    for el in a:
        if all([el_i not in exclusion_items for el_i in el]):
            if el in within_key:
                within_list[-1] += 1
            else:
                across_list[-1] += 1
within_list_proportion = [float(x)/float(y) if y is not 0 else np.nan for x, y in zip(within_list, totals_list)]
across_list_proportion = [float(x)/float(y) if y is not 0 else np.nan for x, y in zip(across_list, totals_list)]

In [17]:
data = pandas.read_csv('TimeTravelTask_TimeOnly.csv', skiprows=1)

num_elements = len(within_list_proportion)

data['within_list_proportion'] = pandas.Series(within_list_proportion)
data['across_list_proportion'] = pandas.Series(across_list_proportion)
data['within'] = pandas.Series(within_list)
data['across'] = pandas.Series(across_list)
data['top'] = pandas.Series([6./7.]*num_elements)
data['bottom'] = pandas.Series([1./7.]*num_elements)

columns_proportion = ['top', 'bottom', 'within_list_proportion', 'across_list_proportion']
titles_proportion = ['', '', '', 'Within vs. Across Proportion']
legend_labels_proportion = ["Across Chance", "Within Chance", "Within", "Across"]
ylabels_proportion = ['', '', '', 'Proportion of Misassignments']

columns = ['within', 'across']
titles = ['', 'Within vs. Across']
legend_labels = ["Within", "Across"]
ylabels = ['', 'Number of Misassigned Items']

visualize_columns(data, columns_proportion, titles_proportion, ylabels_proportion, separate_plots=False, legend_labels=legend_labels_proportion, verbose_anova=True)
visualize_columns(data, columns, titles, ylabels, separate_plots=False, legend_labels=legend_labels, verbose_anova=True)


__________________________________________________
No Significant (p=nan) change in top overall.
__________________________________________________
__________________________________________________
No Significant (p=nan) change in bottom overall.
__________________________________________________
__________________________________________________
Significant (p=4.01485426036e-07) change in within_list_proportion overall.

Significant (p=0.0181511063692) change in First vs. Second.
No Significant (p=0.0764991305703) change in Second vs. Third.
No Significant (p=0.997239193399) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: within_list_proportion

  Effect          df  MSE         F ges p.value

1  trial 2.77, 85.80 0.05 13.87 *** .16  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast    estimate         SE df t.ratio p.value

 X0 - X1  -0.16804315 0.05610468 93  -2.995  0.0182

 X0 - X2  -0.30498512 0.05610468 93  -5.436  <.0001

 X0 - X3  -0.31608383 0.05610468 93  -5.634  <.0001

 X1 - X2  -0.13694196 0.05610468 93  -2.441  0.0765

 X1 - X3  -0.14804067 0.05610468 93  -2.639  0.0472

 X2 - X3  -0.01109871 0.05610468 93  -0.198  0.9972



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=0.00489901408485) change in across_list_proportion overall.

No Significant (p=0.999143517347) change in First vs. Second.
Significant (p=0.0280635923527) change in Second vs. Third.
No Significant (p=0.950446356818) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: across_list_proportion

  Effect          df  MSE       F ges p.value

1  trial 2.82, 87.51 0.05 4.74 ** .06    .005

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast    estimate         SE df t.ratio p.value

 X0 - X1   0.00718006 0.05376307 93   0.134  0.9991

 X0 - X2   0.15974702 0.05376307 93   2.971  0.0194

 X0 - X3   0.13101438 0.05376307 93   2.437  0.0772

 X1 - X2   0.15256696 0.05376307 93   2.838  0.0281

 X1 - X3   0.12383433 0.05376307 93   2.303  0.1046

 X2 - X3  -0.02873264 0.05376307 93  -0.534  0.9504



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=0.00203091801531) change in within overall.

Significant (p=0.0358647525425) change in First vs. Second.
No Significant (p=0.735608638458) change in Second vs. Third.
No Significant (p=0.828623077631) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: within

  Effect           df  MSE       F ges p.value

1  trial 2.91, 122.05 1.65 5.30 ** .06    .002

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast    estimate        SE  df t.ratio p.value

 X0 - X1  -0.74418605 0.2724781 126  -2.731  0.0359

 X0 - X2  -1.02325581 0.2724781 126  -3.755  0.0015

 X0 - X3  -0.79069767 0.2724781 126  -2.902  0.0225

 X1 - X2  -0.27906977 0.2724781 126  -1.024  0.7356

 X1 - X3  -0.04651163 0.2724781 126  -0.171  0.9982

 X2 - X3   0.23255814 0.2724781 126   0.853  0.8286



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=4.8750538701e-07) change in across overall.

No Significant (p=0.184299033765) change in First vs. Second.
Significant (p=0.0112203148343) change in Second vs. Third.
No Significant (p=0.929525279935) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: across

  Effect           df  MSE         F ges p.value

1  trial 2.40, 100.81 1.42 14.72 *** .12  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast  estimate        SE  df t.ratio p.value

 X0 - X1  0.4651163 0.2296795 126   2.025  0.1843

 X0 - X2  1.1860465 0.2296795 126   5.164  <.0001

 X0 - X3  1.3255814 0.2296795 126   5.771  <.0001

 X1 - X2  0.7209302 0.2296795 126   3.139  0.0112

 X1 - X3  0.8604651 0.2296795 126   3.746  0.0015

 X2 - X3  0.1395349 0.2296795 126   0.608  0.9295



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________

Next we can save these results to an intermediate file for running statistics.


In [18]:
if 'generate_intermediate_files' in vars() and generate_intermediate_files:
    with open('misassignments_by_context.csv', 'w') as fp:
        fp.write('subID,trial,total_misassignments,within_misassignments,across_misassignments,within_misassignment_proportions,across_misassignment_proportions\n')
        for sid, tr, t, w, a, wp, ap in zip(data['subID'], data['trial'], totals_list,within_list ,across_list,within_list_proportion,across_list_proportion):
            fp.write('{0},{1},{2},{3},{4},{5},{6}\n'.format(sid, tr, t, w, a, wp, ap))

Next, we can create the summary file for navigation metrics.


In [19]:
from cogrecon.core.data_flexing.time_travel_task.time_travel_task_analytics import summarize_navigation_data
Note: The next cell can take a significant amount of time to run. If the intermediate data file (*time_travel_task_navigation_summary.csv* by default) already exists, consider skipping the next cell.

To run the cell, set generate_intermediate_files to True (in [Data Directories](#Data-Directories)).

See the FD_Lacunarity.ipynb for details on how fd_indicies were determined. They can be calculated for individuals by setting fd_indicies_domain=None. Otherwise a list of scale indicies is expected (in this case, deteremined by the average window across participants).


In [20]:
if 'generate_intermediate_files' in vars() and generate_intermediate_files:
    summarize_navigation_data(search_directory=data_directory, 
                              fd_indicies_time=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
                              fd_indicies_space=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
                              fd_indicies_spacetime=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])  # For Time Travel Task specific analyses

In [21]:
import pandas

# Load the data
data_nav = pandas.read_csv('time_travel_task_navigation_summary.csv')

In [22]:
columns = ['time_travelled', 'space_travelled', 'context_boundary_crossings',
           'fd_time', 'fd_space', 'fd_spacetime',
           'lacunarity_time', 'lacunarity_space', 'lacunarity_spacetime']
titles = ['Temporal Distance', 'Spatial Distance', 'Boundary Crossings',
          'Fractal Dimension Time', 'Fractal Dimension Space', 'Fractal Dimension Spacetime',
          'Lacunarity Time', 'Lacunarity Space', 'Lacunarity Spacetime']
ylabels = ['Distance Travelled (seconds)', 'Distance Travelled (meters)', 'Number of Instances',
           '', '', '', '', '', '']

visualize_columns(data_nav, columns, titles, ylabels, separate_plots=True, subplot_shape=[3, 3], fig_size=(15, 15), verbose_anova=True)


__________________________________________________
Significant (p=8.42343612172e-23) change in time_travelled overall.

Significant (p=1.15869425166e-10) change in First vs. Second.
Significant (p=0.000167247987021) change in Second vs. Third.
No Significant (p=0.139946487251) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: time_travelled

  Effect           df      MSE         F ges p.value

1  trial 2.40, 100.75 79540.78 75.01 *** .49  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast estimate       SE  df t.ratio p.value

 X1 - X2  401.0956 54.38806 126   7.375  <.0001

 X1 - X3  637.2363 54.38806 126  11.716  <.0001

 X1 - X4  754.7665 54.38806 126  13.877  <.0001

 X2 - X3  236.1406 54.38806 126   4.342  0.0002

 X2 - X4  353.6709 54.38806 126   6.503  <.0001

 X3 - X4  117.5303 54.38806 126   2.161  0.1399



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=2.97608139645e-15) change in space_travelled overall.

Significant (p=7.97314603229e-09) change in First vs. Second.
Significant (p=0.0449278597293) change in Second vs. Third.
No Significant (p=0.428293573544) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: space_travelled

  Effect          df      MSE         F ges p.value

1  trial 2.22, 93.26 48787.21 44.81 *** .38  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast  estimate       SE  df t.ratio p.value

 X1 - X2  268.37050 40.98163 126   6.549  <.0001

 X1 - X3  376.78148 40.98163 126   9.194  <.0001

 X1 - X4  439.09770 40.98163 126  10.715  <.0001

 X2 - X3  108.41097 40.98163 126   2.645  0.0449

 X2 - X4  170.72719 40.98163 126   4.166  0.0003

 X3 - X4   62.31622 40.98163 126   1.521  0.4283



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=3.00006790276e-20) change in context_boundary_crossings overall.

Significant (p=3.29975627933e-08) change in First vs. Second.
Significant (p=0.000372002650334) change in Second vs. Third.
No Significant (p=0.147846590447) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: context_boundary_crossings

  Effect           df    MSE         F ges p.value

1  trial 2.43, 102.23 227.59 60.87 *** .43  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast  estimate       SE  df t.ratio p.value

 X1 - X2  18.348837 2.930658 126   6.261  <.0001

 X1 - X3  30.465116 2.930658 126  10.395  <.0001

 X1 - X4  36.720930 2.930658 126  12.530  <.0001

 X2 - X3  12.116279 2.930658 126   4.134  0.0004

 X2 - X4  18.372093 2.930658 126   6.269  <.0001

 X3 - X4   6.255814 2.930658 126   2.135  0.1478



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=1.05535465676e-22) change in fd_time overall.

Significant (p=9.49764348723e-07) change in First vs. Second.
Significant (p=0.00199186464646) change in Second vs. Third.
Significant (p=0.00450450048434) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: fd_time

  Effect           df  MSE         F ges p.value

1  trial 2.85, 119.60 0.00 58.60 *** .24  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast   estimate          SE  df t.ratio p.value

 X1 - X2  0.01934879 0.003484737 126   5.552  <.0001

 X1 - X3  0.03214208 0.003484737 126   9.224  <.0001

 X1 - X4  0.04408976 0.003484737 126  12.652  <.0001

 X2 - X3  0.01279329 0.003484737 126   3.671  0.0020

 X2 - X4  0.02474097 0.003484737 126   7.100  <.0001

 X3 - X4  0.01194768 0.003484737 126   3.429  0.0045



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=6.14774369458e-25) change in fd_space overall.

Significant (p=4.39237690664e-09) change in First vs. Second.
Significant (p=0.000728344124328) change in Second vs. Third.
Significant (p=0.0377067024702) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: fd_space

  Effect           df  MSE         F ges p.value

1  trial 2.87, 120.37 0.00 67.08 *** .47  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast   estimate          SE  df t.ratio p.value

 X1 - X2  0.05939640 0.008908303 126   6.668  <.0001

 X1 - X3  0.09461872 0.008908303 126  10.621  <.0001

 X1 - X4  0.11878094 0.008908303 126  13.334  <.0001

 X2 - X3  0.03522232 0.008908303 126   3.954  0.0007

 X2 - X4  0.05938454 0.008908303 126   6.666  <.0001

 X3 - X4  0.02416222 0.008908303 126   2.712  0.0377



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=1.06093061523e-27) change in fd_spacetime overall.

Significant (p=4.18660571944e-06) change in First vs. Second.
Significant (p=1.63926172593e-05) change in Second vs. Third.
Significant (p=0.000171541141844) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: fd_spacetime

  Effect           df  MSE         F ges p.value

1  trial 2.90, 121.79 0.00 77.94 *** .42  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast   estimate          SE  df t.ratio p.value

 X1 - X2  0.03211099 0.006147585 126   5.223  <.0001

 X1 - X3  0.06229018 0.006147585 126  10.132  <.0001

 X1 - X4  0.08894184 0.006147585 126  14.468  <.0001

 X2 - X3  0.03017919 0.006147585 126   4.909  <.0001

 X2 - X4  0.05683085 0.006147585 126   9.244  <.0001

 X3 - X4  0.02665166 0.006147585 126   4.335  0.0002



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=6.00912074424e-13) change in lacunarity_time overall.

Significant (p=0.000431938871002) change in First vs. Second.
Significant (p=0.00531148253659) change in Second vs. Third.
No Significant (p=0.49449341518) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: lacunarity_time

  Effect           df  MSE         F ges p.value

1  trial 2.48, 104.07 0.00 31.31 *** .21  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast    estimate          SE  df t.ratio p.value

 X1 - X2  0.014553688 0.003554263 126   4.095  0.0004

 X1 - X3  0.026559395 0.003554263 126   7.473  <.0001

 X1 - X4  0.031576639 0.003554263 126   8.884  <.0001

 X2 - X3  0.012005708 0.003554263 126   3.378  0.0053

 X2 - X4  0.017022952 0.003554263 126   4.789  <.0001

 X3 - X4  0.005017244 0.003554263 126   1.412  0.4945



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=3.78302629274e-30) change in lacunarity_space overall.

Significant (p=2.215949646e-11) change in First vs. Second.
Significant (p=1.0365984873e-05) change in Second vs. Third.
Significant (p=0.0333096841737) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: lacunarity_space

  Effect           df  MSE         F ges p.value

1  trial 2.85, 119.62 0.06 92.13 *** .49  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast  estimate         SE  df t.ratio p.value

 X1 - X2  0.3953030 0.05141887 126   7.688  <.0001

 X1 - X3  0.6532194 0.05141887 126  12.704  <.0001

 X1 - X4  0.7950722 0.05141887 126  15.463  <.0001

 X2 - X3  0.2579164 0.05141887 126   5.016  <.0001

 X2 - X4  0.3997692 0.05141887 126   7.775  <.0001

 X3 - X4  0.1418528 0.05141887 126   2.759  0.0333



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=5.04441045759e-34) change in lacunarity_spacetime overall.

Significant (p=5.98687766029e-12) change in First vs. Second.
Significant (p=4.11527318112e-07) change in Second vs. Third.
Significant (p=0.000622543612228) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: lacunarity_spacetime

  Effect           df  MSE          F ges p.value

1  trial 2.79, 117.33 0.07 117.52 *** .60  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast  estimate         SE  df t.ratio p.value

 X1 - X2  0.4420103 0.05572179 126   7.932  <.0001

 X1 - X3  0.7614710 0.05572179 126  13.666  <.0001

 X1 - X4  0.9841673 0.05572179 126  17.662  <.0001

 X2 - X3  0.3194607 0.05572179 126   5.733  <.0001

 X2 - X4  0.5421570 0.05572179 126   9.730  <.0001

 X3 - X4  0.2226963 0.05572179 126   3.997  0.0006



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________

Click Order Analysis

This section contains the analysis for examining changes in click order during study. First we define our primary metrics of evaluation. ktcd will give us a tuple of the two distance metrics for a given permutation from the root permutation (i.e. [1,2,3,...,n]).

Function Definitions

This next section of code is fairly elaborate. It defines the two distance metrics, a function for generating a look-up-table for the probabilities of the given distance coordinates, and a visualization function which animates the trial-over-trial points.


In [43]:
from math import factorial
import scipy.stats as stats
import scipy.spatial as spatial
import numpy as np
import itertools as itools

from tqdm import tqdm
from IPython.display import HTML
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import rc, cm

# Decompose a list into contiguous sections (i.e. 2,3,4,1,5,6,8,7 becomes [[2,3,4],[1],[5,6],[8],[7]])
def continuous_decomposition(seq):
    decomposition = [[]]
    for i in seq:
        if len(decomposition[0]) == 0:
            decomposition[0].append(i)
        elif decomposition[-1][-1] == i - 1:
            decomposition[-1].append(i)
        else:
            decomposition.append([i])
    return decomposition

# Returns the normalized contiguous decomposition of a permutation 
# (i.e. (the number of contiguous sublists - 1)/(the length of the permutation - 1))
# If this function returns 0, the list was the elements [1,2,...,len(p)]. If 1, the list had no contiguous sublists.
def contiguous_distance(p):
    return (float(len(continuous_decomposition(p))) - 1) / (len(p) - 1)

# Wraps scipy.stats.kendalltau, setting the target list to [1,2,...,len(p)] and returning just the correlation coefficient
def kendall_tau(p):
    r, _ = stats.kendalltau([x+1 for x in range(0, len(p))], p)
    return r

# Helper function which returns the kendall_tau and contiguous_distance values for a permutation
def kendall_tau_contiguity_distance(p):
    return kendall_tau(p), contiguous_distance(p)

# Helper function which shortens the name of kendall_tau_contiguity_distance to ktcd
def ktcd(p):
    return kendall_tau_contiguity_distance(p)

# This function returns a probability lookup table given a particular size of permutation for the ktcd methods.
# Note that it can take a VERY long time to execute on set sizes larger than 10.
def get_ktcd_probability_lut(perm_size, verbose=True):
    if perm_size > 10:
        print("Warning: Permutation sizes greater than 10 can take a very long time to execute. Set verbose=False to disable this message.")
    target = [i+1 for i in range(0, perm_size)]
    rs0 = []
    rs1 = []
    perm_length = np.prod(list(range(1, len(target) + 1)))
    
    for idx, perm in enumerate(tqdm(itools.permutations(target), total=factorial(len(target)), desc="Computing Permutations for LUT")):
        r, cr = kendall_tau_contiguity_distance(perm)
        rs0.append(r)
        rs1.append(cr)
    cs = []
    rs_zipped = zip(rs0, rs1)
    unique = []
    unique_count = []
    for r0, r1 in zip(rs0, rs1):
        if not (r0, r1) in unique:
            unique.append((r0, r1))
            unique_count.append(rs_zipped.count((r0, r1)))
    rs0_unique, rs1_unique = np.transpose(unique)

    probability_dictionary = {}
    for u, uc in zip(unique, unique_count):
        probability_dictionary[u] = float(uc)/float(perm_length)

    return probability_dictionary

# Function for visualizing a combination of Kentall Tau and Cycle Rearrangement Distance
def visualize_trial_over_trial_3d(root_lut, multi_data, n_interpolated_points=50, interval=33, weights=None, fontsize='x-large', animate=True):
    lutA = root_lut

    if animate:
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.set_xlabel('Kendall Tau Distance')
        ax.set_ylabel('Contiguity Distance')
        ax.set_zlabel('Probability')
    else:
        fig = plt.figure()
        ax1 = fig.add_subplot(221, projection='3d')
        ax2 = fig.add_subplot(222, projection='3d')
        ax3 = fig.add_subplot(223, projection='3d')
        ax4 = fig.add_subplot(224, projection='3d')
        axs = [ax1, ax2, ax3, ax4]
        ax = axs[0]
        for ax in axs:
            ax.set_xlabel('Kendall Tau Distance', fontsize=15, labelpad=10)
            ax.set_ylabel('Contiguity Distance', fontsize=15, labelpad=10)
            ax.set_zlabel('Probability', fontsize=15, labelpad=10)
    
    keys = lut.keys()
    k0, k1 = np.transpose(keys)
    if animate:
        ax.scatter(k0, k1, lut.values(), c=lut.values(), s=16)
    else:
        for ax in axs:
            ax.scatter(k0, k1, lut.values(), c=lut.values(), s=16)
    
    # This function is used for animation
    def update_plot(i, data, scat, txt):
        txt.set_text('Trial:' + str(float(i)/float(n_interpolated_points) + 1), fontsize=20)
        pts = []
        for d in data:
            pts.append(list(d[i]))
        scat._offsets3d = np.transpose(pts)
        return scat,

    rgb = cm.get_cmap('viridis')(np.linspace(0.0, 1.0, 4))[np.newaxis, :, :3][0]
    
    points_data = []
    start_points = []
    
    distances = [[], [], [], []]
    for data in tqdm(multi_data, desc="Processing Simulated Data"):
        dists = [kendall_tau_contiguity_distance(p) for p in data]
            
        probs = [lut[d] for d in dists if d in lut.keys()]
        
        d0, d1 = np.transpose(dists)
        for i, (d0t, d1t) in enumerate(zip(d0, d1)):
            distances[i].append((d0t, d1t))
        
        lerp_points_x = []
        lerp_points_y = []
        lerp_points_z = []
        for idx in range(0, len(d0) - 1):
            lerp_points_x += list(np.linspace(d0[idx], d0[idx + 1], n_interpolated_points, endpoint=True))
            lerp_points_y += list(np.linspace(d1[idx], d1[idx + 1], n_interpolated_points, endpoint=True))
            lerp_points_z += list(np.linspace(probs[idx], probs[idx + 1], n_interpolated_points, endpoint=True))

        point_data = zip(lerp_points_x, lerp_points_y, lerp_points_z)
        points_data.append(point_data)
        
        if animate:
            ax.scatter(d0, d1, probs, c=rgb, marker='s', s=50)
        else:
            for ax, x, y, z in zip(axs, d0, d1, probs):
                ax.scatter([x], [y], [z], c=(1.0, 0.0, 0.0, 0.1), marker='s', s=50, edgecolors='k', linewidths=0.5)
        start_points.append([d0[0], d1[0], probs[0]])
    
    x, y, z = np.transpose(start_points)
    if animate:
        scatter_plot = ax.scatter(x, y, z, c=['r'], marker='s', s=50)

    x_means = [np.mean(np.transpose(dist)[0]) for dist in distances]
    y_means = [np.mean(np.transpose(dist)[1]) for dist in distances]
    z_means = [np.mean(pps) for pps in [[lut[d] for d in dists if d in lut.keys()] for dists in distances]]
    if animate:
        mean_scatter_plot = ax.scatter(x_means, y_means, z_means, c='b', marker='o', s=150)
    
        txt = ax.text2D(0.05, 0.95, "Trial 4", transform=ax.transAxes, size=fontsize)
        ani = animation.FuncAnimation(fig, update_plot, frames=len(lerp_points_x), interval=interval,
                                  fargs=(points_data, scatter_plot, txt))

        rc('animation', html='html5')
        ani.to_html5_video()
        
        plt.show()
        
        return ani
    else:
        for idx, (ax, x, y, z) in enumerate(zip(axs, x_means, y_means, z_means)):
            txt = ax.text2D(0.05, 0.95, "Trial {0}".format(idx+1), transform=ax.transAxes, size=fontsize)
            ax.scatter([x], [y], [z], c='b', marker='o', s=150)
            ax.plot([x, x], [0, 1], [0, 0], c='b', linestyle='--')
            ax.plot([-1, 1], [y, y], [0, 0], c='b', linestyle='--')
        plt.tight_layout()
        plt.show()

Process the Click Order

This section reads the intermediate file and turns the click indicies into a permutation which can be analyzed by the algorithms defined above.


In [24]:
import pandas
import ast

# Load the data
data_nav = pandas.read_csv('time_travel_task_navigation_summary.csv')

inverse = data_nav['inverse']

# Process the lists of indicies
raw_indicies = [ast.literal_eval(row) for row in data_nav['click_order'].values]
sorted_indicies = []
indicies = []

# Simplify the indicies to their ordinal position (i.e. [0, 2, 3, 1, 5, ...])
for row, inv in zip(raw_indicies, inverse):
    if inv:
        sorted_list, index_list = zip(*sorted(zip(row, list(reversed(range(0, len(row)))))))
    else:
        sorted_list, index_list = zip(*sorted(zip(row, list(range(0, len(row))))))
    sorted_indicies.append(sorted_list)
    indicies.append(index_list)

# Remove items 8 and 9 as they had no temporal information
temporal_only_indicies = []
for row in indicies:
    index_list = list(row)
    index_list.remove(8)
    index_list.remove(9)
    temporal_only_indicies.append(index_list)

trials = data_nav['trial']
distances = [ktcd(perm) for perm in temporal_only_indicies]

Finalize Data Transform

Finally, we transform the data into a NxTxP list where N is the number of participants, T is the number of trials, and P is the length of the permutation.


In [25]:
vis_data = [np.array(temporal_only_indicies)[list(trials.values == i)] for i in [1, 2, 3, 4]]
vis_data = np.transpose(vis_data, axes=(1,0,2))
lut = get_ktcd_probability_lut(8)


Computing Permutations for LUT: 100%|██████████████████████████████████████████| 40320/40320 [00:20<00:00, 1976.57it/s]

Save the Data


In [26]:
if 'generate_intermediate_files' in vars() and generate_intermediate_files:
    with open('click_order_data.csv', 'w') as fp:
        fp.write('subID,trial,kendall_tau_distance,contiguity_distance\n')
        for sid, tr, kt, c in zip(data_nav['subID'], data_nav['trial'], *np.transpose(distances)):
            fp.write('{0},{1},{2},{3}\n'.format(sid, tr, kt, c))

Visualize

Finally, call the visualization function. This function interpolates over the trials where the height is the probability given a random permutation, the lighter dots are the earlier trials, and the darker dots are the later trials, and the red dots are an animated interpolation across the trials. Deviating away from the peak probability region indicates a preference towards some permutation with low probability.


In [27]:
# Note: you'll need to change the ffmpeg path to use this on your machine
def embed_animation_as_gif(_animation, ffmpeg_path=r'C:\mingw2\bin\ffmpeg.exe'):
    if not os.path.exists(ffmpeg_path):
        return _animation
    _animation.save('animation.mp4')
    os.system("ffmpeg -i animation.mp4 animation.gif -y")
    data='0'
    IMG_TAG = '<img src="data:image/gif;base64,{0}">'
    with open('animation.gif', 'rb') as f:
        data = f.read()
        data = data.encode('base64')
    return HTML(IMG_TAG.format(data))

In [28]:
data_dist = pandas.DataFrame()
data_dist['subID'] = data_nav['subID']
data_dist['trial'] = trials
data_dist['kendall_tau_distance'] = pandas.Series(list(np.transpose(distances)[0]))
data_dist['contiguity_distance'] = pandas.Series(list(np.transpose(distances)[1]))

columns = ['kendall_tau_distance', 'contiguity_distance']
titles = ['Kendal Tau', 'Contiguity']
ylabels = ['Distance', 'Distance']

visualize_columns(data_dist, columns, titles, ylabels, separate_plots=True, verbose_anova=True)


__________________________________________________
Significant (p=2.27943915327e-07) change in kendall_tau_distance overall.

No Significant (p=0.376042329797) change in First vs. Second.
No Significant (p=0.233374277182) change in Second vs. Third.
No Significant (p=0.0608905320786) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: kendall_tau_distance

  Effect           df  MSE         F ges p.value

1  trial 2.83, 118.84 0.11 13.49 *** .13  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast   estimate         SE  df t.ratio p.value

 X1 - X2  -0.1112957 0.06907564 126  -1.611  0.3760

 X1 - X3  -0.2425249 0.06907564 126  -3.511  0.0034

 X1 - X4  -0.4169435 0.06907564 126  -6.036  <.0001

 X2 - X3  -0.1312292 0.06907564 126  -1.900  0.2334

 X2 - X4  -0.3056478 0.06907564 126  -4.425  0.0001

 X3 - X4  -0.1744186 0.06907564 126  -2.525  0.0609



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________
__________________________________________________
Significant (p=6.32752681676e-05) change in contiguity_distance overall.

No Significant (p=0.742751572154) change in First vs. Second.
No Significant (p=0.208536579934) change in Second vs. Third.
No Significant (p=0.184722949492) change in Third vs. Fourth.
Anova Table (Type 3 tests)



Response: contiguity_distance

  Effect          df  MSE        F ges p.value

1  trial 2.29, 96.29 0.08 9.77 *** .10  <.0001

---

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1



Sphericity correction method: GG 

 contrast   estimate        SE  df t.ratio p.value

 X1 - X2  0.05315615 0.0525287 126   1.012  0.7428

 X1 - X3  0.15614618 0.0525287 126   2.973  0.0183

 X1 - X4  0.26245847 0.0525287 126   4.996  <.0001

 X2 - X3  0.10299003 0.0525287 126   1.961  0.2085

 X2 - X4  0.20930233 0.0525287 126   3.985  0.0007

 X3 - X4  0.10631229 0.0525287 126   2.024  0.1847



P value adjustment: tukey method for comparing a family of 4 estimates 

__________________________________________________

In [44]:
import matplotlib
%matplotlib inline

matplotlib.rcParams['figure.figsize'] = (20,10)
anim = visualize_trial_over_trial_3d(lut, vis_data, animate=False)


Processing Simulated Data: 100%|███████████████████████████████████████████████████████| 43/43 [00:00<00:00, 54.57it/s]

In [46]:
dists = [[kendall_tau_contiguity_distance(p) for p in data] for data in vis_data]

In [49]:
matplotlib.rcParams['figure.figsize'] = (20, 5)
prob = lut[(0.99999999999999978, 0.0)]
plt.bar([1, 2, 3, 4], [len([x for x in dat if np.isclose(x[0], 1.0) and np.isclose(x[1], 0.0)])/43. for dat in np.transpose(dists, axes=(1,0,2))], label='Proportion per trial')
plt.xlabel('Trial', fontsize=15)
plt.ylabel('Proportion of Participants', fontsize=15)
plt.title('Proportion of Participants on the (1, 0) Point', fontsize=15)
plt.xticks([1, 2, 3, 4])
plt.plot([0.5, 4.5], [prob, prob], '--', c='r', label='Change Level')
plt.legend(fontsize=15)
plt.show()



In [52]:
prob = lut[(0.99999999999999978, 0.0)]
print('{:0.6f}'.format(prob))


0.000025

In [53]:
%%capture
import matplotlib

matplotlib.rcParams['figure.figsize'] = (20,10)
anim = visualize_trial_over_trial_3d(lut, vis_data)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-53-494a1d8ce201> in <module>()
      2 
      3 matplotlib.rcParams['figure.figsize'] = (20,10)
----> 4 anim = visualize_trial_over_trial_3d(lut, vis_data)

<ipython-input-43-232f4c01bdbb> in visualize_trial_over_trial_3d(root_lut, multi_data, n_interpolated_points, interval, weights, fontsize, animate)
    161 
    162         rc('animation', html='html5')
--> 163         ani.to_html5_video()
    164 
    165         plt.show()

C:\Program Files\Anaconda3\envs\iposition\lib\site-packages\matplotlib\animation.pyc in to_html5_video(self, embed_limit)
   1411                                 bitrate=rcParams['animation.bitrate'],
   1412                                 fps=1000. / self._interval)
-> 1413                 self.save(f.name, writer=writer)
   1414 
   1415             # Now open and base64 encode

C:\Program Files\Anaconda3\envs\iposition\lib\site-packages\matplotlib\animation.pyc in save(self, filename, writer, fps, dpi, codec, bitrate, extra_args, metadata, extra_anim, savefig_kwargs)
   1252                 for anim in all_anim:
   1253                     # Clear the initial frame
-> 1254                     anim._init_draw()
   1255                 for data in zip(*[a.new_saved_frame_seq()
   1256                                   for a in all_anim]):

C:\Program Files\Anaconda3\envs\iposition\lib\site-packages\matplotlib\animation.pyc in _init_draw(self)
   1790         # artists.
   1791         if self._init_func is None:
-> 1792             self._draw_frame(next(self.new_frame_seq()))
   1793 
   1794         else:

C:\Program Files\Anaconda3\envs\iposition\lib\site-packages\matplotlib\animation.pyc in _draw_frame(self, framedata)
   1812         # Call the func with framedata and args. If blitting is desired,
   1813         # func needs to return a sequence of any artists that were modified.
-> 1814         self._drawn_artists = self._func(framedata, *self._args)
   1815         if self._blit:
   1816             if self._drawn_artists is None:

<ipython-input-43-232f4c01bdbb> in update_plot(i, data, scat, txt)
    106     # This function is used for animation
    107     def update_plot(i, data, scat, txt):
--> 108         txt.set_text('Trial:' + str(float(i)/float(n_interpolated_points) + 1), fontsize=20)
    109         pts = []
    110         for d in data:

TypeError: set_text() got an unexpected keyword argument 'fontsize'

In [32]:
import IPython.display as display
display_obj = anim
if 'generate_embedded_animations' in vars() and generate_embedded_animations and 'embed_animation_as_gif' in vars():
    display_obj = embed_animation_as_gif(display_obj)
display.display_html(display_obj)


Note: If the above video does not display, it can be viewed here: [https://youtu.be/GytLbbDbLO0](https://youtu.be/GytLbbDbLO0)

Hierarchical Linear Modeling of Navigation vs. Test Variables

This section shows the statistical analysis of the various Study and Test variables and their associated predictive power.


In [54]:
import pandas

# Load all data
data_summary = pandas.read_csv('time_travel_task_test_summary.csv')
data_time = pandas.read_csv('TimeTravelTask_TimeOnly.csv', skiprows=1)
data_space = pandas.read_csv('TimeTravelTask_SpaceOnly.csv', skiprows=1)
data_nav = pandas.read_csv('time_travel_task_navigation_summary.csv')
data_missassignment_by_context = pandas.read_csv('misassignments_by_context.csv')
data_order = pandas.read_csv('click_order_data.csv')

# Fix inconsistent indexing in some files
data_summary['trial'] = [x-1 for x in data_summary['trial'].values]
data_nav['trial'] = [x-1 for x in data_nav['trial'].values]
data_order['trial'] = [x-1 for x in data_order['trial'].values]

# Confirm subID and trial match across all data
assert all([a==b==c==d==e==f for a,b,c,d,e,f in zip(data_order['subID'].values, data_missassignment_by_context['subID'].values, data_nav['subID'].values, data_time['subID'].values, data_space['subID'].values, data_summary['subID'].values)]), 'subIDs do not match in intermediate files'
assert all([a==b==c==d==e==f for a,b,c,d,e,f in zip(data_order['trial'].values, data_missassignment_by_context['trial'].values, data_nav['trial'].values, data_time['trial'].values, data_space['trial'].values, data_summary['trial'].values)]), 'trials do not match in intermediate files'

data = pandas.DataFrame()

# Random Factors
data['subID'] = data_summary['subID']
data['trial'] = data_summary['trial']

# Study Time Factors (independent variables)

# AS) Simple Path Factors
data['space_travelled'] = data_nav['space_travelled']
data['time_travelled'] = data_nav['time_travelled']

# BS) Complex Path Factors
data['fd_time'] = data_nav['fd_time']
data['fd_space'] = data_nav['fd_space']
data['fd_spacetime'] = data_nav['fd_spacetime']
data['lacunarity_time'] = data_nav['lacunarity_time']
data['lacunarity_space'] = data_nav['lacunarity_space']
data['lacunarity_spacetime'] = data_nav['lacunarity_spacetime']

# CS) Context Path Factors
data['context_boundary_crossings'] = data_nav['context_boundary_crossings']

# DS) Order Factors
data['kendall_tau_distance'] = data_order['kendall_tau_distance']
data['contiguity_distance'] = data_order['contiguity_distance']

# Test Time Factors (dependent variables)

# AT) Simple Factors
data['space_misplacement'] = data_summary['space_misplacement']
data['time_misplacement'] = data_summary['time_misplacement']
data['event_type_correct_count'] = data_summary['event_type_correct_count']

# BT) Context Factors
data['across_context_boundary_effect'] = data_summary['context_crossing_dist_exclude_wrong_color_pairs']
data['within_context_boundary_effect'] = data_summary['context_noncrossing_dist_exclude_wrong_color_pairs']
data['context_boundary_effect'] = data_summary['context_crossing_dist_exclude_wrong_color_pairs'] - data_summary['context_noncrossing_dist_exclude_wrong_color_pairs']

# CT) Relational Memory Factors
data['accurate_misassignment_space'] = data_space['Accurate Misassignment']
data['accurate_misassignment_time'] = data_time['Accurate Misassignment']

# DT) Relational Memory and Context Factors
data['within_misassignments'] = data_missassignment_by_context['within_misassignments']
data['across_misassignments'] = data_missassignment_by_context['across_misassignments']

if 'generate_intermediate_files' in vars() and generate_intermediate_files:
    data.to_csv('full_dataset.csv')

Relationships of Interest

  • Do Simple or Complex Path Factors (AS, BS) predict Simple Factors (AT), Relational Memory Factors (CT), or Relational Memory and Context Factors (DT),
  • Does the Context Path Factor (CS) predict Context Factors (BT) or Relational Memory and Context Factors (DT),
  • Do Order Factors (DS) predict Any Test Factors (AT, BT, CT, DT)?

Import R Modules for HLM

Because Python just isn't the right environment for this sort of stats, we'll use nlme in R using rpy2 as an interface.


In [55]:
from rpy2.robjects import pandas2ri
import rpy2.robjects as robjects
import numpy as np

pandas2ri.activate()

Just in case nlme is not properly installed, we can try to install it. If prompts appear, you'll need to accept the install in order to use the next code sections.


In [56]:
import rpy2.robjects.packages as rpackages
from rpy2.robjects.vectors import StrVector
from rpy2.robjects import r

utils = rpackages.importr('utils')
utils.chooseCRANmirror(ind=1)

# R package names
packnames = ['nlme', 'stats', 'reghelper', 'MuMIn', 'afex']

names_to_install = [x for x in packnames if not rpackages.isinstalled(x)]
if len(names_to_install) > 0:
    utils.install_packages(StrVector(names_to_install))

Now we can convert the data and import the nlme package.


In [57]:
r_dataframe = pandas2ri.py2ri(data)

nlme = rpackages.importr('nlme')
rstats = rpackages.importr('stats')
reghelper = rpackages.importr('reghelper')
mumin = rpackages.importr('MuMIn')
afex = rpackages.importr('afex')

Next we can run the model and print out the t-Table.


In [58]:
# correlation=nlme.corSymm(form=r.formula('~1 | subID/trial'))
random_effects_model = '~ trial | subID'
navigation = 'time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime'
order = 'kendall_tau_distance + contiguity_distance'
model_formulas = [
    # Misplacement vs. Navigation Models
    'time_misplacement ~ ' + navigation,
    'space_misplacement ~ ' + navigation,
    
    # Misassignment vs. Navigation Models
    'accurate_misassignment_space ~ ' + navigation,
    'accurate_misassignment_time ~ ' + navigation,

    # Context Boundary Crossing Models
    'within_misassignments ~ context_boundary_crossings', 
    'across_misassignments ~ context_boundary_crossings', 
    'context_boundary_effect ~ context_boundary_crossings', # Note: na.omit is needed due to CBE having nan values

    # Order Models (Note all output variables are used because no prior hypotheses were made about order's influence)
    'time_misplacement ~ ' + order,
    'space_misplacement ~ ' + order,
    'accurate_misassignment_space ~ ' + order,
    'accurate_misassignment_time ~ ' + order,
    'within_misassignments ~ ' + order,
    'across_misassignments ~ ' + order,
    'context_boundary_effect ~ ' + order # Note: na.omit is needed due to CBE having nan values
    
]

transform_functions = [np.sqrt, lambda x: np.log(np.log(np.log(x))), 
                       lambda x: x, lambda x: x, ## these are never normal
                       lambda x: x, np.cbrt, lambda x: x]
                       # np.sqrt, np.cbrt, np.log, lambda x: 1/x, lambda x: x
data_transformed = data.copy(True)
for c, tf in zip(['time_misplacement', 'space_misplacement', 
              'accurate_misassignment_space', 'accurate_misassignment_time', 
              'within_misassignments', 'across_misassignments', 'context_boundary_effect'], transform_functions):
    data_transformed[c] = data_transformed[c].apply(tf)
r_transformed_dataframe = pandas2ri.py2ri(data_transformed)

models = [nlme.lme(r.formula(model_formula),
                   random=r.formula(random_effects_model), 
                   data=r_transformed_dataframe, 
                   control=nlme.lmeControl(maxIter=100, msMaxIter=100, opt='optim'), # Note: 'optim' is needed to avoid failure to converge
                   **{'na.action': 'na.omit'} # Other options can be found here: https://stat.ethz.ch/R-manual/R-devel/library/stats/html/na.fail.html
                  )
          for model_formula in model_formulas]

# Uncomment this to view all the possible keys
# print(r.summary(models[0]).names)

# We can pick certain keys to ignore during printing
ignore_keys = ['modelStruct', 'dims', 'contrasts', 'coefficients', 'varFix',
               'sigma', 'apVar', 'numIter', 'groups', 'logLik', 
               'call', 'terms', 'fitted', 'method', 'residuals', 
               'fixDF', 'na.action', 'data' , 'corFixed', # 'tTable'
               'BIC', 'AIC'
              ]

for model, name in zip(models, model_formulas):
    for key in r.summary(model).names:
        if key not in ignore_keys:
            print("_"*len(name))
            print(name)
            print("_"*len(name))
            print(r.summary(model).rx2(key))
            print(reghelper.beta(model).rx2('tTable'))


____________________________________________________________________________________________________________________________________________________
time_misplacement ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
____________________________________________________________________________________________________________________________________________________
                             Value    Std.Error  DF    t-value    p-value

(Intercept)          -77.083139270 43.961801598 121 -1.7534117 0.08206366

time_travelled         0.003001533  0.001421575 121  2.1114142 0.03679427

space_travelled       -0.003766413  0.002087657 121 -1.8041341 0.07369792

fd_time               22.313183995 12.601744414 121  1.7706425 0.07913833

fd_space              -9.998432665  9.050927540 121 -1.1046860 0.27148753

fd_spacetime          -8.260295692 15.742316692 121 -0.5247192 0.60073844

lacunarity_time       13.815264102 12.166828743 121  1.1354860 0.25841588

lacunarity_space      -1.038711340  2.355975481 121 -0.4408838 0.66008387

lacunarity_spacetime   4.754214429  3.187189222 121  1.4916637 0.13838990

                             Value  Std.Error  DF    t-value    p-value

(Intercept)             0.05331425 0.09014305 121  0.5914406 0.55532861

time_travelled.z        0.35796130 0.16953627 121  2.1114142 0.03679427

space_travelled.z      -0.29889772 0.16567378 121 -1.8041341 0.07369792

fd_time.z               0.21649227 0.12226763 121  1.7706425 0.07913833

fd_space.z             -0.18852774 0.17066184 121 -1.1046860 0.27148753

fd_spacetime.z         -0.12288010 0.23418259 121 -0.5247192 0.60073844

lacunarity_time.z       0.10674075 0.09400446 121  1.1354860 0.25841588

lacunarity_space.z     -0.12938232 0.29346130 121 -0.4408838 0.66008387

lacunarity_spacetime.z  0.65911386 0.44186492 121  1.4916637 0.13838990

_____________________________________________________________________________________________________________________________________________________
space_misplacement ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
_____________________________________________________________________________________________________________________________________________________
                             Value    Std.Error  DF    t-value    p-value

(Intercept)          -3.797892e+00 2.387425e+00 121 -1.5907904 0.11426610

time_travelled        9.677525e-05 8.421687e-05 121  1.1491196 0.25277308

space_travelled      -2.734564e-04 1.239076e-04 121 -2.2069384 0.02920519

fd_time               1.132271e+00 6.592880e-01 121  1.7174154 0.08846161

fd_space             -4.692435e-01 4.964494e-01 121 -0.9451989 0.34644098

fd_spacetime          5.328410e-01 8.536459e-01 121  0.6241944 0.53367500

lacunarity_time       3.770941e-01 6.579332e-01 121  0.5731495 0.56760713

lacunarity_space      2.019310e-01 1.288837e-01 121  1.5667686 0.11978034

lacunarity_spacetime  3.178846e-02 1.772896e-01 121  0.1793024 0.85800016

                             Value  Std.Error  DF    t-value    p-value

(Intercept)             0.01115737 0.07703051 121  0.1448434 0.88507547

time_travelled.z        0.22347715 0.19445858 121  1.1492275 0.25272877

space_travelled.z      -0.41999972 0.19039980 121 -2.2058832 0.02928093

fd_time.z               0.21243733 0.12390715 121  1.7144880 0.08899935

fd_space.z             -0.17137423 0.18128974 121 -0.9453057 0.34638668

fd_spacetime.z          0.15407868 0.24591477 121  0.6265532 0.53213247

lacunarity_time.z       0.05657098 0.09842420 121  0.5747670 0.56651604

lacunarity_space.z      0.48702313 0.31087533 121  1.5666188 0.11981538

lacunarity_spacetime.z  0.08471298 0.47600636 121  0.1779661 0.85904722

_______________________________________________________________________________________________________________________________________________________________
accurate_misassignment_space ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
_______________________________________________________________________________________________________________________________________________________________
                             Value    Std.Error  DF      t-value    p-value

(Intercept)          -4.318383e+01 1.884319e+01 121 -2.291746684 0.02364908

time_travelled       -2.285388e-04 6.487672e-04 121 -0.352266241 0.72525141

space_travelled       2.878526e-06 9.557975e-04 121  0.003011649 0.99760202

fd_time               5.552664e+00 5.413745e+00 121  1.025660517 0.30709771

fd_space             -5.752223e+00 3.925624e+00 121 -1.465301665 0.14543230

fd_spacetime          7.504740e+00 6.705263e+00 121  1.119231284 0.26525837

lacunarity_time       8.337037e+00 5.251004e+00 121  1.587703243 0.11496322

lacunarity_space      1.290843e+00 1.010748e+00 121  1.277115989 0.20400655

lacunarity_spacetime -6.425495e-01 1.379286e+00 121 -0.465856742 0.64215553

                               Value Std.Error  DF      t-value   p-value

(Intercept)            -0.0492259985 0.1028466 121 -0.478635040 0.6330620

time_travelled.z       -0.0795553745 0.2258388 121 -0.352266241 0.7252514

space_travelled.z       0.0006667785 0.2213998 121  0.003011649 0.9976020

fd_time.z               0.1572529967 0.1533188 121  1.025660517 0.3070977

fd_space.z             -0.3165889560 0.2160572 121 -1.465301665 0.1454323

fd_spacetime.z          0.3258654233 0.2911511 121  1.119231284 0.2652584

lacunarity_time.z       0.1880180218 0.1184214 121  1.587703243 0.1149632

lacunarity_space.z      0.4693212013 0.3674852 121  1.277115989 0.2040065

lacunarity_spacetime.z -0.2600189198 0.5581521 121 -0.465856742 0.6421555

______________________________________________________________________________________________________________________________________________________________
accurate_misassignment_time ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
______________________________________________________________________________________________________________________________________________________________
                             Value    Std.Error  DF    t-value      p-value

(Intercept)          -3.606294e+01 37.783549524 121 -0.9544615 0.3417530192

time_travelled        2.346639e-04  0.001184308 121  0.1981443 0.8432646408

space_travelled      -1.387033e-03  0.001716044 121 -0.8082737 0.4205192870

fd_time               4.547853e+00 10.285598082 121  0.4421574 0.6591646189

fd_space             -1.736507e+01  7.471431667 121 -2.3241953 0.0217826438

fd_spacetime         -1.734717e+01 13.234161732 121 -1.3107872 0.1924120644

lacunarity_time       8.534735e+00 10.515471204 121  0.8116360 0.4185943145

lacunarity_space     -5.342630e+00  1.988021831 121 -2.6874102 0.0082146969

lacunarity_spacetime  9.758282e+00  2.640142960 121  3.6961187 0.0003302134

                             Value  Std.Error  DF    t-value      p-value

(Intercept)             0.01871199 0.09268054 121  0.2018978 0.8403357041

time_travelled.z        0.03950646 0.19938220 121  0.1981443 0.8432646405

space_travelled.z      -0.15538548 0.19224363 121 -0.8082737 0.4205192871

fd_time.z               0.06228969 0.14087673 121  0.4421574 0.6591646190

fd_space.z             -0.46221993 0.19887310 121 -2.3241953 0.0217826438

fd_spacetime.z         -0.36428681 0.27791454 121 -1.3107872 0.1924120641

lacunarity_time.z       0.09308720 0.11469083 121  0.8116360 0.4185943147

lacunarity_space.z     -0.93942919 0.34956673 121 -2.6874102 0.0082146969

lacunarity_spacetime.z  1.90978253 0.51669946 121  3.6961187 0.0003302134

__________________________________________________
within_misassignments ~ context_boundary_crossings
__________________________________________________
                                  Value   Std.Error  DF    t-value      p-value

(Intercept)                 1.383073506 0.253620125 128  5.4533271 2.453625e-07

context_boundary_crossings -0.003928159 0.005119371 128 -0.7673127 4.443087e-01

                                   Value  Std.Error  DF    t-value   p-value

(Intercept)                  -0.08543594 0.09857782 128 -0.8666852 0.3877362

context_boundary_crossings.z -0.05508413 0.07178837 128 -0.7673127 0.4443087

__________________________________________________
across_misassignments ~ context_boundary_crossings
__________________________________________________
                                 Value   Std.Error  DF  t-value      p-value

(Intercept)                0.599541432 0.107052448 128 5.600446 1.247492e-07

context_boundary_crossings 0.008852032 0.001953559 128 4.531233 1.328371e-05

                                 Value  Std.Error  DF   t-value      p-value

(Intercept)                  0.1024860 0.10760542 128 0.9524239 3.426771e-01

context_boundary_crossings.z 0.2795703 0.06169852 128 4.5312328 1.328371e-05

____________________________________________________
context_boundary_effect ~ context_boundary_crossings
____________________________________________________
                                 Value   Std.Error DF  t-value     p-value

(Intercept)                0.566874530 0.157008796 70 3.610464 0.000570393

context_boundary_crossings 0.009830039 0.004131585 70 2.379241 0.020078614

                                 Value  Std.Error DF   t-value    p-value

(Intercept)                  0.0657322 0.11196296 70 0.5870888 0.55903294

context_boundary_crossings.z 0.2360517 0.09921301 70 2.3792414 0.02007861

______________________________________________________________
time_misplacement ~ kendall_tau_distance + contiguity_distance
______________________________________________________________
                          Value Std.Error  DF    t-value      p-value

(Intercept)           8.4928062 0.8123019 127 10.4552332 7.726184e-19

kendall_tau_distance -0.5242025 0.6105153 127 -0.8586231 3.921661e-01

contiguity_distance   1.7901225 0.9023129 127  1.9839265 4.942049e-02

                             Value  Std.Error  DF    t-value    p-value

(Intercept)             0.20850474 0.09686842 127  2.1524532 0.03325272

kendall_tau_distance.z -0.06664453 0.07763666 127 -0.8584156 0.39228021

contiguity_distance.z   0.16785328 0.08461823 127  1.9836539 0.04945128

_______________________________________________________________
space_misplacement ~ kendall_tau_distance + contiguity_distance
_______________________________________________________________
                           Value  Std.Error  DF   t-value     p-value

(Intercept)          0.131733337 0.04276823 127 3.0801678 0.002536552

kendall_tau_distance 0.009178022 0.03235582 127 0.2836591 0.777133547

contiguity_distance  0.067673521 0.04812118 127 1.4063148 0.162072785

                            Value  Std.Error  DF   t-value    p-value

(Intercept)            0.22070773 0.09321666 127 2.3676854 0.01940932

kendall_tau_distance.z 0.02268301 0.07967157 127 0.2847065 0.77633275

contiguity_distance.z  0.12280653 0.08738627 127 1.4053298 0.16236473

_________________________________________________________________________
accurate_misassignment_space ~ kendall_tau_distance + contiguity_distance
_________________________________________________________________________
                          Value Std.Error  DF    t-value   p-value

(Intercept)           0.1976749 0.3137121 127  0.6301155 0.5297511

kendall_tau_distance -0.1138125 0.2534920 127 -0.4489788 0.6542122

contiguity_distance   0.3947977 0.3439495 127  1.1478364 0.2531937

                             Value  Std.Error  DF    t-value   p-value

(Intercept)            -0.15432464 0.10861713 127 -1.4208132 0.1578217

kendall_tau_distance.z -0.04224746 0.09409679 127 -0.4489788 0.6542122

contiguity_distance.z   0.10807492 0.09415534 127  1.1478364 0.2531937

________________________________________________________________________
accurate_misassignment_time ~ kendall_tau_distance + contiguity_distance
________________________________________________________________________
                          Value Std.Error  DF   t-value      p-value

(Intercept)           3.6307415 0.6390141 127  5.681787 8.654446e-08

kendall_tau_distance -0.8408582 0.5140736 127 -1.635677 1.043833e-01

contiguity_distance   1.8962016 0.7238354 127  2.619659 9.874102e-03

                             Value  Std.Error  DF    t-value     p-value

(Intercept)             0.07705158 0.08584287 127  0.8975885 0.371103393

kendall_tau_distance.z -0.15095430 0.09228860 127 -1.6356766 0.104383341

contiguity_distance.z   0.25104234 0.09583018 127  2.6196586 0.009874102

__________________________________________________________________
within_misassignments ~ kendall_tau_distance + contiguity_distance
__________________________________________________________________
                           Value Std.Error  DF    t-value    p-value

(Intercept)           1.10633657 0.4598015 127  2.4061177 0.01756361

kendall_tau_distance -0.09605293 0.3695074 127 -0.2599486 0.79532438

contiguity_distance   0.19106488 0.5232267 127  0.3651665 0.71559454

                             Value  Std.Error  DF    t-value   p-value

(Intercept)            -0.11444088 0.09477764 127 -1.2074672 0.2294962

kendall_tau_distance.z -0.02763378 0.10630480 127 -0.2599486 0.7953244

contiguity_distance.z   0.04053688 0.11100930 127  0.3651665 0.7155945

__________________________________________________________________
across_misassignments ~ kendall_tau_distance + contiguity_distance
__________________________________________________________________
                           Value Std.Error  DF    t-value     p-value

(Intercept)           0.61806927 0.1835640 127  3.3670514 0.001005785

kendall_tau_distance -0.03206439 0.1433065 127 -0.2237469 0.823313750

contiguity_distance   0.43559778 0.2039400 127  2.1359112 0.034605650

                             Value  Std.Error  DF    t-value    p-value

(Intercept)             0.12015680 0.10548318 127  1.1391086 0.25680191

kendall_tau_distance.z -0.02077607 0.09285520 127 -0.2237469 0.82331375

contiguity_distance.z   0.20814488 0.09745015 127  2.1359112 0.03460565

____________________________________________________________________
context_boundary_effect ~ kendall_tau_distance + contiguity_distance
____________________________________________________________________
                           Value Std.Error DF    t-value    p-value

(Intercept)          0.301762234 0.3078270 69 0.98029828 0.33036365

kendall_tau_distance 0.006240326 0.2662117 69 0.02344121 0.98136599

contiguity_distance  0.851329009 0.3445409 69 2.47090857 0.01595087

                             Value  Std.Error DF    t-value    p-value

(Intercept)            0.053904137 0.09930012 69 0.54284061 0.58898879

kendall_tau_distance.z 0.003074336 0.13115091 69 0.02344121 0.98136599

contiguity_distance.z  0.309300961 0.12517702 69 2.47090857 0.01595087

We can see the overall fit of the various models in this next section.


In [59]:
r_squared_values = np.array([np.array(mumin.r_squaredGLMM_lme(model)) for model in models]).transpose()
values = [model_formulas, r_squared_values[0], r_squared_values[1]]
columns = ["Model Formulas", "Marginal R^2 (Fixed Effects)", "Conditional R^2 (Fixed + Random Effects)"]
r_squared_data_frame = pandas.DataFrame({c: v for c, v in zip(columns, values)})
r_squared_data_frame


Out[59]:
Conditional R^2 (Fixed + Random Effects) Marginal R^2 (Fixed Effects) Model Formulas
0 0.748184 0.424196 time_misplacement ~ time_travelled + space_tra...
1 0.697343 0.398569 space_misplacement ~ time_travelled + space_tr...
2 0.545255 0.167708 accurate_misassignment_space ~ time_travelled ...
3 0.583562 0.286782 accurate_misassignment_time ~ time_travelled +...
4 0.335485 0.002982 within_misassignments ~ context_boundary_cross...
5 0.566862 0.080744 across_misassignments ~ context_boundary_cross...
6 0.298260 0.043242 context_boundary_effect ~ context_boundary_cro...
7 0.758482 0.052151 time_misplacement ~ kendall_tau_distance + con...
8 0.769449 0.011383 space_misplacement ~ kendall_tau_distance + co...
9 0.587469 0.019411 accurate_misassignment_space ~ kendall_tau_dis...
10 0.455743 0.157032 accurate_misassignment_time ~ kendall_tau_dist...
11 0.326597 0.003975 within_misassignments ~ kendall_tau_distance +...
12 0.578655 0.051835 across_misassignments ~ kendall_tau_distance +...
13 0.261712 0.121788 context_boundary_effect ~ kendall_tau_distance...

We can also plot the random coefficients for subID and trial. First we'll extract the data then plot.


In [60]:
import matplotlib.pyplot as plt
%matplotlib inline

num_rows = int(np.ceil(len(models)/3.))
fig, axes = plt.subplots(num_rows, 3)
fig.set_size_inches((15, num_rows*5))
axes = [item for sublist in axes for item in sublist]

for idx, (model, ax) in enumerate(zip(models, axes)):
    terms = r.summary(model).rx2('terms').r_repr()
    c = str(terms.split('~')[0].strip())

    title = 'model #{0} ({1})'.format(idx, terms, c)
    ax.set_title(title[:30] + '...')
    ax.set_ylabel(c)
    ax.set_xlabel('trial')
    
    #yd = np.transpose([np.array(pandas.Series(data[c][data['trial'] == n]).fillna(method='backfill')) for n in [0, 1, 2, 3]])
    yd = np.transpose([data_transformed[c][data_transformed['trial'] == n] for n in [0, 1, 2, 3]])
    # Get the subject coefficients
    subject_lines = pandas2ri.ri2py(r.summary(model).rx2('coefficients').rx2('random').rx2('subID'))
    x = np.array([0, 1, 2, 3])
    ys = [x*slope + intercept for intercept, slope in subject_lines]
    
    # Get the mean line from the t table
    # Note: This section is commented out because I didn't properly look for the variable of interest, 
    # so the index may change depending on the model
    #
    # mean_line = pandas2ri.ri2py(r.summary(model).rx2('tTable'))
    # mean = x*mean_line[1][0] + mean_line[1][1]
    # plt.plot(list(x), list(mean), c='r', marker='>')
    
    # Plot all the lines
    for y, label, y2 in zip(ys, list(np.linspace(0.0, 1.0, len(ys))), yd):
        ax.plot(list(x), list(y), c='b', marker='>', alpha=0.25)
        ax.plot(list(x), y2 - np.nanmean(yd, axis=0), c='g', alpha=0.1)

    

# Clean up empty extra subplots
for idx in range(1, 3-len(models)%3 + 1):
    axes[-idx].axis('off')
    
plt.show()


We can visualize the correlations as well.


In [61]:
import matplotlib.pyplot as plt

num_rows = int(np.ceil(len(models)/3.))
fig, axes = plt.subplots(num_rows, 3)
fig.set_size_inches((15, num_rows*5))
axes = [item for sublist in axes for item in sublist]

print_buffer = ''

for model, name, ax in zip(models, model_formulas, axes):
    print_buffer += str("_"*len(name)) +'\r\n'
    print_buffer += str(name)+'\r\n'
    print_buffer += str("_"*len(name))+'\r\n'
    print_buffer += str(r.summary(model).rx2('corFixed'))+'\r\n'
    correlations = pandas2ri.ri2py(r.summary(model).rx2('corFixed'))
    ax.imshow(correlations)

# Clean up empty extra subplots
for idx in range(1, 3-len(models)%3 + 1):
    axes[-idx].axis('off')

plt.show()

print(print_buffer)


____________________________________________________________________________________________________________________________________________________
time_misplacement ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
____________________________________________________________________________________________________________________________________________________
                     (Intercept) time_travelled space_travelled      fd_time

(Intercept)           1.00000000     0.14047694     -0.01351956  0.469312654

time_travelled        0.14047694     1.00000000     -0.59897855  0.033353085

space_travelled      -0.01351956    -0.59897855      1.00000000  0.012070753

fd_time               0.46931265     0.03335309      0.01207075  1.000000000

fd_space             -0.03129961     0.24382309     -0.57470378 -0.030681106

fd_spacetime         -0.17983948    -0.36978198      0.35844300  0.025255563

lacunarity_time      -0.97048561    -0.04245662      0.02804367 -0.605118170

lacunarity_space     -0.18866538     0.09143340     -0.14245603  0.003773354

lacunarity_spacetime  0.19160479    -0.14029865      0.01445053 -0.121591357

                        fd_space fd_spacetime lacunarity_time lacunarity_space

(Intercept)          -0.03129961  -0.17983948     -0.97048561     -0.188665379

time_travelled        0.24382309  -0.36978198     -0.04245662      0.091433396

space_travelled      -0.57470378   0.35844300      0.02804367     -0.142456035

fd_time              -0.03068111   0.02525556     -0.60511817      0.003773354

fd_space              1.00000000  -0.30233683      0.01471047     -0.060695844

fd_spacetime         -0.30233683   1.00000000      0.04561965      0.703815322

lacunarity_time       0.01471047   0.04561965      1.00000000      0.080886782

lacunarity_space     -0.06069584   0.70381532      0.08088678      1.000000000

lacunarity_spacetime -0.08613757  -0.75679222     -0.08543884     -0.894647391

                     lacunarity_spacetime

(Intercept)                    0.19160479

time_travelled                -0.14029865

space_travelled                0.01445053

fd_time                       -0.12159136

fd_space                      -0.08613757

fd_spacetime                  -0.75679222

lacunarity_time               -0.08543884

lacunarity_space              -0.89464739

lacunarity_spacetime           1.00000000

_____________________________________________________________________________________________________________________________________________________
space_misplacement ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
_____________________________________________________________________________________________________________________________________________________
                     (Intercept) time_travelled space_travelled     fd_time

(Intercept)           1.00000000     0.16130048    -0.018331672  0.48479933

time_travelled        0.16130048     1.00000000    -0.612665245  0.02620977

space_travelled      -0.01833167    -0.61266524     1.000000000  0.02155112

fd_time               0.48479933     0.02620977     0.021551121  1.00000000

fd_space             -0.02493296     0.27749195    -0.578769059 -0.03981675

fd_spacetime         -0.18198280    -0.36840795     0.380439956  0.05536835

lacunarity_time      -0.97003734    -0.05788367     0.031628970 -0.61676029

lacunarity_space     -0.18694481     0.11625928    -0.132082307  0.01734407

lacunarity_spacetime  0.17471101    -0.17282196    -0.006093707 -0.13465985

                        fd_space fd_spacetime lacunarity_time lacunarity_space

(Intercept)          -0.02493296  -0.18198280     -0.97003734      -0.18694481

time_travelled        0.27749195  -0.36840795     -0.05788367       0.11625928

space_travelled      -0.57876906   0.38043996      0.03162897      -0.13208231

fd_time              -0.03981675   0.05536835     -0.61676029       0.01734407

fd_space              1.00000000  -0.31669855      0.01250103      -0.08482333

fd_spacetime         -0.31669855   1.00000000      0.04717886       0.71027541

lacunarity_time       0.01250103   0.04717886      1.00000000       0.08290690

lacunarity_space     -0.08482333   0.71027541      0.08290690       1.00000000

lacunarity_spacetime -0.06727209  -0.75369914     -0.08158972      -0.88839918

                     lacunarity_spacetime

(Intercept)                   0.174711013

time_travelled               -0.172821961

space_travelled              -0.006093707

fd_time                      -0.134659852

fd_space                     -0.067272087

fd_spacetime                 -0.753699143

lacunarity_time              -0.081589721

lacunarity_space             -0.888399175

lacunarity_spacetime          1.000000000

_______________________________________________________________________________________________________________________________________________________________
accurate_misassignment_space ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
_______________________________________________________________________________________________________________________________________________________________
                     (Intercept) time_travelled space_travelled     fd_time

(Intercept)           1.00000000     0.14220483    -0.011743056  0.47075321

time_travelled        0.14220483     1.00000000    -0.586798187  0.01207292

space_travelled      -0.01174306    -0.58679819     1.000000000  0.04928369

fd_time               0.47075321     0.01207292     0.049283691  1.00000000

fd_space             -0.02985897     0.20850904    -0.556576277 -0.04073182

fd_spacetime         -0.12221286    -0.31518867     0.327577154  0.09425301

lacunarity_time      -0.96986337    -0.04175812     0.025605973 -0.60788997

lacunarity_space     -0.16080731     0.09809549    -0.126586644  0.06271783

lacunarity_spacetime  0.14424983    -0.16317345     0.000363102 -0.18895324

                         fd_space fd_spacetime lacunarity_time lacunarity_space

(Intercept)          -0.029858974  -0.12221286    -0.969863371      -0.16080731

time_travelled        0.208509038  -0.31518867    -0.041758125       0.09809549

space_travelled      -0.556576277   0.32757715     0.025605973      -0.12658664

fd_time              -0.040731815   0.09425301    -0.607889971       0.06271783

fd_space              1.000000000  -0.29535404     0.008498887      -0.12532073

fd_spacetime         -0.295354040   1.00000000    -0.016494262       0.74592831

lacunarity_time       0.008498887  -0.01649426     1.000000000       0.04346706

lacunarity_space     -0.125320733   0.74592831     0.043467062       1.00000000

lacunarity_spacetime -0.035556978  -0.78756599    -0.031642203      -0.89082482

                     lacunarity_spacetime

(Intercept)                   0.144249835

time_travelled               -0.163173449

space_travelled               0.000363102

fd_time                      -0.188953244

fd_space                     -0.035556978

fd_spacetime                 -0.787565992

lacunarity_time              -0.031642203

lacunarity_space             -0.890824818

lacunarity_spacetime          1.000000000

______________________________________________________________________________________________________________________________________________________________
accurate_misassignment_time ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
______________________________________________________________________________________________________________________________________________________________
                      (Intercept) time_travelled space_travelled       fd_time

(Intercept)           1.000000000     0.13528904    -0.004811261  5.282524e-01

time_travelled        0.135289041     1.00000000    -0.598948218  3.378199e-02

space_travelled      -0.004811261    -0.59894822     1.000000000  1.115723e-02

fd_time               0.528252445     0.03378199     0.011157227  1.000000e+00

fd_space             -0.044241071     0.25161515    -0.580149262 -3.339330e-02

fd_spacetime         -0.165557115    -0.40132963     0.367895988  4.056776e-02

lacunarity_time      -0.972988210    -0.03536400     0.016965615 -6.487774e-01

lacunarity_space     -0.183655021     0.07177568    -0.143002151 -7.309706e-05

lacunarity_spacetime  0.185862522    -0.11911894     0.015544434 -1.154095e-01

                        fd_space fd_spacetime lacunarity_time lacunarity_space

(Intercept)          -0.04424107  -0.16555711     -0.97298821    -1.836550e-01

time_travelled        0.25161515  -0.40132963     -0.03536400     7.177568e-02

space_travelled      -0.58014926   0.36789599      0.01696561    -1.430022e-01

fd_time              -0.03339330   0.04056776     -0.64877744    -7.309706e-05

fd_space              1.00000000  -0.31957665      0.03043863    -8.177884e-02

fd_spacetime         -0.31957665   1.00000000      0.02907532     7.080431e-01

lacunarity_time       0.03043863   0.02907532      1.00000000     7.582100e-02

lacunarity_space     -0.08177884   0.70804308      0.07582100     1.000000e+00

lacunarity_spacetime -0.06430309  -0.75925077     -0.07991298    -8.972101e-01

                     lacunarity_spacetime

(Intercept)                    0.18586252

time_travelled                -0.11911894

space_travelled                0.01554443

fd_time                       -0.11540947

fd_space                      -0.06430309

fd_spacetime                  -0.75925077

lacunarity_time               -0.07991298

lacunarity_space              -0.89721009

lacunarity_spacetime           1.00000000

__________________________________________________
within_misassignments ~ context_boundary_crossings
__________________________________________________
                           (Intercept) context_boundary_crossings

(Intercept)                  1.0000000                 -0.8173885

context_boundary_crossings  -0.8173885                  1.0000000

__________________________________________________
across_misassignments ~ context_boundary_crossings
__________________________________________________
                           (Intercept) context_boundary_crossings

(Intercept)                  1.0000000                 -0.7433392

context_boundary_crossings  -0.7433392                  1.0000000

____________________________________________________
context_boundary_effect ~ context_boundary_crossings
____________________________________________________
                           (Intercept) context_boundary_crossings

(Intercept)                  1.0000000                 -0.7763847

context_boundary_crossings  -0.7763847                  1.0000000

______________________________________________________________
time_misplacement ~ kendall_tau_distance + contiguity_distance
______________________________________________________________
                     (Intercept) kendall_tau_distance contiguity_distance

(Intercept)            1.0000000           -0.6480909          -0.9021224

kendall_tau_distance  -0.6480909            1.0000000           0.6010106

contiguity_distance   -0.9021224            0.6010106           1.0000000

_______________________________________________________________
space_misplacement ~ kendall_tau_distance + contiguity_distance
_______________________________________________________________
                     (Intercept) kendall_tau_distance contiguity_distance

(Intercept)            1.0000000           -0.6582258          -0.9115754

kendall_tau_distance  -0.6582258            1.0000000           0.6019438

contiguity_distance   -0.9115754            0.6019438           1.0000000

_________________________________________________________________________
accurate_misassignment_space ~ kendall_tau_distance + contiguity_distance
_________________________________________________________________________
                     (Intercept) kendall_tau_distance contiguity_distance

(Intercept)            1.0000000           -0.7584205          -0.8850275

kendall_tau_distance  -0.7584205            1.0000000           0.6667594

contiguity_distance   -0.8850275            0.6667594           1.0000000

________________________________________________________________________
accurate_misassignment_time ~ kendall_tau_distance + contiguity_distance
________________________________________________________________________
                     (Intercept) kendall_tau_distance contiguity_distance

(Intercept)            1.0000000           -0.7201248          -0.9354643

kendall_tau_distance  -0.7201248            1.0000000           0.6623522

contiguity_distance   -0.9354643            0.6623522           1.0000000

__________________________________________________________________
within_misassignments ~ kendall_tau_distance + contiguity_distance
__________________________________________________________________
                     (Intercept) kendall_tau_distance contiguity_distance

(Intercept)            1.0000000           -0.7153877          -0.9422322

kendall_tau_distance  -0.7153877            1.0000000           0.6604752

contiguity_distance   -0.9422322            0.6604752           1.0000000

__________________________________________________________________
across_misassignments ~ kendall_tau_distance + contiguity_distance
__________________________________________________________________
                     (Intercept) kendall_tau_distance contiguity_distance

(Intercept)            1.0000000           -0.6841906          -0.9115985

kendall_tau_distance  -0.6841906            1.0000000           0.6366613

contiguity_distance   -0.9115985            0.6366613           1.0000000

____________________________________________________________________
context_boundary_effect ~ kendall_tau_distance + contiguity_distance
____________________________________________________________________
                     (Intercept) kendall_tau_distance contiguity_distance

(Intercept)            1.0000000           -0.8340949          -0.9378133

kendall_tau_distance  -0.8340949            1.0000000           0.7513771

contiguity_distance   -0.9378133            0.7513771           1.0000000


And we can compare multiple models of interest. For instance, if we create a larger model that combines all simple and complex navigation variables, we can see if the fit is better than if we use restricted models.


In [62]:
# Note: One interesting example of model comparisons is comparing the spatial and temporal path metrics predictive power
# over spatial or temporal misplacement. i.e.:
#
# model_0 = 'space_misplacement ~ (space_travelled + fd_space + lacunarity_space)'
# model_1 = 'space_misplacement ~ (time_travelled + fd_time + lacunarity_time)'
# and
# model_0 = 'time_misplacement ~ (space_travelled + fd_space + lacunarity_space)'
# model_1 = 'time_misplacement ~ (time_travelled + fd_time + lacunarity_time)'
#
# In both cases, the temporal path metrics resulted in a better fit than the spatial ones, 
# even when the test metric was spatial.

# Define two models to compare
model_0 = 'time_misplacement ~ (space_travelled + fd_space + lacunarity_space)'
model_1 = model_formulas[0]

# Make a list of formulas to pass to the model function
step_mf = [model_0, model_1]

step_models = [nlme.lme(r.formula(model_formula),
                   random=r.formula(random_effects_model), 
                   data=r_transformed_dataframe, 
                   control=nlme.lmeControl(maxIter=100, msMaxIter=100, opt='optim'), # Note: 'optim' is needed to avoid failure to converge
                   **{'na.action': 'na.omit'} # Other options can be found here: https://stat.ethz.ch/R-manual/R-devel/library/stats/html/na.fail.html
                  )
          for model_formula in step_mf]

# Get the model results and run an anova to compare the models
m0, m1 = step_models
result = r.anova(m0, m1)

# Convert the output of the anova into a Pandas DataFrame for convenience
summary_frame = pandas.DataFrame(np.transpose(np.concatenate([[[step_mf[0], step_mf[1]]], np.array(result[2:])])))
for idx, c in enumerate(summary_frame): # Coerce to numeric all but the first column
    if idx != 0: summary_frame[c] = pandas.to_numeric(summary_frame[c], errors='coerce')
    
# Name the columns for convenience
summary_frame.columns = ['Model Formula', 'Df', 'AIC', 'BIC', 'logLik', 'Model', 'Chisq', 'P Value'][0:len(summary_frame.columns)]

print("_"*50 + "\r\nANOVA Summary")
print(summary_frame)

print("_"*50 + "\r\nResult\r\n" + "_"*50)

# If the P Value is significant, check the BIC to determine which model was a better fit (lower BIC is better fit)
best_model_idx = -1
if len(summary_frame.columns) == 5:
    print('The Models are identitcal.')
elif summary_frame['P Value'][1] < 0.05:
    print('The models were significantly different.')
    if summary_frame['BIC'][0] > summary_frame['BIC'][1]:
        print("The second model ({0}) is significantly better than the first.".format(step_mf[1]))
        best_model_idx = 1
    else:
        print("The first model ({0}) is significantly better than the second.".format(step_mf[0]))
        best_model_idx = 0
else:
    print('The models were NOT significantly different.')

print("_"*50 + "\r\nBest Model t Table(s)\r\n" + "_"*50)

if best_model_idx == -1:
    print(r.summary(m0).rx2('tTable'))
    print(r.summary(m1).rx2('tTable'))
    print("_"*50 + "\r\nBest Model Beta Table(s)\r\n" + "_"*50)
    print(reghelper.beta(m0).rx2('tTable'))
    print(reghelper.beta(m1).rx2('tTable'))
    best_model = step_models[0]
else:
    print(r.summary(step_models[best_model_idx]).rx2('tTable'))
    print("_"*50 + "\r\nBest Model Beta Table(s)\r\n" + "_"*50)
    print(reghelper.beta(step_models[best_model_idx]).rx2('tTable'))
    best_model = step_models[best_model_idx]


__________________________________________________
ANOVA Summary
                                       Model Formula    Df         AIC  \
0  time_misplacement ~ (space_travelled + fd_spac...   8.0  821.575468   
1  time_misplacement ~ time_travelled + space_tra...  13.0  778.263780   

          BIC      logLik  Model      Chisq       P Value  
0  846.567180 -402.787734    1.0        NaN           NaN  
1  818.482532 -376.131890    2.0  53.311688  2.902476e-10  
__________________________________________________
Result
__________________________________________________
The models were significantly different.
The second model (time_misplacement ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime) is significantly better than the first.
__________________________________________________
Best Model t Table(s)
__________________________________________________
                             Value    Std.Error  DF    t-value    p-value

(Intercept)          -77.083139270 43.961801598 121 -1.7534117 0.08206366

time_travelled         0.003001533  0.001421575 121  2.1114142 0.03679427

space_travelled       -0.003766413  0.002087657 121 -1.8041341 0.07369792

fd_time               22.313183995 12.601744414 121  1.7706425 0.07913833

fd_space              -9.998432665  9.050927540 121 -1.1046860 0.27148753

fd_spacetime          -8.260295692 15.742316692 121 -0.5247192 0.60073844

lacunarity_time       13.815264102 12.166828743 121  1.1354860 0.25841588

lacunarity_space      -1.038711340  2.355975481 121 -0.4408838 0.66008387

lacunarity_spacetime   4.754214429  3.187189222 121  1.4916637 0.13838990

__________________________________________________
Best Model Beta Table(s)
__________________________________________________
                             Value  Std.Error  DF    t-value    p-value

(Intercept)             0.05331425 0.09014305 121  0.5914406 0.55532861

time_travelled.z        0.35796130 0.16953627 121  2.1114142 0.03679427

space_travelled.z      -0.29889772 0.16567378 121 -1.8041341 0.07369792

fd_time.z               0.21649227 0.12226763 121  1.7706425 0.07913833

fd_space.z             -0.18852774 0.17066184 121 -1.1046860 0.27148753

fd_spacetime.z         -0.12288010 0.23418259 121 -0.5247192 0.60073844

lacunarity_time.z       0.10674075 0.09400446 121  1.1354860 0.25841588

lacunarity_space.z     -0.12938232 0.29346130 121 -0.4408838 0.66008387

lacunarity_spacetime.z  0.65911386 0.44186492 121  1.4916637 0.13838990

Note that the Beta coefficients can be used to determine the relative imporance of the various predictor variables in the chosen model. The larger the beta coefficient (i.e. the first column in the Beta Tables) the better a predictor the independent variable is of the dependent variable.

Finally, we can test for normality of our residuals to confirm that the model is appropriately capturing the effect.


In [63]:
%matplotlib inline
import matplotlib.pyplot as plt
import scipy.stats as stats
import matplotlib.mlab as mlab

def residual_plot_1d(model, level=0, label=''):
    f, (ax0, ax1) = plt.subplots(1, 2)
    f.set_size_inches(15., 5.)
    
    data = np.array(r.residuals(model, level=level))

    n, bins, patches = ax0.hist(data, normed=1,)
    (mu, sigma) = stats.norm.fit(data)
    y = mlab.normpdf( bins, mu, sigma)
    l = ax0.plot(bins, y, 'r--', linewidth=1)

    res = stats.probplot(data, dist=stats.loggamma, sparams=(2.5,), plot=ax1)
    
    ax0.set_xlabel(label)
    ax0.set_ylabel('Probability')
    ax0.set_title(r'$\mathrm{Histogram\ of\ IQ:}\ ' + '\mu={0},\ \sigma={1}$'.format(mu, sigma))
    ax0.grid(True)
    ax1.grid(True)
    
    return data

mfs = model_formulas # [model_formulas[x] for x in [0, 1, 3, 5, 6]]

norm_models = [nlme.lme(r.formula(model_formula),
                   random=r.formula(random_effects_model), 
                   data=r_transformed_dataframe, 
                   control=nlme.lmeControl(maxIter=100, msMaxIter=100, opt='optim'), # Note: 'optim' is needed to avoid failure to converge
                   **{'na.action': 'na.omit'} # Other options can be found here: https://stat.ethz.ch/R-manual/R-devel/library/stats/html/na.fail.html
                  )
          for model_formula in mfs]

for model, form in zip(norm_models, mfs):
    model_under_test = model
    print(form)
    res0 = residual_plot_1d(model_under_test, level=0)
    res1 = residual_plot_1d(model_under_test, level=1)

    k2, p = stats.normaltest(res0)
    print('k2 = {0}, p = {1}'.format(k2, p))
    if p < 0.05:
        print('The residuals were NOT normal.')
    else:
        print('The residuals were normal.')
    k2, p = stats.normaltest(res1)
    print('k2 = {0}, p = {1}'.format(k2, p))
    if p < 0.05:
        print('The residuals were NOT normal.')
    else:
        print('The residuals were normal.')

    plt.show()


time_misplacement ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
k2 = 1.5442160167, p = 0.46203806092
The residuals were normal.
k2 = 2.78752352515, p = 0.248140102579
The residuals were normal.
space_misplacement ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
k2 = 0.413449608782, p = 0.813243420214
The residuals were normal.
k2 = 1.42823828236, p = 0.489623210824
The residuals were normal.
accurate_misassignment_space ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
k2 = 89.0058069144, p = 4.70581229249e-20
The residuals were NOT normal.
k2 = 84.4157977768, p = 4.67027463588e-19
The residuals were NOT normal.
accurate_misassignment_time ~ time_travelled + space_travelled + fd_time + fd_space + fd_spacetime + lacunarity_time + lacunarity_space + lacunarity_spacetime
k2 = 7.02660117975, p = 0.0297983996518
The residuals were NOT normal.
k2 = 2.94785980569, p = 0.229023673545
The residuals were normal.
within_misassignments ~ context_boundary_crossings
k2 = 37.5970880369, p = 6.85324195553e-09
The residuals were NOT normal.
k2 = 32.2292873967, p = 1.00345791746e-07
The residuals were NOT normal.
across_misassignments ~ context_boundary_crossings
k2 = 1.67435346253, p = 0.432931080422
The residuals were normal.
k2 = 5.62817790674, p = 0.0599593196004
The residuals were normal.
context_boundary_effect ~ context_boundary_crossings
k2 = 3.93993952239, p = 0.139461073287
The residuals were normal.
k2 = 5.68089551103, p = 0.0583995114061
The residuals were normal.
time_misplacement ~ kendall_tau_distance + contiguity_distance
k2 = 21.9422245128, p = 1.71912116311e-05
The residuals were NOT normal.
k2 = 1.54465740039, p = 0.461936104138
The residuals were normal.
space_misplacement ~ kendall_tau_distance + contiguity_distance
k2 = 2.87201141204, p = 0.23787601034
The residuals were normal.
k2 = 3.27858352763, p = 0.194117474638
The residuals were normal.
accurate_misassignment_space ~ kendall_tau_distance + contiguity_distance
k2 = 96.8727348449, p = 9.21197827313e-22
The residuals were NOT normal.
k2 = 98.9532090022, p = 3.25524501017e-22
The residuals were NOT normal.
accurate_misassignment_time ~ kendall_tau_distance + contiguity_distance
k2 = 4.90961353994, p = 0.085879788392
The residuals were normal.
k2 = 1.22409176735, p = 0.542240372761
The residuals were normal.
within_misassignments ~ kendall_tau_distance + contiguity_distance
k2 = 38.4931519404, p = 4.37842848553e-09
The residuals were NOT normal.
k2 = 29.711475304, p = 3.53374423621e-07
The residuals were NOT normal.
across_misassignments ~ kendall_tau_distance + contiguity_distance
k2 = 3.68533163972, p = 0.158394611282
The residuals were normal.
k2 = 4.44320678468, p = 0.108435105347
The residuals were normal.
context_boundary_effect ~ kendall_tau_distance + contiguity_distance
k2 = 12.8374699051, p = 0.001630717866
The residuals were NOT normal.
k2 = 12.2877929071, p = 0.00214654339565
The residuals were NOT normal.

Animate trial-over-trial relationship between two variables

We can animate the relationship between two variables using the following code. Note that the next code block will quickly generate the plot object, but we visualize it in the following cell (which can take some time to run).


In [80]:
%%capture

import matplotlib.pyplot as plt
from matplotlib import animation, rc
from IPython.display import HTML
import scipy.stats as stats
import os
import IPython.display as display


import statsmodels.api as smapi
from statsmodels.formula.api import ols
import statsmodels.graphics as smgraphics

rc('animation', html='html5')
%matplotlib inline

relations = [
             ['across_misassignments', 'context_boundary_crossings'],
             ['context_boundary_effect', 'context_boundary_crossings'],
             ['accurate_misassignment_time', 'fd_space'],
             ['accurate_misassignment_time', 'lacunarity_space'],
             ['accurate_misassignment_time', 'lacunarity_spacetime'],
             ['time_misplacement', 'time_travelled'], 
             ['space_misplacement', 'space_travelled']
]

def get_animation_from_data(xs, ys, title='', x_label='', y_label='', animate=True):
    def update_plot(t):
        if t+1 >= len(xs): # For pausing at the end
            t = 2.99
        index = int(np.floor(t))
        nt = t % 1.0
        
        newPoints = np.transpose([xs[index+1], ys[index+1]])
        originalPoints = np.transpose([xs[index], ys[index]])
        interpolation = originalPoints*(1-nt) + newPoints*nt
        
        scat.set_offsets(interpolation)
        
        line_x = np.linspace(np.min(xs), np.max(xs), 10)
        newLine = np.transpose([line_x, np.array([fits[index+1][0]*x + fits[index+1][1] for x in line_x])])
        originalLine = np.transpose([line_x, np.array([fits[index][0]*x + fits[index][1] for x in line_x])])
        interpolation = originalLine*(1-nt) + newLine*nt
        
        line_plot[0].set_xdata(np.transpose(interpolation)[0])
        line_plot[0].set_ydata(np.transpose(interpolation)[1])
        
        r = fits[index][2]*(1-nt) + fits[index+1][2]*nt
        p = fits[index][3]*(1-nt) + fits[index+1][3]*nt
        
        txt.set_text('p=' + "{:.2f}".format(p) + '\n' + 'r=' + "{:.2f}".format(r))
        
        return scat,
    
    if animate:
        fig = plt.figure()
        ax = plt.gca()
    else:
        fig = plt.figure()
        ax1 = fig.add_subplot(221)
        ax2 = fig.add_subplot(222)
        ax3 = fig.add_subplot(223)
        ax4 = fig.add_subplot(224)
        axs = [ax1, ax2, ax3, ax4]
        ax = axs[0]
        for ax in axs:
            ax.set_xlabel(x_label)
            ax.set_ylabel(y_label)
    
    masks = [[ ~np.isnan(varx) & ~np.isnan(vary) for varx, vary in zip(x, y)] for x, y in zip(xs, ys)]
    
    for idx, (x, y, mask) in enumerate(zip(xs, ys, masks)):
        regression = ols("data ~ x", data=dict(data=y[mask], x=x[mask])).fit()
        test = regression.outlier_test()
        outliers = []
        try:
            outliers = ((i, x[i],y[i]) for i,t in enumerate(test['bonf(p)']) if t < 0.5)
            print 'Outliers: ', list(outliers)
        except:
            pass
        for outlier in outliers:
            del masks[idx][outerliers[0]]
            del xs[idx][outerliers[0]]
            del xs[idx][outerliers[0]]
        

    
    fits = [stats.linregress(x[mask], y[mask]) for x, y, mask in zip(xs, ys, masks)]
    
    scat = plt.scatter([], [], color='white', edgecolors ='black')
    
    if animate:
        txt = plt.text(1, 0, '', fontsize=12, ha='right', va='bottom', transform=ax.transAxes)
        line_plot = plt.plot([], [], color='black')
        anim = animation.FuncAnimation(fig, update_plot, frames=np.arange(0, 4, 0.01), interval=33)
        plt.title(title)
        [plt.scatter(x, y, label=idx+1, alpha=0.5) for idx, (x, y) in enumerate(zip(xs, ys))]
        plt.legend(loc=2)
        plt.tight_layout()
    else:
        plt.suptitle(title)
        fig.set_size_inches((15, 8))
        for idx, (x, y, ax, fit) in enumerate(zip(xs, ys, axs, fits)):
            ax.set_title('Trial {0}'.format(idx+1))
            txt = plt.text(1, 0, '', fontsize=12, ha='right', va='bottom', transform=ax.transAxes)
            ax.scatter(x, y, label=idx+1, alpha=0.5)
            line_plot = plt.plot([], [], color='black')
            line_x = np.linspace(np.min(x), np.max(x), 10)
            line_y = np.array([fit[0]*x + fit[1] for x in line_x])
            ax.plot(line_x, line_y, 'k')
            r = fit[2]
            p = fit[3]
            txt.set_text('p=' + "{:.2f}".format(p) + '\n' + 'r=' + "{:.2f}".format(r))
            plt.tight_layout()
    
    if animate:
        plt.close()
        return anim

def get_animation(relation, animate=True):
    xs = [data[relation[1]][data['trial'] == n] for n in [0, 1, 2, 3]]
    ys = [data[relation[0]][data['trial'] == n] for n in [0, 1, 2, 3]]

    return get_animation_from_data(xs, ys, title=relation[1].replace('_',' ').title() + ' vs. ' + relation[0].replace('_',' ').title(), x_label=relation[1].replace('_',' ').title(), y_label=relation[0].replace('_',' ').title(), animate=animate)

# Note: you'll need to change the ffmpeg path to use this on your machine
def embed_animation_as_gif(_animation, ffmpeg_path=r'C:\mingw2\bin\ffmpeg.exe'):
    if not os.path.exists(ffmpeg_path):
        return _animation
    _animation.save('animation.mp4')
    os.system("ffmpeg -i animation.mp4 animation.gif -y")
    data='0'
    IMG_TAG = '<img src="data:image/gif;base64,{0}">'
    with open('animation.gif', 'rb') as f:
        data = f.read()
        data = data.encode('base64')
    return HTML(IMG_TAG.format(data))

In [81]:
for relation in relations:
    display_obj = get_animation(relation, animate=False)
    if 'generate_embedded_animations' in vars() and generate_embedded_animations and 'embed_animation_as_gif' in vars():
        display_obj = embed_animation_as_gif(display_obj)
    display.display_html(display_obj)


Outliers:  []
Outliers:  Outliers:  [(42, 9, 0)]
Outliers:  Outliers:  []
Outliers:  Outliers:  Outliers:  Outliers:  []
Outliers:  []
Outliers:  Outliers:  []
Outliers:  []
Outliers:  []
Outliers:  []
Outliers:  []
Outliers:  []
Outliers:  []
Outliers:  []
Outliers:  []
Outliers:  []
Outliers:  [(17, 609.71758448699995, 173.17978572799998)]
Outliers:  Outliers:  Outliers:  []
Outliers:  Outliers:  Outliers: 

Plotting the Residuals of the Fit

Next, we can plot the same effect in terms of the residuals after accounting for the random effects.


In [60]:
import matplotlib.pyplot as plt

relations = [
             ['across_misassignments', 'context_boundary_crossings'],
             ['context_boundary_effect', 'context_boundary_crossings'],
             ['accurate_misassignment_time', 'fd_space'],
             ['accurate_misassignment_time', 'lacunarity_space'],
             ['accurate_misassignment_time', 'lacunarity_spacetime'],
             ['time_misplacement', 'time_travelled'], 
             ['space_misplacement', 'space_travelled']
]

relation_models = [models[x] for x in [5, 6, 3, 3, 3, 0, 1]]

def plot_residuals(r0, r1, model, title=''):
    # Make new figure
    plt.figure()
    # Get the subject coefficients
    subject_lines = pandas2ri.ri2py(r.summary(model).rx2('coefficients').rx2('random').rx2('subID'))
    x = np.array([0, 1, 2, 3])
    ys = [x*slope + intercept for intercept, slope in subject_lines]
    
    # Get the relation data
    r0_data = [data[r0][data['trial'] == n] for n in list(x)]
    r1_data = [data[r1][data['trial'] == n] for n in list(x)]
    
    # Compute the residuals of the target variable
    r0_resid = np.transpose(np.array(ys)) - np.array(r0_data)
    
    return get_animation_from_data(r0_resid, r1_data, title=title)

In [61]:
for relation in relations:
    r0, r1 = relation
    display_obj = plot_residuals(r0, r1, relation_models[0], title=r0 + ' vs. ' + r1)
    if 'generate_embedded_animations' in vars() and generate_embedded_animations and 'embed_animation_as_gif' in vars():
        display_obj = embed_animation_as_gif(display_obj)
    display.display_html(display_obj)


<matplotlib.figure.Figure at 0x3c1bee10>
<matplotlib.figure.Figure at 0x5e759320>
<matplotlib.figure.Figure at 0x30a550b8>
<matplotlib.figure.Figure at 0x3961ba58>
<matplotlib.figure.Figure at 0x5880a198>
<matplotlib.figure.Figure at 0x421d8d68>
<matplotlib.figure.Figure at 0x8abd1cc0>

Visualization

Next, we'll do some basic visualization of Navigation.


In [8]:
from cogrecon.core.data_flexing.time_travel_task.time_travel_task_binary_reader import read_binary_file
import os
import numpy as np

In [17]:
#data_directory = r'C:\Users\Kevin\Documents\GitHub\msl-iposition-pipeline\examples\saved_data\Paper Data (cleaned)'
#data_file = '022_4_1_0_2016-10-12_16-10-25.dat'
data_directory = r'C:\Users\Kevin\Desktop\v6.0'
data_file = r'999_1_15_0_2018-04-09_19-13-32.dat'

iterations = read_binary_file(os.path.join(data_directory, data_file))

In [18]:
ts = [iterations[i]['time_val'] for i in range(0, len(iterations))]
xs = [iterations[i]['x'] for i in range(0, len(iterations))]
ys = [iterations[i]['z'] for i in range(0, len(iterations))]
atds = [(iterations[i]['datetime'] - iterations[0]['datetime']).total_seconds() for i in range(0, len(iterations))]

In [19]:
from math import atan2,degrees

def GetAngleOfLineBetweenTwoPoints(p1, p2):
    xDiff = p2['x'] - p1['x']
    yDiff = p2['y'] - p1['y']
    return degrees(atan2(yDiff, xDiff))

In [20]:
import matplotlib.pyplot as plt
from matplotlib.patches import Wedge, Rectangle, Circle

fov = 60.0
idx = int(len(iterations)/1.14)
window = 2.
time_points = [4, 10, 16, 25, 34, 40, 46, 51]
space_points = [[18, -13], [-13, 9], [-10, -2], [6, -2], [17, -8], [-2, -7], [-15, -15], [6, 18], [14, 6], [-2, 10]]
e = 'k'

plt.figure(figsize=(10, 10))
plt.xlabel('Space X')
plt.ylabel('Space Y')
angle = GetAngleOfLineBetweenTwoPoints({'x':xs[idx], 'y': ys[idx]}, {'x': xs[idx+10], 'y': ys[idx+10]})
plt.gca().add_artist(Rectangle((-20,-20),40,40, color='k', alpha=0.4, fill=False))
plt.gca().add_artist(Wedge((xs[idx], ys[idx]), 10, angle-fov, angle+fov, color='r', alpha=0.4))
plt.gca().set_aspect('equal')
for i, sp in enumerate(space_points):
    if i == len(time_points) - 1:
        plt.gca().add_artist(Circle((sp[0], sp[1]), 10, fill=False, alpha=1, edgecolor='k'))
    plt.gca().add_artist(Circle((sp[0], sp[1]), 10, color='g', alpha=0.1, edgecolor=e))
plt.scatter(np.transpose(space_points)[0], np.transpose(space_points)[1], c='g')
plt.scatter([xs[idx]], [ys[idx]], c='k', alpha=1, zorder=10)
plt.plot(xs, ys)

plt.figure(figsize=(10, 10))
plt.xlabel('Participant Time')
plt.ylabel('Timeline Time')
plt.gca().add_artist(Rectangle((0,0), atds[-1], 60, color='k', alpha=0.4, fill=False))
plt.gca().add_artist(Rectangle((0, ts[idx]-window/2.), atds[-1], window, color='r', alpha=0.4))
for i, tp in enumerate(time_points):
    if i == len(time_points) - 1:
        plt.gca().add_artist(Rectangle((0, tp-window/2.), atds[-1], window, fill=False, alpha=1, edgecolor='k'))
    plt.gca().add_artist(Rectangle((0, tp-window/2.), atds[-1], window, color='g', alpha=0.1))
plt.scatter([atds[idx]], [ts[idx]], c='k', alpha=1, zorder=10)
plt.plot(atds, ts)
plt.gca().set_aspect('equal')

plt.show()



In [21]:
import matplotlib.pyplot as plt
from matplotlib.patches import Wedge, Rectangle
from mpl_toolkits.mplot3d import Axes3D
import mpl_toolkits.mplot3d.art3d as pl3d

fov = 60.0
idx = int(len(iterations)/1.13)
window = 2.

fig = plt.figure(figsize=(10, 10))
ax = fig.gca(projection='3d')


ax.set_xlabel('Space X')
ax.set_ylabel('Space Y')
ax.set_zlabel('Participant Time')
angle = GetAngleOfLineBetweenTwoPoints({'x':xs[idx], 'y': ys[idx]}, {'x': xs[idx+10], 'y': ys[idx+10]})
w = Wedge((xs[idx], ys[idx]), 10, angle-fov, angle+fov, color='r', alpha=0.4)
# plt.gca().add_artist(Rectangle((-20,-20),40,40, color='k', alpha=0.4, fill=False))
# plt.gca().add_artist(Wedge((xs[idx], ys[idx]), 10, angle-fov, angle+fov, color='r', alpha=0.4))
plt.gca().set_aspect('equal')
# plt.scatter([xs[idx]], [ys[idx]], c='k', alpha=1, zorder=10)
ax.plot(xs, ys, ts)

# plt.gca().add_artist(Rectangle((0, ts[idx]-window/2.), atds[-1], window, color='r', alpha=0.4))
plt.gca().set_aspect('equal')
window = 2

def extrude_polygon(pts, zmid, zmin, zmax, slices=10):
    x, y = np.transpose(pts)
    zs = [[zmid-offset] * len(x) for offset in np.linspace(zmin, zmax, slices)]
    _polys = [zip(x, y, z) for z in zs]
    
    return _polys

def graph_polygons_with_highlighted_edges(_polys, ax, color='r', alpha=0.1, edge_color='k', edge_alpha=0.4):
    coll = pl3d.Poly3DCollection(_polys)
    coll_ends = pl3d.Poly3DCollection([_polys[0], _polys[-1]])
    coll.set_alpha(alpha)
    coll_ends.set_alpha(edge_alpha)
    coll.set_edgecolor(edge_color)
    coll_ends.set_edgecolor(edge_color)
    coll.set_facecolor(color)
    coll_ends.set_facecolor(color)
    ax.add_collection3d(coll)
    ax.add_collection3d(coll_ends)


polys = extrude_polygon(w.get_path().vertices, ts[idx], -window/2.,window/2.)
graph_polygons_with_highlighted_edges(polys, ax)


for s, t in zip(space_points, time_points):
    c = Circle((s[0], s[1]), 10, color='g', alpha=0.1, edgecolor=e)
    pts = (c.get_path().vertices*10 + s)
    polys = extrude_polygon(pts, t, -window/2.,window/2.)
    graph_polygons_with_highlighted_edges(polys, ax, color='g', alpha=0.01, edge_alpha=0.1)

plt.show()



In [31]:
import cogrecon.core.data_flexing.time_travel_task.time_travel_task_to_iposition as ttt2i

In [32]:
data_directory = r'C:\Users\Kevin\Desktop\v6.0\tmp'
data_output_directory = r'C:\Users\Kevin\Desktop\v6.0'

In [40]:
ttt2i.time_travel_task_to_iposition(data_directory, data_output_directory, file_regex="\d\d\d_\d_14_\d_\d\d\d\d-\d\d-\d\d_\d\d-\d\d-\d\d.dat")


2018-04-09 19:29:01 DESKTOP-LKC15NF root[21884] INFO Found 4 data files in 0.0019998550415 seconds.
2018-04-09 19:29:02 DESKTOP-LKC15NF root[21884] INFO 999,1
2018-04-09 19:29:02 DESKTOP-LKC15NF root[21884] INFO 999,1
2018-04-09 19:29:03 DESKTOP-LKC15NF root[21884] INFO 999,1
2018-04-09 19:29:04 DESKTOP-LKC15NF root[21884] INFO 999,1

In [41]:
from cogrecon.core.batch_pipeline import batch_pipeline
from cogrecon.core.data_flexing.time_travel_task.time_travel_task_analytics import summarize_test_data

In [42]:
summarize_test_data(search_directory=data_directory, file_regex="\d\d\d_\d_14_\d_\d\d\d\d-\d\d-\d\d_\d\d-\d\d-\d\d.dat")  # For Time Travel Task specific analyses


2018-04-09 19:29:11 DESKTOP-LKC15NF root[21884] INFO Found 4 data files in 0.000999927520752 seconds.
2018-04-09 19:29:12 DESKTOP-LKC15NF root[21884] INFO 999,1,0,2018-04-09 19:12:32,8,False,False,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan
2018-04-09 19:29:12 DESKTOP-LKC15NF root[21884] INFO 999,1,1,2018-04-09 19:12:32,8,False,False,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan
2018-04-09 19:29:13 DESKTOP-LKC15NF root[21884] INFO 999,1,2,2018-04-09 19:12:32,8,False,False,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan
2018-04-09 19:29:14 DESKTOP-LKC15NF root[21884] INFO 999,1,3,2018-04-09 19:12:32,8,False,False,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan
Out[42]:
True

In [43]:
batch_pipeline(str(data_output_directory), 'TimeTravelTask_TimeOnly.csv', data_shape=(4, 10, 3),
               collapse_trials=False, trial_by_trial_accuracy=False,
               dimension=3, removal_dim_indicies=[0, 1], actual_coordinate_prefixes=True)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-43-05949bc854c5> in <module>()
      1 batch_pipeline(str(data_output_directory), 'TimeTravelTask_TimeOnly.csv', data_shape=(4, 10, 3),
      2                collapse_trials=False, trial_by_trial_accuracy=False,
----> 3                dimension=3, removal_dim_indicies=[0, 1], actual_coordinate_prefixes=True)

C:\Program Files\Anaconda3\envs\iposition\lib\site-packages\cogrecon\core\batch_pipeline.pyc in batch_pipeline(search_directory, out_filename, data_shape, dimension, accuracy_z_value, trial_by_trial_accuracy, flags, collapse_trials, manual_threshold, actual_coordinate_prefixes, category_independence_enabled, category_prefixes, order_greedy_deanonymization_enabled, order_prefixes, removal_dim_indicies, _data_coordinates_file_suffix, _order_file_suffix, _category_file_suffix, _actual_coordinates_file_suffix)
    232     assert len(search_directory) > 0, "search_directory must have length greater than 0: {0}".format(search_directory)
    233     if data_shape:
--> 234         validate_list_format(data_shape, dimension=1, require_numeric=True, list_name="data_shape")
    235     assert isinstance(out_filename, str), \
    236         "out_filename is not string: {0}".format(out_filename)

C:\Program Files\Anaconda3\envs\iposition\lib\site-packages\cogrecon\core\batch_pipeline.pyc in validate_list_format(l, require_numeric, dimension, list_name)
     42     if require_numeric:
     43         assert all(isinstance(x, int) or isinstance(x, float) for x in
---> 44                    np.ndarray.flatten(np.array([item for sublist in l for item in sublist]))), \
     45             "{1} contains some non int or float values: {0}".format(l, list_name)
     46 

TypeError: 'int' object is not iterable

In [ ]: