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

add VBR_save function, add handling of temporary files in tests #82

Merged
merged 3 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ vbr/temp
Projects/1_LabData/1_Attenuation/not_used/
*.m~
*.idea
.vbr_test_data_dir
23 changes: 23 additions & 0 deletions docs/_pages/gettingstarted/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,26 @@ VBR.out.anelastic.eburgers_psp.V % anelastic-dependent seismic shear wave veloci
VBR.out.viscous.HZK2011.eta_total % composite steady state creep viscosity
```
As noted above, any frequency dependence is stored in an additional dimension. For example, if ```size(VBR.in.SV.T)``` is (50,100) and ```numel(VBR.in.SV.f)``` is 3, then ```size(VBR.out.anelastic.eburgers_psp.V)``` will be (50,100,3).


## 7. Saving results

To save your results, you can manually save the ```VBR``` structure as usual in MATLAB. You can, however, also
use the `VBR_save` function:

```matlab
VBR_save(VBR, "my_vbrc_results.mat")
```

This function is useful to ensure that the ```VBR``` structure is saved following in
chrishavlin marked this conversation as resolved.
Show resolved Hide resolved
a standardized way, which at present is mainly useful for loading ```VBRc```
output in the Python wrapper of the VBRc, ```pyVBRc```([link](https://github.com/vbr-calc/pyVBRc)).

Additionally, `VBR_save` allows you to easily exclude the `VBR.in.SV` structure from the saved file:

```matlab
VBR_save(VBR, "my_vbrc_results_without_SV.mat", 1)
```

This can be useful if you wish to save disk space and instead reconstruct your state variables
on re-load (which you must do manually!).
3 changes: 3 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# v1.1.3

## New Features
* add a `VBR_save` function for saving `VBR` structures
* add framework for handling temporary files in test suite
21 changes: 21 additions & 0 deletions vbr/testing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,24 @@ whether or not some code runs without error, then your function should always re

If you are adding a test that is not compatible with octave, add the test function name
to the test configuration in the `get_config.m` file.

### saving data during tests

If you want to save data as part of running your test, save files to the directory in the
`vbr_test_data_dir` field of the configuration structure returned by `get_config()`. This
ensures that any temporary tests files are cleared after running the tests. To use it, you
can do the following within a test:

```
test_config = get_config();
save_dir = test_config.vbr_test_data_dir;
fname = fullfile(save_dir, "my_test_file.mat");
```

No need to delete the file within the test, this is done automatically in `run_tests.m`.

The default directory for the temporary files is `.vbr_test_data_dir` (which will
be created on first run). To change the default, you can set the environment variable
`VBR_TEST_DATA_DIR` to any path you like (in bash or zsh,
`export VBR_TEST_DATA_DIR=/my/preferred/path`) and a `.vbr_test_data_dir` subdirectory
will be created there instead.
12 changes: 12 additions & 0 deletions vbr/testing/get_config.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,16 @@
% as a matlab-only test.
test_config.matlab_only = {'test_matlab_only_test_trigger';};

% directory for temporary files generated by tests
vbr_test_data_dir = getenv("VBR_TEST_DATA_DIR");
if numel(vbr_test_data_dir) == 0
vbr_test_data_dir = fullfile(".", ".vbr_test_data_dir");
else
vbr_test_data_dir = fullfile(vbr_test_data_dir, ".vbr_test_data_dir");
end
if exist(vbr_test_data_dir, 'dir') == 0
mkdir(vbr_test_data_dir)
end
test_config.vbr_test_data_dir = vbr_test_data_dir;

end
10 changes: 9 additions & 1 deletion vbr/testing/run_tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,15 @@
end
end


% cleanup
test_files_to_clean = dir(test_config.vbr_test_data_dir);
for ifile = 1:numel(test_files_to_clean)
maybe_fi = test_files_to_clean(ifile);
if maybe_fi.isdir == 0
fname = fullfile(maybe_fi.folder, maybe_fi.name);
delete(fname);
end
end
end

function [TestResults,failedCount, SkippedTests, ErrorMessages] = runTheMfiles(mfiles, test_config)
Expand Down
24 changes: 24 additions & 0 deletions vbr/testing/test_vbr_get_config.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function TestResult = test_vbr_get_config()
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check that the save function works
% TestResult struct with fields:
% .passed True if passed, False otherwise.
% .fail_message Message to display if false
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

TestResult.passed = true;
TestResult.fail_message = '';

test_config = get_config();

expected_fields = {"matlab_only"; "vbr_test_data_dir";};
for ifield = 1:numel(expected_fields)
if ~isfield(test_config, expected_fields{ifield})
msg = [' test_config is missing ', expected_fields{ifield}, ' field'];
TestResult.passed = false;
TestResult.fail_message = msg;
disp(msg)
end
end

end
53 changes: 53 additions & 0 deletions vbr/testing/test_vbr_save.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
function TestResult = test_vbr_save()
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check that the save function works
% TestResult struct with fields:
% .passed True if passed, False otherwise.
% .fail_message Message to display if false
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

TestResult.passed = true;
TestResult.fail_message = '';

VBR.in.elastic.methods_list={'anharmonic';'anh_poro'};
VBR.in.anelastic.methods_list={'xfit_premelt'};

% frequencies to calculate at
VBR.in.SV.f = [0.01,0.1];

% Define the Thermodynamic State
VBR.in.SV.T_K=linspace(500,1400,10)+273;
sz=size(VBR.in.SV.T_K);
VBR.in.SV.P_GPa = 2 * ones(sz); % pressure [GPa]
VBR.in.SV.T_K = 1473 * ones(sz); % temperature [K]
VBR.in.SV.rho = 3300 * ones(sz); % density [kg m^-3]
VBR.in.SV.sig_MPa = 10 * ones(sz); % differential stress [MPa]
VBR.in.SV.dg_um = 0.01 * 1e6 * ones(sz); % grain size [um]
VBR.in.SV.Tsolidus_K=1200*ones(sz); % solidus
VBR.in.SV.phi = 0.0 * ones(sz); % melt fraction

VBR = VBR_spine(VBR);
test_config = get_config();
save_dir = test_config.vbr_test_data_dir;

save_file = fullfile(save_dir, "test_vbr_save.mat");
VBR_save(VBR, save_file)
VBR_loaded = load(save_file);
if sum(VBR.in.SV.T_K == VBR_loaded.in.SV.T_K) ~= sz
msg = [' saved VBR structure does not match'];
TestResult.passed = false;
TestResult.fail_message = msg;
disp(msg)
end

save_file = fullfile(save_dir, "test_vbr_save_no_SV.mat");
VBR_save(VBR, save_file, 1)
VBR_loaded = load(save_file);
if isfield(VBR_loaded.in, 'SV')
msg = [' saved VBR structure should not contain SV when excluded.'];
TestResult.passed = false;
TestResult.fail_message = msg;
disp(msg)
end

end
2 changes: 0 additions & 2 deletions vbr/testing/test_vbrcore_002.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
% Define the Thermodynamic State
VBR.in.SV.T_K=linspace(500,1400,100)+273;
sz=size(VBR.in.SV.T_K);
n1 = 3;
n2 = 5;
VBR.in.SV.P_GPa = 2 * ones(sz); % pressure [GPa]
VBR.in.SV.T_K = 1473 * ones(sz); % temperature [K]
VBR.in.SV.rho = 3300 * ones(sz); % density [kg m^-3]
Expand Down
43 changes: 43 additions & 0 deletions vbr/vbrCore/functions/io_functions/VBR_save.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
function VBR_save(VBR, fname, exclude_SVs)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Save a VBR structure to disk.
%
% Parameters
% ----------
% VBR
% the VBR structure to save
% fname
% the filename, will append .mat if not present
% exclude_SVs
% set to 1 to exclue VBR.in.SV from save file. Useful for
% reducing disk-space when saving multiple results.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if exist('exclude_SVs','var') && exclude_SVs == 1
VBRout = struct();

% copy input fields except for VBR.in.SV
flds = fieldnames(VBR.in);
for ifield = 1:numel(flds)
if ~strcmp(flds{ifield}, 'SV')
VBRout.in.(flds{ifield}) = VBR.in.(flds{ifield});
end
end

% copy remaining
flds = fieldnames(VBR);
for ifield = 1:numel(flds)
if ~strcmp(flds{ifield}, 'in')
VBRout.(flds{ifield}) = VBR.(flds{ifield});
end
end
else
VBRout = VBR;
end

isOctave = is_octave();
if isOctave
save(fname, "-struct", "VBRout", "-mat-binary");
else
save(fname, "-struct", "VBRout");
end
end