function [ success ] = rfc(pFilename, pFloatDetails, pData, pTrajectory) %RFC Saves the given data to the filename in RFC format. % % Parameters: % pFilename (string) The destination filename. % pFloatDetails (struct) The FLOAT section that is stored in an RFB % file. % pData (matrix) The data that should be written to the RFC file. % Each line contains one set of data. The matrix format needs to % be the following: % IFLAG MESSAGE_NUMBER MESSAGE_DATE TEMP PRES LAT LON u v w % pTrajectory (struct) The trajectory data according to the memory % data format specification, see projects wiki. %% Initialize return variables success = false; %% Initialize variables required for processing headerString = ''; dataString = ''; %% Parameter check parameterError = false; if (~isstring(pFilename) && ~ischar(pFilename)) warning([mfilename ': Given filename is neither a string nor a char!']); parameterError = true; end if (~isstruct(pFloatDetails)) warning([mfilename ': Given float details is not a struct!']); parameterError = true; end expectedDataColumns = 10; if (size(pData, 2) ~= expectedDataColumns) warning([mfilename ': Given data has ' site(pData, 2) ' columns, but ' ... num2str(expectedDataColumns) ' expected!']); parameterError = true; end if (parameterError) return; else clear parameterError; end %% Replace all NaN with default values defaultValues = repmat(-999, 10); defaultValues(4) = -9.99; % temperature default value % start at index 4 because the first three do not have default values for i = 4:size(pData, 2) nanIndex = find(isnan(pData(:, i))); if ~isempty(nanIndex) pData(nanIndex, i) = repmat(defaultValues(i), 1, size(pData, 1)); end clear nanIndex; end %% Prepare header and add it to the file string % FLOAT NAME floatname = num2str(pFloatDetails.floatname); % FLOAT CYCLE cycle = num2str(pFloatDetails.cycle(1)); % LAUNCH PARAMETER launchPositionLat = num2str(pFloatDetails.cycle(2), '%3.2f'); launchPositionLon = num2str(pFloatDetails.cycle(3), '%3.2f'); launchTime = [pFloatDetails.launchtime, 0]; launchTimeRafosDays = num2str( ... artoa.convert.dmy2rd(launchTime(3), launchTime(2), launchTime(1)) ... ); launchTime = num2str(launchTime); % RECOVER PARAMETER recoverTime = [pFloatDetails.recovertime, 0]; recoverTimeRafosDays = num2str( ... artoa.convert.dmy2rd(recoverTime(3), recoverTime(2), recoverTime(1)) ... ); recoverTime = num2str(recoverTime); % FIRST SURFACE POSITION surfacePositionLat = num2str(pFloatDetails.cycle(9), '%3.2f'); surfacePositionLon = num2str(pFloatDetails.cycle(10), '%3.2f'); % CYCLE PARAMETER floatCycleStartTime = [pFloatDetails.cycle(4:8), 0]; % seconds always zero floatCycleStartTimeRafosDays = num2str( ... artoa.convert.dmy2rd(floatCycleStartTime(3), floatCycleStartTime(2), floatCycleStartTime(1)) ... + artoa.convert.hms2rd(floatCycleStartTime(4), floatCycleStartTime(5), 0) ... ); floatCycleStartTime = num2str(floatCycleStartTime); floatCycleEndTime = [pFloatDetails.cycle(11:15), 0]; % seconds always zero floatCycleEndTimeRafosDays = num2str( ... artoa.convert.dmy2rd(floatCycleEndTime(3), floatCycleEndTime(2), floatCycleEndTime(1)) ... + artoa.convert.hms2rd(floatCycleEndTime(4), floatCycleEndTime(5), 0) ... ); floatCycleEndTime = num2str(floatCycleEndTime); header = { ... ['** Float: ' floatname], ... ['** Variables: InterpFlag LineNum RafosDay Temp Pres Lat Lon U V W'], ... ['** Units : # # # degC dbar deg deg cm/s cm/s mm/s'], ... ['** Dummies : NA NA NA -9.99 -999 999 999 999 999 999'], ... ['** Cycle : ' cycle], ... ['** Launch position (Cycle Start position): ' ... launchPositionLat ' ' launchPositionLon], ... ['** Surface position (Cycle End position) : ' ... surfacePositionLat ' ' surfacePositionLon], ... ['** Cycle Start time : ' floatCycleStartTime ' (RAFOS day ' floatCycleStartTimeRafosDays ')'], ... ['** Launch time : ' launchTime ' (RAFOS day ' launchTimeRafosDays ')'], ... ['** Cycle End time : ' floatCycleEndTime ' (RAFOS day ' floatCycleEndTimeRafosDays ')'], ... ['** First surface Position time : ' recoverTime ' (RAFOS day ' recoverTimeRafosDays ')'], ... ['** Float clock offset (init/final) : ' num2str(pFloatDetails.offset(1,end)) ' / ' num2str(pFloatDetails.offset(2,end)),' seconds'], ... ['** -------'] ... }; headerString = strjoin(header, newline); %% COLLECT DATA STRING for i = 1:size(pData, 1) dataString = [ ... dataString ... sprintf('%12d%12d%12.2f%12.3f%12.1f%12.3f%12.3f%12.2f%12.2f%12.2f\n', pData(i, :)) ... ]; end %% IF NO TRAJECTORY AVAILABLE if (nargin == 3) headerString = [headerString newline ' * No trajectory information, flt not tracked.' newline]; saveToFile(pFilename, headerString, dataString); success = true; return; elseif (~isstruct(pTrajectory)) warning('Trajectory variable is not a struct. It will NOT be used!'); end %% TRAJECTORY IS AVAILABLE if (pTrajectory.dopplerCorrection == 1) dopplerCorrectionUsed = 'yes'; else dopplerCorrectionUsed = 'no'; end trajectoryHeader = { ... ['** Tracking method: ' char(pTrajectory.trackingMethod)], ... ['** Interpolation method: ' char(pTrajectory.interpolationMethod)], ... ['** Interpolation step size: ' num2str(pTrajectory.interval) ' hours'], ... ['** Interpolation gap size: ' num2str(pTrajectory.gapSize)], ... ['** Doppler correction: ' dopplerCorrectionUsed], ... ['** -------'], ... ['** Sound source combinations: (rafos day, sound sources, reference position, sound speed)'] ... }; trajectoryHeader = strjoin(trajectoryHeader, newline); soundSourcesHeader = ''; for i = 1:length(pTrajectory.soundSources) currentCombination = pTrajectory.soundSources(i); soundSourcesHeader = [ ... soundSourcesHeader ... '** ' num2str(currentCombination.begin) ' to ' num2str(currentCombination.end) ': ' ... strjoin(currentCombination.sources, ' ') ' ' ... num2str(currentCombination.referencePosition) ' ' ... num2str(currentCombination.soundSpeed) ... newline ... ]; end soundSourcesHeader = [ ... soundSourcesHeader ... '** -------' newline ... '** Additional Float clock offsets, seconds (beginning, end): ' ... num2str(pTrajectory.additionalFloatOffsetBegin) ... ' ' ... num2str(pTrajectory.additionalFloatOffsetEnd) newline ... '** -------' newline ... ' * l ----------' ... ]; headerString = [ ... headerString newline... trajectoryHeader newline ... soundSourcesHeader newline ... ]; %% Save to file saveToFile(pFilename, headerString, dataString); %% Update return variable success = true; %% Nested functions function saveToFile(pFilename, pHeader, pData) fid = fopen(pFilename, 'w'); fprintf(fid, pHeader); fprintf(fid, pData); fclose(fid); end end