Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/pupil bench issues #60

Merged
merged 2 commits into from
Apr 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/pspm_pupil/exp1/fit.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@
options.exclude_missing = struct('segment_length', exclude_segment_length, 'cutoff', exclude_cutoff);

out = pspm_glm(model, options);
[out, stats] = exclude_and_average(out, csp, out.stats_exclude);
stats = exclude_and_average(out, csp, out.stats_exclude);
end
2 changes: 1 addition & 1 deletion examples/pspm_pupil/exp2/fit.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@

out = pspm_glm(model, options);
not_exclude = zeros(1, numel(cell2mat(csp)), 'uint8');
[out, stats] = exclude_and_average(out, csp, not_exclude);
stats = exclude_and_average(out, csp, not_exclude);
end
2 changes: 1 addition & 1 deletion examples/pspm_pupil/exp4/fit.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
options.exclude_missing = struct('segment_length', exclusion_seg_len, 'cutoff', trial_exclusion_threshold);

out = pspm_glm(model, options);
[out, stats] = exclude_and_average(out, csp, out.stats_exclude);
stats = exclude_and_average(out, csp, out.stats_exclude);
end

function [out, stats] = condition_wise(inarg)
Expand Down
11 changes: 7 additions & 4 deletions examples/pspm_pupil/exp7/bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,23 @@

MODEL_PATH = "exp7"
EXP_OUTPUT_PATH = pathjoin(util.OUT_PATH, MODEL_PATH)
PP_LIST = ["pfe", "valid_fixations"]

if __name__ == "__main__":
os.makedirs(EXP_OUTPUT_PATH, exist_ok=True)
# prepare models
model_list = [
("pfe", {}),
("valid_fixations", {"fixation_angle": 5.0}),
]
models = [
PsPMModel(
lib_paths=util.LIB_PATHS,
import_base_path=MODEL_PATH,
predict_fn="fit_all",
model_spec={"model_str": pp},
name=pp,
model_spec=dict({"model_str": model_str}, **params),
name=model_str,
)
for pp in PP_LIST
for model_str, params in model_list
]

