ladcp2cdf.m
changeset 11 d71acdec556a
parent 0 0a450563f904
child 17 f5a63c03d9c8
--- a/ladcp2cdf.m	Thu Jul 18 04:12:24 2013 -0400
+++ b/ladcp2cdf.m	Wed Sep 18 14:29:58 2013 +0000
@@ -1,143 +1,176 @@
-function [] = ladcp2cdf(fname,struct,st2,st3,st4,st5,st6,st7);
-% function [] = ladcp2cdf(fname,struct,st2,st3,st4,st5,st6,st7);
+function [] = ladcp2cdf(fname,dr_struct,da,p,ps,f,att);
+% function [] = ladcp2cdf(fname,dr_struct,da,p,ps,f,att);
 %
-% function to save LADCP data into a netcdf file
+% function to save LADCP data into a netcdf file for MatLab version 2012a
+%
+% input  :	fname		- output filename
+%			dr_struct	- main inversion results (velocity profiles)
+%			da..att	- arbitrary metadata structures
 %
-% input  :	fname		- filename
-%		struct		- structure containing the data
-%		struct2		- structure containing the attributes
-%
-% version 0.1	last change 08.03.2002
+% Created By:   Diana Cardoso, Bedford Institute of Oceangraphy
+%               Diana.Cardoso@dfo-mpo.gc.ca
+% Description:  Based on LDEO software to Process LADCP, version IX.8,
+%               script ladcp2cdf.m version 0.1	last change 08.03.2002. 
+%               maintained by A.M. Thurnherr and downloaded from:
+%       http://www.ldeo.columbia.edu/cgi-bin/ladcp-cgi-bin/hgwebdir.cgi
+%       The function ladcp2cdf was changed to run with the the Matlab
+%       version 2012, which now supports netcdf.
+
+%======================================================================
+%                    L A D C P 2 C D F . M 
+%                    doc: Thu Aug 15 10:52:55 2013
+%                    dlm: Wed Aug 28 12:31:16 2013
+%                    (c) 2013 A.M. Thurnherr, from code contributed by D. Cardoso
+%                    uE-Info: 99 0 NIL 0 0 72 0 2 8 NIL ofnI
+%======================================================================
 
-% Felix Tubiana Added Variable Attributes 12.12.03
-% G.Krahmann, LDEO Mar 2002
-% warning off MATLAB:DeprecatedLogicalAPI
+% NOTES:
+%	- This version creates slightly different files than the original version
+%	  created by Visbeck/Krahmann. In the original version, the contents of the
+%	  dr structure end up as top-level variables and the contents of
+%	  the da, p, ps, f and att structures end of as global attributes. In 
+%	  the new version, the latter are saved as sub-structures, with _struct appended
+%	  to the internal names to avoid conflicts.
+
+% HISTORY:
+%   Aug 15, 2013: - incorporated this code, supplied Diana Cardoso, into IX_10beta
+%		  - modified doc in header
+%		  - renamded struct variable to dr_struct
+%		  - removed 'cd' in and out of results directory (pathnames work just fine)
+%		  - delete netcdfile before it is written to (old 'clobber' option)
+%		  - removed 'l' suffix from all dims
+%		  - replaced yes/no logical vals by true/false
+%		  - renamed substructures from st2..st6 to internal names (da,p,ps,f,att)
+%   Aug 28, 2013: - incorporated bug fix provided by Diana Cardoso to prevent lat,lon,name and 
+%		    date to be stored 2cd in the nc file, which can make the code
+%		    bomb if the length of any other var is 6 (or equal to the length of name?)
 
 % check arguments
 if nargin<2
   error('need two input arguments')
 end
-if ~isstruct(struct)
-  error('second argument must be a structure')
+if ~isstruct(dr_struct)
+  error('second argument must be a dr structure')
 end
 
-% check filename
-fname = deblank(fname);
-
-nc = netcdf(fname,'clobber');
-
-if isempty(nc)
-  error('can not open netcdf file')
+netcdfile = deblank(fname); %remove any blanks from string end
+if exist(netcdfile,'file')
+	delete(netcdfile)
 end
 
