-
Notifications
You must be signed in to change notification settings - Fork 73
/
jsave.m
146 lines (130 loc) · 4.79 KB
/
jsave.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
function varargout = jsave(filename, varargin)
%
% jsave
% or
% jsave(fname)
% varlist=jsave(fname,'param1',value1,'param2',value2,...)
%
% Store variables in a workspace to a JSON or binary JSON file
%
% authors:Qianqian Fang (q.fang <at> neu.edu)
% created on 2020/05/31
%
% input:
% fname: (optional) output file name; if not given, save to 'default.pmat'
% if fname has a '.json' or '.jdt' suffix, a text-based
% JSON/JData file will be created (slow); if the suffix is '.pmat' or
% '.jdb', a Binary JData (https://github.com/NeuroJSON/bjdata/) file will be created.
% opt: (optional) a struct to store parsing options, opt can be replaced by
% a list of ('param',value) pairs - the param string is equivalent
% to a field in opt. opt can have the following
% fields (first in [.|.] is the default)
%
% ws ['caller'|'base']: the name of the workspace in which the
% variables are to be saved
% vars [{'var1','var2',...}]: cell array of variable names to be saved
% matlab [0|1] if set to 1, use matlab's built-in jsonencode to
% store encoded data to a json file; output file
% must have a suffix of .jdt
%
% all options for savebj/savejson (depends on file suffix)
% can be used to adjust the output unless "'matlab',1" is used
%
% output:
% varlist: a list of variables loaded
%
% examples:
% jsave % save all variables in the 'caller' workspace to jamdata.pmat
% jsave('mydat.pmat','vars', {'v1','v2',...}) % save selected variables
% jsave('mydat.pmat','compression','lzma')
%
% license:
% BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details
%
% -- this function is part of JSONLab toolbox (http://openjdata.org/jsonlab)
%
if (nargin == 0)
filename = [pwd filesep 'default.pmat'];
end
opt = varargin2struct(varargin{:});
if (~isfield(opt, 'nthread'))
opt.nthread = 4;
end
if (~isfield(opt, 'compression'))
if (exist('zipmat'))
opt.compression = 'blosc2zstd';
else
opt.compression = 'zlib';
end
end
if (~isfield(opt, 'shuffle'))
opt.shuffle = 1;
end
if (~isfield(opt, 'typesize'))
opt.typesize = 4;
end
ws = jsonopt('ws', 'caller', opt);
allvar = evalin(ws, 'whos');
varlist = jsonopt('vars', {allvar.name}, opt);
[isfound, dontsave] = ismember(varlist, {allvar.name});
if (any(isfound == 0))
error('specified variable is not found');
end
header = struct;
body = struct;
metadata = struct('CreateDate', datestr(now, 29), ...
'CreateTime', datestr(now, 'hh:mm:ss'), ...
'OriginalName', filename, ...
'BJDataVersion', 'v1_draft-2');
vers = ver('MATLAB');
if (isempty(vers))
vers = ver('Octave');
[verstr, releasedate] = version;
vers.Release = verstr;
vers.Date = releasedate;
end
metadata.CreatorApp = vers.Name;
metadata.CreatorVersion = vers.Version;
metadata.CreatorRelease = vers.Release;
metadata.ReleaseDate = vers.Date;
metadata.FormatVersion = 1;
metadata.Parameters = opt;
header.(encodevarname('_DataInfo_')) = metadata;
for i = 1:length(varlist)
header.(varlist{i}) = allvar(dontsave(i));
body.(varlist{i}) = evalin(ws, varlist{i});
end
if (nargout == 1)
varargout{1} = header;
end
defaultopt = {'compression', opt.compression, 'nthread', opt.nthread, ...
'shuffle', opt.shuffle, 'typesize', opt.typesize, 'keeptype', 1, 'array2struct', 1};
if (jsonopt('matlab', 0, opt) && exist('jsonencode', 'builtin'))
if (isempty(regexp(filename, '\.[jJ][sS][oO][nN]$', 'once')))
filename = regexprep(filename, '\.[a-zA-Z]+$', '.jdt');
end
output.WorkspaceHeader = jdataencode(header, 'prefix', 'x', 'base64', 1, varargin{:});
headerjson = jsonencode(output);
clear output;
output.WorkspaceData = jdataencode(body, 'AnnotateArray', 1, 'base64', 1, ...
'UseArrayZipSize', 1, 'MapAsStruct', 1, 'prefix', 'x', defaultopt{:}, varargin{:});
bodyjson = jsonencode(output);
clear output;
fid = fopen(filename, jsonopt('writemode', 'w', opt));
fwrite(fid, headerjson);
fwrite(fid, sprintf('\n\n\n'));
fwrite(fid, bodyjson);
fclose(fid);
elseif (jsonopt('usemmap', 0, opt) == 1)
bodyjson = savejd('WorkspaceData', body, ...
defaultopt{:}, varargin{:});
header.(encodevarname('_MMap_')) = loadjd(bodyjson, 'mmaponly', 1, varargin{:});
savejd('WorkspaceHeader', header, 'filename', filename, varargin{:});
fid = fopen(filename, 'ab+');
fwrite(fid, bodyjson);
fclose(fid);
else
savejd('WorkspaceHeader', header, 'filename', filename, varargin{:});
savejd('WorkspaceData', body, 'filename', filename, 'append', 1, ...
defaultopt{:}, varargin{:});
end