suite = util.get_test_suite(EXP_OUTPUT_PATH)
Expand Down
16 changes: 15 additions & 1 deletion examples/pspm_pupil/libcommon/exclude_and_average.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
function [glm, stats] = exclude_and_average(glm, csp, exclude_arr)
function [stats] = exclude_and_average(glm, csp, exclude_arr)
% Compute CS+ and CS- beta stat averages from a fitted single-trial GLM structure.
%
% Parameters
% ----------
% glm : Fitted single-trial GLM structure.
%
% csp : A logical array where csp(i) is 1 if ith trial is a CS+
%
% exclude_arr : A logical array where exclude_arr(i) is 1 if ith trial should be
% excluded from the average.
%
% Returns
% -------
% stats : A 2-element array holding the CS+ and CS- beta averages.
csp = cell2mat(csp);
bfno = glm.bf.bfno;
stats_csp = 0;
Expand Down
16 changes: 16 additions & 0 deletions examples/pspm_pupil/libcommon/fit_all.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
function stats = fit_all(inarg)
% Fit all the subjects in the dataset given in inarg structure using the currently
% loaded fit.m function.
%
% Before the dataset is fit, it is copied to a temporary location specified with
% inarg.tmp_out_path so that the original data is left unmodified.
%
% Parameters
% ----------
% inarg : Structure with the following fields:
% .datapath : field holding the path to the dataset to fit.
% .tmp_out_path : field holding the path to the temporary location to copy the dataset.
% .subject_ids : Array of subject IDs to fit
%
% Returns
% -------
% stats : Array with shape [2, n_subj] holding CS+ and CS- beta fits for each subject.
orig_datapath = inarg.datapath;
ds_name = split(orig_datapath, '/');
ds_name = ds_name{end};
Expand Down
14 changes: 14 additions & 0 deletions examples/pspm_pupil/libcommon/get_conditions.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
function [pupil_fpath, conditions] = get_conditions(datapath, subj_id)
% Return the pupil paths and timing structure for a subject. The type of the
% dataset is inferred from datapath.
%
% Parameters
% ----------
% datapath : Path to the dataset.
% subj_id : ID of the subject
%
% Returns
% -------
% pupil_fpath : Path or cell array holding the paths to the pupil files (all sessions)
% for the given subject.
% conditions : Struct or cell array holding the condition structures (all sessions)
% for the given subject.
fparts = split(datapath, filesep);
if isempty(fparts{end})
dataset_name = fparts{end-1};
Expand Down
13 changes: 13 additions & 0 deletions examples/pspm_pupil/libcommon/get_conditions_doxmem2.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
function [pupil_fpath, conditions] = get_conditions_doxmem2(datapath, subj_id)
% Return the pupil paths and timing structure for a subject from DoxMem2 dataset.
%
% Parameters
% ----------
% datapath : Path to the doxmem2 dataset.
% subj_id : ID of the subject
%
% Returns
% -------
% pupil_fpath : Cell array holding the paths to the pupil files (all sessions) for the
% given subject.
% conditions : Cell array holding the condition structures (all sessions) for the
% given subject.
cogent_fpath = {...
fullfile(datapath, sprintf('DoxMem2_cogent_%.2d_sn1.mat', subj_id)),
fullfile(datapath, sprintf('DoxMem2_cogent_%.2d_sn2.mat', subj_id)),
Expand Down
13 changes: 13 additions & 0 deletions examples/pspm_pupil/libcommon/get_conditions_fer02.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
function [pupil_fpath, conditions] = get_conditions_fer02(datapath, subj_id)
% Return the pupil paths and timing structure for a subject from FER02 dataset.
%
% Parameters
% ----------
% datapath : Path to the FER02 dataset.
% subj_id : ID of the subject
%
% Returns
% -------
% pupil_fpath : Cell array holding the paths to the pupil files (all sessions) for the
% given subject.
% conditions : Cell array holding the condition structures (all sessions) for the
% given subject.
cogent_fpath = {};
cogent = {};
try
Expand Down
11 changes: 11 additions & 0 deletions examples/pspm_pupil/libcommon/get_conditions_fss6b.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
function [pupil_fpath, conditions] = get_conditions_fss6b(datapath, subj_id)
% Return the pupil paths and timing structure for a subject from FSS6B dataset.
%
% Parameters
% ----------
% datapath : Path to the FSS6B dataset.
% subj_id : ID of the subject
%
% Returns
% -------
% pupil_fpath : Path to the pupil file for the given subject.
% conditions : Condition structure for the given subject.
pupil_fpath = fullfile(datapath, sprintf('FSS6B_pupil_%.2d.mat', subj_id));
psych_fpath = fullfile(datapath, sprintf('FSS6B_psych_%.2d.mat', subj_id));
pupil = load(pupil_fpath);
Expand Down
13 changes: 13 additions & 0 deletions examples/pspm_pupil/libcommon/get_conditions_li.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
function [pupil_fpath, conditions] = get_conditions_li(datapath, subj_id)
% Return the pupil paths and timing structure for a subject from LI dataset.
%
% Parameters
% ----------
% datapath : Path to the LI dataset.
% subj_id : ID of the subject
%
% Returns
% -------
% pupil_fpath : Cell array holding the paths to the pupil files (all sessions) for the
% given subject.
% conditions : Cell array holding the condition structures (all sessions) for the
% given subject.
pupil_fpath = {...
fullfile(datapath, sprintf('LI_pupil_%.2d_sn1.mat', subj_id)),...
fullfile(datapath, sprintf('LI_pupil_%.2d_sn2.mat', subj_id)) ...
Expand Down
13 changes: 13 additions & 0 deletions examples/pspm_pupil/libcommon/get_conditions_pubfe.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
function [pupil_fpath, conditions] = get_conditions_pubfe(datapath, subj_id)
% Return the pupil paths and timing structure for a subject from PubFe dataset.
%
% Parameters
% ----------
% datapath : Path to the PubFe dataset.
% subj_id : ID of the subject
%
% Returns
% -------
% pupil_fpath : Cell array holding the paths to the pupil files (all sessions) for the
% given subject.
% conditions : Cell array holding the condition structures (all sessions) for the
% given subject.
pupil_fpath = {...
fullfile(datapath, sprintf('PubFe_pupil_%.2d_sn1.mat', subj_id)),...
fullfile(datapath, sprintf('PubFe_pupil_%.2d_sn2.mat', subj_id)) ...
Expand Down
11 changes: 11 additions & 0 deletions examples/pspm_pupil/libcommon/get_conditions_sc4b.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
function [pupil_fpath, conditions] = get_conditions_sc4b(datapath, subj_id)
% Return the pupil paths and timing structure for a subject from SC4B dataset.
%
% Parameters
% ----------
% datapath : Path to the SC4B dataset.
% subj_id : ID of the subject
%
% Returns
% -------
% pupil_fpath : Path to the pupil file for the given subject.
% conditions : Condition structure for the given subject.
pupil_fpath = fullfile(datapath, sprintf('SC4B_pupil_%.2d_sn1.mat', subj_id));
cogent_fpath = fullfile(datapath, sprintf('SC4B_cogent_%.2d.mat', subj_id));
pupil = load(pupil_fpath);
Expand Down
11 changes: 11 additions & 0 deletions examples/pspm_pupil/libcommon/get_conditions_vc7b.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
function [pupil_fpath, conditions] = get_conditions_vc7b(datapath, subj_id)
% Return the pupil paths and timing structure for a subject from VC7B dataset.
%
% Parameters
% ----------
% datapath : Path to the VC7B dataset.
% subj_id : ID of the subject
%
% Returns
% -------
% pupil_fpath : Path to the pupil file for the given subject.
% conditions : Condition structure for the given subject.
pupil_fpath = fullfile(datapath, sprintf('VC7B_pupil_%.2d_sn1.mat', subj_id));
psych_fpath = fullfile(datapath, sprintf('VC7B_psych_%.2d.mat', subj_id));
pupil = load(pupil_fpath);
Expand Down
11 changes: 11 additions & 0 deletions examples/pspm_pupil/libcommon/perc_miss_overall.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
function perc = perc_miss_overall(fp, channel)
% Return the overall missing data percentage of the data of a subject in
% the given channel.
%
% Parameters
% ----------
% fp : Path or cell to the paths (all sessions) of a subject.
% channel : Channels on which miss percentage should be computed.
%
% Returns
% -------
% perc : Overall missing data percentage in the range [0, 100].
if ~iscell(fp)
fp = {fp};
end
Expand Down
12 changes: 11 additions & 1 deletion examples/pspm_pupil/libcommon/pp_pfe.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
function sts = pp_pfe(pupil_fpath)
% Perform pupil foreshortening error correction on the data of a subject.
% If the gaze channels are in pixels, they are first converted to milimeters.
%
% Parameters
% ----------
% pupil_fpath : Path or cell of paths (all sessions) to pupil data of a subject.
%
% Returns
% -------
% sts : Status flag.
opt.mode = 'auto';
opt.C_z = 525;
opt.C_z = 625;
for i = 1:numel(pupil_fpath)
fpath = pupil_fpath{i};
try
Expand Down
10 changes: 10 additions & 0 deletions examples/pspm_pupil/libcommon/pp_valid_fixations.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
function sts = pp_valid_fixations(pupil_fpath, fixation_angle)
% Perform valid fixations filtering on the data of a subject.
% If the gaze channels are in pixels, they are first converted to milimeters.
%
% Parameters
% ----------
% pupil_fpath : Path or cell of paths (all sessions) to pupil data of a subject.
%
% Returns
% -------
% sts : Status flag.
for i = 1:numel(pupil_fpath)
fpath = pupil_fpath{i};
try
Expand Down
17 changes: 15 additions & 2 deletions examples/pspm_pupil/libcommon/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@
import numpy as np
import pandas as pd

Dataset = namedtuple("Dataset", "name subject_ids")

DATA_PATH = "data"
OUT_PATH = "output"
LIB_PATHS = ["/home/eozd/bachlab/pspm/src", "libcommon"]


class Dataset:
"""
Simple class to represent a dataset (e.g. doxmem2)
"""

def __init__(self, *args, name, subject_ids):
self.name = name
self.subject_ids = subject_ids
Expand All @@ -34,6 +36,10 @@ def __init__(self, *args, name, subject_ids):


def sm_to_pandas(sm):
"""
Convert a score matrix that is the result of sciunit TestSuite
to a regular pandas dataframe.
"""
n_rows, n_cols = sm.shape
arr = np.empty(shape=(n_rows, n_cols), dtype=np.float64)
for i in range(n_rows):
Expand All @@ -44,6 +50,9 @@ def sm_to_pandas(sm):


def get_obs_dict_list(exp_output_path):
"""
Get the observation dictionary that can be used in cognibench framework.
"""
obs_dict_list = [
{
"stimuli": {
Expand All @@ -59,6 +68,10 @@ def get_obs_dict_list(exp_output_path):


def get_test_suite(exp_output_path):
"""
Construct a test suite for pupil benchmarking. Each dataset in DATASET_LIST
will be a separate test in the suite.
"""
# prepare tests
obs_dict_list = get_obs_dict_list(exp_output_path)
CohensD = partialclass(scores.CohensDScore, min_score=-5, max_score=5)
Expand Down
2 changes: 1 addition & 1 deletion examples/pspm_pupil/run_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# STEPS
# 1. If there is no data folder, download datasets using download_datasets.sh
# 2. Change PsPM src folder path in libcommon/util.py line 14
# 2. Change PsPM src folder path in libcommon/util.py LIB_PATHS definition
# 3. Run this script
#
# Outputs will be stored in output folder
Expand Down