Skip to content

Commit

Permalink
Merge pull request #520 from bachlab/448-release-pspm-version-61
Browse files Browse the repository at this point in the history
Finalise for release 6.1
  • Loading branch information
teddychao authored Aug 24, 2023
2 parents a2ec447 + 207caaa commit ccbf3c8
Show file tree
Hide file tree
Showing 25 changed files with 1,252 additions and 68 deletions.
Binary file modified doc/PsPM_Developers_Guide.pdf
Binary file not shown.
877 changes: 872 additions & 5 deletions doc/PsPM_Manual.lyx

Large diffs are not rendered by default.

Binary file modified doc/PsPM_Manual.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion doc/PsPM_References.lyx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
\renewcommand{\textendash}{--}
\renewcommand{\textemdash}{---}

\usepackage{stix2}
\usepackage{bera}
\usepackage{enumitem} \setlist[itemize]{noitemsep}
\end_preamble
\use_default_options true
Expand Down
Binary file modified doc/PsPM_References.pdf
Binary file not shown.
Binary file modified doc/release_notes.pdf
Binary file not shown.
178 changes: 173 additions & 5 deletions doc/release_notes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
\usepackage{esint}
\usepackage[unicode=true]
{hyperref}

\usepackage[cmintegrals,cmbraces]{newtxmath}
\usepackage{ebgaramond-maths}
\usepackage[T1]{fontenc}


\usepackage{bera}

\makeatletter

Expand Down Expand Up @@ -69,7 +68,7 @@
framexleftmargin=1pt,
frame=l}
\renewcommand{\lstlistingname}{Listing}
\title{PsPM Release Notes\\ ~\\ Version 6.0.0}
\title{PsPM Release Notes\\ ~\\ Version 6.1.0}

\begin{document}
\maketitle
Expand Down Expand Up @@ -928,6 +927,175 @@ \subsection*{For Developers}
\end{itemize}
\end{itemize}