-
-% look for the three dimension bases
+%Determine dimensions of variables
 lbot = 0;
 lz = 0;
 ltim = 0;
 lsadcp = 0;
-if isfield(struct,'z');
-  lz = length(getfield(struct,'z'));
-end  
-if isfield(struct,'tim');
-  ltim = length(getfield(struct,'tim'));
+
+if isfield(dr_struct,'z');
+  lz = length(getfield(dr_struct,'z'));
 end  
-if isfield(struct,'zbot');
-  lbot = length(getfield(struct,'zbot'));
+if isfield(dr_struct,'tim');
+  ltim = length(getfield(dr_struct,'tim'));
 end  
-if isfield(struct,'z_sadcp');
-  lsadcp = length(getfield(struct,'z_sadcp'));
+if isfield(dr_struct,'zbot');
+  lbot = length(getfield(dr_struct,'zbot'));
+end  
+if isfield(dr_struct,'z_sadcp');
+  lsadcp = length(getfield(dr_struct,'z_sadcp'));
 end  
 
-% define dimensions in netcdf file
-if lz>0
-  nc('z') = fix(lz);
-end
-if ltim>0
-  nc('tim') = fix(ltim);
-end
-if lbot>0
-  nc('zbot') = fix(lbot);
-end
-if lsadcp>0
-  nc('z_sadcp') = fix(lsadcp);
-end
-nc('lat') = 1;
-nc('lon') = 1;
-nc('date') = 6;
-nc('name') = length(getfield(struct,'name'));
-
-% define standard variables
-nc{'lat'} = ncfloat('lat');
-nc{'lon'} = ncfloat('lat');
-nc{'date'} = ncint('date');
-nc{'name'} = ncchar('name');
+% % define dimensions in netcdf file and standard variables
+nccreate(netcdfile,'lat','Dimensions',{'lat' 1},'Datatype','single');
+nccreate(netcdfile,'lon','Dimensions',{'lon' 1},'Datatype','single');
+nccreate(netcdfile,'date','Dimensions',{'date' 6},'Datatype','int32');
+nccreate(netcdfile,'name','Dimensions',{'name' length(getfield(dr_struct,'name'))},'Datatype','char');
 
 % store standard variables
-nc{'lat'}(:) = struct.lat;
-nc{'lon'}(:) = struct.lon;
-nc{'date'}(:) = struct.date;
-nc{'name'}(:) = struct.name;
+ncwrite(netcdfile,'lat',dr_struct.lat);
+ncwrite(netcdfile,'lon',dr_struct.lon);
+ncwrite(netcdfile,'date',dr_struct.date);
+ncwrite(netcdfile,'name',dr_struct.name);
 
 % parse fieldnames, define the proper variable and store it
-fnames = fieldnames(struct);
+fnames = fieldnames(dr_struct);
+nn=strncmp('name',fnames,6); nla=strncmp('lat',fnames,3); 	% find, name, lat,lon,date from fnames
+nlo=strncmp('lon',fnames,3); nda=strncmp('date',fnames,4);
+ntot=[nn+nla+nlo+nda]; Ktot = logical(ntot);
+fnames(Ktot,:)=[];						% remove , name, lat,lon,date from fnames
+
 for n=1:size(fnames,1)
-  dummy = getfield(struct,fnames{n});
+  dummy = getfield(dr_struct,fnames{n});
   if length(dummy)==lz
