commit af986a42977a692fb925feec5cc9ef8b32dcf5a0
Author: Joshua Simmons <z3288267@ad.unsw.edu.au>
Date:   Tue Feb 20 10:47:20 2018 +1100

    init commit

diff --git a/RUN_sbeach_model.m b/RUN_sbeach_model.m
new file mode 100644
index 0000000..51f653a
--- /dev/null
+++ b/RUN_sbeach_model.m
@@ -0,0 +1,120 @@
+% Written by Joshua Simmons 11/02/2015 and updated 17/11/2017
+% to convert from fielddata storage struct to SBEACH toolbox.
+
+clear
+clc
+
+%% Settings
+%profiledata locations
+basedatapath = '.\example\input_data\';
+setupoutputpath = '.\temp\';
+infooutpath = '.\example\setup_info\';
+
+sbeachexepath = '.\sbeach_exe\final_exe\SBEACH.exe';
+
+%meta
+site = 'narrabeen';
+stormid = '2015';
+
+%write file to
+writetofile = 1; %boolean 1 = write to file, 0 = just SBEACHout.
+
+% other parameters;
+sbts = 2; %time step length minutes
+%% Code - format the data
+%load profile data - account for different data names - lin/poly
+pfdata = load([basedatapath 'morphology\processed\morphology_' site '_' stormid '.mat']);
+fns1 = fieldnames(pfdata);
+pfdata = pfdata.(fns1{1});
+
+%load wavedata
+wavedata = load([basedatapath 'fielddata\wave\processed\wavedata_' site '_' stormid '.mat']);
+fns2 = fieldnames(wavedata);
+wavedata = wavedata.(fns2{1});
+
+%load tidedata
+tidedata = load([basedatapath 'fielddata\tide\processed\tidedata_' site '_' stormid '.mat']);
+fns3 = fieldnames(tidedata);
+tidedata = tidedata.(fns3{1});
+
+% load the profileinfo file
+profileinfo = load([infooutpath 'profileinfo_' site '.mat']);
+fns2 = fieldnames(profileinfo);
+profileinfo = profileinfo.(fns2{1});
+
+%check for dimension match
+if length(pfdata.data) ~= length(wavedata.ns.data)
+    error('Wave data information does not match the morphology data')
+end
+
+%get the depth contour
+sbdepth = wavedata.ns.contour(1:2);
+
+pathrun = cell(length(pfdata.data),1);
+
+%do the modelling
+fprintf('Setting up %d SBEACH models...', length(pfdata.data))
+for ii = 1:length(pfdata.data)
+    if ~isnan(pfdata.data(ii).initial.x)
+        fprintf('%d..',ii)
+        pfid = ['PF' num2str(ii)];
+        
+        %get profile info    
+        pfx = pfdata.data(ii).initial.x;
+        pfz = pfdata.data(ii).initial.z;
+
+        %angle of pf from true north
+        pfangle = profileinfo.data(ii).TN; %angle from true north
+    
+        outpath = [setupoutputpath 'sb_' pfid '\'];
+%         outpath = [setupoutputpath 'sb_' site '_' stormid '_' pfid '\'];
+        
+        sb_model = fsbeach_setupmodel(...
+            'bathy',    { 'x', pfx, 'z', pfz}, ...
+            'waves',    { 'time', wavedata.ns.data(ii).datenums, 'Hsig', wavedata.ns.data(ii).Hsig, 'Tp1', wavedata.ns.data(ii).Tp1, ...
+                         'ang', wavedata.ns.data(ii).Wdir, 'pfang', pfangle}, ...
+            'tide',     { 'time', tidedata.time,'elev', tidedata.tide}, ...
+            'settings', { 'DT', sbts, 'K', 2.5e-6, 'BMAX', 28.5, 'D50', 0.455 ...
+                        }, ...
+            'path', outpath, ...
+            'name', ['sb_' pfid] ...
+        );
+        
+        % variable grid can be specified in settings with e.g.:
+        % 'NGRID', 3,  'DXV', [1 5 10], 'NDXV', [115 30 28]
+        
+        % hard bottom can be specified in bathy with e.g.:
+        % 'hbz', pfz-1
+    
+        measured(ii).x = pfdata.data(ii).measured.x;
+        measured(ii).z = pfdata.data(ii).measured.z;
+        
+        pathrun{ii} = sb_model.path;
+    end
+end
+
+fprintf('\n')
+fprintf('Running %d SBEACH models...', length(pathrun))
+%now run sbeach EXE on the files setup
+for ii = 1:length(pathrun)
+    fprintf('%d..',ii)
+    [fail, cmdout] = fsbeach_runmodel(pathrun{ii},sbeachexepath);
+    if fail
+        error(cmdout);
+    end
+end
+
+fprintf('\n')
+fprintf('Collecting SBEACH results...\n')
+%now collect the sbeach results
+sbout = fsbeach_collectresults(pathrun);
+
+fprintf('Getting measured data...\n')
+%attached the measured data
+sbout.measured = measured;
+
+fprintf('Processing SBEACH results...\n')
+%evaulate results
+sbout = fsbeach_processresults(sbout);
+
+fprintf('Done!\n')
\ No newline at end of file
diff --git a/SBEACH_GLUE_setup.m b/SBEACH_GLUE_setup.m
new file mode 100644
index 0000000..42e4b7b
--- /dev/null
+++ b/SBEACH_GLUE_setup.m
@@ -0,0 +1,169 @@
+% Written by Joshua Simmons 11/02/2015 and updated on 11/01/2016
+% to convert from fielddata storage struct to SBEACH compatible format.
+
+clear
+clc
+
+%% Settings
+%all the initial files location
+%specify folder with Mitch's bathymetry and field data setup for xbeach.
+setupoutputpath = 'D:\7 Erosion Models\a_nb_model_comparison\sbeach\model_setup\setup_folders\';
+setupbasepath = 'D:\7 Erosion Models\a_nb_model_comparison\sbeach\model_setup\';
+
+basebatchrunpath = 'D:\7 Erosion Models\a_nb_model_comparison\sbeach\model_results\src\';
+
+% meta
+site = 'deewhy';
+
+% stormid = '2007';
+% stormid = '2011';
+% stormid = '2014';
+stormid = '2015';
+
+%profile info - CHECK
+pfno = 5;
+
+% model parameters
+%parameter vals - leave as '' if params to be generated
+paramload = 'D:\7 Erosion Models\a_nb_model_comparison\sbeach\params\bigparams_K_EPS_BMAX.mat';
+% paramload = '';
+
+%or specify stats
+paramsname = {'K','EPS','BMAX'}; %K divided by 3600 below to bring into seconds, Cs for R2;
+% paramsrange = {[0.5e-6 2.5e-6],[0.001 0.003],[15 30]}; % give range as [min max] then fed into rand()
+paramsrange = {[1.75e-6 1.75e-6],[0.002 0.002],[28.5 28.5]}; % give range as [min max] then fed into rand()
+nruns = 10000; %number of parameter conmbinations
+
+nrunst = 1;
+nrunend = 10000;
+
+%% Code - format the data
+%generate param combos
+if isempty(paramload)
+    for aa = 1:length(paramsname)
+        tmpmin = paramsrange{aa}(1);
+        tmpmax = paramsrange{aa}(2);
+        params(:,aa) = (tmpmax-tmpmin).*rand(nruns,1) + tmpmin;
+    end
+    bigparams.name = paramsname;
+    bigparams.value = params;
+else
+    bigparams = load(paramload);
+    fnsparams = fieldnames(bigparams);
+    bigparams = bigparams.(fnsparams{1,1});
+    params = bigparams.value;
+    if sum(strcmp(bigparams.name,paramsname)) ~= length(paramsname)
+        error('Parameter names in loaded file do not match those specified')
+    end
+end
+
+%load pf info
+profileinfo = load([setupbasepath 'setup_info\profileinfo_' site '.mat']);
+fns2 = fieldnames(profileinfo);
+profileinfo = profileinfo.(fns2{1});
+%load cfg info
+cfginfo = load([setupbasepath 'setup_info\cfginfo_' site '_' stormid '_PF' num2str(pfno) '.mat']);
+fns3 = fieldnames(cfginfo);
+cfginfo = cfginfo.(fns3{1});
+
+%get the names of the files copying across
+dns1 = dir([setupoutputpath 'sb_' site '_' stormid '_PF' num2str(pfno) '\']);
+dns1dirs = {dns1.name};  % Get a list of the subdirectories
+dns1ind2 = ~ismember(dns1dirs,{'.','..'});  % Find index of subdirectories
+dns1 = dns1(dns1ind2);
+
+allfilelocs = cell(nruns,1);
+% not done VVVV
+%do the modelling
+for ii = nrunst:nrunend
+    CFGname = ['PF' num2str(pfno) '_Run_' num2str(ii) '.CFG'];
+    tmpprintdir = [basebatchrunpath site '_' stormid '_PF' num2str(pfno) '\PF' num2str(pfno) '_Run_' num2str(ii) '\'];
+    if ~exist(tmpprintdir,'dir')
+        mkdir(tmpprintdir)
+    end
+    %now copy the setup files across
+    copyfile([setupoutputpath 'sb_' site '_' stormid '_PF' num2str(pfno) '\*'],tmpprintdir);
+    
+    % now change the contents of CFG file
+    fin   = fopen([setupbasepath 'base.CFG']) ;   
+    fout  = fopen([tmpprintdir 'temp.CFG'], 'w');
+    tline = fgetl(fin);
+    while ischar(tline)
+        %replace:
+        %filename
+        if (~isempty(strfind(tline, '%RPLCNAME%')))
+            tline = strrep(tline, '%RPLCNAME%', ['_Run_' num2str(ii)]);
+        end
+        %profile ID
+        if (~isempty(strfind(tline, '%RPLCPFID%')))
+            tline = strrep(tline, '%RPLCPFID%', ['PF' num2str(pfno)]);
+        end
+        %run number
+        if (~isempty(strfind(tline, '%RPLCRNUM%')))
+            tline = strrep(tline, '%RPLCRNUM%', num2str(ii));
+        end
+        %calculation cells
+        %number
+        if (~isempty(strfind(tline, '%RPLCNDX%')))
+            tline = strrep(tline, '%RPLCNDX%', num2str(cfginfo.NDX));
+        end
+        %landward boundary
+        if (~isempty(strfind(tline, '%RPLCXSTART%')))
+            tline = strrep(tline, '%RPLCXSTART%', num2str(cfginfo.XSTART));
+        end
+        %spacing between
+        if (~isempty(strfind(tline, '%RPLCDXC%')))
+            tline = strrep(tline, '%RPLCDXC%', num2str(cfginfo.DXC));
+        end
+        
+        %calculation time
+        %number
+        if (~isempty(strfind(tline, '%RPLCNDT%')))
+            tline = strrep(tline, '%RPLCNDT%', num2str(cfginfo.NDT));
+        end
+        %steps
+        if (~isempty(strfind(tline, '%RPLCDT%')))
+            tline = strrep(tline, '%RPLCDT%', num2str(cfginfo.DT));
+        end
+        
+        %steps
+        if (~isempty(strfind(tline, '%RPLCD50%')))
+            tline = strrep(tline, '%RPLCD50%', num2str(profileinfo.data(pfno).d50*1000));
+        end
+        
+        %check for params
+        for aa = 1:length(paramsname)
+            if (~isempty(strfind(tline, ['%RPLC' paramsname{aa} '%']))) 
+                tline = strrep(tline, ['%RPLC' paramsname{aa} '%'], num2str(params(ii,aa)));
+            end
+        end
+        %now print the final string
+        fprintf(fout,'%s\r\n',tline);    
+        tline = fgetl(fin);
+    end
+    fclose(fin);
+    fclose(fout);
+    
+    %rename CFG to original name
+    try
+        movefile([tmpprintdir 'temp.CFG'],[tmpprintdir CFGname])
+    catch
+        fileattrib([tmpprintdir 'temp.CFG'],'+w')
+        movefile([tmpprintdir 'temp.CFG'],[tmpprintdir CFGname])
+    end
+    
+    %change file name
+    for jj = 1:length(dns1)
+        movefile([tmpprintdir dns1(jj).name],[tmpprintdir 'PF' num2str(pfno) '_Run_' num2str(ii) dns1(jj).name(end-3:end)])
+    end
+    
+    %save location of file
+    allfilelocs{ii,1} = ['PF' num2str(pfno) '_Run_' num2str(ii) '\PF' num2str(pfno) '_Run_' num2str(ii)];
+end
+
+%write allfilelocs to .txt
+fid = fopen([basebatchrunpath site '_' stormid '_PF' num2str(pfno) '\SBEACHrun_loc.txt'],'w');
+for kk = 1:length(allfilelocs)
+    fprintf(fid,'%s\r\n',allfilelocs{kk});
+end
+fclose(fid);
\ No newline at end of file
diff --git a/SBEACH_storm_setup.m b/SBEACH_storm_setup.m
new file mode 100644
index 0000000..f02f9e3
--- /dev/null
+++ b/SBEACH_storm_setup.m
@@ -0,0 +1,140 @@
+% Written by Joshua Simmons 11/02/2015 and updated 20/01/2016
+% to convert from fielddata storage struct to SBEACH compatible format.
+
+clear
+clc
+
+%% Settings
+%profiledata locations
+basedatapath = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\';
+setupoutputpath = 'D:\7 Erosion Models\a_nb_model_comparison\sbeach\model_setup\setup_folders\';
+infooutpath = 'D:\7 Erosion Models\a_nb_model_comparison\sbeach\model_setup\setup_info\';
+
+%meta
+site = 'monavale';
+
+% stormid = '2007';
+% stormid = '2011';
+% stormid = '2014';
+stormid = '2015';
+
+%write file to
+writetofile = 1; %boolean 1 = write to file, 0 = just SBEACHout.
+
+% other parameters;
+sbts = 5; %time step length minutes
+%% Code - format the data
+%load profile data - account for different data names - lin/poly
+pfdata = load([basedatapath 'morphology\processed\morphology_' site '_' stormid '.mat']);
+fns1 = fieldnames(pfdata);
+pfdata = pfdata.(fns1{1});
+
+%load wavedata
+wavedata = load([basedatapath 'fielddata\wave\processed\wavedata_' site '_' stormid '.mat']);
+fns2 = fieldnames(wavedata);
+wavedata = wavedata.(fns2{1});
+
+%load tidedata
+tidedata = load([basedatapath 'fielddata\tide\processed\tidedata_' site '_' stormid '.mat']);
+fns3 = fieldnames(tidedata);
+tidedata = tidedata.(fns3{1});
+
+% load the profileinfo file
+profileinfo = load([infooutpath 'profileinfo_' site '.mat']);
+fns2 = fieldnames(profileinfo);
+profileinfo = profileinfo.(fns2{1});
+
+%check for dimension match
+if length(pfdata.data) ~= length(wavedata.ns.data)
+    error('Wave data information does not match the morphology data')
+end
+
+%check start time
+if tidedata.time(1) ~= wavedata.os.datenums(1)
+    error('Start times for wave and tide data dont match')
+end
+if tidedata.time(end) ~= wavedata.os.datenums(end)
+    error('End times for wave and tide data dont match. Make sure start/end times are hourly (for wave data).')
+end
+
+%check and allocate time parameters;
+sbtidetime = round((tidedata.time - tidedata.time(1))*24*60);
+%check time steps
+diffsbtidetime = diff(sbtidetime);
+if any(diffsbtidetime~=diffsbtidetime(1))
+    error('Inconsistent time steps in tide data');
+end
+
+%now check the wave data lines up (os only required the rest if copied)
+sbwavetime = round((wavedata.os.datenums - wavedata.os.datenums(1))*24*60);
+diffsbwavetime = diff(sbwavetime);
+if any(diffsbwavetime~=diffsbwavetime(1))
+    error('Inconsistent time steps in wave data');
+end
+
+%get the depth contour
+sbdepth = wavedata.ns.contour(1:2);
+
+%do the modelling
+for ii = 1:length(pfdata.data)
+    if ~isnan(pfdata.data(ii).initial.x)
+        pfid = ['PF' num2str(ii)];
+        %get profile info    
+        prifile = [pfdata.data(ii).initial.x pfdata.data(ii).initial.z]; %initial pf
+
+        %angle of pf from true north
+        pfangle = profileinfo.data(ii).TN; %angle from true north
+
+        %create the other information required for files
+        % for .WAV and .ANG file - wave height/period and angle files
+        wavfile = [wavedata.ns.data(ii).Hsig wavedata.ns.data(ii).Tp1];
+        angfile = -1*(wavedata.ns.data(ii).Wdir-pfangle); %correct to SBEACH wave angle convention as per report 3 pg 19
+        wavets = sbwavetime(2)-sbwavetime(1); %wave time step minutes
+
+        % for .ELV file - water elevation file
+        elvfile = tidedata.tide;
+        tidets = sbtidetime(2)-sbtidetime(1); %tide time step
+
+        totaltimewav = sbwavetime(end);
+        totaltimetide = sbtidetime(end);
+        if totaltimewav - totaltimetide ~= 0
+            disp('Warning: difference between wave and tide total times')
+        end
+        totaltime = totaltimetide;
+        totalmodeltimesteps = totaltime/sbts;
+
+        disp([pfid ':'])
+        disp(['A.10 - Total Time steps: ' num2str(totalmodeltimesteps)])
+        disp(['B.6 - DTWAV: ' num2str(wavets)])
+        disp(['B.11 - DTANG: ' num2str(wavets)])
+        disp(['B.12 - DMEAS: ' sbdepth])
+        disp(['B.20 - DTELEV: ' num2str(tidets)])
+
+        outpath = [setupoutputpath 'sb_' site '_' stormid '_' pfid '\'];
+
+        cfginfo.NDT = totalmodeltimesteps;
+        cfginfo.DT = sbts;
+        cfginfo.DXC = pfdata.data(ii).initial.x(2)-pfdata.data(ii).initial.x(1);
+        cfginfo.NDX = length(pfdata.data(ii).initial.x)-1;
+        [cfginfo.XSTART,~] = min(pfdata.data(ii).initial.x);
+        cfginfo.DTWAV = wavets;
+        cfginfo.DTANG = wavets;
+        cfginfo.DMEAS = str2double(sbdepth);
+        cfginfo.DTELEV = tidets;
+
+
+        %write to files
+        if writetofile
+            if ~exist(outpath, 'dir')
+                mkdir(outpath)
+            else
+                delete([outpath '\*'])
+            end        
+            writetofilepri(prifile, outpath, [site '_' stormid '_' pfid])
+            writetofilewav(wavfile, outpath, [site '_' stormid '_' pfid])
+            writetofileang(angfile, outpath, [site '_' stormid '_' pfid])
+            writetofileelv(elvfile, outpath, [site '_' stormid '_' pfid])
+            save([infooutpath 'cfginfo_' site '_' stormid '_' pfid '.mat'],'cfginfo')
+        end
+    end
+end
\ No newline at end of file
diff --git a/calc_TNorientation.m b/calc_TNorientation.m
new file mode 100644
index 0000000..92917b1
--- /dev/null
+++ b/calc_TNorientation.m
@@ -0,0 +1,38 @@
+% Written by Joshua Simmons 20/01/16 to calculate angle for TN for SBeach
+% modelling purposes.
+
+% NOTE: this code assumes that the furthest offshore point (-10m) is the
+% x(end) and the furthest inshore point is in x(1) (in line with the xbeach
+% co-ordinate system)
+
+clear
+clc
+
+% load('D:\7 Erosion Models\a_nb_model_comparison\xbeach\other_data\narra_xyz_for_alfa.mat')
+% 
+% for ii = 1:length(pfxy)
+%     x = [pfxy(ii).x(1) pfxy(ii).x(end)];
+%     y = [pfxy(ii).y(1) pfxy(ii).y(end)];
+%     
+%     if x(2)-x(1)>0
+%         intang = atand((y(2)-y(1))/(x(2)-x(1)));
+%         ang = 90 - intang;
+%     elseif x(2)-x(1)<0
+%         intang = atand((y(2)-y(1))/(x(2)-x(1)));
+%         ang = 270 - intang;
+%     end
+%     TN(ii,1) = ang;
+% end
+
+%or else get information from site specific file
+addpath('J:\Coastal\')
+coastalinit
+
+% pfs = {'PF1','PF2','PF4','PF6','PF8'};
+% pfs = {'PF1','PF2','PF3'};
+pfs = {'PF1','PF2','PF3','PF4','PF5'};
+
+for ii = 1:length(pfs)
+    [~,rot_angle] = get_rotation_specs('DEEWH',pfs{ii});
+    alfa(ii,1) = -rot_angle*180/pi;
+end
\ No newline at end of file
diff --git a/example/input_data/fielddata/stormdates_narra.mat b/example/input_data/fielddata/stormdates_narra.mat
new file mode 100644
index 0000000..8009d09
Binary files /dev/null and b/example/input_data/fielddata/stormdates_narra.mat differ
diff --git a/example/input_data/fielddata/stormdates_other.mat b/example/input_data/fielddata/stormdates_other.mat
new file mode 100644
index 0000000..3a7a562
Binary files /dev/null and b/example/input_data/fielddata/stormdates_other.mat differ
diff --git a/example/input_data/fielddata/tide/code/tidedataget.m b/example/input_data/fielddata/tide/code/tidedataget.m
new file mode 100644
index 0000000..fba5416
--- /dev/null
+++ b/example/input_data/fielddata/tide/code/tidedataget.m
@@ -0,0 +1,44 @@
+% Written by Joshua Simmons 04/01/2016
+% Description: used to tranform offshore to nearshore mike21 using the code
+% OS2NS_MIKE21.m
+
+clear
+clc
+
+%% Settings
+%tide gauge data
+guagedataloc = 'J:\Coastal\Data\Tide\Sydney\Processed\SydTideData.mat';
+
+site = 'Narrabeen'; %embayment of interest
+
+%storm details
+stormdatesloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\stormdates_narra.mat';
+storm = {'2007', '2011', '2014', '2015'};
+
+% save?
+savebool = 1;
+% datasave location
+saveloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\tide\processed\';
+
+%% Code
+%load buoy data,profile data and lookup table
+guagedata = load(guagedataloc);
+
+stormdates = load(stormdatesloc);
+
+% narrow down to date range
+for ii = 1:length(storm)
+    startdate = stormdates.(['storm_' storm{ii}]).startdate;
+    enddate = stormdates.(['storm_' storm{ii}]).enddate;
+    
+    validentries = find(guagedata.SydTideData.time>=startdate & guagedata.SydTideData.time<=enddate);
+    
+    tidedata.tide = guagedata.SydTideData.tide(validentries);
+    tidedata.time = guagedata.SydTideData.time(validentries);
+   
+    if savebool
+        save([saveloc 'tidedata_' lower(site) '_' storm{ii} '.mat'],'tidedata') 
+    end
+    
+    clear tidedata startdate enddate validentries
+end
\ No newline at end of file
diff --git a/example/input_data/fielddata/tide/code/tidedataget_other.m b/example/input_data/fielddata/tide/code/tidedataget_other.m
new file mode 100644
index 0000000..bc645a8
--- /dev/null
+++ b/example/input_data/fielddata/tide/code/tidedataget_other.m
@@ -0,0 +1,44 @@
+% Written by Joshua Simmons 04/01/2016
+% Description: used to tranform offshore to nearshore mike21 using the code
+% OS2NS_MIKE21.m
+
+clear
+clc
+
+%% Settings
+%tide gauge data
+guagedataloc = 'J:\Coastal\Data\Tide\Sydney\Processed\SydTideData.mat';
+
+site = 'Monavale'; %embayment of interest
+
+%storm details
+stormdatesloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\stormdates_other.mat';
+storm = {'2014', '2015'};
+
+% save?
+savebool = 1;
+% datasave location
+saveloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\tide\processed\';
+
+%% Code
+%load buoy data,profile data and lookup table
+guagedata = load(guagedataloc);
+
+stormdates = load(stormdatesloc);
+
+% narrow down to date range
+for ii = 1:length(storm)
+    startdate = stormdates.(['storm_' storm{ii}]).startdate;
+    enddate = stormdates.(['storm_' storm{ii}]).enddate;
+    
+    validentries = find(guagedata.SydTideData.time>=startdate & guagedata.SydTideData.time<=enddate);
+    
+    tidedata.tide = guagedata.SydTideData.tide(validentries);
+    tidedata.time = guagedata.SydTideData.time(validentries);
+   
+    if savebool
+        save([saveloc 'tidedata_' lower(site) '_' storm{ii} '.mat'],'tidedata') 
+    end
+    
+    clear tidedata startdate enddate validentries
+end
\ No newline at end of file
diff --git a/example/input_data/fielddata/tide/processed/tidedata_narrabeen_2015.mat b/example/input_data/fielddata/tide/processed/tidedata_narrabeen_2015.mat
new file mode 100644
index 0000000..9e71718
Binary files /dev/null and b/example/input_data/fielddata/tide/processed/tidedata_narrabeen_2015.mat differ
diff --git a/example/input_data/fielddata/wave/code/fmikeos2ns.m b/example/input_data/fielddata/wave/code/fmikeos2ns.m
new file mode 100644
index 0000000..bf1042f
--- /dev/null
+++ b/example/input_data/fielddata/wave/code/fmikeos2ns.m
@@ -0,0 +1,105 @@
+function nswaves = fmikeos2ns(oswaves, LookUps, site, contour, location)
+    % Written by Joshua Simmons (WRL) 03/11/2014 
+    % to transform waves from offshore (OS) to nearshore (NS) using MIKE21 model
+    % oswaves - OS wave data - oswaves.Hsig(Significant wave height)/
+    % oswaves.Tp1(Peak period)/oswaves.Wdir(Incident wave direction)
+    % LookUps - MIKE21 wave model output in file "OEH_ARC_PointOutput.mat"
+    % site - embayment of interest - i.e. 'Narrabeen'
+    % contour - 10 or 15 (m) contour for NS output
+    % location - either pure S co-ord (see Mitchell Harley's xyz2spz 
+    % transformation) or location.E and location.N - refers to output 
+    % location for NS waves (gets nearest MIKE21 point)
+    %
+    %V1.1 - updated by Joshua Simmons 21/01/2015 to patch Wamberal/Wanda
+    %error.
+    
+    %find site and contour indices
+    siteidx = getnameidx(LookUps(:,2), site);
+    
+    %apply fix for Wamberal and Wanda
+    % from TM on 21/01/2015: "I've found an error in the .mat file for the
+    % look-up tables; in the pdf I say that all output for all locations runs 
+    % north to south - for Wamberal and Wanda it seems I've output them south to north.
+    % So if you are using output from these two sites, if you haven't realised already, 
+    % alongshore gradients will look inverted."
+    for aa = 1:2; 
+        LookUps{6,1}{aa,1} = flipud(LookUps{6,1}{aa,1}); LookUps{6,1}{aa,1}(:,1) = flipud(LookUps{6,1}{aa,1}(:,1)); 
+        LookUps{7,1}{aa,1} = flipud(LookUps{7,1}{aa,1}); LookUps{7,1}{aa,1}(:,1) = flipud(LookUps{7,1}{aa,1}(:,1));
+    end
+
+    if contour == 10
+        contouridx = 1;
+    elseif contour == 15;
+        contouridx = 2;
+    else
+        error('Contour information not available, select either 10 or 15m contour')
+    end
+    
+    %extract scenarios for easy lookup
+    scenariosidx = getnameidx(LookUps(:,2), 'Offshore Wave Scenarios');
+    scenarios = LookUps{scenariosidx,1};
+    
+    %get nearest location available for output
+    Eouts = LookUps{siteidx,1}{contouridx,1}(:,2);
+    Nouts = LookUps{siteidx,1}{contouridx,1}(:,3);
+    
+    if strcmp(site,'Narrabeen')
+        %compares closes alongshore spacing (s) for log-spiral narrabeen
+        xyz_data.x = cell2mat(Eouts);
+        xyz_data.y = cell2mat(Nouts);
+        xyz_data.z = zeros(size(Eouts));
+        spz = xyz2spz(xyz_data,'NARRA');
+        [~,locationidx] = min(abs(location-spz.s));
+    else
+        %gets nearest output point
+        dists = sqrt((location.E-cell2mat(Eouts)).^2+(location.N-cell2mat(Nouts)).^2);
+        [~,locationidx] = min(abs(dists));
+    end
+    
+    fcount = 1;
+    %loop through oswaves and lookup nswaves
+    for ii = 1:length(oswaves.Hsig)
+        tmpHs = oswaves.Hsig(ii);
+        tmpTp = oswaves.Tp1(ii);
+        tmpWdir = oswaves.Wdir(ii);
+        
+        %find closest scenario match
+        [~,Hsidx] = min(abs(tmpHs-scenarios(:,1)));
+        tmpHsround = scenarios(Hsidx,1);
+        [~,Tpidx] = min(abs(tmpTp-scenarios(:,2)));
+        tmpTpround = scenarios(Tpidx,2);
+        [~,Wdiridx] = min(abs(tmpWdir-scenarios(:,3)));
+        tmpWdirround = scenarios(Wdiridx,3);
+        
+        iter1ind = find(scenarios(:,3) == tmpWdirround);
+        iter2ind = find(scenarios(iter1ind,2) == tmpTpround);
+        iter3ind = find(scenarios(iter1ind(iter2ind),1) == tmpHsround);
+        
+        iter4ind = iter1ind(iter2ind(iter3ind));
+        
+        %now get ns lookup information if available
+        if isempty(iter4ind)
+            %get the closest wave height to scenario chosen
+            [~,iter3ind] = min(abs(tmpHs-scenarios(iter1ind(iter2ind),1)));
+            iter4ind = iter1ind(iter2ind(iter3ind));
+            diffHs = scenarios(iter4ind,1)-tmpHs;
+            disp(['No match found for oswaves(' num2str(ii) ') wave height off by ' num2str(diffHs) 'm']);
+        end
+        
+        nstmp = LookUps{siteidx,1}{contouridx,1}{locationidx,4}(iter4ind,:);
+        %store the values from the lookup table
+        nswaves.Hsig(ii,1) = nstmp(1);
+        nswaves.Hmax(ii,1) = nstmp(2);
+        nswaves.Tp1(ii,1) = nstmp(3);
+        nswaves.T01(ii,1) = nstmp(4);
+        nswaves.Wdir(ii,1) = nstmp(5);
+        nswaves.power(ii,1) = nstmp(6);
+    end
+        try
+            nswaves.date = oswaves.date;
+            nswaves.time = oswaves.time;
+            nswaves.datenums = oswaves.datenums;
+        catch
+            nswaves.datenums = oswaves.datenums;
+        end
+end
\ No newline at end of file
diff --git a/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21.m b/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21.m
new file mode 100644
index 0000000..5540332
--- /dev/null
+++ b/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21.m
@@ -0,0 +1,95 @@
+% Written by Joshua Simmons 04/01/2016
+% Description: used to tranform offshore to nearshore mike21 using the code
+% OS2NS_MIKE21.m
+
+clear
+clc
+
+%% Settings
+%buoy data
+buoydataloc = 'J:\Coastal\Data\Wave\Sydney\Processed\SydneyProcessed_CSIROGapFill.mat';
+% the non CSIRO filtered data is the only data available after 2014 so fill
+% from the recent data with gaps.
+backupbuoydata = 'J:\Coastal\Data\Wave\Sydney\Processed\SydneyProcessed.mat';
+
+%location of mike21 runcode
+mike21loc = 'J:\Coastal\Tools\Nearshore Wave Transformations\MIKE21\';
+%location of MALT
+maltloc = 'J:\Coastal\Tools\MALT Logspiral Transformation\';
+%location of profiles for which wave data is required.
+profiledataloc = [437 850 1750 2606 3420]; % s co-ordinate
+
+site = 'Narrabeen'; %embayment of interest
+contour = 10; %m - 10m or 15m contour?
+
+%storm details
+stormdatesloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\stormdates_narra.mat';
+storm = {'2007', '2011', '2014', '2015'};
+
+% save?
+savebool = 1;
+% datasave location
+saveloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\wave\processed\';
+
+%% Code
+% for MIKE21 code and MALT
+addpath(mike21loc);
+addpath(maltloc);
+%load buoy data,profile data and lookup table
+buoydata = load(buoydataloc);
+backupbuoydata = load(backupbuoydata);
+load('OEH_ARC_PointOutput.mat');
+stormdates = load(stormdatesloc);
+
+% narrow down to date range
+for ii = 1:length(storm)
+    startdate = stormdates.(['storm_' storm{ii}]).startdate;
+    enddate = stormdates.(['storm_' storm{ii}]).enddate;
+    
+    validentries = find(buoydata.dates>=startdate & buoydata.dates<=enddate);
+    % if nothing then revert to backup
+    if isempty(validentries) || validentries(end) == length(buoydata.dates)
+        validentries = find(backupbuoydata.dates>=startdate & backupbuoydata.dates<=enddate);
+        oswaves.Hsig = backupbuoydata.Hsig(validentries);
+        oswaves.Tp1 = backupbuoydata.Tp(validentries);
+        oswaves.Wdir = backupbuoydata.Wdir(validentries);
+        oswaves.datenums = backupbuoydata.dates(validentries);        
+    else
+        oswaves.Hsig = buoydata.Hsig(validentries);
+        oswaves.Tp1 = buoydata.Tp(validentries);
+        oswaves.Wdir = buoydata.Wdir(validentries);
+        oswaves.datenums = buoydata.dates(validentries);
+    end
+    
+    fns1 = fieldnames(oswaves);
+    for kk = 1:length(fns1)
+        if any(isnan(oswaves.(fns1{kk})))
+            error('NaN values in wave data')
+        end
+    end
+    
+    tic
+    parfor jj = 1:length(profiledataloc)
+        location = profiledataloc(jj);
+        nswaves = OS2NS_MIKE21(oswaves, LookUps, site, contour, location);
+        
+        % bug fix to ensure no inaccurate wave period estimates
+        nswaves.Tp1 = oswaves.Tp1;
+        
+        tmp(jj) = nswaves;
+    end
+    wavedata.ns.data = tmp;
+    toc
+    
+    wavedata.os = oswaves;
+    
+    wavedata.ns.model = 'MIKE21';
+    wavedata.ns.contour = [num2str(contour) 'm'];
+    wavedata.ns.location = profiledataloc;
+    
+    if savebool
+        save([saveloc 'wavedata_' lower(site) '_' storm{ii} '.mat'],'wavedata') 
+    end
+    
+    clear wavedata oswaves startdate enddate validentries tmp
+end
\ No newline at end of file
diff --git a/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_deewhy.m b/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_deewhy.m
new file mode 100644
index 0000000..17ca5d3
--- /dev/null
+++ b/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_deewhy.m
@@ -0,0 +1,99 @@
+% Written by Joshua Simmons 04/01/2016
+% Description: used to tranform offshore to nearshore mike21 using the code
+% OS2NS_MIKE21.m
+
+clear
+clc
+
+%% Settings
+%buoy data
+buoydataloc = 'J:\Coastal\Data\Wave\Sydney\Processed\SydneyProcessed_CSIROGapFill.mat';
+% the non CSIRO filtered data is the only data available after 2014 so fill
+% from the recent data with gaps.
+backupbuoydata = 'J:\Coastal\Data\Wave\Sydney\Processed\SydneyProcessed.mat';
+
+%location of mike21 runcode
+mike21loc = 'J:\Coastal\Tools\Nearshore Wave Transformations\MIKE21\';
+%location of MALT
+maltloc = 'J:\Coastal\Tools\MALT Logspiral Transformation\';
+%location of profiles for which wave data is required.
+% profiledataloc = [6275797.660794820 6275692.739810870 6275536.815570840]; % Northings co-ordinate - Bilgola (at 10m contour)
+% profiledataloc = [6272148.185 6272338.391 6272389.496 6271924.185 6271823.724]; % Northings co-ordinate - Mona Vale (at 10m contour)
+profiledataloc = [6264042.586 6264127.494 6263995.016 6263745.956 6263879.058]; % Northings co-ordinate - Dee Why (at 10m contour)
+profiledataloc2 = [343633.9263 343038.1544 342940.1201 342757.2994 342848.2807]; % Eastings co-ordinate - Dee Why (at 10m contour)
+
+site = 'DeeWhy'; %embayment of interest
+contour = 10; %m - 10m or 15m contour?
+
+%storm details
+stormdatesloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\stormdates_other.mat';
+storm = {'2014', '2015'};
+
+% save?
+savebool = 1;
+% datasave location
+saveloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\wave\processed\';
+
+%% Code
+% for MIKE21 code and MALT
+addpath(mike21loc);
+addpath(maltloc);
+%load buoy data,profile data and lookup table
+buoydata = load(buoydataloc);
+backupbuoydata = load(backupbuoydata);
+load('OEH_ARC_PointOutput.mat');
+stormdates = load(stormdatesloc);
+
+% narrow down to date range
+for ii = 1:length(storm)
+    startdate = stormdates.(['storm_' storm{ii}]).startdate;
+    enddate = stormdates.(['storm_' storm{ii}]).enddate;
+    
+    validentries = find(buoydata.dates>=startdate & buoydata.dates<=enddate);
+    % if nothing then revert to backup
+    if isempty(validentries) || validentries(end) == length(buoydata.dates)
+        validentries = find(backupbuoydata.dates>=startdate & backupbuoydata.dates<=enddate);
+        oswaves.Hsig = backupbuoydata.Hsig(validentries);
+        oswaves.Tp1 = backupbuoydata.Tp(validentries);
+        oswaves.Wdir = backupbuoydata.Wdir(validentries);
+        oswaves.datenums = backupbuoydata.dates(validentries);        
+    else
+        oswaves.Hsig = buoydata.Hsig(validentries);
+        oswaves.Tp1 = buoydata.Tp(validentries);
+        oswaves.Wdir = buoydata.Wdir(validentries);
+        oswaves.datenums = buoydata.dates(validentries);
+    end
+    
+    fns1 = fieldnames(oswaves);
+    for kk = 1:length(fns1)
+        if any(isnan(oswaves.(fns1{kk})))
+            error('NaN values in wave data')
+        end
+    end
+    
+    tic
+    for jj = 1:length(profiledataloc)
+        location.N = profiledataloc(jj);
+        location.E = profiledataloc2(jj);
+        nswaves = fmikeos2ns(oswaves, LookUps, site, contour, location);
+        
+        % bug fix to ensure no inaccurate wave period estimates
+        nswaves.Tp1 = oswaves.Tp1;
+        
+        tmp(jj) = nswaves;
+    end
+    wavedata.ns.data = tmp;
+    toc
+    
+    wavedata.os = oswaves;
+    
+    wavedata.ns.model = 'MIKE21';
+    wavedata.ns.contour = [num2str(contour) 'm'];
+    wavedata.ns.location = profiledataloc;
+    
+    if savebool
+        save([saveloc 'wavedata_' lower(site) '_' storm{ii} '.mat'],'wavedata') 
+    end
+    
+    clear wavedata oswaves startdate enddate validentries tmp
+end
\ No newline at end of file
diff --git a/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_end_effects_check.m b/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_end_effects_check.m
new file mode 100644
index 0000000..5dae8fa
--- /dev/null
+++ b/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_end_effects_check.m
@@ -0,0 +1,105 @@
+% Written by Joshua Simmons 04/01/2016
+% Description: used to tranform offshore to nearshore mike21 using the code
+% OS2NS_MIKE21.m
+
+clear
+clc
+
+%% Settings
+%buoy data
+buoydataloc = 'J:\Coastal\Data\Wave\Sydney\Processed\SydneyProcessed_CSIROGapFill.mat';
+% the non CSIRO filtered data is the only data available after 2014 so fill
+% from the recent data with gaps.
+backupbuoydata = 'J:\Coastal\Data\Wave\Sydney\Processed\SydneyProcessed.mat';
+
+%location of mike21 runcode
+mike21loc = 'J:\Coastal\Tools\Nearshore Wave Transformations\MIKE21\';
+%location of MALT
+maltloc = 'J:\Coastal\Tools\MALT Logspiral Transformation\';
+%location of profiles for which wave data is required.
+profiledataloc = [90:20:3870]; % s co-ordinate
+
+site = 'Narrabeen'; %embayment of interest
+contour = 10; %m - 10m or 15m contour?
+
+%storm details
+stormdatesloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\stormdates_narra.mat';
+storm = {'2007', '2011', '2014', '2015'};
+
+% save?
+savebool = 0;
+% datasave location
+saveloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\wave\processed\';
+
+%% Code
+% for MIKE21 code and MALT
+addpath(mike21loc);
+addpath(maltloc);
+%load buoy data,profile data and lookup table
+buoydata = load(buoydataloc);
+backupbuoydata = load(backupbuoydata);
+load('OEH_ARC_PointOutput.mat');
+stormdates = load(stormdatesloc);
+
+% narrow down to date range
+for ii = 1:length(storm)
+    startdate = stormdates.(['storm_' storm{ii}]).startdate;
+    enddate = stormdates.(['storm_' storm{ii}]).enddate;
+    
+    validentries = find(buoydata.dates>=startdate & buoydata.dates<=enddate);
+    % if nothing then revert to backup
+    if isempty(validentries) || validentries(end) == length(buoydata.dates)
+        validentries = find(backupbuoydata.dates>=startdate & backupbuoydata.dates<=enddate);
+        oswaves.Hsig = backupbuoydata.Hsig(validentries);
+        oswaves.Tp1 = backupbuoydata.Tp(validentries);
+        oswaves.Wdir = backupbuoydata.Wdir(validentries);
+        oswaves.datenums = backupbuoydata.dates(validentries);        
+    else
+        oswaves.Hsig = buoydata.Hsig(validentries);
+        oswaves.Tp1 = buoydata.Tp(validentries);
+        oswaves.Wdir = buoydata.Wdir(validentries);
+        oswaves.datenums = buoydata.dates(validentries);
+    end
+    
+    fns1 = fieldnames(oswaves);
+    for kk = 1:length(fns1)
+        if any(isnan(oswaves.(fns1{kk})))
+            error('NaN values in wave data')
+        end
+    end
+    
+    tic
+    parfor jj = 1:length(profiledataloc)
+        location = profiledataloc(jj);
+        nswaves = OS2NS_MIKE21(oswaves, LookUps, site, contour, location);
+        
+        % bug fix to ensure no inaccurate wave period estimates
+        nswaves.Tp1 = oswaves.Tp1;
+        
+%         tmp(jj) = nswaves;
+        Hsig(:,jj) = nswaves.Hsig(:,1);
+        Wdir(:,jj) = nswaves.Wdir(:,1);
+        power(:,jj) = nswaves.power(:,1);
+    end
+    dataout(ii).s = profiledataloc;
+    dataout(ii).Hsig = Hsig;
+    dataout(ii).Wdir = Wdir;
+    dataout(ii).power = power;
+    dataout(ii).osWdir = oswaves.Wdir;
+    dataout(ii).osHsig = oswaves.Hsig;
+%     wavedata.ns.data = tmp;
+    toc
+    
+    wavedata.os = oswaves;
+    
+    wavedata.ns.model = 'MIKE21';
+    wavedata.ns.contour = [num2str(contour) 'm'];
+    wavedata.ns.location = profiledataloc;
+    
+    if savebool
+        save([saveloc 'wavedata_' lower(site) '_' storm{ii} '.mat'],'wavedata') 
+    end
+    
+    clear wavedata oswaves startdate enddate validentries
+    clear power s Hsig Wdir
+end
\ No newline at end of file
diff --git a/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_other.m b/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_other.m
new file mode 100644
index 0000000..f3927e1
--- /dev/null
+++ b/example/input_data/fielddata/wave/code/run_OS_to_NS_mike21_other.m
@@ -0,0 +1,99 @@
+% Written by Joshua Simmons 04/01/2016
+% Description: used to tranform offshore to nearshore mike21 using the code
+% OS2NS_MIKE21.m
+
+clear
+clc
+
+%% Settings
+%buoy data
+buoydataloc = 'J:\Coastal\Data\Wave\Sydney\Processed\SydneyProcessed_CSIROGapFill.mat';
+% the non CSIRO filtered data is the only data available after 2014 so fill
+% from the recent data with gaps.
+backupbuoydata = 'J:\Coastal\Data\Wave\Sydney\Processed\SydneyProcessed.mat';
+
+%location of mike21 runcode
+mike21loc = 'J:\Coastal\Tools\Nearshore Wave Transformations\MIKE21\';
+%location of MALT
+maltloc = 'J:\Coastal\Tools\MALT Logspiral Transformation\';
+%location of profiles for which wave data is required.
+% profiledataloc = [6275797.660794820 6275692.739810870 6275536.815570840]; % Northings co-ordinate - Bilgola (at 10m contour)
+% profiledataloc = [6272148.185 6272338.391 6272389.496 6271924.185 6271823.724]; % Northings co-ordinate - Mona Vale (at 10m contour)
+profiledataloc = [6264042.586 6264127.494 6263995.016 6263745.956 6263879.058]; % Northings co-ordinate - Dee Why (at 10m contour)
+
+
+
+site = 'DeeWhy'; %embayment of interest
+contour = 10; %m - 10m or 15m contour?
+
+%storm details
+stormdatesloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\stormdates_other.mat';
+storm = {'2014', '2015'};
+
+% save?
+savebool = 1;
+% datasave location
+saveloc = 'D:\7 Erosion Models\a_nb_model_comparison\input_data\fielddata\wave\processed\';
+
+%% Code
+% for MIKE21 code and MALT
+addpath(mike21loc);
+addpath(maltloc);
+%load buoy data,profile data and lookup table
+buoydata = load(buoydataloc);
+backupbuoydata = load(backupbuoydata);
+load('OEH_ARC_PointOutput.mat');
+stormdates = load(stormdatesloc);
+
+% narrow down to date range
+for ii = 1:length(storm)
+    startdate = stormdates.(['storm_' storm{ii}]).startdate;
+    enddate = stormdates.(['storm_' storm{ii}]).enddate;
+    
+    validentries = find(buoydata.dates>=startdate & buoydata.dates<=enddate);
+    % if nothing then revert to backup
+    if isempty(validentries) || validentries(end) == length(buoydata.dates)
+        validentries = find(backupbuoydata.dates>=startdate & backupbuoydata.dates<=enddate);
+        oswaves.Hsig = backupbuoydata.Hsig(validentries);
+        oswaves.Tp1 = backupbuoydata.Tp(validentries);
+        oswaves.Wdir = backupbuoydata.Wdir(validentries);
+        oswaves.datenums = backupbuoydata.dates(validentries);        
+    else
+        oswaves.Hsig = buoydata.Hsig(validentries);
+        oswaves.Tp1 = buoydata.Tp(validentries);
+        oswaves.Wdir = buoydata.Wdir(validentries);
+        oswaves.datenums = buoydata.dates(validentries);
+    end
+    
+    fns1 = fieldnames(oswaves);
+    for kk = 1:length(fns1)
+        if any(isnan(oswaves.(fns1{kk})))
+            error('NaN values in wave data')
+        end
+    end
+    
+    tic
+    for jj = 1:length(profiledataloc)
+        location = profiledataloc(jj);
+        nswaves = OS2NS_MIKE21(oswaves, LookUps, site, contour, location);
+        
+        % bug fix to ensure no inaccurate wave period estimates
+        nswaves.Tp1 = oswaves.Tp1;
+        
+        tmp(jj) = nswaves;
+    end
+    wavedata.ns.data = tmp;
+    toc
+    
+    wavedata.os = oswaves;
+    
+    wavedata.ns.model = 'MIKE21';
+    wavedata.ns.contour = [num2str(contour) 'm'];
+    wavedata.ns.location = profiledataloc;
+    
+    if savebool
+        save([saveloc 'wavedata_' lower(site) '_' storm{ii} '.mat'],'wavedata') 
+    end
+    
+    clear wavedata oswaves startdate enddate validentries tmp
+end
\ No newline at end of file
diff --git a/example/input_data/fielddata/wave/processed/wavedata_narrabeen_2015.mat b/example/input_data/fielddata/wave/processed/wavedata_narrabeen_2015.mat
new file mode 100644
index 0000000..15b3848
Binary files /dev/null and b/example/input_data/fielddata/wave/processed/wavedata_narrabeen_2015.mat differ
diff --git a/example/input_data/fielddata/wave/~$2007_survey_to_survey_wave_data.xlsx b/example/input_data/fielddata/wave/~$2007_survey_to_survey_wave_data.xlsx
new file mode 100644
index 0000000..fd0b6a9
Binary files /dev/null and b/example/input_data/fielddata/wave/~$2007_survey_to_survey_wave_data.xlsx differ
diff --git a/example/input_data/morphology/processed/morphology_narrabeen_2015.mat b/example/input_data/morphology/processed/morphology_narrabeen_2015.mat
new file mode 100644
index 0000000..235d6a9
Binary files /dev/null and b/example/input_data/morphology/processed/morphology_narrabeen_2015.mat differ
diff --git a/example/setup_info/profileinfo_narrabeen.mat b/example/setup_info/profileinfo_narrabeen.mat
new file mode 100644
index 0000000..9203935
Binary files /dev/null and b/example/setup_info/profileinfo_narrabeen.mat differ
diff --git a/formatpfdata.m b/formatpfdata.m
new file mode 100644
index 0000000..c31dff5
--- /dev/null
+++ b/formatpfdata.m
@@ -0,0 +1,21 @@
+function [pfdataout] = formatpfdata(xin,zin,interpspace)
+    % Written by Joshua Simmons 11/02/2015 - to format profile data as
+    % required (linear interploation etc etc
+    % Input:
+    % xin = cross shore
+    % zin = elevation
+    % interppspace = regular spacing of the profile to be linearly
+    %                interpolated to. Leave as "NaN" if raw input points to
+    %                be used.
+    % Output:
+    % structure with .x,.z formatted as required.
+    if isnan(interpspace)
+        pfdataout.x = xin;
+        pfdataout.z = zin;
+    else
+        minx = min(xin);
+        maxx = max(xin);
+        pfdataout.x = [minx:interpspace:maxx];
+        pfdataout.z = interp1(xin,zin,pfdataout.x);
+    end
+end
\ No newline at end of file
diff --git a/fsbeach_checktsdata.m b/fsbeach_checktsdata.m
new file mode 100644
index 0000000..4e538e6
--- /dev/null
+++ b/fsbeach_checktsdata.m
@@ -0,0 +1,36 @@
+% SBEACH toolbox - fsbeach_checktsdata
+% Written by Joshua Simmons 11/2017
+
+% returns all the SBEACH default values
+
+%   Syntax:
+%   OPT = fsbeach_checktsdata()
+
+%   Input:
+%   waves     = wave data structure - output by fsbeach_genwaves
+%   tides     = tide data structure - output by fsbeach_gentides
+
+function fsbeach_checktsdata(waves,tide)
+    % check the tide and wave data matches
+    if tide.time(1) ~= waves.time(1)
+        error('Start times for wave and tide data dont match')
+    end
+    if tide.time(end) ~= waves.time(end)
+        error('End times for wave and tide data dont match. Make sure start/end times are hourly (for wave data).')
+    end
+    
+    %check and allocate time parameters;
+    tt = round((tide.time - tide.time(1))*24*60);
+    %check time steps
+    dtt = diff(tt);
+    if any(dtt~=dtt(1))
+        error('Inconsistent time steps in tide data');
+    end
+
+    %now check the wave data lines up (os only required the rest if copied)
+    wt = round((waves.time - waves.time(1))*24*60);
+    dwt = diff(wt);
+    if any(dwt~=dwt(1))
+        error('Inconsistent time steps in wave data');
+    end
+end
\ No newline at end of file
diff --git a/fsbeach_collectresults.m b/fsbeach_collectresults.m
new file mode 100644
index 0000000..27fff60
--- /dev/null
+++ b/fsbeach_collectresults.m
@@ -0,0 +1,34 @@
+% SBEACH toolbox - fsbeach_collectresults
+% Written by Joshua Simmons 11/2017
+
+%   Syntax:
+%   sbout = fsbeach_collectresults(sblocs)
+%
+%   Input:
+%   sblocs    =  Cell array of locations where SBEACH has been run
+
+%   Output:
+%   sbout     = structure with sbeach data;
+
+function sbout = fsbeach_collectresults(sblocs)
+    for ii = 1:length(sblocs)
+        fid = fopen([sblocs{ii} '.Excel.ASSUPPLIED'],'r');
+        formatSpec = '%f %f %f';
+        sizeA = [3 Inf];
+        tempresults = fscanf(fid,formatSpec,sizeA)';
+        fclose(fid);
+        clear fid
+
+        %get computed profile
+        sbout.computed(ii).z(:,1) = tempresults(:,3);
+        sbout.computed(ii).x = tempresults(:,1);
+
+        %input bathy
+        sbout.input(ii).x = tempresults(:,1);
+        sbout.input(ii).z = tempresults(:,2);
+        
+        %now get wave elevations etc
+        fid = fopen([sblocs{ii} '.XVR'],'r');
+        sbout.xvr(ii) = fsbeach_readxvrfile(fid);
+    end
+end
\ No newline at end of file
diff --git a/fsbeach_genbathy.m b/fsbeach_genbathy.m
new file mode 100644
index 0000000..6227ae8
--- /dev/null
+++ b/fsbeach_genbathy.m
@@ -0,0 +1,103 @@
+% SBEACH toolbox - fsbeach_genbathy
+% Written by Joshua Simmons 11/2017
+
+%   Syntax:
+%   bathyout = fsbeach_genbathy(varargin)
+%
+%   Input:
+%   varargin  = x:          x-coordinates of bathymetry
+%               z:          z-coordinates of bathymetry
+%               hbz:        z-coordinates of hard bottom
+%               ne:         vector or matrix of the size of z containing
+%                           either booleans indicating if a cell is
+%                           non-erodable or a numeric value indicating the
+%                           thickness of the erodable layer on top of a
+%                           non-erodable layer
+%
+%   Output:
+%   bathyout        = stucture of x and z
+
+function bathyout = fsbeach_genbathy(outpath,name,settings,varargin)
+    OPT = struct( ...
+        'x', [0 100 200 300 400 500]', ...
+        'z', [-10 -5 0 1 3 10]', ...
+        'hbz', NaN, ...
+        'ne', [] ...
+    );
+
+    OPT = setproperty(OPT, varargin{:});
+    
+    %transpose them if needed
+    OPT = fsbeach_makecolumn(OPT,{'x','z','ne'});
+    
+    %check they can be zipped
+    if length(OPT.x) ~= length(OPT.z)
+        error('x is of length %d, while z is of length %d...',length(OPT.x),length(OPT.z))
+    end
+    
+    xin = OPT.x; %store x input
+    
+    %check that constant grid is provided as required by SBEACH
+    diffx = diff(OPT.x);
+    dx = diffx(1);
+    if any(diffx~=dx)
+        dx = mode(diffx);
+        fprintf('\n')
+        warning('SBEACH requires constant spacing - interpolating to a regular grid with spacing of %d...',dx)
+        newx = [OPT.x(1):dx:OPT.x(end)]';
+        newz = interp1(OPT.x,OPT.z,newx);
+        OPT.x = newx;
+        OPT.z = newz;
+        clear newx newz
+    end
+    
+    if settings.NGRID
+        tempdx = [0];
+        for ii = 1:settings.NGRID
+            tempdx = [tempdx; ones(settings.NDXV(ii),1).*settings.DXV(ii)];
+        end
+        newx = OPT.x(1) + cumsum(tempdx);
+        
+        if newx(end) ~= OPT.x(end)
+            error(['Variable grid is wrong, please adjust DXV and NDXV so that'...
+                'xstart = %d and xend = %d. Currently xend = %d.'],newx(1),OPT.x(end),newx(end))
+        end
+        
+        newz = interp1(OPT.x,OPT.z,newx);
+        OPT.x = newx;
+        OPT.z = newz;
+        clear newx newz
+    end
+    
+    if ~isnan(OPT.hbz)
+        OPT.hbz = interp1(xin,OPT.hbz,OPT.x);
+    end
+    
+    %check they are in the right direction
+    if mean(diff(OPT.x)) < 0
+        OPT.x = flip(OPT.x);
+        OPT.z = flip(OPT.z);
+        if ~isnan(OPT.hbz)
+            OPT.hbz = flip(OPT.hbz);
+        end            
+    end
+    if mean(diff(OPT.z)) > 0
+        fprintf('\n')
+        error('Please ensure x coordinate system is increasing offshore')
+    end
+    
+    %zip
+    prifile = [OPT.x OPT.z]; %initial pf
+    
+    %and write
+    writetofilepri(prifile, outpath, name)
+    
+    if ~isnan(OPT.hbz)
+        hdbfile = [OPT.x OPT.hbz]; %hard bottom pf
+        writetofilehdb(hdbfile, outpath, name);
+    end     
+        
+    bathyout.x = OPT.x;
+    bathyout.z = OPT.z;
+    bathyout.hbz = OPT.hbz;
+end
\ No newline at end of file
diff --git a/fsbeach_gentide.m b/fsbeach_gentide.m
new file mode 100644
index 0000000..069b32c
--- /dev/null
+++ b/fsbeach_gentide.m
@@ -0,0 +1,33 @@
+% SBEACH toolbox - fsbeach_gentide
+% Written by Joshua Simmons 11/2017
+
+%   Syntax:
+%   tideout = fsbeach_gentide(varargin)
+%
+%   Input:
+%   varargin  = time:   array of measurement times for tide (minutes)
+%               elev:   array of waterlevels at seaward model border (m)
+%
+%   Output:
+%   tideout        = stucture of time and elevation
+
+function tideout = fsbeach_gentide(outpath,name,varargin)
+    OPT = struct( ...
+        'time', [0 100 200 300 400 500]', ...
+        'elev', [1 1.2 1.1 1.5 1]' ...
+    );
+
+    OPT = setproperty(OPT, varargin{:});
+    
+    %transpose them if needed
+    OPT = fsbeach_makecolumn(OPT,{'time','elev'});
+    
+    %zip
+    elvfile = OPT.elev; %initial pf
+    
+    %and write
+    writetofileelv(elvfile, outpath, name)
+    
+    tideout.time = OPT.time;
+    tideout.elev = OPT.elev;
+end
\ No newline at end of file
diff --git a/fsbeach_genwaves.m b/fsbeach_genwaves.m
new file mode 100644
index 0000000..96f63ef
--- /dev/null
+++ b/fsbeach_genwaves.m
@@ -0,0 +1,62 @@
+% SBEACH toolbox - fsbeach_genwaves
+% Written by Joshua Simmons 11/2017
+
+%   Syntax:
+%   wavesout = fsbeach_genwaves(varargin)
+%
+%   Input:
+%   varargin  = time:       array of measurement times for w (minutes)
+%
+%               Hsig:       significant wave height (m)
+%               Tp1:        peak wave period (s)
+%               ang:        wave direction (degrees from True North)
+%               pfang:      Profile orientation - from the shore to the 
+%                           most seaward point (degrees from True North)
+%
+%   Output:
+%   wavesout        = structure array of wave inputs
+
+function wavesout = fsbeach_genwaves(outpath,name,varargin)
+    OPT = struct( ...
+        'time', [0 100 200 300 400 500]', ...
+        'Hsig', [0 100 200 300 400 500]', ...
+        'Tp1', [-10 -5 0 1 3 10]', ...
+        'ang', [-10 -5 0 1 3 10]', ...
+        'pfang', NaN ...
+    );
+
+    OPT = setproperty(OPT, varargin{:});
+    
+    %transpose them if needed
+    OPT = fsbeach_makecolumn(OPT,{'time','Hsig','Tp1','ang'});
+    
+    %check they can be zipped
+    if length(OPT.Hsig) ~= length(OPT.Tp1)
+        error('Hsig is of length %d, while Tp1 is of length %d...',length(OPT.Hsig),length(OPT.Tp1))
+    end
+    
+    %zip wave data
+    wavfile = [OPT.Hsig OPT.Tp1];
+    
+    % correct for SBEACH wave angle convention 
+    % See SBEACH Report 3 - User's manual (pg 19)
+    if isnan(OPT.pfang)
+        error('Please provide the orientation of your profile as pfang.')
+    end
+    
+    angfile = OPT.pfang - OPT.ang;
+    
+    %check
+    if any(abs(angfile)>90)
+        warning('Check the orientation of your profile relative to the waves.')
+    end
+
+    %and write
+    writetofilewav(wavfile, outpath, name)
+    writetofileang(angfile, outpath, name)
+    
+    wavesout.time = OPT.time;
+    wavesout.Hsig = OPT.Hsig;
+    wavesout.Tp1 = OPT.Tp1;
+    wavesout.ang = angfile;
+end
\ No newline at end of file
diff --git a/fsbeach_getdefaults.m b/fsbeach_getdefaults.m
new file mode 100644
index 0000000..65bfc29
--- /dev/null
+++ b/fsbeach_getdefaults.m
@@ -0,0 +1,109 @@
+% SBEACH toolbox - fsbeach_getdefaults
+% Written by Joshua Simmons 11/2017
+
+% returns all the SBEACH default values
+
+%   Syntax:
+%   OPT = fsbeach_getdefaults()
+
+function OPT = fsbeach_getdefaults()
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % A - MODEL SETUP
+    OPT.TITLE = 'Test';
+    OPT.UNITS = 1;
+    OPT.NDX = NaN;
+    OPT.XSTART = NaN;
+    OPT.IDX = 0;
+    OPT.DXC = 1;
+    OPT.NGRID = 0;
+    OPT.DXV = 0;
+    OPT.NDXV = 0;
+    OPT.NDT = NaN;
+    OPT.DT = 5;
+    OPT.NWR = 0;
+    OPT.WRI = 0;
+    OPT.ICOMP = 0;
+    OPT.ELV1 = 0;
+    OPT.ELV2 = 0.25;
+    OPT.ELV3 = 0.5;
+    OPT.EDP1 = 0.5;
+    OPT.EDP2 = 1;
+    OPT.EDP3 = 1.5;
+    OPT.REFELV = 0;
+    
+    % Calibration parameters
+    OPT.K = 1.75e-06;
+    OPT.EPS = 0.002;
+    OPT.LAMM = 0.5;
+    
+    OPT.TEMPC = 20;
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % B - WAVES/WATER ELEVATION/WIND
+    OPT.WVTYPE = 2;
+    OPT.IWAVE = 1;
+    OPT.HIN = 0;
+    OPT.T = 0;
+    OPT.DTWAV = NaN;
+    OPT.IANG = 1;
+    OPT.ZIN = 0;
+    OPT.DTANG = NaN;
+    OPT.DMEAS = NaN; %0 is deepwater
+    OPT.IRAND = 0;
+    OPT.ISEED = 4567;
+    OPT.RPERC = 5;
+    OPT.IELEV = 1;
+    OPT.TELEV = 0;
+    OPT.DTELV = NaN;
+    OPT.IWIND = 0;
+    OPT.W = 0;
+    OPT.ZWIND = 0;
+    OPT.DTWND = 60;
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % C - BEACH
+    OPT.TPIN = 1;
+    OPT.SCHEM = 1;
+    OPT.XLAND = 0;
+    OPT.DLAND = [];
+    OPT.XLBDUNE = [];
+    OPT.DLBDUNE = [];
+    OPT.XLCDUNE = [];
+    OPT.DLCDUNE = [];
+    OPT.XSCDUNE = [];
+    OPT.DSCDUNE = [];
+    OPT.XBERMS = [];
+    OPT.DBERMS = [];
+    OPT.XBERME = [];
+    OPT.DBERME = [];
+    OPT.XFORS = [];
+    OPT.DFORS = [];
+    
+    %Calibration params
+    OPT.DFS = 0.5;
+    OPT.D50 = 0.35;
+    OPT.BMAX = 17.2;
+
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % D - BEACH FILL
+    OPT.IBCHFILL = 0;
+    OPT.XBFS = 0;
+    OPT.XBFE = 0;
+    OPT.NFILL = 0;
+    OPT.XF = [];
+    OPT.EFILL = [];
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % E - SEAWALL/REVETMENT
+    OPT.ISWALL = 0;
+    OPT.XSWALL = 0;
+    OPT.ISWFAIL = 0;
+    OPT.PEFAIL = 0;
+    OPT.WEFAIL = 0;
+    OPT.HFAIL = 0;
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % F - HARD BOTTOM
+    OPT.IHBOT = 0;
+    OPT.SCF = 1;
+end
\ No newline at end of file
diff --git a/fsbeach_getstdsettings.m b/fsbeach_getstdsettings.m
new file mode 100644
index 0000000..a30ad81
--- /dev/null
+++ b/fsbeach_getstdsettings.m
@@ -0,0 +1,55 @@
+% SBEACH toolbox - fsbeach_getstdsettings
+% Written by Joshua Simmons 11/2017
+
+% returns all the SBEACH default values
+
+%   Syntax:
+%   OPT = fsbeach_getstdsettings()
+
+%   Input:
+%   bathy     = bathy data structure - output by fsbeach_genbathy
+%   waves     = wave data structure - output by fsbeach_genwaves
+%   tides     = tide data structure - output by fsbeach_gentides
+%
+%   Output:
+%   OPT        = settings
+
+function OPT = fsbeach_getstdsettings(bathy, waves, tide, OPT)
+        % preliminary work
+        diffx = diff(bathy.x);
+        dx = diffx(1);
+        
+        wavestt = (waves.time(end)-waves.time(1))*24*60;
+        dwt = round((waves.time(2)-waves.time(1))*24*60);
+        if isstruct(tide)
+            tidett = (tide.time(end)-tide.time(1))*24*60; %total time
+            dtt = round((tide.time(2)-tide.time(1))*24*60); %time steps
+        end
+        
+        % Section A
+        OPT.DXC = dx;
+        OPT.NDX = length(bathy.x); %number of cells
+        if isnan(OPT.XSTART)
+            OPT.XSTART = bathy.x(1); %landward calculation boundary
+        else
+            warning('XSTART is %d m from first profile point',OPT.XSTART - bathy.x(1))
+        end
+        
+        OPT.NDT = round(wavestt/OPT.DT);
+
+        % Section B
+        OPT.DTWAV = dwt;
+        OPT.DTANG = dwt;
+        if isnan(OPT.DMEAS)
+            OPT.DMEAS = -min(bathy.z); %assume it is input at the boundary if not specified
+        end
+        
+        if isstruct(tide)
+            OPT.DTELV = dtt;
+        end
+        
+        % Section F - check for hard bottom
+        if ~isnan(bathy.hbz)
+            OPT.IHBOT = 1;
+        end
+end
\ No newline at end of file
diff --git a/fsbeach_makecolumn.m b/fsbeach_makecolumn.m
new file mode 100644
index 0000000..fb2e141
--- /dev/null
+++ b/fsbeach_makecolumn.m
@@ -0,0 +1,18 @@
+% SBEACH toolbox - fsbeach_makecolumn
+% Written by Joshua Simmons 11/2017
+
+% convert to column vectors
+%   Syntax:
+%   OPT = fsbeach_makecolumn(OPT,vars)
+%
+%   Input:
+%   OPT:        toolbox OPT structure
+%   vars:       variable names to be checked in structure
+
+function OPT = fsbeach_makecolumn(OPT,vars)
+    for ii = 1:length(vars)
+        if ~iscolumn(OPT.(vars{ii}))
+            OPT.(vars{ii}) = OPT.(vars{ii})';
+        end
+    end
+end
\ No newline at end of file
diff --git a/fsbeach_modelskill.m b/fsbeach_modelskill.m
new file mode 100644
index 0000000..1f051c3
--- /dev/null
+++ b/fsbeach_modelskill.m
@@ -0,0 +1,211 @@
+function [bss, rmse, dVc, dVm, ddV] = fsbeach_modelskill(measured, computed, initial)
+%edited by Joshua Simmons 04/04/2016 to revise definitions of r2 etc
+%XB_SKILL  Computes a variety skill scores
+%
+%   Computes a variety skill scores: R^2, Sci, Relative bias, Brier Skill
+%   Score. Special feature: within the XBeach testbed, the results are
+%   stored to be able to show the development of the different skill scores
+%   in time.
+%
+%   Syntax:
+%   [r2 sci relbias bss] = xb_skill(measured, computed, varargin)
+%
+%   Input:
+%   measured  = Measured data where the first column contains independent
+%               values and the second column contains dependent values
+%   computed  = Computed data where the first column contains independent
+%               values and the second column contains dependent values
+%   initial   = Initial data where the first column contains independent 
+%               values and the second column contains dependent values
+%   varargin  = var:    Name of the variable that is supplied
+%
+%   Output:
+%   bss       = Brier Skill Score
+%   rb20      = Regression through origin R2 value 
+%
+%   Example
+%   [r2 sci relbias bss] = xb_skill(measured, computed)
+%   [r2 sci relbias bss] = xb_skill(measured, computed, 'var', 'zb')
+%
+%   See also xb_plot_skill
+
+%% Copyright notice
+%   --------------------------------------------------------------------
+%   Copyright (C) 2011 Deltares
+%       Bas Hoonhout
+%
+%       bas.hoonhout@deltares.nl	
+%
+%       Rotterdamseweg 185
+%       2629HD Delft
+%
+%   This library is free software: you can redistribute it and/or
+%   modify it under the terms of the GNU Lesser General Public
+%   License as published by the Free Software Foundation, either
+%   version 2.1 of the License, or (at your option) any later version.
+%
+%   This library is distributed in the hope that it will be useful,
+%   but WITHOUT ANY WARRANTY; without even the implied warranty of
+%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%   Lesser General Public License for more details.
+%
+%   You should have received a copy of the GNU Lesser General Public
+%   License along with this library. If not, see <http://www.gnu.org/licenses/>.
+%   --------------------------------------------------------------------
+
+% This tool is part of <a href="http://OpenEarth.nl">OpenEarthTools</a>.
+% OpenEarthTools is an online collaboration to share and manage data and 
+% programming tools in an open source, version controlled environment.
+% Sign up to recieve regular updates of this function, and to contribute 
+% your own tools.
+
+%% Version <http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html>
+% Created: 13 Apr 2011
+% Created with Matlab version: 7.9.0.529 (R2009b)
+
+% $Id: xb_skill.m 4725 2011-06-27 12:58:48Z hoonhout $
+% $Date: 2011-06-27 14:58:48 +0200 (ma, 27 jun 2011) $
+% $Author: hoonhout $
+% $Revision: 4725 $
+% $HeadURL: https://repos.deltares.nl/repos/OpenEarthTools/trunk/matlab/applications/xbeach/xb_analysis/xb_skill.m $
+% $Keywords: $
+
+%% read options
+
+if ~exist('initial', 'var'); initial = []; end;
+
+%% xbeach bugfix    
+% bug - sometime xbeach has suprious points on the end (a flat end to
+% the profile) this is fake so remove it.
+if length(computed)>=10
+    if nanmean(computed(1:10,2)) < nanmean(computed(end-9:end,2))
+        %xbeach direction
+        spr_len = length(diff(computed(:,2))) - find(diff(computed(:,2))~=0,1,'last');
+        computed(end-spr_len+1:end,2) = NaN;
+    else
+        spr_len = find(diff(computed(:,2))~=0,1,'first');
+        computed(1:spr_len-1,2) = NaN;
+    end
+    if spr_len > 2
+        disp(['Warning check computed points, ' num2str(spr_len) ' points found to be spurious'] )
+    end    
+end
+
+%% remove nans
+
+measured = measured(~any(isnan(measured), 2),:);
+computed = computed(~any(isnan(computed), 2),:);
+
+if ~isempty(initial)
+    initial  = initial (~any(isnan(initial ), 2),:);
+end
+
+%% compute skills
+
+[bss rmse dVc dVm ddV] = deal(nan);
+
+if size(measured,1) > 1 && size(computed,1) > 1
+    
+    x       = unique([computed(:,1) ; measured(:,1)]);
+    x       = x(~isnan(x));
+
+    zmt     = interp1(measured(:,1), measured(:,2), x);    
+    zct     = interp1(computed(:,1), computed(:,2), x);
+
+    % determine active zone
+    if ~isempty(initial)
+        zit = interp1(initial(:,1),  initial(:,2),  x);
+        
+        %average over 10 steps for small spikes
+        dzmi = smooth(abs(zmt-zit),10);
+        dzmi((isnan(zmt)|isnan(zit))) = 0;
+        dzcm = smooth(abs(zct-zmt),10);
+        dzcm((isnan(zct)|isnan(zmt))) = 0;
+        
+        dz  = max(dzmi,dzcm);
+        %has to be more change than a standard measurement error (10cm say) 
+        zi1 = find(dz>0.1,1,'first');
+        zi2 = find(dz>0.1,1,'last');
+
+        x   = x  (zi1:zi2);
+        zmt = zmt(zi1:zi2);
+        zct = zct(zi1:zi2);
+        zit = zit(zi1:zi2);
+    end
+    
+    %% clear all nan values in input (to avoid problems with interpolation)
+    %all equal at this point and assign values for BSS calc
+    x0 = x;
+    xc = x;
+    xm = x;
+    z0 = zit;
+    zc = zct;
+    zm = zmt;
+    
+    x0(isnan(z0)) = [];
+    z0(isnan(z0)) = [];
+    xc(isnan(zc)) = [];
+    zc(isnan(zc)) = [];
+    xm(isnan(zm)) = [];
+    zm(isnan(zm)) = [];
+
+    %% determine new grid covered by all profiles
+    x_new = unique([x0' xc' xm']);
+
+    %% interpolate profiles onto new grid
+    [x0,id1] = unique(x0);
+    [xc,id2] = unique(xc);
+    [xm,id3] = unique(xm);
+    z0 = z0(id1);
+    zc = zc(id2);
+    zm = zm(id3);
+
+    z0_new = interp1(x0, z0, x_new);
+    zc_new = interp1(xc, zc, x_new);
+    zm_new = interp1(xm, zm, x_new);
+
+    % reduce vectors if any nans are left
+    id = ~(isnan(z0_new) | isnan(zc_new) | isnan(zm_new));
+    [x_new z0_new zc_new zm_new] = deal(x_new(id), z0_new(id), zc_new(id), zm_new(id));
+
+    %% Calculate volume change
+    try
+        Vc = volumefind(x_new,zc_new,0);
+        Vm = volumefind(x_new,zm_new,0);
+        V0 = volumefind(x_new,z0_new,0);
+        
+        dVm = Vm-V0; %measured volume change
+        dVc = Vc-V0; %computed volume change
+        ddV = dVc-dVm; %predicted volume change - measured
+        nddV = ddV/abs(V0-Vm);
+    catch
+        dVm = NaN;
+        dVc = NaN;
+        ddV = NaN;
+        nddV = NaN;
+    end
+    %% derive weight
+    % weight is defined as half of diff left and half of diff right of each
+    % point; first and last point are considered to have only one side.
+    weight = diff([x_new(1) diff(x_new)/2 + x_new(1:end-1) x_new(end)]);
+    weight = weight / sum(weight);
+
+    %% calculate BSS only
+    % brier skill score
+    if ~isempty(initial)
+        mse_p = sum( (zm_new - zc_new).^2 .* weight );
+        mse_0 = sum( (zm_new - z0_new).^2 .* weight );
+        bss = 1. - (mse_p/mse_0);
+    else
+        bss = 1-(std(zc-zm))^2/var(zm);
+    end
+    
+    %% Calculate others
+    
+    rmse     = sqrt(mean((zc_new-zm_new).^2));
+    rmsm    = sqrt(mean(zm_new.^2));
+    sci     = rmse/max(rmsm,abs(mean(zm_new)));
+    relbias = mean(zc_new-zm_new)/max(rmsm,abs(mean(zm_new)));
+    
+end
+
diff --git a/fsbeach_processresults.m b/fsbeach_processresults.m
new file mode 100644
index 0000000..08457e9
--- /dev/null
+++ b/fsbeach_processresults.m
@@ -0,0 +1,71 @@
+% SBEACH toolbox - fsbeach_processresults
+% Written by Joshua Simmons 11/2017
+
+%   Syntax:
+%   sbout = fsbeach_processresults(sblocs)
+%
+%   Input:
+%   sbout    =  structure with input, computed and measured
+
+%   Output:
+%   sbout     = structure with sbeach data and statistics;
+
+function sbout = fsbeach_processresults(sbout)
+    for ii = 1:length(sbout.input)
+        xin = sbout.input(ii).x;
+        zin = sbout.input(ii).z;
+        xcomp = sbout.computed(ii).x;
+        zcomp = sbout.computed(ii).z;
+        xmeas = sbout.measured(ii).x;
+        zmeas = sbout.measured(ii).z;
+        
+        try
+            [tmpbss, tmprmse, dVc, dVm, ddV] = fsbeach_modelskill([xmeas zmeas], [xcomp zcomp], [xin zin]);
+
+            %calculate BSS above MSL
+            %first get points above MSL - for measured and then apply that
+            %to all - cant take these independently as may only get say one
+            %point for modelled and then xb_skill interpolates.
+            %BSS deals well if based on measured as the -10 and x
+            %determinant - it only finds the interpolated values with
+            %info so will deal if initpf doesnt stretch to all of
+            %measured pf
+            keepme1 = find(zmeas>0);
+            if xmeas(keepme1(1))>xmeas(keepme1(end))
+                keepmo1 = find(xcomp>xmeas(keepme1(end)) & xcomp<xmeas(keepme1(1)));
+                keepin1 = find(xin>xmeas(keepme1(end)) & xin<xmeas(keepme1(1)));
+            elseif xmeas(keepme1(1))<xmeas(keepme1(end))
+                keepmo1 = find(xcomp<xmeas(keepme1(end)) & xcomp>xmeas(keepme1(1)));
+                keepin1 = find(xin<xmeas(keepme1(end)) & xin>xmeas(keepme1(1)));
+            end
+            [tmpabMSLbss, tmpabMSLrmse, ~, ~, ~] = fsbeach_modelskill([xmeas(keepme1) zmeas(keepme1)], [xcomp(keepmo1) zcomp(keepmo1)], [xin(keepin1) zin(keepin1)]);
+
+            %calculate BSS below MSL
+            keepme2 = find(zmeas<0);
+            if xmeas(keepme2(1))>xmeas(keepme2(end))
+                keepmo2 = find(xcomp>xmeas(keepme2(end)) & xcomp<xmeas(keepme2(1)));
+                keepin2 = find(xin>xmeas(keepme2(end)) & xin<xmeas(keepme2(1)));
+            elseif xmeas(keepme2(1))<xmeas(keepme2(end))
+                keepmo2 = find(xcomp<xmeas(keepme2(end)) & xcomp>xmeas(keepme2(1)));
+                keepin2 = find(xin<xmeas(keepme2(end)) & xin>xmeas(keepme2(1)));
+            end
+            [tmpbeMSLbss,tmpbeMSLrmse, ~, ~, ~] = fsbeach_modelskill([xmeas(keepme2) zmeas(keepme2)], [xcomp(keepmo2) zcomp(keepmo2)], [xin(keepin2) zin(keepin2)]);
+
+            %store results
+            sbout.stats(ii).bss = tmpbss;
+            sbout.stats(ii).rmse = tmprmse;
+            sbout.stats(ii).dVc = dVc;
+            sbout.stats(ii).dVm = dVm;
+            sbout.stats(ii).ddV = ddV;
+
+            sbout.stats(ii).aboveMSL.bss = tmpabMSLbss;
+            sbout.stats(ii).aboveMSL.rmse = tmpabMSLrmse;
+
+            sbout.stats(ii).belowMSL.bss = tmpbeMSLbss;
+            sbout.stats(ii).belowMSL.rmse = tmpbeMSLrmse;
+        catch
+            disp(['Run number ' num2str(ii) ' failed.'])           
+            continue
+        end
+    end
+end
diff --git a/fsbeach_readxvrfile.m b/fsbeach_readxvrfile.m
new file mode 100644
index 0000000..79acae2
--- /dev/null
+++ b/fsbeach_readxvrfile.m
@@ -0,0 +1,43 @@
+% SBEACH toolbox - fsbeach_collectresults
+% Written by Joshua Simmons 02/2018
+
+%   Syntax:
+%   dataout     = fsbeach_readxvrfile(fid)
+%
+%   Input:
+%   fid         = file id of .XVR file from which data is to be extracted
+
+%   Output:
+%   dataout     = structure with sbeach data;
+
+function dataout = fsbeach_readxvrfile(fid)
+    ln = fgets(fid); % first line
+    %header material
+    while ln(1) ~= '_'
+        ln = fgets(fid);
+    end
+    
+    for ii = 1:8
+        tmpd = [];
+        while any(isletter(ln)) || ln(1) == '_'
+            ln = fgets(fid);
+        end
+        while ln(1) ~= '_' && ~any(isletter(ln)) && ischar(ln)
+            tmpd = [tmpd; sscanf(ln,'%f')];
+            ln = fgets(fid);
+        end
+        tmpdataout(ii).data = tmpd;
+    end
+    
+    padlen = length(tmpdataout(1).data)-length(tmpdataout(2).data);
+    
+    %max value
+    dataout.Hmax = padarray(tmpdataout(2).data,padlen,0,'pre');
+    dataout.TWLmax = padarray(tmpdataout(4).data,padlen,0,'pre');
+    dataout.depmax = padarray(tmpdataout(6).data,padlen,0,'pre');
+    
+    %time step of max
+    dataout.tsHmax = padarray(tmpdataout(3).data,padlen,0,'pre');
+    dataout.tsTWLmax = padarray(tmpdataout(5).data,padlen,0,'pre');
+    dataout.tsdepmax = padarray(tmpdataout(7).data,padlen,0,'pre');
+end
\ No newline at end of file
diff --git a/fsbeach_runmodel.m b/fsbeach_runmodel.m
new file mode 100644
index 0000000..892d3b4
--- /dev/null
+++ b/fsbeach_runmodel.m
@@ -0,0 +1,18 @@
+% SBEACH toolbox - fsbeach_runmodel
+% Written by Joshua Simmons 11/2017
+
+%   Syntax:
+%   success = fsbeach_runmodel(cfgpath,exepath)
+%
+%   Input:
+%   cfgpath     = path to SBEACH .CFG file (and other files setup by
+%                 fsbeach_setupmodel()
+%   exepath     = path to SBEACH exe
+
+%   Output:
+%   success     = bool;
+
+function [fail, cmdout] = fsbeach_runmodel(cfgpath,exepath)
+    cmdin = ['"' exepath '"' ' -cfgFN ' '"' cfgpath '"'];
+    [fail, cmdout] = system(cmdin);
+end
\ No newline at end of file
diff --git a/fsbeach_runsetup.asv b/fsbeach_runsetup.asv
new file mode 100644
index 0000000..315765d
--- /dev/null
+++ b/fsbeach_runsetup.asv
@@ -0,0 +1,6 @@
+% SBEACH toolbox
+% Written by Joshua Simmons
+
+function out = fsbeach_runsetup()
+    
+end
\ No newline at end of file
diff --git a/fsbeach_runsetup.m b/fsbeach_runsetup.m
new file mode 100644
index 0000000..fcca4c7
--- /dev/null
+++ b/fsbeach_runsetup.m
@@ -0,0 +1,6 @@
+% SBEACH toolbox
+% Written by Joshua Simmons
+
+function out = fsbeach_runsetup()
+
+end
\ No newline at end of file
diff --git a/fsbeach_setupmodel.m b/fsbeach_setupmodel.m
new file mode 100644
index 0000000..72f13a8
--- /dev/null
+++ b/fsbeach_setupmodel.m
@@ -0,0 +1,96 @@
+% SBEACH toolbox - fsbeach_setupmodel
+% Written by Joshua Simmons 11/2017
+
+% Note this code is specifically written to align with (and borrows code
+% from) the XBeach matlab toolbox so as to make the use of both models
+% streamlined.
+
+%   Syntax:
+%   OPT = fsbeach_setupmodel(varargin)
+%
+%   Input:
+%   varargin  = bathy:      cell array of name/value pairs of bathymetry
+%                           settings supplied to fsbeach_genbathy
+%               waves:      cell array of name/value pairs of waves
+%                           settings supplied to fsbeach_genwaves
+%               tide:       cell array of name/value pairs of tide
+%                           settings supplied to fsbeach_gentide
+%               settings:   cell array of name/value pairs of model
+%                           settings supplied to fsbeach_writecfg
+%               path:       destination directory of model setup, if
+%                           written to disk
+%
+%   Output:
+%   OPT         = options
+
+function out = fsbeach_setupmodel(varargin)
+    OPT = struct( ...
+        'bathy', {{}}, ...
+        'waves', {{}}, ...
+        'tide', {{}}, ...
+        'settings', {{}}, ...
+        'path', [pwd '\temp\'], ...
+        'name', 'sbeach_test' ...
+    );
+
+    OPT = setproperty(OPT, varargin{:});
+    
+    %check we are ready to write!
+    if ~isdir(OPT.path)
+        mkdir(OPT.path)
+    else
+        %delete any old SBEACH files
+        delete(fullfile(OPT.path,'*.PRI'));
+        delete(fullfile(OPT.path,'*.WAV'));
+        delete(fullfile(OPT.path,'*.ANG'));
+        delete(fullfile(OPT.path,'*.ELV'));
+        delete(fullfile(OPT.path,'*.HDB'));
+        delete(fullfile(OPT.path,'*.CFG'));
+        delete(fullfile(OPT.path,'*.AsSupplied'));
+        delete(fullfile(OPT.path,'*.LOG'));
+        delete(fullfile(OPT.path,'*.PRC'));
+        delete(fullfile(OPT.path,'*.RPTNew'));
+        delete(fullfile(OPT.path,'*.XVR'));
+    end
+    
+    %%% Initial settings
+    %get defaults
+    settingsOPT = fsbeach_getdefaults();
+    %apply any setttings as needed
+    settingsOPT = setproperty(settingsOPT, OPT.settings);
+    
+    %%% Bathy
+    %print to file
+    bathy = fsbeach_genbathy(OPT.path,OPT.name,settingsOPT,OPT.bathy{:});
+    
+    %%% Waves 
+    %print to file
+    waves = fsbeach_genwaves(OPT.path,OPT.name,OPT.waves{:});
+    
+    %%% Tide 
+    %print to file
+    if isempty(OPT.tide) && ~any(strcmp(OPT.settings,'IELEV'))
+        error('Please supply tide or use the IELEV setting to supply constant WL.')
+    elseif ~isempty(OPT.tide)
+        tide = fsbeach_gentide(OPT.path,OPT.name,OPT.tide{:});
+        %check timeseries data
+        fsbeach_checktsdata(waves,tide);
+    else
+        tide = NaN; % no tide supplied
+    end
+    
+    %%% Final settings
+    % get standard settings from bathy, waves and tides
+    settingsOPT = fsbeach_getstdsettings(bathy, waves, tide, settingsOPT);
+    
+    %write the configuration file
+    fsbeach_writecfg(OPT.path,OPT.name,settingsOPT);
+    
+    %%% Output
+    %structure out
+    out.bathy = bathy;
+    out.waves = waves;
+    out.tides = tide;
+    out.settings = settingsOPT;
+    out.path = [OPT.path OPT.name];
+end
\ No newline at end of file
diff --git a/fsbeach_writecfg.m b/fsbeach_writecfg.m
new file mode 100644
index 0000000..19cc855
--- /dev/null
+++ b/fsbeach_writecfg.m
@@ -0,0 +1,18 @@
+% SBEACH toolbox - fsbeach_writecfg
+% Written by Joshua Simmons 11/2017
+
+%   Syntax:
+%   wavesout = fsbeach_writecfg(outpath,standard_settings,varargin)
+%
+%   Input:
+%   outpath:                output path for CFG file
+%   standard_settings:      standard settings for bathy, waves, tide etc.
+%
+%   varargin  = sbeach settings
+%
+%   Output:
+%   cfg        = all config settings
+
+function fsbeach_writecfg(outpath,name,OPT)    
+    writetofilecfg(OPT, outpath, name);
+end
\ No newline at end of file
diff --git a/sbeach_exe/final_exe/SBEACH.exe b/sbeach_exe/final_exe/SBEACH.exe
new file mode 100644
index 0000000..c6eac25
Binary files /dev/null and b/sbeach_exe/final_exe/SBEACH.exe differ
diff --git a/setproperty.m b/setproperty.m
new file mode 100644
index 0000000..c4ec1bb
--- /dev/null
+++ b/setproperty.m
@@ -0,0 +1,471 @@
+function [OPT Set Default] = setproperty(OPT, inputCell, varargin)
+% SETPROPERTY  generic routine to set values in PropertyName-PropertyValue pairs
+%
+% Routine to set properties based on PropertyName-PropertyValue 
+% pairs (aka <keyword,value> pairs). Can be used in any function 
+% where PropertyName-PropertyValue pairs are used.
+%   
+%
+% [OPT Set Default] = setproperty(OPT, inputCell, varargin)
+%
+% input:
+% OPT       = structure in which fieldnames are the keywords and the values 
+%             are the defaults 
+% inputCell = must be a cell array containing single struct, or a set of
+%             'PropertyName', PropertyValue,... pairs. It is best practice 
+%             to pass the varargin of the calling function as the 2nd argument.  
+%             Property names must be strings. If they contain a dot (.) this is
+%             interpreted a field separator. This can be used to assign 
+%             properties on a subfield level.
+% varargin  = series of 'PropertyName', PropertyValue,... pairs to set 
+%             methods for setproperty itself.
+%           
+% output:
+% OPT     = structure, similar to the input argument OPT, with possibly
+%           changed values in the fields
+% Set     = structure, similar to OPT, values are true where OPT has been 
+%           set (and possibly changed)
+% Default = structure, similar to OPT, values are true where the values of
+%           OPT are equal to the original OPT
+%
+% Example calls:
+% 
+% [OPT Set Default] = setproperty(OPT, vararginOfCallingFunction)
+% [OPT Set Default] = setproperty(OPT, {'PropertyName', PropertyValue,...})
+% [OPT Set Default] = setproperty(OPT, {OPT2})
+%
+% Any number of leading  structs with 
+% any number of trailing <keyword,value> pairs:
+% [OPT Set Default] = setproperty(OPT1, OPT2, ..., OPTn)
+% [OPT Set Default] = setproperty(OPT1, OPT2, ..., OPTn,'PropertyName', PropertyValue,...)
+%
+%     Different methods for dealing with class changes of variables, or 
+%     extra fields (properties that are not in the input structure) can 
+%     be defined as property-value pairs. Valid properties are
+%     onExtraField and onClassChange:
+%
+% PROPERTY       VALUE
+% onClassChange: ignore          ignore (default)
+%                warn            throw warning
+%                error           throw error
+% onExtraField:  silentIgnore    silently ignore the field
+%                warnIgnore      ignore the field and throw warning      
+%                silentAppend    silently append the field to OPT
+%                warnAppend      append the field to OPT and throw warning 
+%                error           throw error (default)
+%
+% Example calls:
+%
+% [OPT Set Default] = setproperty(OPT, vararginOfCallingFunction,'onClassChange','warn')
+% [OPT Set Default] = setproperty(OPT, {'PropertyName', PropertyValue},'onExtraField','silentIgnore')
+%
+%
+% Example: 
+%
+% +------------------------------------------->
+% function y = dosomething(x,'debug',1)
+% OPT.debug  = 0;
+% OPT        = setproperty(OPT, varargin);
+% y          = x.^2;
+% if OPT.debug; plot(x,y);pause; end
+% +------------------------------------------->
+%
+% legacy syntax is also supported, but using legacy syntax prohibits the 
+% setting of onClassChange and onExtraField methods:
+%
+% [OPT Set Default] = setproperty(OPT, varargin{:})
+%  OPT              = setproperty(OPT, 'PropertyName', PropertyValue,...)
+%  OPT              = setproperty(OPT, OPT2)
+%
+% input:
+% OPT      = structure in which fieldnames are the keywords and the values are the defaults 
+% varargin = series of PropertyName-PropertyValue pairs to set
+% OPT2     = is a structure with the same fields as OPT. 
+%
+%            Internally setproperty translates OPT2 into a set of
+%            PropertyName-PropertyValue pairs (see example below) as in:
+%            OPT2    = struct( 'propertyName1', 1,...
+%                              'propertyName2', 2);
+%            varcell = reshape([fieldnames(OPT2)'; struct2cell(OPT2)'], 1, 2*length(fieldnames(OPT2)));
+%            OPT     = setproperty(OPT, varcell{:});
+%
+% Change log:
+%    2011-09-30: full code rewrite to include:
+%                 - setpropertyInDeeperStruct functionality
+%                 - user defined handling of extra fields 
+%                 - class change warning/error message
+%
+% See also: VARARGIN, STRUCT, MERGESTRUCTS
+
+%% Copyright notice
+%   --------------------------------------------------------------------
+%   Copyright (C) 2009 Delft University of Technology
+%       C.(Kees) den Heijer
+%
+%       C.denHeijer@TUDelft.nl	
+%
+%       Faculty of Civil Engineering and Geosciences
+%       P.O. Box 5048
+%       2600 GA Delft
+%       The Netherlands
+%
+%   This library is free software; you can redistribute it and/or
+%   modify it under the terms of the GNU Lesser General Public
+%   License as published by the Free Software Foundation; either
+%   version 2.1 of the License, or (at your option) any later version.
+%
+%   This library is distributed in the hope that it will be useful,
+%   but WITHOUT ANY WARRANTY; without even the implied warranty of
+%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%   Lesser General Public License for more details.
+%
+%   You should have received a copy of the GNU Lesser General Public
+%   License along with this library; if not, write to the Free Software
+%   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+%   USA
+%   or http://www.gnu.org/licenses/licenses.html, http://www.gnu.org/, http://www.fsf.org/
+%   --------------------------------------------------------------------
+
+% This tools is part of <a href="http://OpenEarth.Deltares.nl">OpenEarthTools</a>.
+% OpenEarthTools is an online collaboration to share and manage data and 
+% programming tools in an open source, version controlled environment.
+% Sign up to recieve regular updates of this function, and to contribute 
+% your own tools.
+
+%% Version <http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html>
+% Created: 26 Feb 2009
+% Created with Matlab version: 7.4.0.287 (R2007a)
+
+% $Id: setproperty.m 8036 2013-02-05 21:06:43Z boer_g $
+% $Date: 2013-02-05 22:06:43 +0100 (Tue, 05 Feb 2013) $
+% $Author: boer_g $
+% $Revision: 8036 $
+% $HeadURL: https://svn.oss.deltares.nl/repos/openearthtools/trunk/matlab/setproperty.m $
+% $Keywords: $
+
+%% shortcut function if there is nothing to set (1)
+if nargin==1||isempty(inputCell)
+    if nargout > 1 % process Set
+        flds1         = fieldnames(OPT);
+        Set = [flds1,repmat({false},size(flds1))]';
+        Set = struct(Set{:});
+    end
+    if nargout > 2 % process Default
+        Default = [flds1,repmat({true},size(flds1))]';
+        Default = struct(Default{:});
+    end
+    return
+end
+
+%% check and parse inputCell (usually the varargin struct in the calling function)
+% determine mode from class of the second argument
+switch(class(inputCell))
+    case 'struct'   
+        % recursively let setproperty peel all leading structs 
+        % with optional trailing keyword,value> pairs
+        inputCell = setproperty(inputCell,varargin{:});
+        inputCell = struct2arg(inputCell);
+        varargin  = {};
+    case 'char'
+        % legay syntax mode
+        inputCell = [{inputCell} varargin];
+        varargin  = {};
+    case 'cell'
+        % recursively let setproperty peel all leading structs from cell
+        if isstruct(inputCell{1})
+           inputCell = {setproperty(inputCell{:})};
+        end
+    otherwise
+        error('SETPROPERTY:inputCell',...
+            'Second input must be a cell, (or a char or struct for legacy syntax)')
+end
+
+
+%% shortcut function if there is nothing to set (2)
+if numel(inputCell) == 1 && isempty(inputCell{1})
+    if nargout > 1 % process Set
+        flds1         = fieldnames(OPT);
+        Set = [flds1,repmat({false},size(flds1))]';
+        Set = struct(Set{:});
+    end
+    if nargout > 2 % process Default
+        Default = [flds1,repmat({true},size(flds1))]';
+        Default = struct(Default{:});
+    end
+    return
+end
+
+if odd(length(inputCell))
+    %then length must be 1
+    if length(inputCell) == 1
+        %then the inputCell must be a structure
+        if ~isstruct(inputCell{1})
+            error('SETPROPERTY:inputCell',...
+                'Second argument inputCell must be a cell containing a single struct or property/value pairs')
+        end
+        flds2  = fieldnames(inputCell{1})';
+        newVal = struct2cell(inputCell{1})';
+    else
+        error('SETPROPERTY:inputCell',...
+            'Second argument inputCell must be a cell containing a single struct or property/value pairs')
+    end
+else
+    flds2  = inputCell(1:2:end);
+    if ~all(cellfun(@ischar,flds2))
+        error('SETPROPERTY:inputCell',...
+            'Second argument inputCell, property names should be strings')
+    end
+    newVal = inputCell(2:2:end);
+end
+
+
+%% check and parse varargin
+
+if length(varargin) > 4
+    error('Too many input arguments to setpropoerty.');
+end
+% error(nargchk(0, 4, length(varargin), 'struct'))
+if odd(length(varargin))
+     error('SETPROPERTY:varargin',...
+                        'Set onClassChange and onExtraField with the varargin, as keyword value pairs');
+end
+
+onExtraField       = 'error';
+onClassChange      = 'ignore';
+if ~isempty(varargin)
+    for ii = 1:2:length(varargin)
+        switch varargin{ii}
+            case 'onClassChange'
+                if ischar(varargin{ii+1}) && ismember(varargin(ii+1),...
+                        {'ignore','warn','error'})
+                    onClassChange = varargin{ii+1};
+                else
+                    error('SETPROPERTY:InvalidMethod',...
+                        'Valid methods for onClassChange are: ignore, warn and error');
+                end
+            case 'onExtraField'
+                if ischar(varargin{ii+1}) && ismember(varargin(ii+1),...
+                        {'silentAppend','warnAppend','silentIgnore','warnIgnore','error'})
+                    onExtraField = varargin{ii+1};
+                else
+                    error('SETPROPERTY:InvalidMethod',...
+                        'Valid methods for onExtraField are: append, silentIgnore, warnIgnore, error');
+                end
+            otherwise
+                error('SETPROPERTY:InvalidKeyword', ...
+                    'Supported keywords are onClassChange and onExtraField');
+        end
+    end
+end
+
+switch onClassChange
+    case 'warn'
+        warnOnClassChange  = true;
+        errorOnClassChange = false;
+    case 'error'
+        warnOnClassChange  = false;
+        errorOnClassChange = true;
+    case 'ignore'
+        warnOnClassChange  = false;
+        errorOnClassChange = false;
+end
+
+%% copy the original OPT only if Default has to be returned
+if nargout > 2
+    OPToriginal = OPT;
+end
+%% check field names, and distinguish between field to set and extra fields
+% flds1 contains field names of OPT
+flds1         = fieldnames(OPT);
+
+% fldsCell contains field names to assign, split per subfield
+fldsCell      = regexp(flds2,'[^\.]*','match');
+fldsCellLen   = cellfun(@length,fldsCell);
+% check if all field names are valid to assign
+allFieldNames  = [fldsCell{:}];
+validFieldName = cellfun(@(x) (isvarname(x) | iskeyword(x)),allFieldNames); % a field like 'case' is allowed also, but is not a valid varname
+if ~all(validFieldName)
+    error('SETPROPERTY:invalidFieldName',...
+        '\nThe following field name is not valid: %s',allFieldNames{~validFieldName});
+end
+
+% identify fldsToSet for simple field names (without subfields)
+
+% fldsToSet     = ismember(flds2,flds1); 
+% As ismember is rather slow, this is replaced by more optimized code
+
+fldsToSet = false(size(flds2));
+for ii = find(fldsCellLen==1)
+    fldsToSet(ii) = any(strcmp(flds2(ii),flds1));
+end
+
+% identify fldsToSet for field names with subfields)
+for ii = find(fldsCellLen>1)
+    fldsToSet(ii) = isfield2(OPT,fldsCell{ii});
+end
+
+
+% all other fields are either to be set, or extra
+fldsExtra     = ~fldsToSet;
+
+%% process fldsToSet
+if any(fldsToSet)
+    for ii = find(fldsToSet)
+        switch length(fldsCell{ii})
+            case 1
+                if warnOnClassChange || errorOnClassChange
+                    class1 = class(OPT.(fldsCell{ii}{1}));
+                    class2 = class(newVal{ii});
+                    classChange(flds2{ii},class1,class2,warnOnClassChange,errorOnClassChange);
+                end
+                OPT.(fldsCell{ii}{1}) = newVal{ii};
+            case 2
+                if warnOnClassChange || errorOnClassChange
+                    class1 = class(OPT.(fldsCell{ii}{1}).(fldsCell{ii}{2}));
+                    class2 = class(newVal{ii});
+                    classChange(flds2{ii},class1,class2,warnOnClassChange,errorOnClassChange);
+                end
+                OPT.(fldsCell{ii}{1}).(fldsCell{ii}{2}) = newVal{ii};
+            otherwise
+                if warnOnClassChange || errorOnClassChange
+                    class1 = class(getfield(OPT,fldsCell{ii}{:}));
+                    class2 = class(newVal{ii});
+                    classChange(flds2{ii},class1,class2,warnOnClassChange,errorOnClassChange);
+                end
+                OPT = setfield(OPT,fldsCell{ii}{:},newVal{ii});
+        end
+    end
+end
+
+%% deal with fldsExtra
+if any(fldsExtra)
+    switch lower(onExtraField)
+        case {'silentappend','warnappend'}
+            % append extra fields to OPT
+            for ii = find(fldsExtra)
+                switch length(fldsCell{ii})
+                    case 1
+                        OPT.(flds2{ii}) = newVal{ii};
+                    otherwise
+                        OPT = setfield(OPT,fldsCell{ii}{:},newVal{ii});
+                end
+            end
+            if strcmpi(onExtraField,'warnAppend')
+                % throw a warning
+                warning('SETPROPERTY:ExtraField',...
+                '\nThe following field is Extra and appended to OPT: %s',flds2{fldsExtra});
+            end
+        case 'silentignore'
+            % do nothing, silently ignore extra fields
+        case 'warnignore'
+            warning('SETPROPERTY:ExtraField',...
+                '\nThe following field is Extra and thus ignored: %s',flds2{fldsExtra});
+        case 'error'
+            error('SETPROPERTY:ExtraField',...
+                '\nThe following field is Extra: %s',flds2{fldsExtra});
+    end
+end
+
+%% assign Output
+if nargout > 1 % process Set
+    Set = [flds1,repmat({false},size(flds1))]';
+    Set = struct(Set{:});
+    if any(fldsToSet)
+        for ii = find(fldsToSet)
+            switch length(fldsCell{ii})
+                case 1
+                    Set.(fldsCell{ii}{1}) = true;
+                otherwise % this routine is rather slow, would be nice to add case 2 to cover the most common calls
+                    for nn = 1:length(fldsCell{ii})-1
+                        if ~isstruct(getfield(Set,fldsCell{ii}{1:nn})) %#ok<*GFLD>
+                            substruct = [fieldnames(getfield(OPT,fldsCell{ii}{1:nn})),...
+                                repmat({false},size(fieldnames(getfield(OPT,fldsCell{ii}{1:nn}))))]';
+                            Set = setfield(Set,fldsCell{ii}{1:nn},[]); %#ok<*SFLD>
+                            Set = setfield(Set,fldsCell{ii}{1:nn},struct(substruct{:}));
+                        end  
+                    end
+                    Set = setfield(Set,fldsCell{ii}{:},true);
+            end
+        end
+    end
+    if any(fldsExtra)
+        switch lower(onExtraField)
+            case {'silentappend','warnappend'}
+                for ii = find(fldsExtra)
+                    switch length(fldsCell{ii})
+                        case 1
+                            Set.(flds2{ii}) = true;
+                        otherwise
+                            Set = setfield(Set,fldsCell{ii}{:},true);
+                    end
+                end
+        end
+    end
+end
+
+if nargout > 2 % process Default
+    Default = [flds1,repmat({true},size(flds1))]';
+    Default = struct(Default{:});
+    if any(fldsToSet)
+        for ii = find(fldsToSet)
+            switch length(fldsCell{ii})
+                case 1
+                    Default.(fldsCell{ii}{1}) = ...
+                        isequalwithequalnans(OPToriginal.(fldsCell{ii}{1}),OPT.(fldsCell{ii}{1}));
+                otherwise % this routine is rather slow, would be nice to add case 2 to cover the most common calls
+                    for nn = 1:length(fldsCell{ii})-1
+                        if ~isstruct(getfield(Default,fldsCell{ii}{1:nn})) %#ok<*GFLD>
+                            substruct = [fieldnames(getfield(OPT,fldsCell{ii}{1:nn})),...
+                                repmat({true},size(fieldnames(getfield(OPT,fldsCell{ii}{1:nn}))))]';
+                            Default = setfield(Default,fldsCell{ii}{1:nn},[]); %#ok<*SFLD>
+                            Default = setfield(Default,fldsCell{ii}{1:nn},struct(substruct{:}));
+                        end  
+                    end
+                    Default = setfield(Default,fldsCell{ii}{:},...
+                        isequalwithequalnans(getfield(OPToriginal,fldsCell{ii}{:}),getfield(OPT,fldsCell{ii}{:})));
+            end
+        end
+    end
+    if any(fldsExtra)
+        switch lower(onExtraField)
+            case {'silentappend','warnappend'}
+                for ii = find(fldsExtra)
+                    switch length(fldsCell{ii})
+                        case 1
+                            Default.(flds2{ii}) = false;
+                        otherwise
+                            Default = setfield(Default,fldsCell{ii}{:},false);
+                    end
+                end
+        end
+    end
+end
+
+function tf = isfield2(OPT,fldsCell)
+if isfield(OPT,fldsCell{1})
+    if length(fldsCell) > 1
+        tf = isfield2(OPT.(fldsCell{1}),fldsCell(2:end));
+    else
+        tf = true;
+    end
+else
+    tf = false;
+end
+
+function classChange(fld,class1,class2,warnOnClassChange,errorOnClassChange)
+if ~strcmp(class1,class2)
+    if warnOnClassChange
+        warning('SETPROPERTY:ClassChange', ...
+            'Class change of field ''%s'' from %s to %s',...
+            fld,class1,class2);
+    elseif errorOnClassChange
+        error('SETPROPERTY:ClassChange', ...
+            'Class change of field ''%s'' from %s to %s not allowed',...
+            fld,class1,class2);
+    end
+end
+
+function out = odd(in)
+%ODD   test whether number if odd 
+out = mod(in,2)==1;
+%% EOF
\ No newline at end of file
diff --git a/volumefind.m b/volumefind.m
new file mode 100644
index 0000000..bf3f1ff
--- /dev/null
+++ b/volumefind.m
@@ -0,0 +1,39 @@
+function [VolumeTotal, Beachwidth]  = volumefind(x,z,shore)
+    % Calculates Volume and Beach Width 
+    % Written by Matthew Phillips 2015
+
+    % Define Shoreline Contour and Fixed Landward Column Boundary  
+    ShoreCont = shore; % m AHD
+    BackCol = 1; % column number
+    
+    if ~iscolumn(z)
+        z = z';
+    end
+    if ~iscolumn(x)
+        x = x';
+    end
+    
+    if z(end) > z(1)
+        z = flip(z);
+        x = flip(x);
+    end
+    
+    if x(end) < x(1)
+        x = -x;
+    end
+    
+    xstep = mean(diff(x));
+    shorecol = find(z>=ShoreCont,1,'last')+1;
+
+    % Width at MSL
+    Beachwidth = interp1(z(shorecol-1:shorecol,1),x(shorecol-1:shorecol,1),ShoreCont);
+
+    % Total Volume 
+    Volx = [x(BackCol:shorecol-1); Beachwidth];
+    Volz = [z(BackCol:shorecol-1); ShoreCont];
+    VolumeTotal = trapz(Volx,Volz);
+end
+
+
+
+
diff --git a/writetofileang.m b/writetofileang.m
new file mode 100644
index 0000000..d8323c4
--- /dev/null
+++ b/writetofileang.m
@@ -0,0 +1,18 @@
+function writetofileang(angfile, outpath, pfstring)
+    fid = fopen([outpath '\' pfstring '.ANG'],'w');
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>         *   SBEACH wave input file:       %s.ANG              *\r\n',pfstring);
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C> DIRECTION (DEGREES)\r\n');
+    fprintf(fid,'E>----------------------------------------------------------------\r\n');
+    for ii = 1:length(angfile)
+        if ii == length(angfile)
+            fprintf(fid,'%.3f\r\n', angfile(ii));
+        else
+            fprintf(fid,'%.3f\r\n', angfile(ii));
+        end
+    end
+    fclose(fid);
+end
\ No newline at end of file
diff --git a/writetofilecfg.m b/writetofilecfg.m
new file mode 100644
index 0000000..620bda5
--- /dev/null
+++ b/writetofilecfg.m
@@ -0,0 +1,173 @@
+function writetofilecfg(OPT, outpath, pfstring)
+    fid = fopen([outpath '\' pfstring '.CFG'],'w');
+    fprintf(fid,'         *******************************************************\r\n');
+    fprintf(fid,'         *   SBEACH model configuration file:       %s.CFG   *\r\n',pfstring);
+    fprintf(fid,'         *******************************************************\r\n');
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % A - MODEL SETUP
+    fprintf(fid,'A----------------------------  MODEL SETUP  -------------------------------A\r\n');
+    fprintf(fid,'A.1  RUN TITLE: TITLE\r\n');
+    fprintf(fid,'    %s\r\n',pfstring);
+    fprintf(fid,'A.2  INPUT UNITS (SI=1, AMERICAN CUST.=2): UNITS\r\n');
+    fprintf(fid,'    %d\r\n',OPT.UNITS);
+    fprintf(fid,'A.3  TOTAL NUMBER OF CALCULATION CELLS AND POSITION OF LANDWARD BOUNDARY\r\n');
+    fprintf(fid,'     RELATIVE TO INITIAL PROFILE: NDX, XSTART\r\n');
+    fprintf(fid,'    %d    %d\r\n',OPT.NDX,OPT.XSTART);
+    fprintf(fid,'A.4  GRID TYPE (CONSTANT=0, VARIABLE=1): IDX\r\n');
+    fprintf(fid,'    %d\r\n',OPT.IDX);
+    fprintf(fid,'A.5  COMMENT: IF GRID TYPE IS VARIABLE, CONTINUE TO A.8\r\n');
+    fprintf(fid,'A.6  CONSTANT GRID CELL WIDTH: DXC\r\n');
+    fprintf(fid,'    %d\r\n',OPT.DXC);
+    fprintf(fid,'A.7  COMMENT: IF GRID TYPE IS CONSTANT CONTINUE TO A.10\r\n');
+    fprintf(fid,'A.8  NUMBER OF DIFFERENT GRID CELL REGIONS: NGRID\r\n');
+    fprintf(fid,'    %d\r\n',OPT.NGRID);
+    fprintf(fid,'A.9  GRID CELL WIDTHS AND NUMBER OF CELLS IN EACH REGION FROM LANDWARD\r\n');
+    fprintf(fid,'    TO SEAWARD BOUNDARY: (DXV(I), NDXV(I), I=1,NGRID)\r\n');
+    for ii = 1:length(OPT.NGRID)
+        fprintf(fid,'    %d    %d',OPT.DXV(ii),OPT.NDXV(ii));
+    end
+    fprintf(fid,'\r\n');
+    fprintf(fid,'A.10 NUMBER OF TIME STEPS AND VALUE OF TIME STEP IN MINUTES: NDT,DT\r\n');
+    fprintf(fid,'    %d    %d\r\n',OPT.NDT,OPT.DT);
+    fprintf(fid,'A.11 NUMBER OF TIME STEP(S) INTERMEDIATE OUTPUT IS WANTED: NWR\r\n');
+    fprintf(fid,'    %d\r\n',OPT.NWR);
+    fprintf(fid,'A.12 TIME STEPS OF INTERMEDIATE OUTPUT: (WRI(I), I=1,NWR)\r\n');
+    for ii = 1:length(OPT.NWR)
+        fprintf(fid,'    %d',OPT.WRI(ii));
+    end
+    fprintf(fid,'\r\n');
+    fprintf(fid,'A.13 IS A MEASURED PROFILE AVAILABLE FOR COMPARISON? (NO=0, YES=1): ICOMP\r\n');
+    fprintf(fid,'    %d\r\n',OPT.ICOMP);
+    fprintf(fid,'A.14 THREE PROFILE ELEVATION CONTOURS (MAXIMUM HORIZONTAL RECESSION OF EACH\r\n');
+    fprintf(fid,'     WILL BE DETERMINED): ELV1, ELV2, ELV3\r\n');
+    fprintf(fid,'    %.2f    %.2f    %.2f\r\n',OPT.ELV1,OPT.ELV2,OPT.ELV3);
+    fprintf(fid,'A.15 THREE PROFILE EROSION DEPTHS AND REFERENCE ELEVATION (DISTANCE FROM\r\n');
+    fprintf(fid,'     POSITION OF REFERENCE ELEVATION ON INITIAL PROFILE TO POSITION OF\r\n');
+    fprintf(fid,'     LANDWARD MOST OCCURENCE OF EACH EROSION DEPTH WILL BE DETERMINED\r\n');
+    fprintf(fid,'     EDP1, EDP2, EDP3, REFELV\r\n');
+    fprintf(fid,'    %.2f    %.2f    %.2f    %.2f\r\n',OPT.EDP1,OPT.EDP2,OPT.EDP3,OPT.REFELV);
+    fprintf(fid,'A.16 TRANSPORT RATE COEFFICIENT (m^4/N): K\r\n');
+    fprintf(fid,'    %.3e\r\n',OPT.K);
+    fprintf(fid,'A.17 COEFFICIENT FOR SLOPE-DEPENDENT TERM (m^2/s): EPS\r\n');
+    fprintf(fid,'    %.3f\r\n',OPT.EPS);
+    fprintf(fid,'A.18 TRANSPORT RATE DECAY COEFFICIENT MULTIPLIER: LAMM\r\n');
+    fprintf(fid,'    %.3f\r\n',OPT.LAMM);
+    fprintf(fid,'A.19 WATER TEMPERATURE IN DEGREES C: TEMPC\r\n');
+    fprintf(fid,'    %.2f\r\n',OPT.TEMPC);
+
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % B - WAVES/WATER ELEVATION/WIND
+    fprintf(fid,'B----------------------  WAVES/WATER ELEVATION/WIND  -----------------------B\r\n');
+    fprintf(fid,'B.1  WAVE TYPE (MONOCHROMATIC=1, IRREGULAR=2): WVTYPE\r\n');
+    fprintf(fid,'    %d\r\n',OPT.WVTYPE);
+    fprintf(fid,'B.2  WAVE HEIGHT AND PERIOD INPUT (CONSTANT=0, VARIABLE=1): IWAVE\r\n');
+    fprintf(fid,'    %d\r\n',OPT.IWAVE);
+    fprintf(fid,'B.3  COMMENT: IF WAVE HEIGHT AND PERIOD ARE VARIABLE, CONTINUE TO B.6\r\n');
+    fprintf(fid,'B.4  CONSTANT WAVE HEIGHT AND PERIOD: HIN, T\r\n');
+    fprintf(fid,'    %.3f    %.3f\r\n',OPT.HIN,OPT.T);
+    fprintf(fid,'B.5  COMMENT: IF WAVE HEIGHT AND PERIOD ARE CONSTANT, CONTINUE TO B.7\r\n');
+    fprintf(fid,'B.6  TIME STEP OF VARIABLE WAVE HEIGHT AND PERIOD INPUT IN MINUTES: DTWAV\r\n');
+    fprintf(fid,'    %.2f\r\n',OPT.DTWAV);
+    fprintf(fid,'B.7  WAVE ANGLE INPUT (CONSTANT=0, VARIABLE=1): IANG\r\n');
+    fprintf(fid,'    %d\r\n',OPT.IANG);
+    fprintf(fid,'B.8  COMMENT: IF WAVE ANGLE IS VARIABLE, CONTINUE TO B.11\r\n');
+    fprintf(fid,'B.9  CONSTANT WAVE ANGLE: ZIN\r\n');
+    fprintf(fid,'    %.3f\r\n',OPT.ZIN);
+    fprintf(fid,'B.10 COMMENT: IF WAVE ANGLE IS CONSTANT, CONTINUE TO B.12\r\n');
+    fprintf(fid,'B.11 TIME STEP OF VARIABLE WAVE ANGLE INPUT IN MINUTES: DTANG\r\n');
+    fprintf(fid,'    %.2f\r\n',OPT.DTANG);
+    fprintf(fid,'B.12 WATER DEPTH OF INPUT WAVES (DEEPWATER=0): DMEAS\r\n');
+    fprintf(fid,'    %d\r\n',OPT.DMEAS);
+    fprintf(fid,'B.13 IS RANDOMIZATION OF WAVE HEIGHT DESIRED? (NO=0, YES=1): IRAND\r\n');
+    fprintf(fid,'    %d\r\n',OPT.IRAND);
+    fprintf(fid,'B.14 COMMENT: IF RANDOMIZATION OF WAVE HEIGHT IS NOT DESIRED, CONTINUE TO B.16\r\n');
+    fprintf(fid,'B.15 SEED VALUE FOR RANDOMIZER AND PERCENT OF VARIABILITY: ISEED, RPERC\r\n');
+    fprintf(fid,'    %d    %.2f\r\n',OPT.ISEED,OPT.RPERC);
+    fprintf(fid,'B.16 TOTAL WATER ELEVATION INPUT (CONSTANT=0, VARIABLE=1): IELEV\r\n');
+    fprintf(fid,'    %d\r\n',OPT.IELEV);
+    fprintf(fid,'B.17 COMMENT: IF WATER ELEVATION IS VARIABLE CONTINUE TO B.20\r\n');
+    fprintf(fid,'B.18 CONSTANT TOTAL WATER ELEVATION: TELEV\r\n');
+    fprintf(fid,'    %.3f\r\n',OPT.TELEV);
+    fprintf(fid,'B.19 COMMENT: IF WATER ELEVATION IS CONSTANT, CONTINUE TO B.21\r\n');
+    fprintf(fid,'B.20 TIME STEP OF VARIABLE TOTAL WATER ELEVATION INPUT IN MINUTES: DTELV\r\n');
+    fprintf(fid,'    %.2f\r\n',OPT.DTELV);
+    fprintf(fid,'B.21 WIND SPEED AND ANGLE INPUT (CONSTANT=0, VARIABLE=1): IWIND\r\n');
+    fprintf(fid,'    %d\r\n',OPT.IWIND);
+    fprintf(fid,'B.22 COMMENT: IF WIND SPEED AND ANGLE ARE VARIABLE, CONTINUE TO B.25\r\n');
+    fprintf(fid,'B.23 CONSTANT WIND SPEED AND ANGLE: W,ZWIND\r\n');
+    fprintf(fid,'    %.3f    %.3f\r\n',OPT.W,OPT.ZWIND);
+    fprintf(fid,'B.24 COMMENT: IF WIND SPEED AND ANGLE ARE CONSTANT, CONTINUE TO C.\r\n');
+    fprintf(fid,'B.25 TIME STEP OF VARIABLE WIND SPEED AND ANGLE INPUT IN MINUTES: DTWND\r\n');
+    fprintf(fid,'    %.2f\r\n',OPT.DTWND);
+            
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % C - BEACH
+    fprintf(fid,'C-------------------------------  BEACH  ----------------------------------C\r\n');
+    fprintf(fid,'C.1  TYPE OF INPUT PROFILE (ARBITRARY=1, SCHEMATIZED=2): TPIN\r\n');
+    fprintf(fid,'    %d\r\n',OPT.TPIN);
+    fprintf(fid,'C.2  COMMENT: IF PROFILE TYPE IS ARBITRARY CONTINUE TO C.4\r\n');
+    fprintf(fid,'C.3  LOCATION AND ELEVATION OF LANDWARD BOUNDARY, LANDWARD BASE OF DUNE,\r\n');
+    fprintf(fid,'     LANDWARD CREST OF DUNE, SEAWARD CREST OF DUNE, START OF BERM,\r\n');
+    fprintf(fid,'     END OF BERM, AND FORESHORE: XLAND,DLAND,XLBDUNE,DLBDUNE,XLCDUNE,DLCDUNE,\r\n');
+    fprintf(fid,'     XSCDUNE,DSCDUNE,XBERMS,DBERMS,XBERME,DBERME,XFORS,DFORS\r\n');
+    fprintf(fid,'    %d    %d    %d    %d    %d    %d\r\n',OPT.XLAND,OPT.DLAND,OPT.XLBDUNE,OPT.DLBDUNE,OPT.XLCDUNE,OPT.DLCDUNE);
+    fprintf(fid,'    %d    %d    %d    %d    %d    %d    %d    %d\r\n',OPT.XSCDUNE,OPT.DSCDUNE,OPT.XBERMS,OPT.DBERMS,OPT.XBERME,OPT.DBERME,OPT.XFORS,OPT.DFORS);
+    fprintf(fid,'C.4  DEPTH CORRESPONDING TO LANDWARD END OF SURF ZONE: DFS\r\n');
+    fprintf(fid,'    %.3f\r\n',OPT.DFS);
+    fprintf(fid,'C.5  EFFECTIVE GRAIN SIZE DIAMETER IN MILLIMETERS: D50\r\n');
+    fprintf(fid,'    %.3f\r\n',OPT.D50);
+    fprintf(fid,'C.6  MAXIMUM PROFILE SLOPE PRIOR TO AVALANCHING IN DEGREES: BMAX\r\n');
+    fprintf(fid,'    %.3f\r\n',OPT.BMAX);
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % D - BEACH FILL
+    fprintf(fid,'D------------------------------ BEACH FILL --------------------------------D\r\n');
+    fprintf(fid,'D.1  IS A BEACH FILL PRESENT? (NO=0, YES=1): IBCHFILL\r\n');
+    fprintf(fid,'    %d\r\n',OPT.IBCHFILL);
+    fprintf(fid,'D.2  COMMENT: IF NO BEACH FILL, CONTINUE TO E.\r\n');
+    fprintf(fid,'D.3  POSITION OF START AND END OF BEACH FILL RELATIVE\r\n');
+    fprintf(fid,'     TO INITIAL PROFILE: XBFS, XBFE\r\n');
+    fprintf(fid,'    %.2f    %.2f\r\n',OPT.XBFS,OPT.XBFE);
+    fprintf(fid,'D.4  NUMBER OF REPRESENTATIVE POINTS BETWEEN START\r\n');
+    fprintf(fid,'AND END OF BEACH FILL: NFILL\r\n');
+    fprintf(fid,'    %d\r\n',OPT.NFILL);
+    fprintf(fid,'D.5  LOCATION AND ELEVATION OF REPRESENTATIVE POINTS RELATIVE TO THE\r\n');
+    fprintf(fid,'INITIAL PROFILE: (XF(I), EFILL(I), I=1,NFILL)\r\n');
+    for ii = 1:length(OPT.NFILL)
+        if isempty(OPT.XF)
+            fprintf(fid,'\r\n');
+        else
+            fprintf(fid,'    %.2f    %.2f',OPT.XF(ii),OPT.EFILL(ii));
+        end
+    end
+    fprintf(fid,'\r\n');
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % E - SEAWALL/REVETMENT
+    fprintf(fid,'E--------------------------- SEAWALL/REVETMENT ----------------------------E\r\n');
+    fprintf(fid,'E.1  IS A SEAWALL PRESENT? (NO=0, YES=1): ISWALL\r\n');
+    fprintf(fid,'    %d\r\n',OPT.ISWALL);
+    fprintf(fid,'E.2  COMMENT: IF NO SEAWALL, CONTINUE TO F.\r\n');
+    fprintf(fid,'E.3  LOCATION OF SEAWALL RELATIVE TO INITIAL PROFILE: XSWALL\r\n');
+    fprintf(fid,'    %.2F\r\n',OPT.XSWALL);
+    fprintf(fid,'E.4  IS SEAWALL ALLOWED TO FAIL? (NO=0, YES =1): ISWFAIL\r\n');
+    fprintf(fid,'    %d\r\n',OPT.ISWFAIL);
+    fprintf(fid,'E.5  COMMENT: IF NO SEAWALL FAILURE, CONTINUE TO F.\r\n');
+    fprintf(fid,'E.6  PROFILE ELEVATION AT SEAWALL WHICH CAUSES FAILURE, TOTAL WATER ELEVATION\r\n');
+    fprintf(fid,'     AT SEAWALL WHICH CAUSES FAILURE, AND WAVE HEIGHT AT SEAWALL WHICH CAUSES\r\n');
+    fprintf(fid,'     FAILURE: PEFAIL, WEFAIL,HFAIL\r\n');
+    fprintf(fid,'    %.2f    %.2f    %.2f\r\n',OPT.PEFAIL,OPT.WEFAIL,OPT.HFAIL);
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % F - HARD BOTTOM
+    fprintf(fid,'F------------------------------  HARD BOTTOM  -----------------------------F\r\n');
+    fprintf(fid,'F.1  IS A HARD BOTTOM PRESENT? (NO=0, YES=1): IHBOT\r\n');
+    fprintf(fid,'    %d\r\n',OPT.IHBOT);
+    fprintf(fid,'F.2  COEFFICIENT FOR TRANSPORT GROWTH DOWNDRIFT EXPOSED HARD BOTTOM: SCF\r\n');
+    fprintf(fid,'    %.2f\r\n',OPT.SCF);
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    fprintf(fid,'----------------------------------- END ------------------------------------\r\n');
+
+    fclose(fid);
+end
\ No newline at end of file
diff --git a/writetofileelv.m b/writetofileelv.m
new file mode 100644
index 0000000..e03712d
--- /dev/null
+++ b/writetofileelv.m
@@ -0,0 +1,18 @@
+function writetofileelv(elvfile, outpath, pfstring)
+    fid = fopen([outpath '\' pfstring '.ELV'],'w');
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>         *   SBEACH water elevation input file:       %s.ELV   *\r\n',pfstring);
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C> TOTAL WATER ELEVATION (m or ft)\r\n');
+    fprintf(fid,'E>----------------------------------------------------------------\r\n');
+    for ii = 1:length(elvfile)
+        if ii == length(elvfile)
+            fprintf(fid,'%.3f\r\n', elvfile(ii));
+        else
+            fprintf(fid,'%.3f\r\n', elvfile(ii));
+        end
+    end
+    fclose(fid);
+end
\ No newline at end of file
diff --git a/writetofilehdb.m b/writetofilehdb.m
new file mode 100644
index 0000000..304e1c9
--- /dev/null
+++ b/writetofilehdb.m
@@ -0,0 +1,20 @@
+function writetofilehdb(hdbfile, outpath, namestr)
+    fid = fopen([outpath '\' namestr '.HDB'],'w');
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>         *    SBEACH hard bottom input file:       %s.HDB  *\r\n',namestr);
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C> NUMBER OF POINTS\r\n');
+    fprintf(fid,'C> POSITION (m or ft), ELEVATION (m or ft)\r\n');
+    fprintf(fid,'E>----------------------------------------------------------------\r\n');
+    fprintf(fid,'%d\r\n',length(hdbfile));
+    for ii = 1:length(hdbfile)
+        if ii == length(hdbfile)
+            fprintf(fid,'%.3f %.3f\r\n', hdbfile(ii,1),hdbfile(ii,2));
+        else
+            fprintf(fid,'%.3f %.3f\r\n', hdbfile(ii,1),hdbfile(ii,2));
+        end
+    end
+    fclose(fid);
+end
\ No newline at end of file
diff --git a/writetofilepri.m b/writetofilepri.m
new file mode 100644
index 0000000..69dff44
--- /dev/null
+++ b/writetofilepri.m
@@ -0,0 +1,20 @@
+function writetofilepri(prifile, outpath, namestr)
+    fid = fopen([outpath '\' namestr '.PRI'],'w');
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>         *    SBEACH initial profile input file:       %s.PRI  *\r\n',namestr);
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C> NUMBER OF POINTS\r\n');
+    fprintf(fid,'C> POSITION (m or ft), ELEVATION (m or ft)\r\n');
+    fprintf(fid,'E>----------------------------------------------------------------\r\n');
+    fprintf(fid,'%d\r\n',length(prifile));
+    for ii = 1:length(prifile)
+        if ii == length(prifile)
+            fprintf(fid,'%.3f %.3f\r\n', prifile(ii,1),prifile(ii,2));
+        else
+            fprintf(fid,'%.3f %.3f\r\n', prifile(ii,1),prifile(ii,2));
+        end
+    end
+    fclose(fid);
+end
\ No newline at end of file
diff --git a/writetofileprm.m b/writetofileprm.m
new file mode 100644
index 0000000..a5661a2
--- /dev/null
+++ b/writetofileprm.m
@@ -0,0 +1,20 @@
+function writetofileprm(prmfile, outpath, pfstring, rundescription)
+    fid = fopen([outpath pfstring '\' pfstring '_' rundescription '.PRM'],'w');
+    fprintf(fid,'C>         *******************************************************\n');
+    fprintf(fid,'C>         *    SBEACH initial profile input file:       %s.PRM  *\n',[pfstring '_' rundescription]);
+    fprintf(fid,'C>         *******************************************************\n');
+    fprintf(fid,'C>\n');
+    fprintf(fid,'C>\n');
+    fprintf(fid,'C> NUMBER OF POINTS\n');
+    fprintf(fid,'C> POSITION (m or ft), ELEVATION (m or ft)\n');
+    fprintf(fid,'E>----------------------------------------------------------------\n');
+    fprintf(fid,'%d\n',length(prmfile));
+    for ii = 1:length(prmfile)
+        if ii == length(prmfile)
+            fprintf(fid,'%4.3f %3.3f', prmfile(ii,1),prmfile(ii,2));
+        else
+            fprintf(fid,'%4.3f %3.3f\n', prmfile(ii,1),prmfile(ii,2));
+        end
+    end
+    fclose(fid);
+end
\ No newline at end of file
diff --git a/writetofilewav.m b/writetofilewav.m
new file mode 100644
index 0000000..f7fe3a1
--- /dev/null
+++ b/writetofilewav.m
@@ -0,0 +1,18 @@
+function writetofilewav(wavfile, outpath, pfstring)
+    fid = fopen([outpath '\' pfstring '.WAV'],'w');
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>         *   SBEACH wave input file:       %s.WAV              *\r\n',pfstring);
+    fprintf(fid,'C>         *******************************************************\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C>\r\n');
+    fprintf(fid,'C> HEIGHT (m or ft), PERIOD (sec)\r\n');
+    fprintf(fid,'E>----------------------------------------------------------------\r\n');
+    for ii = 1:length(wavfile)
+        if ii == length(wavfile)
+            fprintf(fid,'%.3f %.3f\r\n', wavfile(ii,1),wavfile(ii,2));
+        else
+            fprintf(fid,'%.3f %.3f\r\n', wavfile(ii,1),wavfile(ii,2));
+        end
+    end
+    fclose(fid);
+end
\ No newline at end of file