\section{PsPM Version 6.1.0}
\subsection*{General}
\begin{itemize}
\item Minimum version of MATLAB
\begin{itemize}
\item The minimum version of MATLAB required for running PsPM is \href{https://uk.mathworks.com/content/dam/mathworks/mathworks-dot-com/support/sysreq/files/SystemRequirements-Release14-ServicePack3_SupportedCompilers.pdf}{MATLAB 7.1 or R14 Service Pack 3}.
\end{itemize}
\item Entering PsPM
\begin{itemize}
\item Entering PsPM is now hybrid based on the version of MATLAB, namely through AppDesigner or Guide. PsPM will be entered through AppDesigner when supported and through Guide for older versions of MATLAB. To call PsPM, users should still use the command \texttt{pspm} in the Command Window of MATLAB, where the appropriate way of entering PsPM will be recognised automatically.
\item Users can still use their preferred way to enter PsPM. To enter PsPM through AppDesigner, please type \texttt{pspm\_appdesigner}. To enter PsPM through Guide, which is the classic entrance, please type \texttt{pspm\_guide}.
\item The AppDesigner version of PsPM UI is newly introduced by MATLAB and the encouraged way for launching PsPM, and it has no functionality difference than the Guide version of PsPM UI.
\item Both AppDesigner and Guide are designed and tested for Windows, macOS (either Intel or Apple Silicon) and Linux. Issues of opening PsPM through either of the two UI systems are encouraged to be reported to PsPM developing group at GitHub.
\end{itemize}
\item Introducing \texttt{pspm\_options}
\begin{itemize}
\item A new function \texttt{pspm\_options} is introduced to PsPM for controlling the default and acceptable values of the struct \texttt{options} used by most PsPM functions. The default values of the fields in the struct \texttt{options} for various functions can be directly checked by searching in \texttt{pspm\_options}.
\item The default values in \texttt{pspm\_options} have been checked and tested for PsPM. If preferred values are different from defaults, users can specify them when calling the corresponding PsPM functions, and the corresponding functions and \texttt{pspm\_options} will always respect the users' specification with the highest priority. However, the user's specification needs to satisfy the condition set in \texttt{pspm\_options}, and invalid values may be reported as errors.
\end{itemize}
\item UI Improvements
\begin{itemize}
\item The UI for the following features has been improved and tested
\begin{itemize}
\item Launchpad (AppDesigner)
\item Launchpad (Guide)
\item Batch editor
\item Display data
\item Contrast manager
\end{itemize}
\end{itemize}
\item Help text
\begin{itemize}
\item The help text has been updated for all PsPM functions. Help text can be checked by right clicking the functions.
\end{itemize}
\end{itemize}
\subsection*{Bug Fixes}
\begin{itemize}
\item UI
\begin{itemize}
\item A bug that used to make PsPM crash when \textit{Pupil size convert} and \textit{Gaze convert} in \textit{Data Preprocessing} were selected has been fixed.
\item A bug that leads to error when PsPM is started offline has been fixed.
\item A bug that leads to incorrect x labels in \texttt{pspm\_rev\_dcm} has been fixed.
\end{itemize}
\item \texttt{pspm\_convert\_...}
\begin{itemize}
\item A bug that leads PsPM to crash, which is caused by outdated UI calling for \texttt{pspm\_convert\_...} functions, has been fixed.
\end{itemize}
\item \texttt{pspm\_get\_eyelink}
\begin{itemize}
\item A bug that causes issues when importing eye link data that is scanned at both left and right sides has been fixed.
\end{itemize}
\item \texttt{pspm\_glm}
\begin{itemize}
\item A bug that incorrectly identifies the NaNs in the input data has been fixed.
\end{itemize}
\item \texttt{pspm\_sf}
\begin{itemize}
\item A bug that has lead to incorrect input datafile assigning has been fixed.
\item A bug that leads PsPM crash when \texttt{pspm\_sf} is analysing data with missing epochs has been fixed.
\item A bug that leads to error when \texttt{pspm\_sf} analyses data where \texttt{time unit} is defined as \texttt{marker} has been fixed.
\end{itemize}
\item \texttt{pspm\_split\_sessions}
\begin{itemize}
\item \texttt{pspm\_split\_sessions} now considers \texttt{marker\_chan\_num} when calling \texttt{pspm\_trim}.
\end{itemize}
\end{itemize}

\subsection*{Improvements}
\begin{itemize}
\item \texttt{channel}
\begin{itemize}
\item We have generalised \texttt{channel} related variables throughout PsPM, which are given as
\begin{itemize}
\item \texttt{chan/channel} to \texttt{channel}
\item \texttt{chans/channels} to \texttt{channels}
\item \texttt{channel\_units/channels\_units/chan\_units/chans\_units} to \texttt{channel\_units}
\item \texttt{chan\_combine} to \texttt{channel\_combine}
\item \texttt{chan\_action} to \texttt{channel\_action}
\item \texttt{channels\_header} to \texttt{channel\_header}
\item \texttt{chantype} to \texttt{channeltype}
\end{itemize}
\end{itemize}
\item \texttt{import\_eyelink}
\begin{itemize}
\item Improved \texttt{import\_eyelink} for adding some support for importing eyelink data converted by higher version of .EDF files.
\end{itemize}
\item \texttt{pspm\_con2}
\begin{itemize}
\item \texttt{pspm\_con2} is now using \texttt{pspm\_overwrite}.
\end{itemize}
\item \texttt{pspm\_dcm} and \texttt{pspm\_dcm\_inv}
\begin{itemize}
\item \texttt{.flexevents} and \texttt{.fixevents} are now fields of \texttt{model} instead of \texttt{options}.
\item \texttt{pspm\_dcm} now uses \texttt{pspm\_get\_timing} to handle missing epochs.
\item Improved missing epoch support
\begin{itemize}
\item The field \texttt{.missing} is now allocated from \texttt{options} to \texttt{model}.
\item \texttt{.missing\_data} is used to load missing epoch data that was loaded from dcm, as an optional field.
\end{itemize}
\item The index is changed so that the first event will not be excluded when at time 0 in session.
\end{itemize}
\item \texttt{pspm\_extract\_segments}
\begin{itemize}
\item The first channel is always referred by \texttt{marker\_chan} as default.
\end{itemize}
\item \texttt{pspm\_glm}
\begin{itemize}
\item The fallback for \texttt{options.exclude\_missing} has been set for \texttt{pspm\_glm}, which is not to exclude any missing epochs.
\item A bug that leads to incorrect missing epoch checking has been fixed.
\item Help text was updated.
\item \texttt{marker\_chan\_num} now refers to the first marker channel as default.
\item \texttt{pspm\_glm} now uses \texttt{pspm\_get\_timing} to handle missing epochs.
\end{itemize}
\item \texttt{pspm\_interp1}
\begin{itemize}
\item \texttt{pspm\_interp1} now considers the data where no valid values are detected and interpolation is not possible, and warnings will be reported in this case.
\end{itemize}
\item \texttt{pspm\_merge}
\begin{itemize}
\item The default value is set to be [1,2], meaning the first channel will be merged as the default option.
\end{itemize}
\item \texttt{pspm\_prepdata}
\begin{itemize}
\item \texttt{pspm\_prepdata} now uses interpolation to handle data with \texttt{NaN}.
\begin{itemize}
\item Data that begins and/or ends with \texttt{NaN} will be filled with the first/last non-\texttt{NaN} values in those positions.
\end{itemize}
\end{itemize}
\item \texttt{pspm\_sf}
\begin{itemize}
\item \texttt{pspm\_sf} now supports missing epochs.
\begin{itemize}
\item Now allow input with \texttt{NaN} that indicates missing epochs.
\item Missing epochs can be specified with options.missing or the automatic \texttt{NaN} detection.
\item Missing epochs will be verified with \texttt{options.missingthresh}.
\item When the missing epochs are longer than 2s, the result out will be converted to \texttt{[]}.
\item The UI of SF analysis now allows using missing epochs from files or not to define any missing epochs.
\end{itemize}
\item \texttt{pspm\_sf} now uses \texttt{pspm\_get\_timing} to handle missing epochs.
\item \texttt{marker\_chan\_num} now refers to the first marker channel as default.
\end{itemize}
\item \texttt{pspm\_sf\_dcm}
\begin{itemize}
\item \texttt{pspm\_sf\_dcm} now uses \texttt{pspm\_interp1} for interpolating data.
\end{itemize}
\item \texttt{pspm\_text}
\begin{itemize}
\item The Matlab file that stores the information of help text \texttt{pspm\_text.mat} will be stored inside the source folder of PsPM and will be deleted when PsPM is quit.
\end{itemize}
\item \texttt{pspm\_trim}
\begin{itemize}
\item \texttt{marker\_chan\_num} now refers to the first marker channel as default.
\end{itemize}
\end{itemize}

\subsection*{Minor Adjustments}
\begin{itemize}
\item \texttt{pspm\_sf}, \texttt{pspm\_glm} and \texttt{pspm\_dcm}.
\begin{itemize}
\item The option \texttt{marker\_chan\_num\_event} is removed.
\item In default, the first marker channel / event channel is always selected and no users' customisation is allowed.
\item The last data channel / wave channel is always selected.
\end{itemize}
\end{itemize}
\subsection*{Reference document}
\begin{itemize}
\item New document \textit{PsPM Reference} for checking the default values and restrictions of \texttt{options} fields.
\end{itemize}

\bibliographystyle{pnas2009}
\bibliography{PsPM}

Expand Down
20 changes: 13 additions & 7 deletions src/Import/smi/import_smi.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@
%__________________________________________________________________________
%
% (C) 2019 Laure Ciernik
% Updated 2021 Teddy Chao
% Updated 2023 Teddy Chao

%% Initialise
global settings
if isempty(settings)
pspm_init;
end

if isempty(varargin)
error('ID:invalid_input', 'import_SMI.m needs at least one input sample_file.');
Expand Down Expand Up @@ -147,13 +153,13 @@
l_eye = any(cell2mat(cellfun(@(x)strcmpi(x,'LEFT'),format_fields,'UniformOutput',0)));
r_eye = any(cell2mat(cellfun(@(x)strcmpi(x,'RIGHT'),format_fields,'UniformOutput',0)));
if l_eye && r_eye
eyesObserved = 'LR';
eyesObserved = settings.eye.cap.b;
% 'LR' means both the left and right eyes are observed,
% and it has no meaning of combining left and right eyes.
elseif l_eye
eyesObserved = 'L';
eyesObserved = settings.eye.cap.l;
else
eyesObserved = 'R';
eyesObserved = settings.eye.cap.r;
end
% Stimulus dimension
sd_pos = strncmpi(header_sample, '## Stimulus Dimension',21);
Expand Down Expand Up @@ -278,7 +284,7 @@
ignore_str_pos{1}=cell(4,1);
ignore_str_pos{2}=cell(4,1);

if strcmpi(eyesObserved, 'LR')
if strcmpi(eyesObserved, settings.eye.cap.b)
% alwas add the time of the beginning of the current trial
% since the measured start and end times are relative to the
% time of the beginning ot the current trial
Expand All @@ -300,7 +306,7 @@
[ignore_str_pos{2}{3},ignore_str_pos{2}{4}]=get_idx(times,start_saccade_r,end_saccade_r);


elseif strcmpi(eyesObserved, 'L')
elseif strcmpi(eyesObserved, settings.eye.cap.l)
start_blink = eventsRaw.blink_l.start(blink_l_trial_sess);%+time;
end_blink = eventsRaw.blink_l.end(blink_l_trial_sess)+time;
start_saccade = eventsRaw.sacc_l.start(sacc_l_trial_sess);%+time;
Expand Down Expand Up @@ -368,7 +374,7 @@
% save column heder of raw data
raw_columns = columns;
data{sn}.raw_columns = raw_columns;
if strcmpi(data{sn}.eyesObserved, 'LR')
if strcmpi(data{sn}.eyesObserved, settings.eye.cap.b)
% pupilL, pupilR, xL, yL, xR, yR, blinkL, blinkR, saccadeL,
% saccadeR
% get idx of different channel
Expand Down
Binary file modified src/ext/matlabbatch/cfg_ui.fig
Binary file not shown.
4 changes: 3 additions & 1 deletion src/ext/matlabbatch/cfg_ui.m
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ function local_showjob(obj,cjob)
set(findobj(handles.cfg_ui,'-regexp', 'Tag','.*(Del)|(Repl)Mod$'),'Enable','on');
mrk = cell(size(sts));
[mrk{dep}] = deal('DEP');
[mrk{~sts}] = deal('X');
[mrk{~sts}] = deal('<- X');
[mrk{~dep & sts}] = deal('');
str = cfg_textfill(handles.modlist, str, mrk, false);
end;
Expand Down Expand Up @@ -528,6 +528,8 @@ function cfg_ui_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for cfg_ui
handles.output = hObject;

pspm_ui(hObject, handles, 'cfg_ui');

% Update handles structure
guidata(hObject, handles);

Expand Down
2 changes: 1 addition & 1 deletion src/ext/matlabbatch/cfg_ui_util.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
end;
end;
else
datastr = 'X';
datastr = '<- X';
end;
namestr = sprintf('%s%s ', indent, contents{1});
varargout{1} = namestr;
Expand Down
Binary file removed src/pspm.fig
Binary file not shown.
Binary file modified src/pspm_appdesigner.mlapp
Binary file not shown.
5 changes: 3 additions & 2 deletions src/pspm_contrast.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function pspm_contrast_OpeningFcn(hObject, eventdata, handles, varargin)
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to pspm_contrast (see VARARGIN)

[hObject, handles] = pspm_ui(hObject, handles, 'contrast');


% Left alignment of text fields
set(handles.textStatus,'HorizontalAlignment','left')
Expand All @@ -80,7 +80,8 @@ function pspm_contrast_OpeningFcn(hObject, eventdata, handles, varargin)

% Choose default command line output for pspm_contrast
handles.output = hObject;

% Apply UI
pspm_ui(hObject, handles, 'contrast');
% Update handles structure
guidata(hObject, handles);

Expand Down
Binary file modified src/pspm_display.fig
Binary file not shown.
22 changes: 11 additions & 11 deletions src/pspm_get_eyelink.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
% -------------------------------------------------------------------------
addpath(pspm_path('backroom'));
for i = 1:numel(data)-1
if strcmpi(data{i}.eyesObserved, settings.eye.left)
if strcmpi(data{i}.eyesObserved, settings.eye.char.l)
mask_chans = {'blink_l', 'saccade_l'};
elseif strcmpi(data{i}.eyesObserved, settings.eye.right)
elseif strcmpi(data{i}.eyesObserved, settings.eye.char.r)
mask_chans = {'blink_r', 'saccade_r'};
elseif strcmpi(data{i}.eyesObserved, settings.eye.bilateral)
elseif strcmpi(data{i}.eyesObserved, settings.eye.char.b)
mask_chans = {'blink_l', 'blink_r', 'saccade_l', 'saccade_r'};
else
warning('ID:invalid_input', ['No valid eye marker is detected, please check input channels.']);
Expand Down Expand Up @@ -312,15 +312,15 @@
if ~isempty(regexpi(import{k}.type, ['_[', settings.lateral.char.c, ']'], 'once'))
if size(n_blink, 2) > 1
eye_t = regexp(import{k}.type, ['.*_([', settings.lateral.char.c, '])'], 'tokens');
n_eye_blink = n_blink(strcmpi(eye_t{1}, {settings.eye.left, settings.eye.right}));
n_eye_blink = n_blink(strcmpi(eye_t{1}, {settings.eye.char.l, settings.eye.char.r}));
else
n_eye_blink = n_blink;
end
sourceinfo.chan_stats{k}.blink_ratio = n_eye_blink / n_data;

if size(n_saccade, 2) > 1
eye_t = regexp(import{k}.type, ['.*_([',settings.lateral.char.c,'])'], 'tokens');
n_eye_saccade = n_saccade(strcmpi(eye_t{1}, {settings.eye.left, settings.eye.right}));
n_eye_saccade = n_saccade(strcmpi(eye_t{1}, {settings.eye.char.l, settings.eye.char.r}));
else
n_eye_saccade = n_saccade;
end
Expand All @@ -340,20 +340,20 @@
left_occurance = any(cell2mat(cellfun(@(x) ~isempty(regexpi(x.type, '_l', 'once')), import,'UniformOutput',0)));
right_occurance = any(cell2mat(cellfun(@(x) ~isempty(regexpi(x.type, '_r', 'once')), import,'UniformOutput',0)));
if left_occurance && right_occurance
sourceinfo.eyesObserved = settings.eye.bilateral;
sourceinfo.eyesObserved = settings.eye.char.b;
elseif left_occurance && ~right_occurance
sourceinfo.eyesObserved = settings.eye.left;
sourceinfo.eyesObserved = settings.eye.char.l;
else
sourceinfo.eyesObserved = settings.eye.right;
sourceinfo.eyesObserved = settings.eye.char.r;
end

% determine best eye
switch sourceinfo.eyesObserved
case settings.eye.left
case settings.eye.char.l
sourceinfo.best_eye = sourceinfo.eyesObserved;
case settings.eye.right
case settings.eye.char.r
sourceinfo.best_eye = sourceinfo.eyesObserved;
case settings.eye.bilateral
case settings.eye.char.b
eye_stat = Inf(1,2);
eye_choice = pspm_eye(sourceinfo.eyesObserved, 'char2cell');
for i = 1:2
Expand Down
Loading

0 comments on commit ccbf3c8

Please sign in to comment.