Skip to content

Commit 94cf13f

Browse files
authored
Param profiles test (#244)
* tests and documentation for *paramProfile functions; repos created when none exist * CHANGELOG
1 parent 1577ccc commit 94cf13f

File tree

4 files changed

+108
-24
lines changed

4 files changed

+108
-24
lines changed

+dat/loadParamProfiles.m

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
function p = loadParamProfiles(expType)
22
%DAT.LOADPARAMPROFILES Loads the parameter sets for given experiment type
3-
% TODO
3+
% Loads a struct of parameter structures from a MAT file called
4+
% 'parameterProfiles'. Each field of this struct is a parameter set name
5+
% for a given expType. Parameters of a given expType can be saved using
6+
% the DAT.SAVEPARAMPROFILE function.
7+
%
8+
% Input:
9+
% expType (char): The name of the experiment type, e.g. ChoiceWorld.
10+
%
11+
% Output:
12+
% p (struct): a scalar struct of parameter sets for the given
13+
% experiment type. Each fieldname holds a different parameter
14+
% structure. The fields are sorted in ASCII dictionary order.
15+
%
16+
% Example:
17+
% dat.saveParamProfile('ChoiceWorld', 'defSet', exp.choiceWorldParams)
18+
% profiles = dat.loadParamProfiles('ChoiceWorld');
19+
% p = exp.Parameters(profiles.defSet);
20+
%
21+
% See also DAT.SAVEPARAMPROFILE, DAT.PATHS
422
%
523
% Part of Rigbox
624

+dat/saveParamProfile.m

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,49 @@
11
function saveParamProfile(expType, profileName, params)
22
%DAT.SAVEPARAMPROFILE Stores the named parameters for experiment type
3-
% TODO
4-
% - Figure out how to save struct without for-loop in 2016b!
3+
% Saves a parameter structure in a MAT file called 'parameterProfiles'.
4+
% Each field of this struct is an expType, and each nested field
5+
% is the set name. Parameters of a given expType can be loaded using the
6+
% DAT.LOADPARAMPROFILES function.
7+
%
8+
% Inputs:
9+
% expType (char): The name of the experiment type, e.g. ChoiceWorld.
10+
% profileName (char): The name of the parameter set being saved. If
11+
% the name already exists in the file for a given expType, it is
12+
% overwritten.
13+
% params (struct): A parameter structure to be saved.
14+
%
15+
% Example:
16+
% dat.saveParamProfile('ChoiceWorld', 'defSet', exp.choiceWorldParams)
17+
% profiles = dat.loadParamProfiles('ChoiceWorld');
18+
% p = exp.Parameters(profiles.defSet);
19+
%
20+
% See also DAT.LOADPARAMPROFILES, DAT.PATHS
21+
%
522
% Part of Rigbox
623

724
% 2013-07 CB created
825
% 2017-02 MW adapted to work in 2016b
926

10-
%path to repositories
27+
% If main repo folders don't exist yet, create them
28+
repos = dat.reposPath('main');
29+
cellfun(@mkdir, repos(~file.exists(repos)))
30+
31+
% Path to repository files
1132
fn = 'parameterProfiles.mat';
12-
repos = fullfile(dat.reposPath('main'), fn);
33+
repos = fullfile(repos, fn);
1334

14-
%load existing profiles for specified expType
35+
% Load existing profiles for specified expType
1536
profiles = dat.loadParamProfiles(expType);
16-
%add (or replace) the params with a field named by profile
37+
% Add (or replace) the params with a field named by profile
1738
profiles.(profileName) = params;
18-
%wrap in a struct for saving
39+
% Wrap in a struct for saving
1940
set = struct;
2041
set.(expType) = profiles;
2142

22-
%save the updated set of profiles to each repos
23-
%where files exist already, append
24-
% cellfun(@(p) save(p, '-struct', 'set', '-append'),
25-
% file.filterExists(repos, true)); % Had to change her to a for loop, sorry
26-
% Chris!
27-
p = file.filterExists(repos, true);
28-
for i = 1:length(p)
29-
save(p{i}, '-struct', 'set', '-append')
30-
end
31-
%and any that don't we should create from scratch
32-
p = file.filterExists(repos, false);
33-
for i = 1:length(p)
34-
save(p{i}, '-struct', 'set')
35-
end
36-
% cellfun(@(p) save(p, '-struct', 'set'), file.filterExists(repos, false));
43+
% Save the updated set of profiles to each repos where files exist already,
44+
% append
45+
saveFn = @(p,name,varargin) save(p, '-struct', 'name', varargin{:});
46+
cellfun(@(p) saveFn(p, set, '-append') , file.filterExists(repos, true));
3747

38-
end
48+
% Any that don't we should create from scratch
49+
cellfun(@(p) saveFn(p, set), file.filterExists(repos, false));

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Starting after Rigbox 2.2.0, this file contains a curated, chronologically order
2424
- correct behaviour when listening to already running experiments `32a2a17` 2019-12-18
2525
- added support for remote error ids in srv.StimulusControl `9d31eea` 2019-11-27
2626
- added tests for eui.ExpPanel `572463c` 2020-01-28
27+
- added tests for *paramProfile functions + no error when saving into new repo `72b04fa` 2010-01-30
2728

2829
## [2.4.1]
2930

tests/dat_test.m

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,60 @@ function test_expExists(testCase)
322322
testCase.verifyTrue(dat.expExists(refs{1}))
323323
end
324324

325+
function test_saveParamProfile(testCase)
326+
% Test saving files when repo folder doesn't yet exist
327+
repos = dat.reposPath('main');
328+
rmdir(repos{1}) % Delete local repo
329+
330+
% Full path to expected files
331+
fn = 'parameterProfiles.mat';
332+
repos = fullfile(repos, fn);
333+
334+
% Test saving some defaults with a given name:
335+
name = 'testName';
336+
expType = 'ChoiceWorld';
337+
dat.saveParamProfile(expType, name, exp.choiceWorldParams)
338+
actual = cellfun(@load, repos); % Load from both locations
339+
for i = 1:length(actual) % Check saved
340+
testCase.verifyEqual(fieldnames(actual(i)), {expType}, 'Failed to append to current file')
341+
testCase.verifyEqual(fieldnames(actual(i).(expType)), {name}, 'Failed to save under given name')
342+
testCase.verifyEqual(actual(i).(expType).(name).type, expType)
343+
end
344+
345+
% Test saving another param profile. Nothing should be overwritten.
346+
name = 'another';
347+
types = {expType; 'BarMapping'};
348+
dat.saveParamProfile(types{end}, name, exp.barMappingParams)
349+
actual = cellfun(@load, repos); % Load from both locations
350+
for i = 1:length(actual) % Check saved
351+
testCase.verifyEqual(fieldnames(actual(i)), types, 'Failed to append to current file')
352+
testCase.verifyEqual(fieldnames(actual(i).(types{end})), {name}, 'Failed to save under given name')
353+
testCase.verifyEqual(actual(i).(types{end}).(name).type, types{end})
354+
end
355+
end
356+
357+
function test_loadParamProfiles(testCase)
358+
% Test loading a specific parameter profile from file
359+
fn = 'parameterProfiles.mat';
360+
repo = fullfile(dat.reposPath('main', 'master'), fn);
361+
362+
name = 'testSet';
363+
expType = 'ChoiceWorld';
364+
set.(expType).testSet = exp.choiceWorldParams;
365+
set.BarMapping.anotherSet = exp.barMappingParams;
366+
save(repo, '-struct', 'set')
367+
368+
% Test loading existing
369+
profiles = dat.loadParamProfiles(expType);
370+
testCase.verifyEqual(fieldnames(profiles), {name}, 'Failed to load profile')
371+
testCase.verifyEqual(profiles.(name).type, expType)
372+
373+
% Test loading non-existing exp type
374+
profiles = testCase.verifyWarningFree(@()dat.loadParamProfiles('fake'));
375+
expected = isstruct(profiles) && isempty(fieldnames(profiles));
376+
testCase.verifyTrue(expected)
377+
end
378+
325379
end
326380

327381
methods (Access = private)

0 commit comments

Comments
 (0)