Changeset 27874
- Timestamp:
- 08/08/23 11:26:37 (20 months ago)
- Location:
- issm/trunk/src/m/contrib/musselman
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified issm/trunk/src/m/contrib/musselman/read_netCDF.m ¶
r27864 r27874 17 17 18 18 function model_copy = read_netCDF(filename) 19 fprintf('NetCDF42C v1.1.1 2\n');19 fprintf('NetCDF42C v1.1.13\n'); 20 20 21 21 % make a model framework to fill that is in the scope of this file … … 39 39 catch 40 40 end % 'results' group doesn't exist 41 42 41 43 42 % see if inversion is in there, if it is we may have to instantiate some classes … … 84 83 global NCData; 85 84 inversionGroup = netcdf.inqNcid(NCData, "inversion"); 86 varid = netcdf.inqVarID(inversionGroup, 'inversion_class_name')85 varid = netcdf.inqVarID(inversionGroup, 'inversion_class_name'); 87 86 inversion_class = convertCharsToStrings(netcdf.getVar(inversionGroup, varid,'char')); 88 if inversion_class == 'm1qn3inversion'87 if strcmp(inversion_class, 'm1qn3inversion') 89 88 model_copy.inversion = m1qn3inversion(); 90 89 disp('Successfully created inversion class instance: m1qn3inversion') 91 elseif inversion_class == 'taoinversion'90 elseif strcmp(inversion_class, 'taoinversion') 92 91 model_copy.inversion = taoinversion(); 93 92 disp('Successfully created inversion class instance: taoinversion') 94 93 else 94 disp('No inversion class was found') 95 95 end 96 96 end … … 109 109 for variable = variables 110 110 [varname, xtype, dimids, numatts] = netcdf.inqVar(group_location_in_file, variable); 111 %disp(varname)112 111 copy_variable_data_to_new_model(group_location_in_file,varname, xtype); 113 112 end 114 catch 113 catch ME 114 rethrow(ME) 115 115 end 116 116 … … 141 141 global NCData; 142 142 %disp(varname) 143 % putting try/catch here so that any errors generated while copying data are logged and not lost by the try/catch in walk_nested_groups 144 try 145 %disp(netcdf.inqGrpNameFull(group_location_in_file)) 146 %disp(class(netcdf.inqGrpNameFull(group_location_in_file))) 147 adress_to_attr = strrep(netcdf.inqGrpNameFull(group_location_in_file), '/', '.'); 148 % netcdf uses Row Major Order but MATLAB uses Column Major Order so we need to transpose all arrays w/ more than 1 dim 149 data = netcdf.getVar(group_location_in_file, netcdf.inqVarID(group_location_in_file, varname)); 150 151 if all(size(data)~=1) 152 data = data.'; 143 % this is an inversion band-aid 144 if strcmp(varname, 'inversion_class_name') 145 % we don't need this 146 else 147 % putting try/catch here so that any errors generated while copying data are logged and not lost by the try/catch in walk_nested_groups function 148 try 149 %disp(netcdf.inqGrpNameFull(group_location_in_file)) 150 %disp(class(netcdf.inqGrpNameFull(group_location_in_file))) 151 adress_to_attr = strrep(netcdf.inqGrpNameFull(group_location_in_file), '/', '.'); 152 153 data = netcdf.getVar(group_location_in_file, netcdf.inqVarID(group_location_in_file, varname)); 154 155 156 % matlab needs to know that ' ' = char() 157 if xtype == 2 && isempty(all(data)) 158 data = cell(char()); 159 elseif numel(data) == 1 && xtype == 3 && data == -32767 160 data = cell(char()); 161 end 162 % band-aid for cell-char-arrays: 163 if xtype == 2 && strcmp(data, 'default') 164 data = {'default'}; 165 end 166 167 % netcdf uses Row Major Order but MATLAB uses Column Major Order so we need to transpose all arrays w/ more than 1 dim 168 if all(size(data)~=1) || xtype == 2 169 data = data.'; 170 end 171 172 % the issm c compiler does not work with int64 datatypes, so we need to convert those to int16 173 % reference this (very hard to find) link for netcdf4 datatypes: https://docs.unidata.ucar.edu/netcdf-c/current/netcdf_8h_source.html 174 %xtype 175 if xtype == 10 176 arg_to_eval = ['model_copy', adress_to_attr, '.', varname, ' = ' , 'double(data);']; 177 eval(arg_to_eval); 178 %disp('saved int64 as int16') 179 else 180 arg_to_eval = ['model_copy', adress_to_attr, '.', varname, ' = ' , 'data;']; 181 eval(arg_to_eval); 182 end 183 184 full_addy = netcdf.inqGrpNameFull(group_location_in_file); 185 %disp(xtype) 186 %class(data) 187 fprintf('Successfully saved %s to %s\n', varname, full_addy); 188 catch e %e is an MException struct 189 fprintf(1,'There was an error with %s! \n', varname) 190 fprintf('The message was:\n%s\n',e.message); 191 fprintf(1,'The identifier was:\n%s\n',e.identifier); 192 disp() 193 % more error handling... 153 194 end 154 155 % the issm c compiler does not work with int64 datatypes, so we need to convert those to int16156 % reference this (very hard to find) link for netcdf4 datatypes: https://docs.unidata.ucar.edu/netcdf-c/current/netcdf_8h_source.html157 %xtype158 if xtype == 10159 arg_to_eval = ['model_copy', adress_to_attr, '.', varname, ' = ' , 'double(data);'];160 eval(arg_to_eval);161 %disp('saved int64 as int16')162 else163 arg_to_eval = ['model_copy', adress_to_attr, '.', varname, ' = ' , 'data;'];164 eval(arg_to_eval);165 end166 167 full_addy = netcdf.inqGrpNameFull(group_location_in_file);168 %disp(xtype)169 %class(data)170 fprintf('Successfully saved %s to %s\n', varname, full_addy);171 catch e %e is an MException struct172 fprintf(1,'The identifier was:\n%s',e.identifier);173 fprintf(1,'There was an error! The message was:\n%s',e.message);174 % more error handling...175 195 end 176 196 end -
TabularUnified issm/trunk/src/m/contrib/musselman/read_netCDF_commit.py ¶
r27859 r27874 24 24 25 25 def read_netCDF(filename): 26 print('NetCDF42C v1.1.1 2')26 print('NetCDF42C v1.1.13') 27 27 28 28 # check if path exists … … 54 54 # walk through each group looking for subgroups and variables 55 55 for group in NCData.groups.keys(): 56 # have to send a custom name to this function: filename.groups['group'] 57 name = "NCData.groups['" + str(group) + "']" 58 walk_nested_groups(name) 56 if 'debris' in group: 57 pass 58 else: 59 # have to send a custom name to this function: filename.groups['group'] 60 name = "NCData.groups['" + str(group) + "']" 61 walk_nested_groups(name) 59 62 63 print("Model Successfully Recreated.") 60 64 return model_copy 61 65 … … 116 120 if str(location_of_variable_in_model + '.' + variable_name) =='results.solutionstep': 117 121 pass 122 # qmu band-aid 123 elif 'qmu.statistics.method' in str(location_of_variable_in_model + '.' + variable_name): 124 pass 118 125 # handle any strings: 119 126 elif 'char' in eval(location_of_variable_in_file + '.dimensions[0]'): … … 151 158 152 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 -
TabularUnified issm/trunk/src/m/contrib/musselman/write_netCDF.m ¶
r27868 r27874 11 11 12 12 function write_netCDF(model_var, filename) 13 disp('MATLAB C2NetCDF4 v1.1.1 2');13 disp('MATLAB C2NetCDF4 v1.1.13'); 14 14 % model_var = class object to be saved 15 15 % filename = path and name to save file under … … 30 30 try 31 31 % if results had meaningful data, save the name of the subclass and class instance 32 NetCDF.groups('results');32 netcdf.inqNcid(NetCDF,'results'); 33 33 results_subclasses_bandaid(model_var); 34 34 % otherwise, ignore … … 41 41 42 42 43 43 44 function make_NetCDF(filename) 45 % matlab can't handle input in the jupyter interface, so we just yell at the user to rename 46 % their file if needed 44 47 % If file already exists delete / rename it 45 48 if exist(filename, 'file') == 2 46 49 fprintf('File %s already exists\n', filename); 50 disp('Please rename your file.') 51 return 47 52 48 53 % If so, inquire for a new name or to delete the existing file 49 newname = input('Give a new name or input "delete" to replace: ', 's'); 50 51 if strcmpi(newname, 'delete') 52 delete(filename); 53 else 54 fprintf('New file name is %s\n', newname); 55 filename = newname; 56 end 57 end 58 % Otherwise create the file and define it globally so other functions can call it 59 global NetCDF; 60 NetCDF = netcdf.create(filename, 'NETCDF4'); 61 netcdf.putAtt(NetCDF, netcdf.getConstant('NC_GLOBAL'), 'history', ['Created ', datestr(now)]); 62 netcdf.defDim(NetCDF, 'Unlim', netcdf.getConstant('NC_UNLIMITED')); % unlimited dimension 63 netcdf.defDim(NetCDF, 'float', 1); % single integer dimension 64 netcdf.defDim(NetCDF, 'int', 1); % single float dimension 65 66 67 fprintf('Successfully created %s\n', filename); 68 end 69 54 %newname = input('Give a new name or input "delete" to replace: ', 's'); 55 56 %if strcmpi(newname, 'delete') 57 %delete filename; 58 %else 59 %fprintf('New file name is %s\n', newname); 60 %filename = newname; 61 %end 62 else 63 % Otherwise create the file and define it globally so other functions can call it 64 global NetCDF; 65 NetCDF = netcdf.create(filename, 'NETCDF4'); 66 netcdf.putAtt(NetCDF, netcdf.getConstant('NC_GLOBAL'), 'history', ['Created ', datestr(now)]); 67 netcdf.defDim(NetCDF, 'Unlim', netcdf.getConstant('NC_UNLIMITED')); % unlimited dimension 68 netcdf.defDim(NetCDF, 'float', 1); % single integer dimension 69 netcdf.defDim(NetCDF, 'int', 1); % single float dimension 70 71 fprintf('Successfully created %s\n', filename); 72 end 73 end 74 75 76 %{ 77 Since python uses subclass instances and MATLAB uses fields, we need to guess which subclass instance python will need 78 given the name of the sub-field in MATLAB. We make this guess based on the name of the MATLAB subfield that will contain 79 the name of the python subclass instance. For example, md.results.StressbalanceSolution is an subfield in MATLAB, 80 but a class instance of solution(). Notice that StressbalanceSolution contains the name "Solution" in it. This is what 81 we will save to the netCDF file for python to pick up. 82 %} 70 83 71 84 function results_subclasses_bandaid(model_var) 72 % Since the results class may have nested classes within it, 73 % we need to record the name of the nested class instance variable as it appears in the model that we're trying to save 85 global NetCDF; 86 % The results class may have nested fields within it, so we need to record the name of 87 % the nested field as it appears in the model that we're trying to save 74 88 quality_control = {}; 75 89 … … 86 100 class_instance_name = class_instance_names{i}; 87 101 88 % Check to see which class its from and record that info in the NetCDF to recreate structure later89 102 % Check to see if there is a solutionstep class instance 90 if isa(results_var.(class_instance_name), 'solutionstep')103 if contains(class_instance_name, 'solutionstep',IgnoreCase=true) 91 104 quality_control{end+1} = 1; 92 write_string_to_netcdf('variable_name', 'solutionstep', 'address_of_child', class_instance_name, 'group', groupid); 105 write_string_to_netcdf('solutionstep', class_instance_name, groupid); 106 disp('Successfully stored class python subclass instance: solutionstep') 93 107 end 94 108 95 109 % Check to see if there is a solution class instance 96 if isa(results_var.(class_instance_name), 'solution')110 if contains(class_instance_name, 'solution',IgnoreCase=true) 97 111 quality_control{end+1} = 1; 98 write_string_to_netcdf('variable_name', 'solution', 'address_of_child', class_instance_name, 'group', groupid); 112 write_string_to_netcdf('solution', class_instance_name, groupid); 113 disp('Successfully stored class python subclass instance: solution') 99 114 end 100 115 101 116 % Check to see if there is a resultsdakota class instance 102 if isa(results_var.(class_instance_name), 'resultsdakota')117 if contains(class_instance_name, 'resultsdakota',IgnoreCase=true) 103 118 quality_control{end+1} = 1; 104 write_string_to_netcdf('variable_name', 'resultsdakota', 'address_of_child', class_instance_name, 'group', groupid); 119 write_string_to_netcdf('resultsdakota', class_instance_name, groupid); 120 disp('Successfully stored class python subclass instance: resultsdakota') 105 121 end 106 122 end … … 137 153 % model_subclass is an object (ie, md.mesh.elements) 138 154 % list_of_layers is a cell array of subclasses/attributes/fields so that we can copy the structure into netcdf (ie, {'mesh', 'elements'}) 139 % Use try/except since model_subclass is either a subclass w/ fields or it's not, no unknown exceptions 155 % need to check if inversion or m1qn3inversion or taoinversion class 156 if numel(given_list_of_layers) == 1 157 if strcmp(given_list_of_layers{1}, 'inversion') 158 create_group(model_subclass, given_list_of_layers); 159 check_inversion_class(model_subclass); 160 end 161 end 162 163 % Use try/except since model_subclass is either a subclass/struct w/ props/fields or it's not, no unknown exceptions 140 164 try 141 165 % look for children - this is where the catch would be called 142 166 children = fieldnames(model_subclass); 167 168 % if there are children, loop through them and see if we need to save any data 143 169 for child = 1:numel(children) 144 170 % record our current location … … 151 177 152 178 % if the empty model does not have this attribute, it's because it's new so we save it to netcdf 153 try 154 location_of_child_in_empty_model = empty_model_subclass.(current_child); 155 catch 156 % empty model didn't have the attr, so we save it to netcdf 157 create_group(location_of_child, list_of_layers); 158 end 159 160 % if the current attribute is a numerical array assume it has valuable data that needs to be saved 161 if isnumeric(location_of_child) && logical(numel(location_of_child) > 1) 162 create_group(location_of_child, list_of_layers); 163 % i don't think I need this line but it's in my python code... 164 % walk_through_subclasses(location_of_child) 165 % if the attributes are identical we don't need to save anything 166 elseif (all(isnan(location_of_child)) && all(isnan(location_of_child_in_empty_model))) || isempty(setxor(location_of_child, location_of_child_in_empty_model)) 167 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers); 168 % if the attributes are not the same we need to save ours 169 else 170 create_group(location_of_child, list_of_layers); 171 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers); 179 % there are 2 cases: the location is a struct, the location is a class 180 if isstruct(model_subclass) 181 % this would mean that the layer above the layer we're interested in is a struct, so 182 % we can navigate our empty model as such 183 if isfield(empty_model_subclass, current_child) 184 % the layer we're interested in does exist, we just need to compare states 185 location_of_child_in_empty_model = empty_model_subclass.(current_child); 186 % if the current attribute is a numerical array assume it has valuable data that needs to be saved 187 if isnumeric(location_of_child) && logical(numel(location_of_child) > 1) 188 create_group(location_of_child, list_of_layers); 189 % if the attributes are identical we don't need to save anything 190 elseif (all(isnan(location_of_child)) && all(isnan(location_of_child_in_empty_model))) || isempty(setxor(location_of_child, location_of_child_in_empty_model)) 191 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers); 192 % if the attributes are not the same we need to save ours 193 else 194 % THE ORDER OF THESE LINES IS CRITICAL 195 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers); 196 create_group(location_of_child, list_of_layers); 197 end 198 % this would mean that the layer we're interested in is not fundamental to the model architecture 199 % and thus needs to be saved to the netcdf 200 else 201 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers); 202 create_group(location_of_child, list_of_layers); 203 end 204 % this would mean it's not a struct, and must be a class/subclass 205 % we now check the state of the class property 206 else 207 try 208 if isprop(empty_model_subclass, current_child) 209 % the layer we're interested in does exist, we just need to compare states 210 location_of_child_in_empty_model = empty_model_subclass.(current_child); 211 % if the current attribute is a numerical array assume it has valuable data that needs to be saved 212 if isnumeric(location_of_child) && logical(numel(location_of_child) > 1) 213 create_group(location_of_child, list_of_layers); 214 215 elseif iscell(location_of_child) 216 % if the attributes are identical we don't need to save anything 217 if isempty(setxor(location_of_child, location_of_child_in_empty_model)) 218 % pass 219 else 220 % otherwise we need to save 221 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers); 222 create_group(location_of_child, list_of_layers); 223 end 224 elseif (all(isnan(location_of_child)) && all(isnan(location_of_child_in_empty_model))) 225 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers); 226 % if the attributes are not the same we need to save ours 227 else 228 % THE ORDER OF THESE LINES IS CRITICAL 229 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers); 230 create_group(location_of_child, list_of_layers); 231 end 232 else 233 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers); 234 create_group(location_of_child, list_of_layers); 235 end 236 catch 237 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers); 238 create_group(location_of_child, list_of_layers); 239 end 172 240 end 173 241 end … … 175 243 % If the caught error is a fieldname error, it's just saying that a variable has no fields and thus can be ignored 176 244 if strcmp(ME.identifier, 'MATLAB:fieldnames:InvalidInput') 245 % do nothing 177 246 % this is if we come accross instances/subfields in our model that are not fundamental to the model class (ie, taoinversion) 178 247 elseif strcmp(ME.identifier, 'MATLAB:UndefinedFunction') 248 walk_through_subclasses(location_of_child, empty_model_subclass, given_list_of_layers); 249 create_group(location_of_child, list_of_layers); 179 250 % If it's a different error, rethrow it to MATLAB's default error handling 180 251 else 252 disp(ME.identifier) 253 disp(given_list_of_layers) 181 254 rethrow(ME); 182 255 end … … 196 269 group = netcdf.defGrp(NetCDF, group_name); 197 270 catch % group was already made 198 group = netcdf.inqNcid(NetCDF, group_name); 199 end 200 % need to check if inversion or m1qn3inversion or taoinversion class 201 if strcmp(group_name, 'inversion') 202 check_inversion_class(location_of_child); 203 end 204 271 group = netcdf.inqNcid(NetCDF, group_name); 272 end 273 205 274 % if the data is nested, create nested groups to match class structure 206 275 if numel(list_of_layers) > 2 207 for name = list_of_layers{2:end-1} 208 % again, the group levels may have already been made 276 % the string() method is really important here since matlab apparently can't handle the infinite complexity of a string without the string method. 277 for name = string(list_of_layers(2:end-1)) 278 % the group levels may have already been made 209 279 try % group hasn't been made 210 280 group = netcdf.defGrp(group, name); … … 214 284 end 215 285 end 216 217 % Lastly, handle the variable(s) 218 variable_name = list_of_layers{end}; 219 create_var(variable_name, location_of_child, group); 220 221 end 222 223 224 286 % if the object is not a variable, we have nothing to save 287 try 288 % if this line works, we're still dealing with a struct and need lower levels 289 if isempty(fieldnames(location_of_child)) 290 % do nothing 291 end 292 catch 293 % if that line doesn't work, it means we're dealing with data 294 % Lastly, handle the variable(s) 295 variable_name = list_of_layers{end}; 296 create_var(variable_name, location_of_child, group); 297 end 298 end 299 300 301 % ironically inversion does not have the same problem as results as inversion subfields 302 % are actually subclasses and not fields 225 303 function check_inversion_class(model_var) 226 304 global NetCDF; … … 229 307 % Check if the function has already been executed 230 308 if isempty(executed) 309 disp('Deconstructing Inversion class instance') 231 310 % Need to make sure that we have the right inversion class: inversion, m1qn3inversion, taoinversion 232 311 groupid = netcdf.inqNcid(NetCDF,'inversion'); … … 234 313 if isa(model_var, 'm1qn3inversion') 235 314 write_string_to_netcdf('inversion_class_name', 'm1qn3inversion', groupid); 236 disp('Successfully saved inversion class instance m1qn3inversion') ;315 disp('Successfully saved inversion class instance m1qn3inversion') 237 316 elseif isa(model_var, 'taoinversion') 238 317 write_string_to_netcdf('inversion_class_name', 'taoinversion', groupid); 239 disp('Successfully saved inversion class instance taoinversion') ;318 disp('Successfully saved inversion class instance taoinversion') 240 319 else 241 320 write_string_to_netcdf('inversion_class_name', 'inversion', groupid); 242 disp('Successfully saved inversion class instance inversion') ;321 disp('Successfully saved inversion class instance inversion') 243 322 end 244 323 % Set the persistent variable to indicate that the function has been executed 245 324 executed = true; 246 else 247 % Code to skip execution if the function has already run 248 end 249 250 325 end 251 326 end 252 327 … … 265 340 if any(size(address_of_child)>1) && ~ischar(address_of_child) 266 341 write_numeric_array_to_netcdf(variable_name, address_of_child, group); 267 268 % check if it's an int 269 elseif mod(address_of_child,1) == 0 || isinteger(address_of_child) && numel(address_of_child) == 1 342 343 % check if it's a string 344 elseif ischar(address_of_child) 345 write_string_to_netcdf(variable_name, address_of_child, group); 346 347 % or an empty variable 348 elseif isempty(address_of_child) 349 variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", intdim); 350 351 % or a list of strings -- this needs work as it can only handle a list of 1 string 352 elseif iscell(address_of_child) && ischar(address_of_child{1}) 353 for i = 1:numel(address_of_child) 354 write_string_to_netcdf(variable_name, address_of_child{i}, group, true); 355 end 356 357 % or an empty list 358 elseif iscell(address_of_child) && isempty(address_of_child) || isa(address_of_child, 'double') && isempty(address_of_child) 270 359 variable = netcdf.defVar(group, variable_name, "NC_INT", intdim); 360 netcdf.putVar(group,variable, -32767); 361 362 % or a bool 363 elseif islogical(address_of_child) 364 % netcdf4 can't handle bool types like true/false so we convert all to int 1/0 and add an attribute named units with value 'bool' 365 variable = netcdf.defVar(group, variable_name, 'NC_SHORT', intdim); 366 netcdf.putVar(group,variable,int8(address_of_child)); 367 % make sure other systems can flag the bool type 368 netcdf.putAtt(group,variable,'units','bool'); 369 370 % or a regular list 371 elseif iscell(address_of_child) 372 disp('made list w/ unlim dim') 373 variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", unlimdim); 271 374 netcdf.putVar(group,variable,address_of_child); 272 375 273 376 % or a float 274 377 elseif isfloat(address_of_child) && numel(address_of_child) == 1 275 378 variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", floatdim); 276 379 netcdf.putVar(group,variable,address_of_child); 277 278 % or a string 279 elseif ischar(address_of_child) 280 write_string_to_netcdf(variable_name, address_of_child, group); 281 282 % or a bool 283 elseif islogical(address_of_child) 284 % netcdf4 can't handle bool types like true/false so we convert all to int 1/0 and add an attribute named units with value 'bool' 285 variable = netcdf.defVar(group, variable_name, 'NC_SHORT', 'int'); 286 netcdf.putVar(group,variable,logical(address_of_child)); 287 % make sure other systems can flag the bool type 288 netcdf.putAtt(group,variable,'units','bool'); 289 290 % or an empty list 291 elseif iscell(address_of_child) && isempty(address_of_child) || isa(address_of_child, 'double') && isempty(address_of_child) 380 381 % or a int 382 elseif mod(address_of_child,1) == 0 || isinteger(address_of_child) && numel(address_of_child) == 1 292 383 variable = netcdf.defVar(group, variable_name, "NC_SHORT", intdim); 293 294 % or a list of strings -- this needs work as it can only handle a list of 1 string295 elseif iscell(address_of_child) && ischar(address_of_child{1})296 for i = 1:numel(address_of_child)297 write_string_to_netcdf(variable_name, address_of_child{i}, group, list = true);298 end299 300 % or a regular list301 elseif iscell(address_of_child)302 disp('made list w/ unlim dim')303 variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", unlimdim);304 384 netcdf.putVar(group,variable,address_of_child); 305 385 … … 331 411 the_string_to_save = address_of_child; 332 412 333 % convert string to 334 uint_method=uint8(the_string_to_save); 335 method_ID = char(uint_method); 336 length_of_the_string = numel(method_ID); 337 338 % Convert the string to character data using string array 339 %str_out = char(the_string_to_save) 340 341 % Determine the length of the string 342 %length_of_the_string = numel(str_out) 343 344 % Check if the dimension already exists, and if not, create it 345 name_of_dimension = ['char', num2str(length_of_the_string)]; 346 try 347 dimID = netcdf.defDim(group, name_of_dimension, length_of_the_string); 348 catch 349 dimID = netcdf.inqDimID(group, name_of_dimension); 350 end 351 % Now we can make a variable in this dimension: 352 string_var = netcdf.defVar(group, variable_name, "NC_CHAR", [dimID]); 353 354 % Finally, we can write the variable: 355 netcdf.putVar(group, string_var, method_ID); 413 if isempty(the_string_to_save) 414 % if the char array is empty, save an empty char 415 name_of_dimension = ['char', num2str(0)]; 416 try 417 dimID = netcdf.defDim(group, name_of_dimension, 0); 418 catch 419 dimID = netcdf.inqDimID(group, name_of_dimension); 420 end 421 % Now we can make a variable in this dimension: 422 string_var = netcdf.defVar(group, variable_name, "NC_CHAR", [dimID]); 423 % we leave empty now 424 else 425 % convert string to 426 uint_method=uint8(the_string_to_save).'; 427 method_ID = char(uint_method); 428 length_of_the_string = numel(method_ID); 429 430 % Convert the string to character data using string array 431 %str_out = char(the_string_to_save) 432 433 % Determine the length of the string 434 %length_of_the_string = numel(str_out) 435 436 % Check if the dimension already exists, and if not, create it 437 name_of_dimension = ['char', num2str(length_of_the_string)]; 438 try 439 dimID = netcdf.defDim(group, name_of_dimension, length_of_the_string); 440 catch 441 dimID = netcdf.inqDimID(group, name_of_dimension); 442 end 443 % Now we can make a variable in this dimension: 444 string_var = netcdf.defVar(group, variable_name, "NC_CHAR", [dimID]); 445 % Finally, we can write the variable (always transpose for matlab): 446 netcdf.putVar(group, string_var, method_ID); 447 end 356 448 357 449 disp(['Successfully transferred data from ', variable_name, ' to the NetCDF']); … … 463 555 end 464 556 end 465 -
TabularUnified issm/trunk/src/m/contrib/musselman/write_netCDF_commit.py ¶
r27859 r27874 24 24 25 25 def write_netCDF(model_var, model_name: str, filename: str): 26 print(' C2NetCDF4 v1.1.12')26 print('Python C2NetCDF4 v1.1.12') 27 27 ''' 28 28 model_var = class object to be saved … … 90 90 91 91 # If so, inqure for a new name or to do delete the existing file 92 newname = input('Give a new name or input"delete" to replace: ')92 newname = input('Give a new name or "delete" to replace: ') 93 93 94 94 if newname == 'delete': … … 134 134 # in the framework of an empty model. If this is the case, we move to the except statement 135 135 try: 136 # if the variable is an array, assume it has relevant data 136 # if the variable is an array, assume it has relevant data (this is because the next line cannot evaluate "==" with an array) 137 137 if isinstance(eval(adress_of_child), np.ndarray): 138 138 create_group(model_var, adress_of_child) 139 walk_through_subclasses(model_var, adress_of_child, model_name)139 # if the attributes are identical we don't need to save anything 140 140 elif eval(adress_of_child) == eval(adress_of_child_in_empty_class): 141 141 walk_through_subclasses(model_var, adress_of_child, model_name) … … 144 144 create_group(model_var, adress_of_child) 145 145 walk_through_subclasses(model_var, adress_of_child, model_name) 146 # AttributeError since the empty_model wouldn't have the same attribute as our model 146 147 except AttributeError: 148 # THE ORDER OF THESE LINES IS CRITICAL 149 walk_through_subclasses(model_var, adress_of_child, model_name) 147 150 create_group(model_var, adress_of_child) 148 walk_through_subclasses(model_var, adress_of_child, model_name)149 151 except AttributeError: pass 150 152 except Exception as e: print(e) … … 166 168 167 169 # if the data is nested, create nested groups to match class structure 168 if len(levels_of_class) > 3:170 if len(levels_of_class) > 2: 169 171 for name in levels_of_class[2:-1]: 170 172 group = group.createGroup(str(name)) … … 349 351 # write the variable: 350 352 variable[:] = eval(adress_of_child) 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
Note:
See TracChangeset
for help on using the changeset viewer.