0001 function [data,selection] = read_netCDF_FVCOM(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 global ftbverbose
0104 subname = 'read_netCDF_FVCOM';
0105
0106 if ftbverbose
0107 fprintf('\nbegin : %s \n', subname)
0108 end
0109
0110
0111
0112
0113
0114 params_opts = {'time', 'data_dir', 'file_netcdf', 'varnames', 'nele_idx', ...
0115 'node_idx', 'siglay_idx', 'siglev_idx', 'timestride'};
0116
0117 if ftbverbose
0118 fprintf('Input parameters being used are:\n')
0119 end
0120 var_in_list = {'all_data', 'netfile_dir', 'file_netcdf', 'varnames', ...
0121 'nele_idx', 'node_idx', 'siglay_idx', 'siglev_idx', 'timestrd'};
0122 all_data = 1;
0123 netfile_dir = '../fvcom_postproc/netcdf';
0124 file_netcdf='*.nc';
0125 siglay_idx=-1;
0126 siglev_idx=-1;
0127 nele_idx=-1;
0128 node_idx=-1;
0129 time_idx=-1;
0130 varnames={};
0131 timestrd=1;
0132 for aa=1:2:nargin
0133 res=strcmp(varargin(aa),params_opts);
0134 if sum(res)
0135 eval([var_in_list{res},' = varargin{aa+1};'])
0136 if ftbverbose
0137 fprintf(' %s\n', params_opts{res})
0138 end
0139 end
0140 end
0141
0142
0143
0144
0145 nele_idx=unique(nele_idx);
0146 node_idx=unique(node_idx);
0147 siglay_idx=unique(siglay_idx);
0148 siglev_idx=unique(siglev_idx);
0149
0150 RestrictDims.Name={'node' 'nele' 'siglay' 'siglev' 'time'};
0151 RestrictDims.idx={node_idx, nele_idx, siglay_idx, siglev_idx, time_idx};
0152
0153 if ~isempty(varnames)
0154 nvarnames = length(varnames);
0155 for nn=1:nvarnames
0156 data.(varnames{nn}) = [];
0157 end
0158 end
0159
0160
0161
0162
0163 file_netcdf=fullfile(netfile_dir, file_netcdf);
0164 filesINdir=dir(file_netcdf);
0165 file_netcdf= fullfile(netfile_dir,filesINdir(1).name);
0166 nc = netcdf.open(file_netcdf, 'NC_NOWRITE');
0167 [PATHSTR,NAME,EXT] = fileparts(file_netcdf)
0168
0169 if ftbverbose
0170 fprintf('NetCDF file %s opened successfully.\n', NAME)
0171 end
0172
0173 info=ncinfo(file_netcdf);
0174
0175 DimsAll=info.Dimensions;
0176
0177 Vars=struct2cell(info.Variables);
0178 vars = squeeze(Vars(1,:,:));
0179
0180
0181
0182
0183 if ftbverbose
0184 fprintf('Using date conversion of +678942 days to go from FVCOM time (Modified Julian Day) to MATLAB time.\n')
0185 end
0186 time_offset = 678942;
0187 idx=find(strcmpi(cat(1,{DimsAll.Name}),'time'));
0188 last_entry=DimsAll(idx).Length;
0189 Itime=[];Itime2=[];
0190
0191 try
0192
0193
0194
0195 Itime.idx=find(strcmpi(vars,'Times'));
0196 Itime.ID=netcdf.inqVarID(nc,'Times');
0197 Itime.sData=ncread(file_netcdf,'Times')
0198 Itime.Data(1) = datenum(Itime.sData(:,1)','yyyy-mm-ddTHH:MM:SS');
0199
0200 Itime.Data(2) = datenum(Itime.sData(:,end)','yyyy-mm-ddTHH:MM:SS');
0201 start_date= Itime.Data(1);
0202 end_date = Itime.Data(2);
0203
0204 var_time = datenum(Itime.sData(:,1:end)','yyyy-mm-ddTHH:MM:SS');
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223 catch me
0224 if ftbverbose
0225 warning('No ''Itime'' and/or ''Itime2'' variables, using less precise ''time'' instead.\n(%s)\n', me.message)
0226 end
0227 Itime.idx=find(strcmpi(vars,'time'));
0228 Itime.ID=netcdf.inqVarID(nc,'time');
0229 Itime.Data(1) = netcdf.getVar(nc,Itime.ID,0,1,'double');
0230
0231 Itime.Data(2) = netcdf.getVar(nc,Itime.ID,last_entry,1,'double');
0232 [start_date,end_date] = deal(Itime.Data(1)+time_offset,Itime.Data(end)+time_offset);
0233 DeltaT=(end_date-start_date)./last_entry;
0234 var_time = start_date:DeltaT:(end_date-DeltaT);
0235 end
0236
0237 if length(all_data) == 2
0238 req_st = datenum(all_data{1},'dd/mm/yy HH:MM:SS');
0239 req_end = datenum(all_data{2},'dd/mm/yy HH:MM:SS');
0240 else
0241 req_st = start_date;
0242 req_end =end_date;
0243 end
0244 time_idx = find(req_st <= var_time & var_time <= req_end );
0245 time_idx = time_idx(1:timestrd:end);
0246
0247 RestrictDims.idx{end}=time_idx;
0248 if ftbverbose
0249 fprintf('Start and end of file: %s - %s\n', datestr(start_date), datestr(end_date))
0250 end
0251
0252
0253
0254
0255
0256 if ftbverbose
0257 fprintf('Possible variables to extract are:\n')
0258 end
0259 for ii = 1:length(vars)
0260 if ftbverbose
0261 fprintf(' %s\n', vars{ii})
0262 end
0263 end
0264 if isempty(varnames)
0265 data = 0;
0266 netcdf.close(nc)
0267 error('Stopping. Choose a variable from the list above.')
0268 end
0269
0270
0271
0272
0273
0274 cc=1;
0275 for dd=1:length(DimsAll)
0276 idx=find(strcmpi(RestrictDims.Name,DimsAll(dd).Name));
0277 if ~isempty(idx)
0278 TEMP{cc}=RestrictDims.Name{idx};
0279 TEMPidx{cc}=RestrictDims.idx{idx};
0280 cc=cc+1;
0281 end
0282 end
0283 RestrictDims.Name = TEMP;
0284 RestrictDims.idx = TEMPidx;
0285 clear TEMP TEMPidx
0286
0287
0288
0289
0290 selection=[];
0291 for aa=1:length(varnames)
0292 selection.(varnames{aa}).start=-1;
0293 selection.(varnames{aa}).count=-1;
0294
0295
0296
0297
0298 if ftbverbose
0299 fprintf('Processing variable %s: ', varnames{aa})
0300 end
0301
0302 clear dimName dimLength
0303
0304 TF = strcmpi(varnames{aa},vars);
0305 if ~isempty(find(TF));
0306 varidx(aa) = find(TF);
0307 TF = sum(TF);
0308 dimens=ndims(aa);
0309 else
0310 netcdf.close(nc)
0311 varargout{1} = 0;
0312 if ftbverbose; fprintf('\n'); end
0313 error('Variable %s NOT found in file. Stopping. Check input variable names.', varnames{aa})
0314 end
0315 varID=netcdf.inqVarID(nc,vars{varidx(aa)});
0316
0317 [name,xtype,dimids,natts] = netcdf.inqVar(nc,varID);
0318 dimens=length(dimids);
0319
0320 for dd=1:length(dimids)
0321 [dimName{dd}, dimLength(dd)] = netcdf.inqDim(nc,dimids(dd));
0322 if ftbverbose
0323 if dd == 1
0324 if length(dimids) == 1
0325 if ftbverbose
0326 fprintf('%i dimension: %s ', dimens, dimName{dd})
0327 end
0328 else
0329 if ftbverbose
0330 fprintf('%i dimensions: %s ', dimens, dimName{dd})
0331 end
0332 end
0333 else
0334 if ftbverbose
0335 fprintf('%s ', dimName{dd})
0336 end
0337 end
0338 end
0339 end
0340 if ftbverbose; fprintf('\n'); end
0341
0342
0343
0344
0345
0346 switch dimens
0347 case 1
0348
0349 switch dimName{1}
0350 case 'time'
0351 if time_idx>=0
0352
0353
0354
0355
0356
0357 eval([varnames{aa},'=netcdf.getVar(nc,varID,time_idx(1)-1,length(time_idx),timestrd,''double'');'])
0358 end
0359 case 'nele'
0360 eval([varnames{aa},'=netcdf.getVar(nc,varID,''double'');'])
0361 if nele_idx>=0
0362 eval([varnames{aa},' = ',varnames{aa},'(nele_idx);'])
0363 end
0364 case 'node'
0365 eval([varnames{aa},'=netcdf.getVar(nc,varID,''double'');'])
0366 if node_idx>=0
0367 eval([varnames{aa},' = ',varnames{aa},'(node_idx);'])
0368 end
0369 otherwise
0370 if ftbverbose
0371 fprintf('Unkown dimension for variable %s. Skipping to next one in function call.\n', name);
0372 end
0373 end
0374 otherwise
0375
0376 do_restrict=zeros(size(dimName));
0377 dimidx=nan(size(dimName));
0378 clear start count stride
0379 for dd=1:length(dimName)
0380 start.(dimName{dd})=[];
0381 count.(dimName{dd})=[];
0382 stride.(dimName{dd})=[];
0383 test=find(strcmpi(RestrictDims.Name,dimName{dd}));
0384 if ~isempty(test); dimidx(dd)=test; end
0385 end
0386
0387
0388 if any(isfinite(dimidx))
0389
0390 for dd=1:length(dimidx)
0391
0392
0393
0394
0395 if ~isnan(dimidx(dd)) && RestrictDims.idx{dimidx(dd)}(1)>=0
0396 if (strcmpi(dimName(dd),'time'))
0397 start.(dimName{dd})=RestrictDims.idx{dimidx(dd)}(1)-1;
0398 count.(dimName{dd})=length(RestrictDims.idx{dimidx(dd)});
0399 stride.(dimName{dd})=timestrd;
0400
0401 else
0402 for ss=1:length(RestrictDims.idx{dimidx(dd)})
0403 start.(dimName{dd})(ss)=RestrictDims.idx{dimidx(dd)}(ss)-1;
0404 count.(dimName{dd})(ss)=1;
0405 stride.(dimName{dd})=1;
0406 end
0407 end
0408 do_restrict(dd)=1;
0409 else
0410 start.(dimName{dd})=0;
0411 count.(dimName{dd})=dimLength(dd);
0412 stride.(dimName{dd})=1;
0413 end
0414 end
0415 else
0416 if ftbverbose
0417 fprintf('Wrong selection of dimensions to extract.\nExtracting all values in current variable.\n');
0418 end
0419 end
0420
0421
0422 cc_names=fieldnames(count);
0423 clear read_start read_count read_stride
0424 switch sum(do_restrict)
0425 case 1
0426 switch find(do_restrict)
0427 case 1
0428
0429 switch dimens
0430
0431 case 2
0432 rr=[min(sum(count.(cc_names{1})),dimLength(1)) min(sum(count.(cc_names{2})),dimLength(2))];
0433 case 3
0434 rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0435 min(sum(count.(cc_names{2})),dimLength(2)),...
0436 min(sum(count.(cc_names{3})),dimLength(3))];
0437 end
0438
0439 eval([varnames{aa},'=nan(rr);'])
0440
0441 read_start(find(~do_restrict))=start.(cc_names{find(~do_restrict)});
0442 read_count(find(~do_restrict))=count.(cc_names{find(~do_restrict)});
0443 read_stride(find(~do_restrict))=stride.(cc_names{find(~do_restrict)});
0444
0445 for cc=1:length(start.(cc_names{find(do_restrict)}))
0446 read_start(find(do_restrict))=start.(cc_names{find(do_restrict)})(cc);
0447 read_count(find(do_restrict))=count.(cc_names{find(do_restrict)})(cc);
0448 read_stride(find(do_restrict))=stride.(cc_names{find(do_restrict)});
0449
0450 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0451
0452 eval([varnames{aa},'(cc,:)=var_dump;'])
0453 clear var_dump
0454 end
0455 case 2
0456
0457 switch dimens
0458
0459 case 2
0460 rr=[min(sum(count.(cc_names{1})),dimLength(1)) min(sum(count.(cc_names{2})),dimLength(2))];
0461 case 3
0462 rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0463 min(sum(count.(cc_names{2})),dimLength(2)),...
0464 min(sum(count.(cc_names{3})),dimLength(3))];
0465 end
0466
0467 eval([varnames{aa},'=nan(rr);'])
0468
0469 read_start(find(~do_restrict))=start.(cc_names{find(~do_restrict)});
0470 read_count(find(~do_restrict))=count.(cc_names{find(~do_restrict)});
0471 read_stride(find(~do_restrict))=stride.(cc_names{find(~do_restrict)});
0472
0473 for cc=1:length(start.(cc_names{logical(do_restrict)}))
0474 read_start(find(do_restrict))=start.(cc_names{find(do_restrict)})(cc);
0475 read_count(find(do_restrict))=count.(cc_names{find(do_restrict)})(cc);
0476 read_stride(find(do_restrict))=stride.(cc_names{find(do_restrict)});
0477 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0478 try
0479 eval([varnames{aa},'(:,cc)=var_dump;'])
0480 catch
0481 eval([varnames{aa},'(:,:,cc)=var_dump;'])
0482
0483 end
0484 clear var_dump
0485 end
0486 case 3
0487
0488 rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0489 min(sum(count.(cc_names{2})),dimLength(2)),...
0490 min(sum(count.(cc_names{3})),dimLength(3))];
0491
0492 eval([varnames{aa},'=nan(rr);'])
0493
0494
0495 for tt=find(~do_restrict)
0496 read_start(tt)=start.(cc_names{tt});
0497 read_count(tt)=count.(cc_names{tt});
0498 read_stride(tt)=stride.(cc_names{tt});
0499
0500 end
0501
0502
0503 if ~isempty(find(dimidx==5))
0504 do_time = find(dimidx==5);
0505
0506 read_start(do_time)=start.(cc_names{do_time});
0507 read_count(do_time)=count.(cc_names{do_time});
0508 read_stride(do_time)=stride.(cc_names{do_time});
0509 eval([varnames{aa},'=netcdf.getVar(nc,varID,read_start,read_count,read_stride,''double'');'])
0510 else
0511 for cc=1:length(start.(cc_names{find(do_restrict)}))
0512 read_start(find(do_restrict))=start.(cc_names{find(do_restrict)})(cc);
0513 read_count(find(do_restrict))=count.(cc_names{find(do_restrict)})(cc);
0514 read_stride(find(do_restrict))=stride.(cc_names{find(do_restrict)});
0515 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0516
0517 switch dimName{find(do_restrict)}
0518 case 'node' | 'nele'
0519 eval([varnames{aa},'(cc,:,:)=var_dump;'])
0520 case 'siglay' | 'siglev'
0521 eval([varnames{aa},'(:,cc,:)=var_dump;'])
0522 case 'time'
0523 eval([varnames{aa},'=var_dump;'])
0524
0525 end
0526 clear var_dump
0527 end
0528
0529 end
0530 end
0531 eval(['selection.',varnames{aa},'.start=start;'])
0532 eval(['selection.',varnames{aa},'.count=count;'])
0533
0534 case 2
0535
0536 switch dimens
0537
0538 case 2
0539 rr=[min(sum(count.(cc_names{1})),dimLength(1)) min(sum(count.(cc_names{2})),dimLength(2))];
0540 case 3
0541 rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0542 min(sum(count.(cc_names{2})),dimLength(2)),...
0543 min(sum(count.(cc_names{3})),dimLength(3))];
0544 end
0545
0546 eval([varnames{aa},'=nan(rr);'])
0547
0548 if ~isempty(find(dimidx==5))
0549 do_time = find(dimidx==5);
0550
0551 read_start(do_time)=start.(cc_names{do_time});
0552 read_count(do_time)=count.(cc_names{do_time});
0553 read_stride(do_time)=stride.(cc_names{do_time});
0554
0555
0556
0557
0558
0559 cc=find(~do_restrict);
0560 if isempty(cc);cc=length(cc_names);end
0561 read_start(cc)=start.(cc_names{cc});
0562 read_count(cc)=count.(cc_names{cc});
0563 read_stride(cc)=stride.(cc_names{cc});
0564 do_other = setdiff(dimidx,[dimidx(cc),5]) ;
0565 do_other=find(dimidx==do_other);
0566
0567 for cc=1:length(start.(cc_names{do_other}))
0568 read_start(do_other)=start.(cc_names{do_other})(cc);
0569 read_count(do_other)=count.(cc_names{do_other})(cc);
0570 read_stride(do_other)=stride.(cc_names{do_other});
0571 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0572 switch do_other
0573 case 1
0574 eval([varnames{aa},'(cc,:,:)=var_dump;'])
0575 case 2
0576 eval([varnames{aa},'(:,cc,:)=var_dump;'])
0577 case 3
0578 eval([varnames{aa},'(:,:,cc)=var_dump;'])
0579 end
0580 clear var_dump
0581 end
0582 else
0583
0584
0585
0586 for kk=1:length(start.(cc_names{1}))
0587
0588 read_start(1)=start.(cc_names{1})(kk);
0589 read_count(1)=count.(cc_names{1})(kk);
0590 read_stride(1)=stride.(cc_names{1});
0591 for cc=1:length(start.(cc_names{2}))
0592 read_start(2)=start.(cc_names{2})(cc);
0593 read_count(2)=count.(cc_names{2})(cc);
0594 read_stride(2)=stride.(cc_names{2});
0595 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0596
0597 eval([varnames{aa},'(kk,cc)=var_dump;'])
0598 clear var_dump
0599 end
0600
0601 end
0602
0603 end
0604
0605 eval(['selection.',varnames{aa},'.start=start;'])
0606 eval(['selection.',varnames{aa},'.count=count;'])
0607
0608 case 3
0609
0610 switch dimens
0611
0612 case 2
0613 rr=[min(sum(count.(cc_names{1})),dimLength(1)) min(sum(count.(cc_names{2})),dimLength(2))];
0614 case 3
0615 rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0616 min(sum(count.(cc_names{2})),dimLength(2)),...
0617 min(sum(count.(cc_names{3})),dimLength(3))];
0618 end
0619
0620 eval([varnames{aa},'=nan(rr);'])
0621
0622 if isempty(find(dimidx==5));disp('This won''t work, try again');return;end
0623 do_time = find(dimidx==5);
0624
0625 read_start(do_time)=start.(cc_names{do_time});
0626 read_count(do_time)=count.(cc_names{do_time});
0627 read_stride(do_time)=stride.(cc_names{do_time});
0628
0629
0630
0631
0632
0633
0634 [~,do_other] = setdiff(dimidx,[dimidx(do_time)]) ;
0635 if length(count.(cc_names{do_other(1)})) <length(count.(cc_names{do_other(2)}))
0636 do_one=do_other(1);do_two=do_other(2);
0637 else
0638 do_one=do_other(2);do_two=do_other(1);
0639 end
0640
0641 for cc=1:length(start.(cc_names{do_one}))
0642 read_start(do_one)=start.(cc_names{do_one})(cc);
0643 read_count(do_one)=count.(cc_names{do_one})(cc);
0644 read_stride(do_one)=stride.(cc_names{do_one});
0645
0646 for pp=1:length(start.(cc_names{do_two}))
0647 read_start(do_two)=start.(cc_names{do_two})(pp);
0648 read_count(do_two)=count.(cc_names{do_two})(pp);
0649 read_stride(do_two)=stride.(cc_names{do_two});
0650
0651 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0652 eval([varnames{aa},'(pp,cc,:)=var_dump;'])
0653 end
0654 clear var_dump
0655 end
0656 eval(['selection.',varnames{aa},'.start=start;'])
0657 eval(['selection.',varnames{aa},'.count=count;'])
0658 case 0
0659
0660 for nn=1:length(cc_names)
0661 read_start(nn)=start.(cc_names{nn});
0662 read_count(nn)=count.(cc_names{nn});
0663 read_stride(nn)=stride.(cc_names{nn});
0664 end
0665 eval([varnames{aa},'=netcdf.getVar(nc,varID,read_start,read_count,read_stride,''double'');'])
0666 eval(['selection.',varnames{aa},'.start=start;'])
0667 eval(['selection.',varnames{aa},'.count=count;'])
0668
0669 end
0670 end
0671 eval(['data.(varnames{aa}) = ',varnames{aa},';'])
0672 eval(['clear ',varnames{aa}])
0673
0674 end
0675
0676
0677
0678
0679
0680 netcdf.close(nc)
0681
0682 if ftbverbose
0683 fprintf('end : %s \n', subname)
0684 end