Home > atmlab > collocations > FieldMultiInstrumentCopier.m

FieldMultiInstrumentCopier

PURPOSE ^

SYNOPSIS ^

This is a script file.

DESCRIPTION ^

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

DOWNLOAD ^

FieldMultiInstrumentCopier.m

SOURCE CODE ^

0001 classdef FieldMultiInstrumentCopier < AssociatedDataset
0002     % Add others
0003     %
0004     % This class is for getting fields from other instruments on the same
0005     % satellite that do not have the same resolution but do have a 1-to-1
0006     % relation with the instrument originally used for collocating.
0007     % An example is to collocate with mhs, then get hirs and amsu-a.
0008     % This does not apply if there are several instruments or datasets
0009     % with exactly the same footprints; in this case, one should use an
0010     % ordinary FieldCopier and use siblings instead.
0011     %
0012     % This is an abstract class. One implementation is
0013     % <a href="matlab:help AssociatedPOESPlusCPR">AssociatedPOESPlusCPR</a>.
0014     %
0015     % WORK IN PROGRESS
0016     %
0017     % FIXME DOC
0018     
0019     % $Id: FieldMultiInstrumentCopier.m 8720 2013-10-21 20:41:39Z gerrit $
0020     
0021     properties (Transient, Abstract)
0022                 
0023         % For instruments sharing a platform with the primary
0024         %
0025         % FIXME DOC
0026         fieldcopier_other_primary
0027         
0028         % For instruments sharing a platform with the secondary
0029         %
0030         % FIXME DOC
0031         fieldcopier_other_secondary
0032 
0033     end
0034     
0035     
0036     properties (Transient)
0037         % This is for fields that are copied from the core
0038         %
0039         % FIXME DOC
0040         fieldcopier_core
0041         
0042         
0043         % FIXME DOC
0044         fieldstruct_other
0045     end
0046     
0047     
0048     properties (Transient, SetAccess = protected)
0049         %members
0050         parent
0051         dependencies
0052     end
0053         
0054     methods (Abstract, Access = protected)
0055         % FIXME DOC
0056         [newline, newpos] = translate(self, processed_core, data_orig, dsname, data_other)
0057     end
0058     
0059     methods
0060         %% constructor
0061         
0062          function self = FieldMultiInstrumentCopier(varargin)
0063              self = self@AssociatedDataset(varargin{:});
0064 %             if isempty(self.members)
0065 %                 self.members = struct(); % temporary default
0066 %             end
0067          end
0068     end
0069     
0070     methods (Access = {?SatDataset})
0071         
0072         %% implementation of abstract methods
0073         
0074         function args = primary_arguments(self, varargin)
0075             args = self.fieldcopier_core.primary_arguments(varargin{:});
0076         end
0077         
0078         function args = secondary_arguments(self, varargin)
0079             args = self.fieldcopier_core.secondary_arguments(varargin{:});
0080         end
0081         
0082         function bool = needs_primary_data(self, varargin)
0083             fields = optargs(varargin, {'all'});
0084             if isequal(fields, 'all')
0085                 bool = self.fieldcopier_core.needs_primary_data(fields);
0086             else
0087                 bool = self.fieldcopier_core.needs_primary_data(...
0088                     intersect(fieldnames(self.fieldcopier_core.members), fields));
0089             end
0090         end
0091         
0092         function bool = needs_secondary_data(self, varargin)
0093             fields = optargs(varargin, {'all'});
0094             if isequal(fields, 'all')
0095                 bool = self.fieldcopier_core.needs_secondary_data(fields);
0096             else
0097                 bool = self.fieldcopier_core.needs_secondary_data(...
0098                     intersect(fieldnames(self.fieldcopier_core.members), fields));
0099             end
0100         end
0101         
0102         function fields = fields_needed_for_dependency(~, ~, ~)
0103             fields = {}; % no dependencies
0104         end
0105         
0106         function [out, localcols] = process_granule(self, processed_core, data1, date1, spec1, data2, date2, spec2, dependencies, depcols, fields)
0107             D = datasets();
0108             
0109             %% copy fields for original instruments
0110             
0111             if isequal(fields, 'all')
0112                 fields_core = fieldnames(self.fieldcopier_core.members);
0113             else
0114                 fields_core = intersect(fieldnames(self.fieldcopier_core.members), fields);
0115             end
0116             [out_core, core_fc_cols] = self.fieldcopier_core.process_granule(...
0117                 processed_core, data1, date1, spec1, data2, date2, spec2, ...
0118                 dependencies, depcols, fields_core);
0119             if isequal(fields, 'all')
0120                 assert(isequal(self.fieldcopier_core.cols, core_fc_cols), ...
0121                     ['atmlab:' mfilename ':wrongcols'], ...
0122                     'Bug in cols :(');
0123                 fields = fieldnames(self.members);
0124             end
0125             allmembers = self.fieldcopier_core.members;
0126             
0127             %% get fields for other instruments on primary
0128             
0129             % (ab)use a FieldCopier also for other instruments on primary
0130             % by editing processed_core and putting in the line/pos for the
0131             % other instruments instead of the original ones
0132             % the abstract method 'translate' is responsible for actually
0133             % performing this conversion
0134             
0135             modes = {'primary', 'secondary'};
0136 
0137             for k = 1:length(modes)
0138                 m = modes{k};
0139                 
0140                 other_instruments{k} = fieldnames(self.(['fieldcopier_other_' m]));
0141                 out_other{k} = {};
0142                 
0143                 switch m
0144                     % sometimes it's the primary where other instruments
0145                     % are considered, sometimes it's the secondary. Prepare
0146                     % all that's differente here to avoid code-repetition
0147                     % later.
0148                     case 'primary'
0149                         data_orig = data1;
0150                         date = date1;
0151                         spec = spec1;
0152                         line_i = self.parent.cols.LINE1;
0153                         pos_i = self.parent.cols.POS1;
0154                         fc_other = self.fieldcopier_other_primary;
0155                         arg_i_other = 2;
0156                     case 'secondary'
0157                         data_orig = data2;
0158                         date = date2;
0159                         spec = spec2;
0160                         line_i = self.parent.cols.LINE2;
0161                         pos_i = self.parent.cols.POS2;
0162                         fc_other = self.fieldcopier_other_secondary;
0163                         arg_i_other = 5;
0164                     otherwise
0165                         error('BUG! CRASH! This place ought to be unreachable!');
0166                 end
0167                 
0168                 for i = 1:length(other_instruments{k})
0169                     other_instrument = other_instruments{k}{i};
0170                     %fields_from_other_instrument = intersect(fields, fieldnames(fc_other.(other_instrument).members));
0171                     fields_from_other_instrument = cellfun(@(X) safegetfield(fc_other.(other_instrument).members.(X), 'realname', X), intersect(fields, fieldnames(fc_other.(other_instrument).members)), 'UniformOutput', false);
0172                     if isempty(fields_from_other_instrument)
0173                         logtext(atmlab('OUT'), 'No need for %s this time\n', other_instrument);
0174                         continue
0175                     end
0176                     logtext(atmlab('OUT'), 'Also taking same-satellite instrument %s\n', ...
0177                         other_instrument);
0178                     try
0179                         % do not remove duplicates
0180                         data_other = D.(other_instrument).read_granule(date, spec, fields_from_other_instrument, false);
0181                     catch ME
0182                         switch ME.identifier
0183                             case {'atmlab:invalid_data'}
0184                                 logtext(atmlab('ERR'), 'Unable to read %s data, skipping and setting filler values\n', ...
0185                                     other_instrument);
0186                                 % return something of the right width
0187                                 flds = fieldnames(fc_other.(other_instrument).members);
0188                                 nrows = size(processed_core, 1);
0189 
0190                                 for fi = 1:length(flds)
0191                                     fld = flds{fi};
0192                                     if ~isfield(fc_other.(other_instrument).members.(fld).atts, 'missing_value')
0193                                         error(['atmlab:' mfilename ':missingmissing'], ...
0194                                             ['Could not find %s.members.%s.atts.missing_value. ' ...
0195                                              'Please define, I need this as a filler (see above).' ...
0196                                              'Missing for the following fields: %s'], ...
0197                                             fc_other.(other_instrument).name, fld, ...
0198                                             sprintf('%s ', flds{cellfun(@(x) ~isfield(fc_other.(other_instrument).members.(x).atts, 'missing_value'), flds)}));
0199                                     end
0200                                     out_other{k}{i}(1:nrows, fc_other.(other_instrument).cols.(fld)) = ...
0201                                         fc_other.(other_instrument).members.(fld).atts.missing_value;
0202                                 end
0203 %                                 hasdim = structfun(@(x)(isfield(x, 'dims')), fc_other.(other_instrument).members);
0204 %                                 sz_singles = sum(~hasdim);
0205 %                                 sz_multid = sum(cellfun(@(x)(fc_other.(other_instrument).members.(x).dims{2}), flds(hasdim)));
0206 %                                 ncols = sz_singles + sz_multid;
0207                                 %nrows = size(processed_core, 1);
0208 %                                 out_other{k}{i} = nan*zeros(nrows, ncols); %#ok<AGROW>
0209                                 continue;
0210                             otherwise
0211                                 ME.rethrow();
0212                         end
0213                     end
0214                     pc_other = processed_core;
0215                 
0216                     
0217                     [other_line, other_pos] = self.translate(processed_core, data_orig, other_instrument, data_other);
0218                 
0219                     pc_other(:, line_i) = other_line;
0220                     pc_other(:, pos_i) = other_pos;
0221        
0222                     % FieldCopier's process_granule also sets 'cols'-structure
0223                     args = {pc_other, data1, date1, spec1, data2, spec2, dependencies, depcols, fields_from_other_instrument};
0224                     args{arg_i_other} = data_other;
0225                     [out_other{k}{i}, cols_other{k}{i}] = fc_other.(other_instrument).process_granule(args{:}); %#ok<AGROW>
0226                    
0227 %                    allmembers = catstruct(allmembers, fc_other.(other_instrument).members);
0228                 end
0229             end
0230                    
0231             % merge matrices and cols-structures appropiately
0232             out = out_core;
0233             newcols = core_fc_cols;
0234             for k = 1:length(modes)
0235                 %m = modes{k};
0236                 for i = 1:length(out_other{k})
0237                     %[out, newcols] = self.merge_matrix(out, newcols, out_other{k}{i}, self.(['fieldcopier_other_' m]).(other_instruments{k}{i}).cols);
0238                     [out, newcols] = self.merge_matrix(out, newcols, out_other{k}{i}, cols_other{k}{i});
0239 
0240                 end
0241             end
0242 %            self.cols = newcols;
0243 %            self.members = allmembers;
0244             localcols = newcols;
0245         end
0246     end
0247 end

Generated on Mon 15-Sep-2014 13:31:28 by m2html © 2005