-    eval(['nc{''',fnames{n},'''} = ncfloat(''z'');'])
-    eval(['nc{''',fnames{n},'''}(:) = dummy;'])
+    nccreate(netcdfile,fnames{n},'Dimensions',{fnames{n} fix(lz)},'Datatype','single');
+    ncwrite(netcdfile,fnames{n},dummy);
   end
   if length(dummy)==ltim
-    eval(['nc{''',fnames{n},'''} = ncfloat(''tim'');'])
-    eval(['nc{''',fnames{n},'''}(:) = dummy;'])
+    nccreate(netcdfile,fnames{n},'Dimensions',{fnames{n} fix(ltim)},'Datatype','single');
+    ncwrite(netcdfile,fnames{n},dummy);
   end
   if length(dummy)==lbot
-    eval(['nc{''',fnames{n},'''} = ncfloat(''zbot'');'])
-    eval(['nc{''',fnames{n},'''}(:) = dummy;'])
+    nccreate(netcdfile,fnames{n},'Dimensions',{fnames{n} fix(lbot)},'Datatype','single');
+    ncwrite(netcdfile,fnames{n},dummy);
   end
   if length(dummy)==lsadcp
-    eval(['nc{''',fnames{n},'''} = ncfloat(''z_sadcp'');'])
-    eval(['nc{''',fnames{n},'''}(:) = dummy;'])
+    nccreate(netcdfile,fnames{n},'Dimensions',{fnames{n} fix(lsadcp)},'Datatype','single');
+    ncwrite(netcdfile,fnames{n},dummy);
   end
 end
+
+add_struct(netcdfile,'da_struct',da)
+add_struct(netcdfile,'p_struct',p)
+add_struct(netcdfile,'ps_struct',ps)
+add_struct(netcdfile,'f_struct',f)
+add_struct(netcdfile,'att_struct',att)
+
+end % function
+
+%----------------------------------------------------------------------
+
+function [] = add_struct(ncf,snm,a)
   
-% parse fieldnames and add them to the netcdf file  
-for i=2:(nargin-1)
-   eval(['a=st',int2str(i),';']);
    fnames = fieldnames(a);
    if isstruct(a)
       if ~isstruct(eval(['a.' fnames{1}])) % No SubStructure
-	 dummy='New Structure';
-	 eval(['nc.',['st',int2str(i)],'=dummy;'])
-	 for n = 1:size(fnames,1)
-	    dummy = getfield(a,fnames{n});
-	    if size(dummy,1)==1
-	       if isstr(dummy)
-		  eval(['nc.',fnames{n},'=dummy;'])
-	       else
-		  eval(['nc.',fnames{n},'=dummy(:);'])
-	       end    
-	    end
-	 end
+	nccreate(ncf,snm,'Datatype','char');
+
+	for n = 1:size(fnames,1)
+		dummy = getfield(a,fnames{n});
+	    	if size(dummy,1)==1
+	       		if isstr(dummy)
+                		ncwriteatt(ncf,snm,fnames{n},dummy);
+	       		elseif islogical(dummy)
+		        	if dummy, dummy='true';
+		               	else, 	  dummy='false';
+		               	end
+				ncwriteatt(ncf,snm,fnames{n},dummy);
+			else
+		                ncwriteatt(ncf,snm,fnames{n},dummy(:));
+			end    
+		end
+	end % for n
       else % SubStructures -> Variable Attributes
-	 for n = 1:size(fnames,1)
-	    atts = eval(['fieldnames(a.' fnames{n} ');']);
-	    for j = 1:size(atts,1)
-	       dummy = eval(['a.' fnames{n} '.' atts{j} ';']);
-	       if size(dummy,1) == 1
-		  if isstr(dummy)
-		     eval(['nc{''',fnames{n}, '''}.' atts{j} '=dummy;'])
-		  else
-		     eval(['nc{''',fnames{n}, '''}.' atts{j} '=dummy(:);'])
-		  end    
-	       end
-	    end	       
-	 end
-      end
-   else
+	for n = 1:size(fnames,1)
+		atts = eval(['fieldnames(a.' fnames{n} ');']);
+	        finfo = ncinfo(ncf);
+        	FieldNames = {finfo. Variables.Name};
+	        existField=strmatch(fnames{n}, FieldNames);
+        	if isempty(existField)
+			nccreate(ncf,fnames{n},'Datatype','char');
+	        end
+		for j = 1:size(atts,1)
+			dummy = eval(['a.' fnames{n} '.' atts{j} ';']);
+			if size(dummy,1) == 1
+				if ischar(dummy)
+		                    ncwriteatt(ncf,fnames{n},atts{j},dummy);
+                		else
+		                    ncwriteatt(ncf,fnames{n},atts{j},dummy(:));
+                		end
+			end
+		end	       
+	 end % for n
+      end % else (substructures or not)
+   else % if issstruct(a)
       disp(' not structure')
    end
-end
+end % function
 
-% close netcdf file
-close(nc)