time | Calls | line |
---|
< 0.001 | 45 | 1 | classdef VariableImportOptions < matlab.io.internal.mixin.HasPropertiesAsNVPairs ...
|
| | 2 | & matlab.mixin.CustomDisplay ...
|
| | 3 | & matlab.mixin.Heterogeneous ...
|
| | 4 | & matlab.io.internal.shared.VarOptsInputs
|
| | 5 | %VARIABLEIMPORTOPTIONS Options for importing a variable from a file
|
| | 6 | %
|
| | 7 | % VariableImportOptions Properties:
|
| | 8 | % Name - The name of the variable on import
|
| | 9 | % Type - The data type of the variable on import
|
| | 10 | % FillValue - A scalar value to fill missing or unconvertible data
|
| | 11 | % TreatAsMissing - Text which is used in a file to represent missing
|
| | 12 | % data, e.g. 'NA'
|
| | 13 | % EmptyFieldRule - How to treat empty field data
|
| | 14 | % QuoteRule - How to treat quoted text.
|
| | 15 | % Prefixes - Prefix characters to be removed from variable on
|
| | 16 | % import
|
| | 17 | % Suffixes - Suffix characters to be removed from variable on
|
| | 18 | % import
|
| | 19 | %
|
| | 20 | % See also
|
| | 21 | % readtable, datastore, matlab.io.spreadsheet.SpreadsheetImportOptions
|
| | 22 | % matlab.io.TextVariableImportOptions
|
| | 23 | % matlab.io.NumericVariableImportOptions
|
| | 24 | % matlab.io.LogicalVariableImportOptions
|
| | 25 | % matlab.io.DatetimeVariableImportOptions
|
| | 26 | % matlab.io.DurationVariableImportOptions
|
| | 27 | % matlab.io.CategoricalVariableImportOptions
|
| | 28 |
|
| | 29 | % Copyright 2016-2018 The MathWorks, Inc.
|
| | 30 | methods (Static, Sealed, Access = protected)
|
| | 31 | function elem = getDefaultScalarElement()
|
| | 32 | elem = matlab.io.TextVariableImportOptions();
|
| | 33 | end
|
| | 34 | end
|
| | 35 |
|
| | 36 | methods (Sealed, Access=?matlab.io.ImportOptions)
|
| | 37 | function obj = overrideType(obj,idx,types)
|
| | 38 | tf = ismember(types,matlab.io.internal.supportedTypeNames());
|
| | 39 |
|
| | 40 | if ~all(tf)
|
| | 41 | error(message('MATLAB:textio:io:UnsupportedConversionType',types{find(~tf,1)}));
|
| | 42 | end
|
| | 43 | % Convert the selection to the requested types.
|
| | 44 | for i = 1:numel(idx)
|
| | 45 | obj(idx(i)) = convertOptsToType(obj(idx(i)),types{i});
|
| | 46 | end
|
| | 47 | end
|
| | 48 | end
|
| | 49 | % Custom Display Methods
|
| | 50 | methods (Sealed, Access = protected)
|
| | 51 | function propgrp = getPropertyGroups(obj)
|
| | 52 | if ~isscalar(obj)
|
| | 53 | propgrp = getPropertyGroups@matlab.mixin.CustomDisplay(obj);
|
| | 54 | else
|
| | 55 | props.Name = obj.Name;
|
| | 56 | props.Type = obj.Type;
|
| | 57 | props.FillValue = obj.FillValue;
|
| | 58 | props.TreatAsMissing = obj.TreatAsMissing;
|
| | 59 | props.QuoteRule = obj.QuoteRule;
|
| | 60 | props.Prefixes = obj.Prefixes;
|
| | 61 | props.Suffixes = obj.Suffixes;
|
| | 62 | props.EmptyFieldRule = obj.EmptyFieldRule;
|
| | 63 |
|
| | 64 | propgrp(1) = matlab.mixin.util.PropertyGroup(props,'Variable Properties:');
|
| | 65 |
|
| | 66 | [type_specific,group_name] = obj.getTypedPropertyGroup();
|
| | 67 |
|
| | 68 | propgrp(2) = matlab.mixin.util.PropertyGroup(type_specific,group_name);
|
| | 69 | end
|
| | 70 | end
|
| | 71 |
|
| | 72 | function h = getHeader(obj)
|
| | 73 | h = getHeader@matlab.mixin.CustomDisplay(obj);
|
| | 74 | end
|
| | 75 |
|
| | 76 | function f = getFooter(obj)
|
| | 77 | f = getFooter@matlab.mixin.CustomDisplay(obj);
|
| | 78 | end
|
| | 79 |
|
| | 80 | function displayEmptyObject(obj)
|
| | 81 | displayEmptyObject@matlab.mixin.CustomDisplay(obj);
|
| | 82 | end
|
| | 83 |
|
| | 84 | function displayNonScalarObject(obj)
|
| | 85 |
|
| | 86 | try
|
| | 87 | isdesktop = usejava('desktop') && desktop('-inuse');
|
| | 88 | catch
|
| | 89 | isdesktop = false;
|
| | 90 | end
|
| | 91 |
|
| | 92 | if ~isrow(obj) || ~isdesktop
|
| | 93 | displayNonScalarObject@matlab.mixin.CustomDisplay(obj);
|
| | 94 | return;
|
| | 95 | end
|
| | 96 |
|
| | 97 | if matlab.internal.display.isHot()
|
| | 98 | name = '<a href="matlab:helpPopup matlab.io.VariableImportOptions" style="font-weight:bold">VariableImportOptions</a>';
|
| | 99 | else
|
| | 100 | name = 'VariableImportOptions';
|
| | 101 | end
|
| | 102 |
|
| | 103 | propNames = {'Name';'Type';'FillValue';'TreatAsMissing';'EmptyFieldRule'; ...
|
| | 104 | 'QuoteRule';'Prefixes';'Suffixes'};
|
| | 105 |
|
| | 106 | s = struct(propNames{1},{obj.Name},...
|
| | 107 | propNames{2},{obj.Type},...
|
| | 108 | propNames{3},{obj.FillValue}, ...
|
| | 109 | propNames{4},{obj.TreatAsMissing},...
|
| | 110 | propNames{5},{obj.EmptyFieldRule}, ...
|
| | 111 | propNames{6},{obj.QuoteRule},...
|
| | 112 | propNames{7},{obj.Prefixes},...
|
| | 113 | propNames{8},{obj.Suffixes});
|
| | 114 |
|
| | 115 | displayVariableBody(obj,name,s);
|
| | 116 | strHelpGetvaropts = '<a href="matlab:helpPopup getvaropts" style="font-weight:regular">getvaropts</a>';
|
| | 117 | fprintf(['\n\t', getString(message('MATLAB:textio:io:GetvaroptsLink')), ' ',strHelpGetvaropts, '\n']);
|
| | 118 | end
|
| | 119 | end
|
| | 120 |
|
| | 121 | % For child class to do custom display
|
| | 122 | methods (Abstract, Access = protected)
|
| | 123 | [type_specific,group_name] = getTypedPropertyGroup(obj);
|
| | 124 | tf = compareVarProps(a,b);
|
| | 125 | end
|
| | 126 |
|
| | 127 | methods (Sealed,Static,Hidden)
|
| | 128 | function obj = getTypedOptionsByName(newType)
|
| | 129 | switch newType
|
| | 130 | case {'double','single','int8','uint8','int16','uint16','int32','uint32','int64','uint64'}
|
| | 131 | obj = matlab.io.NumericVariableImportOptions('Type',newType);
|
| | 132 | case {'char','string'}
|
| | 133 | obj = matlab.io.TextVariableImportOptions('Type',newType);
|
| | 134 | case 'datetime'
|
| | 135 | obj = matlab.io.DatetimeVariableImportOptions();
|
| | 136 | case 'duration'
|
| | 137 | obj = matlab.io.DurationVariableImportOptions();
|
| | 138 | case 'categorical'
|
| | 139 | obj = matlab.io.CategoricalVariableImportOptions();
|
| | 140 | case 'logical'
|
| | 141 | obj = matlab.io.LogicalVariableImportOptions();
|
| | 142 | otherwise
|
| | 143 | assert(false);
|
| | 144 | end
|
| | 145 | end
|
| | 146 | end
|
| | 147 |
|
| | 148 | methods (Access = private)
|
| | 149 | function obj = convertOptsToType(obj,type)
|
| | 150 | % Set the shared properties
|
| | 151 | persistent sharedProperties
|
| | 152 | if isempty(sharedProperties)
|
| | 153 | meta = ?matlab.io.VariableImportOptions;
|
| | 154 | propList = meta.PropertyList;
|
| | 155 | ispublic = false(1,numel(propList));
|
| | 156 | for i = 1:numel(propList)
|
| | 157 | ispublic(i) = ischar(propList(i).GetAccess) && strcmp('public',propList(i).GetAccess);
|
| | 158 | end
|
| | 159 | sharedProperties = setdiff({propList(ispublic).Name},["Type","FillValue"]);
|
| | 160 | end
|
| | 161 |
|
| | 162 | try
|
| | 163 | obj.Type = type;
|
| | 164 | catch
|
| | 165 | oldobj = obj;
|
| | 166 | % First get an object of the new type
|
| | 167 | obj = matlab.io.VariableImportOptions.getTypedOptionsByName(type);
|
| | 168 | % Assign old properties into new properties.
|
| | 169 | for p = sharedProperties
|
| | 170 | obj.(p{:}) = oldobj.(p{:});
|
| | 171 | end
|
| | 172 | end
|
| | 173 | end
|
| | 174 | end
|
| | 175 |
|
| | 176 | methods (Access = {?matlab.io.internal.FastVarOpts,...
|
| | 177 | ?matlab.io.VariableImportOptions,...
|
| | 178 | ?matlab.io.internal.readers.TextDataReader})
|
| | 179 | function s = makeOptsStruct(opts)
|
| | 180 |
|
| | 181 | s.Name = opts.Name_;
|
| | 182 | s.Type = opts.Type_;
|
| | 183 | s.FillValue = opts.getFillValue(opts.FillValue_);
|
| | 184 | s.EmptyFieldRule = opts.EmptyFieldRule;
|
| | 185 | s = opts.addTypeSpecificOpts(s);
|
| | 186 | end
|
| | 187 | end
|
| | 188 |
|
| | 189 | properties (Constant, Access = 'protected')
|
| | 190 | ProtectedNames = ["Name" "Type" "FillValue"];
|
| | 191 | end
|
| | 192 |
|
| | 193 | methods(Static, Hidden)
|
| | 194 | function obj = loadobj(s)
|
| | 195 | % Loads VariableImportOptions object from a MAT file.
|
| | 196 | if isstruct(s)
|
| | 197 | obj = matlab.io.VariableImportOptions.getTypedOptionsByName(s.Type);
|
| | 198 |
|
| | 199 | % Get a list of properties
|
| | 200 | typedSpecifcProps = obj.getTypeSpecificProperties();
|
| | 201 | commonProps = ["Name", "TreatAsMissing", "QuoteRule",...
|
| | 202 | "Prefixes", "Suffixes", "EmptyFieldRule"];
|
| | 203 |
|
| | 204 | if ~isa(obj, 'matlab.io.NumericVariableImportOptions')
|
| | 205 | commonProps = [commonProps "FillValue"];
|
| | 206 | end
|
| | 207 |
|
| | 208 | props = [commonProps typedSpecifcProps];
|
| | 209 |
|
| | 210 | if isfield(s, "Name_")
|
| | 211 | s.Name = s.Name_;
|
| | 212 | s = rmfield(s, "Name_");
|
| | 213 | end
|
| | 214 |
|
| | 215 | % if name is the empty string, do not set the Name property
|
| | 216 | % because setting Name to "", '' explicitly will error
|
| | 217 | name = convertCharsToStrings(s.Name);
|
| | 218 | if isstring(name) && isscalar(name) && strlength(name) == 0
|
| | 219 | props = props(2:end); % removes "Name" from the props list
|
| | 220 | end
|
| | 221 |
|
| | 222 | for ii = 1:numel(props)
|
| | 223 | try
|
| | 224 | % Some properties may not be fields in the struct
|
| | 225 | % if options were saved in earlier releases.
|
| | 226 | obj.(props(ii)) = s.(props(ii));
|
| | 227 | catch ME
|
| | 228 | % Expect a non Existent Field error if loading a
|
| | 229 | % new property that did not exist in an older
|
| | 230 | % release. In this case, the new property is set to
|
| | 231 | % the default value. Otherwise, we have an invalid
|
| | 232 | % value and we will issue the error as a
|
| | 233 | % warning.
|
| | 234 | if ~strcmp(ME.identifier, 'MATLAB:nonExistentField')
|
| | 235 | warning(ME.identifier, '%s', ME.message);
|
| | 236 | end
|
| | 237 | end
|
| | 238 | end
|
| | 239 |
|
| | 240 | % FillValue for numeric values should not be cast into a
|
| | 241 | % different numeric type during load
|
| | 242 | if isa(obj, 'matlab.io.NumericVariableImportOptions')
|
| | 243 | try
|
| | 244 | if isfield(s, "FillValue_")
|
| | 245 | obj.FillValue = s.FillValue_;
|
| | 246 | else
|
| | 247 | obj.FillValue = s.FillValue;
|
| | 248 | end
|
| | 249 | catch ME
|
| | 250 | if ~strcmp(ME.identifier, 'MATLAB:nonExistentField')
|
| | 251 | warning(ME.identifier, '%s', ME.message);
|
| | 252 | end
|
| | 253 | end
|
| | 254 | end
|
| | 255 | else
|
| | 256 | % saved as an object instead of as a struct.
|
| | 257 | obj = s;
|
| | 258 | % explictly set FillValue to store it as the appropriate
|
| | 259 | % type if obj is not a NumericVariableImportOptions
|
| | 260 | if ~isa(obj, 'matlab.io.NumericVariableImportOptions')
|
| | 261 | obj.FillValue = s.FillValue;
|
| | 262 | end
|
| | 263 | end
|
| | 264 | end
|
| | 265 | end
|
| | 266 |
|
| | 267 | methods(Static, Abstract, Access = protected)
|
| | 268 | props = getTypeSpecificProperties();
|
| | 269 | end
|
| | 270 |
|
| | 271 | methods (Hidden)
|
| | 272 | function [cData,info] = convertFromText(varopts,textdata,whitespace)
|
| | 273 | st = varopts.makeOptsStruct();
|
| | 274 | [cData,info] = matlab.io.internal.convertFromText(st,textdata,whitespace);
|
| | 275 | end
|
| | 276 | end
|
| | 277 | end
|
| | 278 |
|
| | 279 | function d = displayVariableBody(obj,name,s)
|
| | 280 | % using message catalog to display the variable options
|
| | 281 | d = " 1x";
|
| | 282 | fprintf(' %s\n\n Variable Options:\n',getString(message('MATLAB:ObjectText:DISPLAY_AND_DETAILS_ARRAY_WITH_PROPS', d + numel(obj),name)));
|
| | 283 | fields = fieldnames(s);
|
| | 284 |
|
| | 285 | C = permute(struct2cell(s),[1,3,2]);
|
| | 286 | % for cell variables, we want to keep the {}
|
| | 287 | classes = cellfun(@class,C,'UniformOutput',false);
|
| | 288 |
|
| | 289 | % convert cell to string
|
| | 290 | isEmptyCell = cellfun(@isempty,C);
|
| | 291 | C(isEmptyCell) = {''};
|
| | 292 | % any cell of size > 1 needs to be converted to char array before
|
| | 293 | % converting to string
|
| | 294 | idx = cellfun(@iscellstr,C);
|
| | 295 | idx = find(idx == 1);
|
| | 296 | prodSymb = matlab.internal.display.getDimensionSpecifier;
|
| | 297 | singleCells = zeros(numel(idx),1);
|
| | 298 | for ii = 1 : numel(idx)
|
| | 299 | [m,n] = size(C{idx(ii)});
|
| | 300 | if m == 1 && n == 1
|
| | 301 | singleCells(ii) = idx(ii);
|
| | 302 | C{idx(ii)} = ['', C{idx(ii)}{1},''];
|
| | 303 | else
|
| | 304 | C{idx(ii)} = ['',num2str(m), prodSymb, num2str(n),' cell'];
|
| | 305 | end
|
| | 306 | end
|
| | 307 | singleCells(singleCells == 0) = [];
|
| | 308 | C = string(C);
|
| | 309 |
|
| | 310 | % truncate Names, FillValue scalar values, TreatAsMissing scalar
|
| | 311 | % values, Prefix scalar values, Suffix scalar values to 30 characters,
|
| | 312 | % and replace newline characters with their display equivalent
|
| | 313 | idx = [find(contains(C,{newline,char(13)})); find(strlength(C) > 30)];
|
| | 314 | for ii = 1 : numel(idx)
|
| | 315 | C(idx(ii)) = matlab.internal.display.truncateLine(C(idx(ii)),30);
|
| | 316 | end
|
| | 317 |
|
| | 318 | C(singleCells) = "'" + C(singleCells) + "'";
|
| | 319 | C(classes == "cell") = "{" + C(classes == "cell") + "}";
|
| | 320 | % replace <missing> with actual values
|
| | 321 | for ii = 1 : size(C,2)
|
| | 322 | if isempty(s(ii).FillValue)
|
| | 323 | C(3,ii) = "";
|
| | 324 | else
|
| | 325 | if isa(s(ii).FillValue,"string") && ismissing(s(ii).FillValue)
|
| | 326 | C(3,ii) = sprintf("<missing>");
|
| | 327 | else
|
| | 328 | if isa(s(ii).FillValue,'logical') || isnumeric(s(ii).FillValue)
|
| | 329 | C(3,ii) = sprintf("%u",s(ii).FillValue);
|
| | 330 | else
|
| | 331 | C(3,ii) = sprintf("%s",s(ii).FillValue);
|
| | 332 | end
|
| | 333 | end
|
| | 334 | end
|
| | 335 | end
|
| | 336 | C(classes == "char") = "'" + C(classes == "char") + "'";
|
| | 337 | C(C == "") = "{}";
|
| | 338 | % construct the variable index headers (1),(2),(3), ...
|
| | 339 | C = [compose("(%d)",1:size(s,2));C];
|
| | 340 | for ii = 1 : size(C,2)
|
| | 341 | C(:,ii) = pad(C(:,ii),max(strlength(C(:,ii))),"left");
|
| | 342 | end
|
| | 343 |
|
| | 344 | % get the variable names (Name, Type, FillValue, etc.)
|
| | 345 | d = [""; string(fields) + ":"];
|
| | 346 | d = pad(d,max(strlength(d(:)))+2,"left");
|
| | 347 | fprintf("%s\n",join(d + " " + join(C," | ",2),newline));
|
| | 348 | end
|
| | 349 |
|