Skip to content

Commit

Permalink
Merge pull request #60 from fmelinscak/bugfix/pupil-bench-issues
Browse files Browse the repository at this point in the history
Bugfix/pupil bench issues
  • Loading branch information
eozd authored Apr 15, 2020
2 parents b3aa4e7 + 97f84b7 commit c5dde54
Show file tree
Hide file tree
Showing 19 changed files with 188 additions and 12 deletions.
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

0 comments on commit c5dde54

Please sign in to comment.