source: issm/trunk/src/m/contrib/musselman/read_netCDF.m@ 27864

Last change on this file since 27864 was 27864, checked in by musselman, 20 months ago

read_netCDF.m: Removed some log statements, added some comments related to functionality for nonstandard subclass instances

File size: 6.8 KB
Line 
1%{
2Given a NetCDF4 file, this set of functions will perform the following:
3 1. Enter each group of the file.
4 2. For each variable in each group, update an empty model with the variable's data
5 3. Enter nested groups and repeat
6
7
8If the model you saved has subclass instances that are not in the standard model() class
9you can:
10 1. Copy lines 30-35, set the "results" string to the name of the subclass instance,
11 2. Copy and modify the make_results_subclasses() function to create the new subclass
12 instances you need.
13From there, the rest of this script will automatically create the new subclass
14instance in the model you're writing to and store the data from the netcdf file there.
15%}
16
17
18function model_copy = read_netCDF(filename)
19 fprintf('NetCDF42C v1.1.12\n');
20
21 % make a model framework to fill that is in the scope of this file
22 global model_copy;
23 model_copy = model();
24
25 % Check if path exists
26 if exist(filename, 'file')
27 fprintf('Opening %s for reading\n', filename);
28
29 % Open the given netCDF4 file
30 global NCData;
31 NCData = netcdf.open(filename, 'NOWRITE');
32 % Remove masks from netCDF data for easy conversion: NOT WORKING
33 %netcdf.setMask(NCData, 'NC_NOFILL');
34
35 % see if results is in there, if it is we have to instantiate some classes
36 try
37 results_group_id = netcdf.inqNcid(NCData, "results");
38 make_results_subclasses();
39 catch
40 end % 'results' group doesn't exist
41
42
43 % see if inversion is in there, if it is we may have to instantiate some classes
44 try
45 inversion_group_id = netcdf.inqNcid(NCData, "inversion");
46 check_inversion_class();
47 catch
48 end % 'inversion' group doesn't exist
49
50 % loop over first layer of groups in netcdf file
51 for group = netcdf.inqGrps(NCData)
52 group_id = netcdf.inqNcid(NCData, netcdf.inqGrpName(group));
53 %disp(netcdf.inqGrpNameFull(group_id))
54 % hand off first level to recursive search
55 walk_nested_groups(group_id);
56 end
57
58 % Close the netCDF file
59 netcdf.close(NCData);
60 disp('Model Successfully Copied')
61 else
62 fprintf('File %s does not exist.\n', filename);
63 end
64end
65
66
67function make_results_subclasses()
68 global model_copy;
69 global NCData;
70 resultsGroup = netcdf.inqNcid(NCData, "results");
71 variables = netcdf.inqVarIDs(resultsGroup);
72 for name = variables
73 class_instance = netcdf.inqVar(resultsGroup, name);
74 class_instance_name = convertCharsToStrings(netcdf.getVar(resultsGroup, name, 'char'));
75 model_copy.results = setfield(model_copy.results, class_instance, class_instance_name);
76 end
77 disp('Successfully recreated results struct')
78end
79
80
81function check_inversion_class()
82 % get the name of the inversion class: either inversion or m1qn3inversion or taoinversion
83 global model_copy;
84 global NCData;
85 inversionGroup = netcdf.inqNcid(NCData, "inversion");
86 varid = netcdf.inqVarID(inversionGroup,'inversion_class_name')
87 inversion_class = convertCharsToStrings(netcdf.getVar(inversionGroup, varid,'char'));
88 if inversion_class == 'm1qn3inversion'
89 model_copy.inversion = m1qn3inversion();
90 disp('Successfully created inversion class instance: m1qn3inversion')
91 elseif inversion_class == 'taoinversion'
92 model_copy.inversion = taoinversion();
93 disp('Successfully created inversion class instance: taoinversion')
94 else
95 end
96end
97
98
99
100function walk_nested_groups(group_location_in_file)
101 global model_copy;
102 global NCData;
103 % try to find vars in current level, if it doesn't work it's because there is nothing there
104 try
105 % we search the current group level for variables by getting this struct
106 variables = netcdf.inqVarIDs(group_location_in_file);
107
108 % from the variables struct get the info related to the variables
109 for variable = variables
110 [varname, xtype, dimids, numatts] = netcdf.inqVar(group_location_in_file, variable);
111 %disp(varname)
112 copy_variable_data_to_new_model(group_location_in_file,varname, xtype);
113 end
114 catch
115 end
116
117 % try to find groups in current level, if it doesn't work it's because there is nothing there
118 try
119 % search for nested groups in the current level to feed back to this function
120 groups = netcdf.inqGrps(group_location_in_file);
121 if not(isempty(groups))
122 for group = groups
123 %disp('found nested group!!')
124 group_id = netcdf.inqNcid(group_location_in_file, netcdf.inqGrpName(group));
125 %disp(netcdf.inqGrpNameFull(group_id))
126 walk_nested_groups(group);
127 end
128 end
129 catch
130 end
131end
132
133%{
134Since there are two types of objects that MATLAB uses (classes and structs), we have to check
135which object we're working with before we can set any fields/attributes of it. After this is completed,
136we can write the data to that location in the model.
137%}
138
139function copy_variable_data_to_new_model(group_location_in_file, varname, xtype)
140 global model_copy;
141 global NCData;
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.';
153 end
154
155 % the issm c compiler does not work with int64 datatypes, so we need to convert those to int16
156 % reference this (very hard to find) link for netcdf4 datatypes: https://docs.unidata.ucar.edu/netcdf-c/current/netcdf_8h_source.html
157 %xtype
158 if xtype == 10
159 arg_to_eval = ['model_copy', adress_to_attr, '.', varname, ' = ' , 'double(data);'];
160 eval(arg_to_eval);
161 %disp('saved int64 as int16')
162 else
163 arg_to_eval = ['model_copy', adress_to_attr, '.', varname, ' = ' , 'data;'];
164 eval(arg_to_eval);
165 end
166
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 struct
172 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 end
176end
177
178
179
Note: See TracBrowser for help on using the repository browser.