Rigbox icon indicating copy to clipboard operation
Rigbox copied to clipboard

Error when 0 or 1 global params

Open k1o0 opened this issue 5 years ago • 0 comments

The following experiment definition will reproduce the error:

function parsBug(~, evts, p, ~, ~, ~, ~)
%% Parameters bug
%  This function demonstrates a bug whereby the experiment fails when there
%  is 1 or 0 global paramters and one or more conditional parameters
%  (excluding numRepeats).  The error occurs of line 13 of
%  util/mergeStruct.m:
%    data = [struct2cell(src); struct2cell(dst)];
%
%    Error using vertcat
%    Dimensions of matrices being concatenated are not consistent.
%
% Tested only on exp.test

% When the following line is un-commented (i.e. there is > 2 global
% parameters) the experiment works.
% p.glob; 

% Define a conditional parameter
A = p.A; %#ok<NASGU>

% Add minimal required structure for example
evts.endTrial = evts.newTrial.delay(1);

try
  p.A = [true, true]; % A conditional parameter
  p.glob = true; % A global parameter
catch
end
end

The issue appears to be an indexing problem. mergeStruct is called by scan, which is set up in the constructor of SignalsExp: https://github.com/cortex-lab/Rigbox/blob/5ccf2be06b777bdb900b9532247298a5a5271516/%2Bexp/trialConditions.m#L22-L25

where allCondPars is a signal containing a nonscalar struct of trial condition parameters and condPar should be a signal containing a single scalar struct of condition parameters for the current trial. The error occurs because for some reason the value of condPar ends up being a nonscalar:

>> src, dst

src = 
  1×17 struct array with fields:
    A

dst = 
  struct with fields:
    expRef: '2019-08-12_1_fake'

I've failed to reproduce this error in the command line with the following:

parsStruct = exp.inferParameters(@parsBug);
parsStruct.expRef = dat.constructExpRef('fake', now, 1);

[~, gpars, cpars] = toConditionServer(exp.Parameters(parsStruct)); % Assort for experiment
[advanceTrial, globalPars, allCondPars] = sig.create; % Create some origin signals
[pars, hasNext, repeatNum] = exp.trialConditions(globalPars, allCondPars, advanceTrial);

globalPars.post(rmfield(gpars,'defFunction')); % Post global parameters struct (scalar)
allCondPars.post(cpars); % Post conditional parameters struct (nonscalar)

advanceTrial.post(true) % Advance the trial to trigger merge

k1o0 avatar Aug 13 '19 07:08 k1o0