Home > fvcom_prepro > write_FVCOM_elevtide.m

write_FVCOM_elevtide

PURPOSE ^

Write an FVCOM surface elevation time series forcing file

SYNOPSIS ^

function write_FVCOM_elevtide(Mobj,MJD,ElevationFile,MyTitle,varargin)

DESCRIPTION ^

 Write an FVCOM surface elevation time series forcing file 

 write_FVCOM_elevtide(Mobj, MJD, ElevationFile, MyTitle)

 DESCRIPTION:
   Write an FVCOM netCDF surface elevation forcing file

 INPUT:
   Mobj = Matlab mesh object with fields:
       obc_nodes - array of boundary node IDs.
       surfaceElevation - array of surface elevation values (shaped [space,
       time]).
   MJD = list of modified Modified Julian Dates of size [times] (defined
       as unlimited in the netCDF file).
   ElevationFile = name of netCDF file.
   MyTitle = casename title, written as global attribute of netCDF file.
   Optional keyword-argument pairs. These control the time variables. This
   script defaults to writing 'Times' only.
   FVCOM needs only one of:
       1. Times: character string of times
       2. Itime and Itime2: integer days and milliseconds since midnight
       3. time: float days.
   FVCOM checks for these in the order above and this script defaults to
   writing Times only. Adjust the keyword-argument pairs to your liking:

   'strtime' = set to true to output the 'Times' variable
   'inttime' = set to true to output the 'Itime' and 'Itime2' variables
   'floattime' = set to true to output the 'time' variable

 OUTPUT:
   ElevationFile, A netCDF FVCOM surface elevations tide forcing file

 EXAMPLE USAGE
   With default settings:
       write_FVCOM_elevtide(Mobj, MJD, '/tmp/elevtide.nc, 'Shelf tides')
   Enable the 'time' variable in the netCDF.
       write_FVCOM_elevtide(Mobj, MJD, '/tmp/elevtide.nc, ...
           'Shelf tides', 'floattime', true)

 Author(s):
   Pierre Cazenave (Plymouth Marine Laboratory)
   Karen Amoudry (National Oceanography Centre Liverpool)

 Revision history
   2012-08-08 (PWC) First version.
   2012-11-14 (PWC) Updated to expect Modified Julian Day rather than
   doing the conversion in here. Also put the pieces in set_elevtide in
   here to simplify the process of writing out an elevation input file.
   2012-12-04 (KJA) Updated to use surface elevation and open boundary
   nodes from Mobj.
   2013-08-16 (KJA) Updated output of Itime2 to avoid rounding errors when
   converting from double to single format.
   2013-09-03 - Removed PWC's fix for timestrings. Issue was due to
   rounding errors caused by mjulian2greg.m, which have now been fixed.
   2014-01-27 - (PWC) Simplify the ftbverbose/report stuff.
   2014-08-11 - (PWC) Add new flags to control which time variables to
   use. FVCOM reads the 'Times' variable first if present, then falls back
   to 'Itime' and 'Itime2' and finally 'time'. Also reinstate the original
   version of the calculation of Itime2 as the rounding effect was
   smoothing out the data too much, affecting its precision.

==========================================================================

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function write_FVCOM_elevtide(Mobj,MJD,ElevationFile,MyTitle,varargin)
0002 % Write an FVCOM surface elevation time series forcing file
0003 %
0004 % write_FVCOM_elevtide(Mobj, MJD, ElevationFile, MyTitle)
0005 %
0006 % DESCRIPTION:
0007 %   Write an FVCOM netCDF surface elevation forcing file
0008 %
0009 % INPUT:
0010 %   Mobj = Matlab mesh object with fields:
0011 %       obc_nodes - array of boundary node IDs.
0012 %       surfaceElevation - array of surface elevation values (shaped [space,
0013 %       time]).
0014 %   MJD = list of modified Modified Julian Dates of size [times] (defined
0015 %       as unlimited in the netCDF file).
0016 %   ElevationFile = name of netCDF file.
0017 %   MyTitle = casename title, written as global attribute of netCDF file.
0018 %   Optional keyword-argument pairs. These control the time variables. This
0019 %   script defaults to writing 'Times' only.
0020 %   FVCOM needs only one of:
0021 %       1. Times: character string of times
0022 %       2. Itime and Itime2: integer days and milliseconds since midnight
0023 %       3. time: float days.
0024 %   FVCOM checks for these in the order above and this script defaults to
0025 %   writing Times only. Adjust the keyword-argument pairs to your liking:
0026 %
0027 %   'strtime' = set to true to output the 'Times' variable
0028 %   'inttime' = set to true to output the 'Itime' and 'Itime2' variables
0029 %   'floattime' = set to true to output the 'time' variable
0030 %
0031 % OUTPUT:
0032 %   ElevationFile, A netCDF FVCOM surface elevations tide forcing file
0033 %
0034 % EXAMPLE USAGE
0035 %   With default settings:
0036 %       write_FVCOM_elevtide(Mobj, MJD, '/tmp/elevtide.nc, 'Shelf tides')
0037 %   Enable the 'time' variable in the netCDF.
0038 %       write_FVCOM_elevtide(Mobj, MJD, '/tmp/elevtide.nc, ...
0039 %           'Shelf tides', 'floattime', true)
0040 %
0041 % Author(s):
0042 %   Pierre Cazenave (Plymouth Marine Laboratory)
0043 %   Karen Amoudry (National Oceanography Centre Liverpool)
0044 %
0045 % Revision history
0046 %   2012-08-08 (PWC) First version.
0047 %   2012-11-14 (PWC) Updated to expect Modified Julian Day rather than
0048 %   doing the conversion in here. Also put the pieces in set_elevtide in
0049 %   here to simplify the process of writing out an elevation input file.
0050 %   2012-12-04 (KJA) Updated to use surface elevation and open boundary
0051 %   nodes from Mobj.
0052 %   2013-08-16 (KJA) Updated output of Itime2 to avoid rounding errors when
0053 %   converting from double to single format.
0054 %   2013-09-03 - Removed PWC's fix for timestrings. Issue was due to
0055 %   rounding errors caused by mjulian2greg.m, which have now been fixed.
0056 %   2014-01-27 - (PWC) Simplify the ftbverbose/report stuff.
0057 %   2014-08-11 - (PWC) Add new flags to control which time variables to
0058 %   use. FVCOM reads the 'Times' variable first if present, then falls back
0059 %   to 'Itime' and 'Itime2' and finally 'time'. Also reinstate the original
0060 %   version of the calculation of Itime2 as the rounding effect was
0061 %   smoothing out the data too much, affecting its precision.
0062 %
0063 %==========================================================================
0064 
0065 global ftbverbose
0066 
0067 subname = 'write_FVCOM_elevtide';
0068 if ftbverbose; fprintf('\nbegin : %s \n', subname); end
0069 
0070 % Default to string times as FVCOM looks for these first.
0071 strtime = true;
0072 inttime = false;
0073 floattime = false;
0074 for vv = 1:2:length(varargin)
0075     switch varargin{vv}
0076         case 'strtime'
0077             strtime = true;
0078         case 'inttime'
0079             inttime = true;
0080         case 'floattime'
0081             floattime = true;
0082     end
0083 end
0084 
0085 % Get a list of the open boundary nodes. Transpose Mobj.obc_nodes so the
0086 % order of the boundary nodes is preserved.
0087 tmpObcNodes = Mobj.obc_nodes';
0088 % Flip it back so it's the same shape as it would have been using the old
0089 % code.
0090 ObcNodes = tmpObcNodes(tmpObcNodes~=0)';
0091 
0092 %--------------------------------------------------------------------------
0093 % Sanity check on input and dimensions
0094 %--------------------------------------------------------------------------
0095 if ischar(MJD(1))
0096     nTimes = size(MJD, 1);
0097 else
0098     nTimes = numel(MJD);
0099 end
0100 if ftbverbose; fprintf('Number of time steps %d\n',nTimes); end
0101 
0102 nObcs = numel(ObcNodes);
0103 if ftbverbose; fprintf('Number of Open Boundary Nodes %d\n',nObcs); end
0104 
0105 [chk1, chk2] = size(Mobj.surfaceElevation);
0106 if nObcs ~= chk1 || nTimes ~= chk2
0107     fprintf('Surface elevation dimensions do not match time series and number of boundary nodes.\n')
0108     fprintf('Surface elevation nodes and time sizes: (%d, %d)\n', chk1, chk2)
0109     fprintf('Boundary nodes size: %d\n', nObcs)
0110     fprintf('Times size: %d\n', nTimes)
0111     error('Input data sizes do not match. Check and try again.');
0112 end
0113 
0114 %%
0115 %--------------------------------------------------------------------------
0116 % Dump the file
0117 %--------------------------------------------------------------------------
0118 
0119 nc=netcdf.create(ElevationFile,'clobber');
0120 
0121 % define global attributes
0122 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'type','FVCOM TIME SERIES ELEVATION FORCING FILE')
0123 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'title',MyTitle)
0124 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'history', sprintf('File created with %s from the MATLAB fvcom-toolbox', subname))
0125 
0126 % define dimensions
0127 nobc_dimid=netcdf.defDim(nc,'nobc',nObcs);
0128 time_dimid=netcdf.defDim(nc,'time',netcdf.getConstant('NC_UNLIMITED'));
0129 date_str_len_dimid=netcdf.defDim(nc,'DateStrLen',26);
0130 
0131 % define variables and attributes
0132 nobc_varid=netcdf.defVar(nc,'obc_nodes','NC_INT',nobc_dimid);
0133 netcdf.putAtt(nc,nobc_varid,'long_name','Open Boundary Node Number');
0134 netcdf.putAtt(nc,nobc_varid,'grid','obc_grid');
0135 
0136 iint_varid=netcdf.defVar(nc,'iint','NC_INT',time_dimid);
0137 netcdf.putAtt(nc,iint_varid,'long_name','internal mode iteration number');
0138 
0139 if floattime
0140     time_varid=netcdf.defVar(nc,'time','NC_FLOAT',time_dimid);
0141     netcdf.putAtt(nc,time_varid,'long_name','time');
0142     netcdf.putAtt(nc,time_varid,'units','days since 1858-11-17 00:00:00');
0143     netcdf.putAtt(nc,time_varid,'format','modified julian day (MJD)');
0144     netcdf.putAtt(nc,time_varid,'time_zone','UTC');
0145 end
0146 
0147 if inttime
0148     itime_varid=netcdf.defVar(nc,'Itime','NC_INT',time_dimid);
0149     netcdf.putAtt(nc,itime_varid,'units','days since 1858-11-17 00:00:00');
0150     netcdf.putAtt(nc,itime_varid,'format','modified julian day (MJD)');
0151     netcdf.putAtt(nc,itime_varid,'time_zone','UTC');
0152 
0153     itime2_varid=netcdf.defVar(nc,'Itime2','NC_INT',time_dimid);
0154     netcdf.putAtt(nc,itime2_varid,'units','msec since 00:00:00');
0155     netcdf.putAtt(nc,itime2_varid,'time_zone','UTC');
0156 end
0157 
0158 if strtime
0159     Times_varid=netcdf.defVar(nc,'Times','NC_CHAR',[date_str_len_dimid, time_dimid]);
0160     netcdf.putAtt(nc,Times_varid,'time_zone','UTC');
0161 end
0162 
0163 elevation_varid=netcdf.defVar(nc,'elevation','NC_FLOAT',[nobc_dimid, time_dimid]);
0164 netcdf.putAtt(nc,elevation_varid,'long_name','Open Boundary Elevation');
0165 netcdf.putAtt(nc,elevation_varid,'units','meters');
0166 
0167 % end definitions
0168 netcdf.endDef(nc);
0169 
0170 % write data
0171 netcdf.putVar(nc,nobc_varid,ObcNodes);
0172 netcdf.putVar(nc,iint_varid,0,nTimes,1:nTimes);
0173 if strtime
0174     % If out MJD data is characters, assume we've already got a suitable
0175     % array of Time strings. Use those to create an MJD array to write to
0176     % netCDF. This is sometimes preferable to having MJD as an array of
0177     % floats in the case where we've read in a 'time' variable from a
0178     % netCDF file and its precision is insufficient to actually store the
0179     % times properly. netCDF, otherwise, create one assuming we've actually
0180     % got Modified Julian Days. If we've been given an array of floats,
0181     % then just dump those to netCDF as before.
0182     if ischar(MJD(1))
0183         nStringOut = MJD';
0184         MJD = datenum(nStringOut', 'YYYY-mm-dd HH:MM:SS.FFF') - 678942;
0185     else
0186         nStringOut = char();
0187         [nYr, nMon, nDay, nHour, nMin, nSec] = mjulian2greg(MJD);
0188         for i=1:nTimes
0189             nDate = [nYr(i), nMon(i), nDay(i), nHour(i), nMin(i), nSec(i)];
0190             nStringOut = [nStringOut, sprintf('%04i/%02i/%02i %02i:%02i:%09.6f', nDate)];
0191         end
0192     end
0193     netcdf.putVar(nc,Times_varid,nStringOut);
0194 end
0195 if floattime
0196     netcdf.putVar(nc,time_varid,0,nTimes,MJD);
0197 end
0198 if inttime
0199     netcdf.putVar(nc,itime_varid,floor(MJD));
0200     netcdf.putVar(nc,itime2_varid,0,nTimes,round(mod(MJD,1) * 24 * 60 * 60 * 1000));
0201 end
0202 netcdf.putVar(nc,elevation_varid,Mobj.surfaceElevation);
0203 
0204 % close file
0205 netcdf.close(nc);
0206 
0207 if ftbverbose; fprintf('end   : %s \n', subname); end
0208

Generated on Wed 20-Feb-2019 16:06:01 by m2html © 2005