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

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

ADD: read_netCDF.m populates a model() variable with data from NetCDF4 files written by write_netCDF.py/.m

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