diff --git a/.gitignore b/.gitignore index 7b56113..912bfb8 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ !*.dry !*.bnw !*.bnd +!*.m NDBCdata.txt WAVE2FLOW_DATA.txt @@ -38,6 +39,7 @@ C7_1400_V2_D.mat C7_1400_V2_C.mat Dec6_250Bed.mat DUNEX_Sept7.mat +NDBCdata.txt # do not ignore fish dir (needed due to the above bullet point) #!/m_map diff --git a/DUNEX_RealtimeV5.m b/DUNEX_RealtimeV5.m new file mode 100644 index 0000000..cacaaa4 --- /dev/null +++ b/DUNEX_RealtimeV5.m @@ -0,0 +1,1021 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +clear all +%cd /project/6008948/alex0042/RealtimeH2 +addpath('NCtoolbox') +addpath('m_map') +setup_nctoolbox +flowGrid = load('Cone7W_100.mat'); +waveGrid = load('Cone7W_250.mat'); + +for masterTime=datetime(2019,09,02,00,00,00):hours(6):datetime(2019,09,08,00,00,00) + masterDate = datetime(year(masterTime),month(masterTime),day(masterTime)); + if masterTime==datetime(2019,09,02,00,00,00) + FIRST_RUN = 1; + else + FIRST_RUN = 0; + + end + + + %% Clean files from previous run + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + + clear HRRR_UTM + + if exist(['ModelIn_4' datestr(masterTime,'YYYY-MM-DD_hh') '.mat'])==2 + + load(['ModelIn_4' datestr(masterTime,'YYYY-MM-DD_hh') '.mat']) + + waterLevels(1:37,:) = waterLevels(1:37,:); + + end + + if masterTime>datetime(2019,09,15,00,00,00) + + %% Import data from NOMADS + %% Extratropical Surge and Tide Operational Forecast System for the Atlantic + % (ESTOFS Atlantic) for water levels + + url = ['http://nomads.ncep.noaa.gov/dods/estofs_atl/'... + datestr(masterTime,'yyyymmdd')... + '/estofs_atl_conus_' datestr(masterTime,'hh') 'z']; + + ESTOFS = ncgeodataset(url); + clear url + + lonESTOFS=ESTOFS{'lon'}(:); + latESTOFS=ESTOFS{'lat'}(:); + + % Find ESTOFS index for grid points along boundry + idxCount=1; + for i = 2:50:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + wlIDX(idxCount,:) = [1082,i]; + + idxCount = idxCount + 1; + end + + wlBoundCount(1) = 0; + wlBoundCount(2) = idxCount -1; + + + for i = 750:55:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + wlIDX(idxCount,:) = [i,1322]; + idxCount = idxCount + 1; + end + + wlBoundCount(3) = idxCount -1; + + for i = 475:55:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + wlIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + wlBoundCount(4) = idxCount -1; + + + clear idxCount gridDeg + + % Extract ESTOFS Water Levels for 36 hours at indexes + waterLevelsGRID = ESTOFS{'etcwlsfc'}(2:38,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + + % Find ESTOFS values from small grid + idxCount=1; + for i = 1:length(idxESTOFS) + waterLevels(:,idxCount) = waterLevelsGRID(:,idxESTOFS(idxCount,1)-min(idxESTOFS(:,1))+1,... + idxESTOFS(idxCount,2)-min(idxESTOFS(:,2))+1); + + idxCount = idxCount + 1; + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + disp('Loaded ESTOFS') + %% Multi-grid Wave model (WAVEWATCH III) + % 4 arc minute US East Coast grid for waves + + url = ['http://nomads.ncep.noaa.gov/dods/wave/mww3/'... + datestr(masterTime,'yyyymmdd')... + '/multi_1.at_4m' datestr(masterTime,'yyyymmdd') '_' datestr(masterTime,'hh') 'z']; + + MWW3 = ncgeodataset(url); + clear url + + lonMWW3=wrapTo180(MWW3{'lon'}(:)); + latMWW3=MWW3{'lat'}(:); + + % Find MWW3 index for grid points along boundry + idxCount=1; + for i = 1:25:length(waveGrid.data.Y)-25 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(end-2,i),waveGrid.data.Y(end-2,i),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(end-2,1:i)).^2+... + diff(waveGrid.data.Y(end-2,1:i)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(end-2,i); + waveUTM(idxCount,2) = waveGrid.data.Y(end-2,i); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + waveBoundCount(1) = 0; + waveBoundCount(2) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:350% Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,end-2),waveGrid.data.Y(i,end-2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,end-2)).^2+... + diff(waveGrid.data.Y(i:end-2,end-2)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,end-2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,end-2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(3) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:240 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,2),waveGrid.data.Y(i,2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,1)).^2+... + diff(waveGrid.data.Y(i:end-2,1)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(4) = idxCount -1; + + clear idxCount + + % Extract WW3 Hs for 36 hours at indexes + wavesGRID_Hs = MWW3{'htsgwsfc'}(1:13,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid htsgwsfc + %swell_1 + % Period + wavesGRID_P = MWW3{'perpwsfc'}(1:13,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... % + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid perpwsfc + %swper_1 + % Direction + wavesGRID_Dir = MWW3{'dirpwsfc'}(1:13,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid dirpwsfc + %swdir_1 + % Find WW3 values from small grid + idxCount=1; + for i = 1:length(idxMWW3) + waves(:,idxCount,1) = wavesGRID_Hs(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Hs + + waves(:,idxCount,2) = wavesGRID_P(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Tp + + waves(:,idxCount,3) = wavesGRID_Dir(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Dir + + idxCount = idxCount + 1; + end + clear idxCount + disp('Loaded WW3') + + end + if masterTime>datetime(2019,09,00,00,00,00) + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % if day(masterTime)<10 + % url = ['http://nomads.ncep.noaadatestr(masterTime,'yyyymmdd').gov/dods/nam/nam'... + % datestr(masterTime,'yyyymmdd')... + % '/nam1hr_' datestr(masterTime,'hh') 'z']; +% url = ['/scratch/alex0042/HRRR/' datestr(masterTime,'yyyymmddhh') '.g2']; +% untar([url '.tar'],['/home/cluster/RealtimeH/HAS011383739/nam_218_' datestr(masterTime,'yyyymmddhh')]); + % else + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; + % end + + + HRRR = ncgeodataset(['D:\Alexander\HRRR_Forecast\' ... + datestr(masterTime,'yyyymmdd') ... + '_' datestr(masterTime,'hh') '00_000.grb2.regrid']); + + % Extract Lat Lon from HRRR +% lonHRRR=wrapTo180(HRRR{'lon'}(:)); +% latHRRR=HRRR{'lat'}(:); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(HRRR{'x'}(:),HRRR{'y'}(:)); + [GridLONAll_R,GridLATAll_R] = m_xy2ll(meshX.*1000,meshY.*1000); + + + +% [latHRRR_Mesh,lonHRRR_Mesh] = meshgrid(GridLATAll_R,GridLONAll_R); %Create Mesh + + % Find Flow Grid IDXs with margin + minGrid(1) = min(min(flowGrid.data.X))-50000; + minGrid(2) = min(min(flowGrid.data.Y))-50000; + + maxGrid(1) = max(max(flowGrid.data.X))+50000; + maxGrid(2) = max(max(flowGrid.data.Y))+50000; + + % [TEMPdeg(1),TEMPdeg(2)] = utm2deg(maxGrid(1),maxGrid(2),'18 T'); + % maxIDX = NearestValue(TEMPdeg,latHRRR_Mesh',lonHRRR_Mesh'); + % + % [TEMPdeg(1),TEMPdeg(2)] = utm2deg(minGrid(1),minGrid(2),'18 T'); + % minIDX = NearestValue(TEMPdeg,latHRRR_Mesh',lonHRRR_Mesh'); + % clear TEMPdeg + [TEMPdeg(1),TEMPdeg(2)] = utm2deg(maxGrid(1),maxGrid(2),'18 T'); + maxIDX = NearestValue(TEMPdeg,GridLATAll_R,GridLONAll_R); + + [TEMPdeg(1),TEMPdeg(2)] = utm2deg(minGrid(1),minGrid(2),'18 T'); + minIDX = NearestValue(TEMPdeg,GridLATAll_R,GridLONAll_R); + clear TEMPdeg + % Extraction index + latIDX_HRRR = minIDX(1)-1:maxIDX(1)+1; + lonIDX_HRRR = minIDX(2)-1:maxIDX(2)+1; + + latHRRR_Y = HRRR{'y'}(latIDX_HRRR); + lonHRRR_X = HRRR{'x'}(lonIDX_HRRR); + % latHRRR_Grid = HRRR{'x'}(latIDX_HRRR); + % lonHRRR_Grid = HRRR{'y'}(lonIDX_HRRR); + clear meshX meshY + [meshX,meshY] = meshgrid(HRRR{'x'}(lonIDX_HRRR)',HRRR{'y'}(latIDX_HRRR)'); + + [lonHRRR_Grid,latHRRR_Grid] = m_xy2ll(meshX.*1000,meshY.*1000); + + clear latHRRR_Mesh minIDX maxIDX + + % Final inport grid for HRRR data + windGridLON = lonHRRR_Grid; + windGridLAT = latHRRR_Grid; + +% if FIRST_RUN == 1 +% % Extract shoreline in model domain +% [windGridLON_HR,windGridLAT_HR] = meshgrid(linspace(wrapTo180(lonHRRR_Grid(1)),wrapTo180(lonHRRR_Grid(end)),100),... +% linspace(wrapTo180(latHRRR_Grid(1)),wrapTo180(latHRRR_Grid(end)),100)); +% +% shoreline = gshhs('gshhs_h.b',double([min(min(windGridLAT_HR)) max(max(windGridLAT_HR))]),... +% double([min(min(windGridLON_HR)) max(max(windGridLON_HR))])); +% clear windGridLON_HR +% save('shoreline.mat','shoreline') +% else + load('shoreline.mat'); +% end + clear windU windV pressure rain temperature wind + if day(masterTime)<12 + for tStep = 1:37 + if tStep ~=100 + % Extract MWW3 Hs for 36 hours at indexes + HRRR = ncgeodataset(['D:\Alexander\HRRR_Forecast\' ... + datestr(masterTime,'yyyymmdd') ... + '_' datestr(masterTime,'hh') '00_0' num2str(tStep-1,'%02d') '.grb2.regrid']); + + windU(tStep,:,:) = HRRR{'u-component_of_wind_height_above_ground'}(1,1,latIDX_HRRR,lonIDX_HRRR); %U Winds @ 10m [m/s] + windV(tStep,:,:) = HRRR{'v-component_of_wind_height_above_ground'}(1,1,latIDX_HRRR,lonIDX_HRRR); %V Winds @ 10m [m/s] + pressure(tStep,:,:) = HRRR{'Pressure_surface'}(1,latIDX_HRRR,lonIDX_HRRR); %Surface Pressure [pa] + if tStep==1 + rain(tStep,:,:) = HRRR{'Total_precipitation_surface_0_Hour_Accumulation'}(1,latIDX_HRRR,lonIDX_HRRR); %Surface precipitation [kg/m^2] + elseif tStep==2 + rain(tStep,:,:) = HRRR{['Total_precipitation_surface_'... + num2str(tStep-1) '_Hour_Accumulation']}(1,latIDX_HRRR,lonIDX_HRRR); + else + rain(tStep,:,:) = HRRR{['Total_precipitation_surface_Mixed_intervals_Accumulation']}(2,latIDX_HRRR,lonIDX_HRRR); + end + wind(tStep,:,:) = sqrt(windU(tStep,:,:).^2+windV(tStep,:,:).^2); + + % Extract Temp + temperature(tStep,:) = squeeze(nanmean(nanmean(HRRR{'Temperature_height_above_ground'}(1,1,latIDX_HRRR,lonIDX_HRRR)- 273.15,2),3)); %Surface Temperature [C] +% rain2(tStep,:,:) = HRRR{['Precipitation_rate_surface']}(1,latIDX_HRRR,lonIDX_HRRR); + + else + windU(tStep,:,:) = windU(tStep-1,:,:); + windV(tStep,:,:) = windV(tStep-1,:,:); + pressure(tStep,:,:) = pressure(tStep-1,:,:); + rain(tStep,:,:) = rain(tStep-1,:,:); + temperature(tStep,:) = temperature(tStep-1,:); + end + end + else + % Extract MWW3 Hs for 36 hours at indexes + windU = HRRR{'ugrd10m'}(1:37,latIDX_HRRR,lonIDX_HRRR); %U Winds @ 10m [m/s] + windV = HRRR{'vgrd10m'}(1:37,latIDX_HRRR,lonIDX_HRRR); %V Winds @ 10m [m/s] + pressure = HRRR{'pressfc'}(1:37,latIDX_HRRR,lonIDX_HRRR); %Surface Pressure [pa] + rain = HRRR{'apcpsfc'}(1:37,latIDX_HRRR,lonIDX_HRRR); %Surface precipitation [kg/m^2] + wind = HRRR{'wind10m'}(1:37,latIDX_HRRR,lonIDX_HRRR); %Surface precipitation [kg/m^2] + + % Extract Temp + temperature = squeeze(nanmean(nanmean(HRRR{'tmpsfc'}(1:37,latIDX_HRRR,lonIDX_HRRR)- 273.15,2),3)); %Surface Temperature [C] + end + disp('Loaded HRRR') + save(['ModelIn_HRRR_' datestr(masterTime,'YYYY-MM-DD_hh') '.mat'],'-v7.3','windU','windV','pressure','rain','wind','temperature','waves','waterLevels') + + disp('Loaded HRRR') + else + load('windGrid.mat'); + end + + load('boundData.mat') + load('shoreline.mat'); +%% IMPORT NCOM +NCOM.Lat = ncread(['D:\Alexander\NCOM\' datestr(masterDate,'YYYYmmDD') '00_t000.nc'],'lat',[331],[240]); +NCOM.Lon = ncread(['D:\Alexander\NCOM\' datestr(masterDate,'YYYYmmDD') '00_t000.nc'],'lon',91,180); +NCOM.depth = ncread(['D:\Alexander\NCOM\' datestr(masterDate,'YYYYmmDD') '00_t000.nc'],'depth'); + +Noffset = hours(masterTime - masterDate); +tStep = Noffset; +tCount = 1; +for Ni = masterTime:hours(3):masterTime+hours(36) + + noData=1; + while noData==1 + NCOM.water_u(:,:,:,tCount) = ncread(['D:\Alexander\NCOM\' datestr(masterDate,'YYYYmmDD') '00_t0' num2str(tStep,'%02d') '.nc'],... + 'water_u',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.water_v(:,:,:,tCount) = ncread(['D:\Alexander\NCOM\' datestr(masterDate,'YYYYmmDD') '00_t0' num2str(tStep,'%02d') '.nc'],... + 'water_v',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.surf_el(:,:,tCount) = ncread(['D:\Alexander\NCOM\' datestr(masterDate,'YYYYmmDD') '00_t0' num2str(tStep,'%02d') '.nc'],... + 'surf_el',[91 331 1],[180 240 1],[1 1 1]); + NCOM.salinity(:,:,:,tCount) = ncread(['D:\Alexander\NCOM\' datestr(masterDate,'YYYYmmDD') '00_t0' num2str(tStep,'%02d') '.nc'],... + 'salinity',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + if (squeeze(NCOM.water_v(100,100,1,end))==0|squeeze(NCOM.water_u(100,100,1,end))==0|squeeze(NCOM.surf_el(100,100,end))==0|squeeze(NCOM.salinity(100,100,1,end))==0)==1 + noData=1; + else + noData=0; + end + end + NCOM.time(tCount) = Ni; + tStep=tStep+3; + tCount = tCount+1; +end +%% NCOM Process + NCOM.mag = vecmag(NCOM.water_u,NCOM.water_v); +depthWeight = [diff(NCOM.depth)' 0]; + +for Layer = 1:40 + DAVfac(:,:,Layer,:) = ones(180,240,1,13).*depthWeight(Layer); +end + DAVtrue = DAVfac; + DAVtrue(isnan(NCOM.mag)==1) = 0; + DAVfac(isnan(NCOM.mag)==1) = nan; + DAVFac2 = sum(DAVtrue,3); + clear DAVtrue + NCOM.dav = nansum(DAVfac.*NCOM.mag,3)./DAVFac2; + NCOM.davX = nansum(DAVfac.*NCOM.water_u,3)./DAVFac2; + NCOM.davY = nansum(DAVfac.*NCOM.water_v,3)./DAVFac2; + + + %% Format data for Delft3D + %% Evap + fileID=fopen('TemperatureRT.eva','w'); + refTime=minutes(masterTime-masterDate); + records=37; + for i = 1 : records + fprintf(fileID,'%d. 0. 0. %2.2f\n',refTime,temperature(i)); + + refTime = refTime + 60;% 1 hour time steps for temperature + end + + fclose(fileID); + + + + + +% %% Water Level +% records=37; +% % boundryNames = {'OceanN','OceanS'}; +% for i = 1:wlBoundCount(4) +% boundryNames(i) = {['East' num2str(i)]}; +% end +% +% % boundryTypes = {'neumann (n)','neumann (n)'}; +% boundryTypes(1:wlBoundCount(4)) = {'water elevation (z)'}; +% +% fileID=fopen('ESTOFS4.bct','w'); + +% for Boundry = 1:length(boundryNames) +% refTime=minutes(masterTime-masterDate); +% if ismember(Boundry,wlBoundCount)==1 +% continue +% end +% +% +% header=[... +% 'table-name ''Boundary Section : %d''\n'... +% 'contents ''Uniform ''\n'... +% 'location ''' boundryNames{Boundry} ' ''\n'... +% 'time-function ''non-equidistant''\n'... +% 'reference-time %d\n'... +% 'time-unit ''minutes''\n'... +% 'interpolation ''linear''\n'... +% 'parameter ''time '' unit ''[min]''\n'... +% 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''[m]''\n'... +% 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''[m]''\n'... +% 'records-in-table %d\n'... +% ]; + + +% fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); +% +% for line = 1:size(waterLevels,1) +% fprintf(fileID,'%d %1.4f %1.4f\n',refTime,waterLevels(line,Boundry),waterLevels(line,Boundry+1)); +% +% refTime=refTime+60; +% end +% end +% +% fclose(fileID); + +% % Boundry definition file +% if FIRST_RUN == 1 +% fileID=fopen('ESTOFS4_Bound.bnd','w'); +% +% for Boundry =1 : length(boundryNames) +% % if Boundry == 1 +% % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); +% % elseif Boundry == 2 +% % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); +% % else +% if ismember(Boundry,wlBoundCount)==1 +% continue +% end +% +% boundStart = wlIDX(Boundry,:); +% boundEnd = wlIDX(Boundry+1,:); +% +% fprintf(fileID,[boundryNames{Boundry} ' Z T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... +% num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 1.0000000e+004\n']); +% % end +% +% end +% fclose(fileID); +% end + %% NCOM ESTOFS +% Currents from NCOM + +idxCount=1; +for i = 2:50:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); +% [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [1081,i]; +% crIDX(idxCount,:) = [2161,i]; + + idxCount = idxCount + 1; +end + +crBoundCount(1) = 0; +crBoundCount(2) = idxCount -1; + +for i = 750:55:1080 % Every 5 km +% for i = round(linspace(1488,2161,14)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); +% [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1320]; +% crIDX(idxCount,:) = [i,2641]; + + idxCount = idxCount + 1; +end +crBoundCount(3) = idxCount -1; + +for i = 475:55:1080 % Every 5 km +% for i = round(linspace(910,2161,26)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); +% [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1]; +% crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; +end +crBoundCount(4) = idxCount -1; + + +clear idxCount gridDeg + +%% Interpolate Water Level +% for tStep = 1:length(tideOutN) +% wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); +% wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); +% wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); +% end +for tStep = 1:37 +wlO(tStep,:) = waterLevels(tStep,:); +end + +%% Match to grid +flowBed = load('D:\Alexander\RealtimeHRRR\Dec6_100Bed.mat'); +clear wlN mag DM dirGrid currents RN_1 currents_2 currents_40 currDir currDir40 +idxCount=1; +for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+0.112; + mag(:,idxCount) = vecmag(currX,currY); + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + +% disp(idxCount) + idxCount = idxCount + 1; + +end + +% fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); +% fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + +clear idxCount + +%% interpolate Currents +clear currentsOut +for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(NCOM.time)); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(masterTime:hours(1):masterTime+hours(36))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + +% for j = 1:length(idxNCOM) +% currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... +% interp2(xIN,yIN,... +% squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1))),... +% xOut,yOut); +% end + +end +idxCount=1; + +for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + RNOut_2(:,i) = currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + else + RNOut_2(:,i) = currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + end + + + + idxCount = idxCount+1; +end + +%% R Boundry Files +records=37; + +for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; +end + +% boundryTypes(1) = {'water elevation (z)'}; +boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; +boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + +fileID=fopen('NCOM_R2.bct','w'); + +for Boundry = [2:length(boundryNames)] + refTime=minutes(masterTime-masterDate); + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + for line = 1:37 + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_2(line,Boundry-1),RNOut_2(line,Boundry)); + + refTime=refTime+60; + end +end + +fclose(fileID); +%% Boundry definition file-R +fileID=fopen('NCOM_R.bnd','w'); +crIDX2=crIDX; +crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+2; +crIDX2(crBoundCount(1)+1:crBoundCount(2),1) = 1082; + +for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end +end +fclose(fileID); + + + %% Waves + records = size(waves,1); + fileID=fopen('WW3.bcw','w'); + + for i = 1:3 + boundryNames(i) = {['East' num2str(i)]}; + end + + for Boundry = 1:3 + refTime=minutes(masterTime-masterDate); + + header=[... + 'location ''East%d''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterTime,'yyyymmdd'))); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''WaveHeight '' unit ''[m]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Period '' unit ''[s]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Direction '' unit ''[N^o]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''DirSpreading '' unit ''[-]''\n'); + end + + for line = 1:records + fprintf(fileID,'%d ',refTime); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,1)); %Hs + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,2)); %Period + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,3)); %Direction + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',4); %Spread + end + fprintf(fileID,'\n'); + + % fprintf(fileID,'%.2f %1.4f %1.4f %1.4f %1.4f\n',refTime,... + % waves(line,Boundry,1),waves(line,Boundry,2),waves(line,Boundry,3),4); + refTime=refTime+180; + end + end + + fclose(fileID); + + + %% Modify MDF file to change reference date + + fileID = fopen('rt_base.mdf'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdf', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 15 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'Itdate = #%04d-%02d-%02d#\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 17 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID,['Tstart = %#.7e \n',... + 'Tstop = %#.7e \n'],refTime,refTime+2160); + + for i = 20:29 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + if FIRST_RUN == 0 + restID = ['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000']; + % if masterTime~=datetime(2019,09,04,06,00,00) + if exist(restID)==2 + eval(['movefile ' restID ' tri-rst.6h_restart']) + end + + fprintf( fileID,['Commnt = initial conditions from restart file\n'... + 'Restid = #6h_restart#\n']); + delete tri-rst.rt* + + else + fprintf( fileID,'Zeta0 = %#.7e \n',nanmean(nanmean(squeeze(waterLevels(:,:))))); + end + + for i = 31:94 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID,[... + 'Flmap = %#.7e 60 %#.7e\n',... + 'Flhis = %#.7e 10 %#.7e\n',... + 'Flpp = %#.7e 60 %#.7e\n'],... + refTime,refTime+2160,refTime,refTime+2160,refTime,refTime+2160); + + for i = 98:109 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + clear cac + %% Modify MDW file to add times and change reference date + + fileID = fopen('rt_base.mdw'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdw', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 7 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'ReferenceDate = %04d-%02d-%02d\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 9 : 71 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % for i = 1 : records + % fprintf( fileID,'[TimePoint] \n Time = %#.7e \n',(i-1).*180); + % end + + bounOri{1}='East'; + bounOri{2}='North'; + bounOri{3}='South'; + bounRot{1}='counter-clockwise'; + bounRot{2}='counter-clockwise'; + bounRot{3}='clockwise'; + + + for Boundry = 1 : 3 + + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = orientation\n'... + 'Orientation = %s\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + 'DistanceDir = %s\n'... + ],Boundry,bounOri{Boundry},bounRot{Boundry}); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'CondSpecAtDist = %d\n',waveDistAlong(Segment)) + end + end + + clear cac + fclose( fileID ); + + + %% Met Files + % Create new UTM grid of the HRRR Data + [UTM1D(:,1),UTM1D(:,2)] = wgs2utm(reshape(windGridLAT,1,[]),reshape(windGridLON,1,[]),... + 18,'N'); + HRRR_UTM(:,:,1) = double(reshape(UTM1D(:,1),size(windGridLON,1),size(windGridLON,2))); + HRRR_UTM(:,:,2) = double(reshape(UTM1D(:,2),size(windGridLON,1),size(windGridLON,2))); + clear UTM1D + + G7LR = load('C7_1400_V2_C.mat'); + + % Remove land rainfall +% if FIRST_RUN == 1 +% landmask=zeros(size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); +% [HR_deg(:,1),HR_deg(:,2)] = utm2deg(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[]),reshape(G7LR.data.Y(1:end-1,1:end-1)',1,[]),repmat('18 S',length(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[])),1)); +% for ShoreLevel = 1:length(shoreline) +% landmask_Temp(:,:) = reshape(inpolygon(HR_deg(:,1),HR_deg(:,2),shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon),size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); +% +% landmask = landmask|landmask_Temp; +% clear landmask_Temp +% +% [shoreTempX,shoreTempY,shoreTempCell] = deg2utm(shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon); +% shoreUTM{ShoreLevel}(:,1) = shoreTempX(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); +% shoreUTM{ShoreLevel}(:,2) = shoreTempY(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); +% clear shoreTempX shoreTempY shoreTempCell +% disp(ShoreLevel) +% end +% save('shorelineInfo.mat','landmask','shoreUTM'); +% else + load('shorelineInfo.mat'); +% end + clear HR_deg ShoreLevel + + + % Zero out met array + HRRR_INTER = zeros(4,37,size(G7LR.data.X(1:end-1,1:end-1),2),size(G7LR.data.X(1:end-1,1:end-1),1)); + + % Interpolate against flowGrid for each time step + for TS = 1:37 + HRRR_INTER(1,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windU(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + HRRR_INTER(2,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windV(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + rainTemp = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(rain(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + rainTemp(landmask)=rainTemp(landmask)*0; % 100% infiltration + HRRR_INTER(3,TS,:,:) = rainTemp; % Convert to hours + clear rainTemp + + HRRR_INTER(4,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(pressure(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + end + + % Set nan to Delft3D zero value + HRRR_INTER(isnan(HRRR_INTER)==1)=-999.000; + + % Create input files + m = size(HRRR_INTER,3); + n = size(HRRR_INTER,4); + d3ddx = 5000; + d3ddy = 5000; + disp(m) + d3d_input_uvpFieldsCL_FUN(masterTime,m,n,... + squeeze(HRRR_INTER(4,:,:,:)),squeeze(HRRR_INTER(1,:,:,:)),squeeze(HRRR_INTER(2,:,:,:)),squeeze(HRRR_INTER(3,:,:,:)),1,'hrrr',37) + + save(['ModelIn_4_HRRR' datestr(masterTime,'YYYY-MM-DD_hh') '.mat'],'-v7.3','windU','windV','pressure','rain','wind','temperature','waves','waterLevels') + + %% Run Delft3D FLOW/WAVE! + % system('. /home/cluster/D7545/enviorment.sh') + try + + + system('./runDuck_Wave.sh') + + eval(['copyfile trim-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut4.dat']) + eval(['movefile trim-rt_run.dat /project/6008948/alex0042/RealtimeH2/' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut4.dat']) + + eval(['copyfile trim-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut4.def']) + eval(['movefile trim-rt_run.def /project/6008948/alex0042/RealtimeH2/' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut4.def']) + + eval(['copyfile wavm-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut4.dat']) + eval(['movefile wavm-rt_run.dat /project/6008948/alex0042/RealtimeH2/' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut4.dat']) + + eval(['copyfile wavm-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut4.def']) + eval(['movefile wavm-rt_run.def /project/6008948/alex0042/RealtimeH2/' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut4.def']) + + eval(['copyfile trih-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_histOut4.dat']) + eval(['movefile trih-rt_run.dat /project/6008948/alex0042/RealtimeH2/' datestr(masterTime,'YYYY-MM-DD_hh') '_histOut4.dat']) + + eval(['copyfile trih-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_histOut4.def']) + eval(['movefile trih-rt_run.def /project/6008948/alex0042/RealtimeH2/' datestr(masterTime,'YYYY-MM-DD_hh') '_histOut4.def']) + + eval(['copyfile ModelIn_4_HRRR' datestr(masterTime,'YYYY-MM-DD_hh') '.mat /project/6008948/alex0042/RealtimeH2/ModelIn_4' datestr(masterTime,'YYYY-MM-DD_hh') '.mat']) + eval(['copyfile tri-rst.rt* /project/6008948/alex0042/RealtimeH2/']) + catch + break + + end + + +end diff --git a/DUNEX_RealtimeV6_CAD.m b/DUNEX_RealtimeV6_CAD.m new file mode 100644 index 0000000..7e1fcf9 --- /dev/null +++ b/DUNEX_RealtimeV6_CAD.m @@ -0,0 +1,1175 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +clear all +%cd /project/6008948/alex0042/RealtimeH2 +addpath('NCtoolbox') +addpath('m_map') +setup_nctoolbox +flowGrid = load('Cone7W_100.mat'); +waveGrid = load('Cone7W_250.mat'); +load('LMSL_RT.mat') + +for masterTime=[datetime(2019,09,02,00,00,00):hours(6):datetime(2019,09,08,00,00,00)] + masterDate = datetime(year(masterTime),month(masterTime),day(masterTime)); + if masterTime==datetime(2019,09,02,00,00,00) + FIRST_RUN = 1; + else + FIRST_RUN = 0; + + end + + + %% Clean files from previous run + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + + clear HRRR_UTM + + load(['ModelIn_4' datestr(masterTime,'YYYY-MM-DD_hh') '.mat']) + + if masterTimedatetime(2019,09,15,00,00,00) + + %% Import data from NOMADS + %% Extratropical Surge and Tide Operational Forecast System for the Atlantic + % (ESTOFS Atlantic) for water levels + + url = ['http://nomads.ncep.noaa.gov/dods/estofs_atl/'... + datestr(masterTime,'yyyymmdd')... + '/estofs_atl_conus_' datestr(masterTime,'hh') 'z']; + + ESTOFS = ncgeodataset(url); + clear url + + lonESTOFS=ESTOFS{'lon'}(:); + latESTOFS=ESTOFS{'lat'}(:); + + % Find ESTOFS index for grid points along boundry + idxCount=1; + for i = 2:50:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + wlIDX(idxCount,:) = [1082,i]; + + idxCount = idxCount + 1; + end + + wlBoundCount(1) = 0; + wlBoundCount(2) = idxCount -1; + + + for i = 750:55:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + wlIDX(idxCount,:) = [i,1322]; + idxCount = idxCount + 1; + end + + wlBoundCount(3) = idxCount -1; + + for i = 475:55:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + wlIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + wlBoundCount(4) = idxCount -1; + + + clear idxCount gridDeg + + % Extract ESTOFS Water Levels for 36 hours at indexes + waterLevelsGRID = ESTOFS{'etcwlsfc'}(2:38,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + + % Find ESTOFS values from small grid + idxCount=1; + for i = 1:length(idxESTOFS) + waterLevels(:,idxCount) = waterLevelsGRID(:,idxESTOFS(idxCount,1)-min(idxESTOFS(:,1))+1,... + idxESTOFS(idxCount,2)-min(idxESTOFS(:,2))+1); + + idxCount = idxCount + 1; + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + disp('Loaded ESTOFS') + %% Multi-grid Wave model (WAVEWATCH III) + % 4 arc minute US East Coast grid for waves + + url = ['http://nomads.ncep.noaa.gov/dods/wave/mww3/'... + datestr(masterTime,'yyyymmdd')... + '/multi_1.at_4m' datestr(masterTime,'yyyymmdd') '_' datestr(masterTime,'hh') 'z']; + + MWW3 = ncgeodataset(url); + clear url + + lonMWW3=wrapTo180(MWW3{'lon'}(:)); + latMWW3=MWW3{'lat'}(:); + + % Find MWW3 index for grid points along boundry + idxCount=1; + for i = 1:25:length(waveGrid.data.Y)-25 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(end-2,i),waveGrid.data.Y(end-2,i),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(end-2,1:i)).^2+... + diff(waveGrid.data.Y(end-2,1:i)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(end-2,i); + waveUTM(idxCount,2) = waveGrid.data.Y(end-2,i); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + waveBoundCount(1) = 0; + waveBoundCount(2) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:350% Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,end-2),waveGrid.data.Y(i,end-2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,end-2)).^2+... + diff(waveGrid.data.Y(i:end-2,end-2)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,end-2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,end-2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(3) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:240 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,2),waveGrid.data.Y(i,2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,1)).^2+... + diff(waveGrid.data.Y(i:end-2,1)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(4) = idxCount -1; + + clear idxCount + + % Extract WW3 Hs for 36 hours at indexes + wavesGRID_Hs = MWW3{'htsgwsfc'}(1:13,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid htsgwsfc + %swell_1 + % Period + wavesGRID_P = MWW3{'perpwsfc'}(1:13,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... % + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid perpwsfc + %swper_1 + % Direction + wavesGRID_Dir = MWW3{'dirpwsfc'}(1:13,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid dirpwsfc + %swdir_1 + % Find WW3 values from small grid + idxCount=1; + for i = 1:length(idxMWW3) + waves(:,idxCount,1) = wavesGRID_Hs(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Hs + + waves(:,idxCount,2) = wavesGRID_P(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Tp + + waves(:,idxCount,3) = wavesGRID_Dir(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Dir + + idxCount = idxCount + 1; + end + clear idxCount + disp('Loaded WW3') + + end + if masterTime>datetime(2019,09,00,00,00,00) + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % if day(masterTime)<10 + % url = ['http://nomads.ncep.noaadatestr(masterTime,'yyyymmdd').gov/dods/nam/nam'... + % datestr(masterTime,'yyyymmdd')... + % '/nam1hr_' datestr(masterTime,'hh') 'z']; + % url = ['/scratch/alex0042/HRRR/' datestr(masterTime,'yyyymmddhh') '.g2']; + % untar([url '.tar'],['/home/cluster/RealtimeH/HAS011383739/nam_218_' datestr(masterTime,'yyyymmddhh')]); + % else + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; + % end + + + HRRR = ncgeodataset(['/home/cluster/DelftRuns/HRRR_Forecast/' ... + datestr(masterTime,'yyyymmdd') ... + '_' datestr(masterTime,'hh') '00_000.grb2.regrid']); + + % Extract Lat Lon from HRRR + % lonHRRR=wrapTo180(HRRR{'lon'}(:)); + % latHRRR=HRRR{'lat'}(:); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(HRRR{'x'}(:),HRRR{'y'}(:)); + [GridLONAll_R,GridLATAll_R] = m_xy2ll(meshX.*1000,meshY.*1000); + + + + % [latHRRR_Mesh,lonHRRR_Mesh] = meshgrid(GridLATAll_R,GridLONAll_R); %Create Mesh + + % Find Flow Grid IDXs with margin + minGrid(1) = min(min(flowGrid.data.X))-50000; + minGrid(2) = min(min(flowGrid.data.Y))-50000; + + maxGrid(1) = max(max(flowGrid.data.X))+50000; + maxGrid(2) = max(max(flowGrid.data.Y))+50000; + + % [TEMPdeg(1),TEMPdeg(2)] = utm2deg(maxGrid(1),maxGrid(2),'18 T'); + % maxIDX = NearestValue(TEMPdeg,latHRRR_Mesh',lonHRRR_Mesh'); + % + % [TEMPdeg(1),TEMPdeg(2)] = utm2deg(minGrid(1),minGrid(2),'18 T'); + % minIDX = NearestValue(TEMPdeg,latHRRR_Mesh',lonHRRR_Mesh'); + % clear TEMPdeg + [TEMPdeg(1),TEMPdeg(2)] = utm2deg(maxGrid(1),maxGrid(2),'18 T'); + maxIDX = NearestValue(TEMPdeg,GridLATAll_R,GridLONAll_R); + + [TEMPdeg(1),TEMPdeg(2)] = utm2deg(minGrid(1),minGrid(2),'18 T'); + minIDX = NearestValue(TEMPdeg,GridLATAll_R,GridLONAll_R); + clear TEMPdeg + % Extraction index + latIDX_HRRR = minIDX(1)-1:maxIDX(1)+1; + lonIDX_HRRR = minIDX(2)-1:maxIDX(2)+1; + + latHRRR_Y = HRRR{'y'}(latIDX_HRRR); + lonHRRR_X = HRRR{'x'}(lonIDX_HRRR); + % latHRRR_Grid = HRRR{'x'}(latIDX_HRRR); + % lonHRRR_Grid = HRRR{'y'}(lonIDX_HRRR); + clear meshX meshY + [meshX,meshY] = meshgrid(HRRR{'x'}(lonIDX_HRRR)',HRRR{'y'}(latIDX_HRRR)'); + + [lonHRRR_Grid,latHRRR_Grid] = m_xy2ll(meshX.*1000,meshY.*1000); + + clear latHRRR_Mesh minIDX maxIDX + + % Final inport grid for HRRR data + windGridLON = lonHRRR_Grid; + windGridLAT = latHRRR_Grid; + + % if FIRST_RUN == 1 + % % Extract shoreline in model domain + % [windGridLON_HR,windGridLAT_HR] = meshgrid(linspace(wrapTo180(lonHRRR_Grid(1)),wrapTo180(lonHRRR_Grid(end)),100),... + % linspace(wrapTo180(latHRRR_Grid(1)),wrapTo180(latHRRR_Grid(end)),100)); + % + % shoreline = gshhs('gshhs_h.b',double([min(min(windGridLAT_HR)) max(max(windGridLAT_HR))]),... + % double([min(min(windGridLON_HR)) max(max(windGridLON_HR))])); + % clear windGridLON_HR + % save('shoreline.mat','shoreline') + % else + load('shoreline.mat'); + % end + clear windU windV pressure rain temperature wind + if day(masterTime)<12 + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % if day(masterTime)<10 + % url = ['http://nomads.ncep.noaadatestr(masterTime,'yyyymmdd').gov/dods/nam/nam'... + % datestr(masterTime,'yyyymmdd')... + % '/nam1hr_' datestr(masterTime,'hh') 'z']; + % url = ['/scratch/alex0042/HRRR/' datestr(masterTime,'yyyymmddhh') '.g2']; + % untar([url '.tar'],['/home/cluster/RealtimeH/HAS011383739/nam_218_' datestr(masterTime,'yyyymmddhh')]); + % else + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; + % end + + + HRRR = ncgeodataset(['/home/cluster/DelftRuns/HRDPS_Forecast/'... + datestr(masterTime,'yyyymmddhh') '.nc']); + + GridLATAll_D = HRRR{'lat'}(:); + GridLONAll_D = HRRR{'lon'}(:); + + lats_D = 1:size(GridLATAll_D,1); + lons_D = 1:size(GridLATAll_D,2); + + % Final inport grid for HRRR data + windGridLON = GridLONAll_D; + windGridLAT = GridLATAll_D; + + % if FIRST_RUN == 1 + % % Extract shoreline in model domain + % [windGridLON_HR,windGridLAT_HR] = meshgrid(linspace(wrapTo180(lonHRRR_Grid(1)),wrapTo180(lonHRRR_Grid(end)),100),... + % linspace(wrapTo180(latHRRR_Grid(1)),wrapTo180(latHRRR_Grid(end)),100)); + % + % shoreline = gshhs('gshhs_h.b',double([min(min(windGridLAT_HR)) max(max(windGridLAT_HR))]),... + % double([min(min(windGridLON_HR)) max(max(windGridLON_HR))])); + % clear windGridLON_HR + % save('shoreline.mat','shoreline') + % else + load('shoreline.mat'); + % end + clear windU windV pressure rain temperature wind + if day(masterTime)<12 + for tStep = 1:37 + if tStep ~=100 + % Extract MWW3 Hs for 36 hours at indexes + HRRR = ncgeodataset(['/home/cluster/DelftRuns/HRDPS_Forecast/'... + datestr(masterTime,'yyyymmddhh') '.nc']); + + windU(tStep,:,:) = HRRR{'HRDPS_P_UUC_10000'}(tStep,:,:).*0.514444; %U Winds @ 10m [m/s] + windV(tStep,:,:) = HRRR{'HRDPS_P_VVC_10000'}(tStep,:,:).*0.514444; %V Winds @ 10m [m/s] + pressure(tStep,:,:) = HRRR{'HRDPS_P_RN_SFC'}(tStep,:,:).*100; %Surface Pressure [pa] + + rainTemp = squeeze(HRRR{'HRDPS_P_RN_SFC'}(tStep:tStep+1,:,:)); + rainTemp(isnan(rainTemp))=0; + rain(tStep,:,:) = diff(rainTemp); + + temperature(tStep,:) = ... + squeeze(nanmean(nanmean(HRRR{'HRDPS_P_TT_10000'}(tStep,:,:),2),3)); %Surface Temperature [C] + + + wind(tStep,:,:) = sqrt(windU(tStep,:,:).^2+windV(tStep,:,:).^2); + + end + end + disp('Loaded CAD') + end + + save(['ModelIn_CAD3_' datestr(masterTime,'YYYY-MM-DD_hh') '.mat'],'-v7.3','windU','windV','pressure','rain','wind','temperature','waves','waterLevels') + else + load('windGrid.mat'); + end + + load('boundData.mat') + load('shoreline.mat'); + end + %% IMPORT NCOM + NCOM.Lat = ncread(['/home/cluster/RT_Dec/NCOM/' datestr(masterDate,'YYYYmmDD') '00_t000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread(['/home/cluster/RT_Dec/NCOM/' datestr(masterDate,'YYYYmmDD') '00_t000.nc'],'lon',91,180); + NCOM.depth = ncread(['/home/cluster/RT_Dec/NCOM/' datestr(masterDate,'YYYYmmDD') '00_t000.nc'],'depth'); + + Noffset = hours(masterTime - masterDate); + tStep = Noffset; + tCount = 1; + for Ni = masterTime:hours(3):masterTime+hours(36) + + noData=1; + while noData==1 + NCOM.water_u(:,:,:,tCount) = ncread(['/home/cluster/RT_Dec/NCOM/' datestr(masterDate,'YYYYmmDD') '00_t0' num2str(tStep,'%02d') '.nc'],... + 'water_u',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.water_v(:,:,:,tCount) = ncread(['/home/cluster/RT_Dec/NCOM/' datestr(masterDate,'YYYYmmDD') '00_t0' num2str(tStep,'%02d') '.nc'],... + 'water_v',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.surf_el(:,:,tCount) = ncread(['/home/cluster/RT_Dec/NCOM/' datestr(masterDate,'YYYYmmDD') '00_t0' num2str(tStep,'%02d') '.nc'],... + 'surf_el',[91 331 1],[180 240 1],[1 1 1]); + NCOM.salinity(:,:,:,tCount) = ncread(['/home/cluster/RT_Dec/NCOM/' datestr(masterDate,'YYYYmmDD') '00_t0' num2str(tStep,'%02d') '.nc'],... + 'salinity',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + if (squeeze(NCOM.water_v(100,100,1,end))==0|squeeze(NCOM.water_u(100,100,1,end))==0|squeeze(NCOM.surf_el(100,100,end))==0|squeeze(NCOM.salinity(100,100,1,end))==0)==1 + noData=1; + else + noData=0; + end + end + NCOM.time(tCount) = Ni; + tStep=tStep+3; + tCount = tCount+1; + end + %% NCOM Process + NCOM.mag = vecmag(NCOM.water_u,NCOM.water_v); + depthWeight = [diff(NCOM.depth)' 0]; + + for Layer = 1:40 + DAVfac(:,:,Layer,:) = ones(180,240,1,13).*depthWeight(Layer); + end + DAVtrue = DAVfac; + DAVtrue(isnan(NCOM.mag)==1) = 0; + DAVfac(isnan(NCOM.mag)==1) = nan; + DAVFac2 = sum(DAVtrue,3); + clear DAVtrue + NCOM.dav = nansum(DAVfac.*NCOM.mag,3)./DAVFac2; + NCOM.davX = nansum(DAVfac.*NCOM.water_u,3)./DAVFac2; + NCOM.davY = nansum(DAVfac.*NCOM.water_v,3)./DAVFac2; + + + %% Format data for Delft3D + %% Evap + fileID=fopen('TemperatureRT.eva','w'); + refTime=minutes(masterTime-masterDate); + records=37; + for i = 1 : records + fprintf(fileID,'%d. 0. 0. %2.2f\n',refTime,temperature(i)); + + refTime = refTime + 60;% 1 hour time steps for temperature + end + + fclose(fileID); + + + + + + % %% Water Level + % records=37; + % % boundryNames = {'OceanN','OceanS'}; + % for i = 1:wlBoundCount(4) + % boundryNames(i) = {['East' num2str(i)]}; + % end + % + % % boundryTypes = {'neumann (n)','neumann (n)'}; + % boundryTypes(1:wlBoundCount(4)) = {'water elevation (z)'}; + % + % fileID=fopen('ESTOFS4.bct','w'); + + % for Boundry = 1:length(boundryNames) + % refTime=minutes(masterTime-masterDate); + % if ismember(Boundry,wlBoundCount)==1 + % continue + % end + % + % + % header=[... + % 'table-name ''Boundary Section : %d''\n'... + % 'contents ''Uniform ''\n'... + % 'location ''' boundryNames{Boundry} ' ''\n'... + % 'time-function ''non-equidistant''\n'... + % 'reference-time %d\n'... + % 'time-unit ''minutes''\n'... + % 'interpolation ''linear''\n'... + % 'parameter ''time '' unit ''[min]''\n'... + % 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''[m]''\n'... + % 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''[m]''\n'... + % 'records-in-table %d\n'... + % ]; + + + % fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + % + % for line = 1:size(waterLevels,1) + % fprintf(fileID,'%d %1.4f %1.4f\n',refTime,waterLevels(line,Boundry),waterLevels(line,Boundry+1)); + % + % refTime=refTime+60; + % end + % end + % + % fclose(fileID); + + % % Boundry definition file + % if FIRST_RUN == 1 + % fileID=fopen('ESTOFS4_Bound.bnd','w'); + % + % for Boundry =1 : length(boundryNames) + % % if Boundry == 1 + % % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % % elseif Boundry == 2 + % % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + % % else + % if ismember(Boundry,wlBoundCount)==1 + % continue + % end + % + % boundStart = wlIDX(Boundry,:); + % boundEnd = wlIDX(Boundry+1,:); + % + % fprintf(fileID,[boundryNames{Boundry} ' Z T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + % num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 1.0000000e+004\n']); + % % end + % + % end + % fclose(fileID); + % end + %% NCOM ESTOFS + % Currents from NCOM + + idxCount=1; + for i = 2:50:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [1081,i]; + % crIDX(idxCount,:) = [2161,i]; + + idxCount = idxCount + 1; + end + + crBoundCount(1) = 0; + crBoundCount(2) = idxCount -1; + + for i = 750:55:1080 % Every 5 km + % for i = round(linspace(1488,2161,14)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1320]; + % crIDX(idxCount,:) = [i,2641]; + + idxCount = idxCount + 1; + end + crBoundCount(3) = idxCount -1; + + for i = 475:55:1080 % Every 5 km + % for i = round(linspace(910,2161,26)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1]; + % crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + crBoundCount(4) = idxCount -1; + + + clear idxCount + + %% Interpolate Water Level + % for tStep = 1:length(tideOutN) + % wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); + % wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); + % wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); + % end + + vDatOrder = [crBoundCount(3)+1:1:crBoundCount(4) ... + crBoundCount(1)+1:1:crBoundCount(2) ... + crBoundCount(3):-1:crBoundCount(2)+1]; + + vDatNavD = LMSL_RT(:,3); + vDatNavD(vDatNavD==-999999)=nan; + + % interp1(vDatNavD(vDatOrder),1:46) + vDatNavD(vDatOrder) = naninterp(vDatNavD(vDatOrder)); + for i = 1:length(idxNCOM) + wlO(:,i) = interp1(masterTime:hours(1):masterTime+hours(36),waterLevels(:,i)+vDatNavD(i),masterTime:minutes(10):masterTime+hours(36),'pchip'); + end + + %% Match to grid + flowBed = load('Dec6_100Bed.mat'); + clear wlN mag DM dirGrid currents RN_1 currents_2 currents_40 currDir currDir40 + idxCount=1; + for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+0.112; + mag(:,idxCount) = vecmag(currX,currY); + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + + % disp(idxCount) + idxCount = idxCount + 1; + + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + %% interpolate Currents + clear currentsOut + for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(NCOM.time)); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(masterTime:minutes(10):masterTime+hours(36))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + % for j = 1:length(idxNCOM) + % currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + % interp2(xIN,yIN,... + % squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1))),... + % xOut,yOut); + % end + + end + idxCount=1; + + + for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + RNOut_2(:,i) = currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + else + RNOut_2(:,i) = currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + end + + + + idxCount = idxCount+1; + end + + %% R Boundry Files + records=length(RNOut_2); + + for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; + end + + % boundryTypes(1) = {'water elevation (z)'}; + boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; + boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + + fileID=fopen('NCOM_R2.bct','w'); + + for Boundry = [2:length(boundryNames)] + refTime=minutes(masterTime-masterDate); + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + for line = 1:records + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_2(line,Boundry-1),RNOut_2(line,Boundry)); + + refTime=refTime+10; + end + end + + fclose(fileID); + %% Boundry definition file-R + fileID=fopen('NCOM_R.bnd','w'); + crIDX2=crIDX; + crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+2; + crIDX2(crBoundCount(1)+1:crBoundCount(2),1) = 1082; + + for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end + end + fclose(fileID); + + + %% Waves + records = size(waves,1); + fileID=fopen('WW3.bcw','w'); + + for i = 1:3 + boundryNames(i) = {['East' num2str(i)]}; + end + + for Boundry = 1:3 + refTime=minutes(masterTime-masterDate); + + header=[... + 'location ''East%d''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterTime,'yyyymmdd'))); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''WaveHeight '' unit ''[m]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Period '' unit ''[s]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Direction '' unit ''[N^o]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''DirSpreading '' unit ''[-]''\n'); + end + + for line = 1:records + fprintf(fileID,'%d ',refTime); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,1)); %Hs + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,2)); %Period + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,3)); %Direction + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',4); %Spread + end + fprintf(fileID,'\n'); + + % fprintf(fileID,'%.2f %1.4f %1.4f %1.4f %1.4f\n',refTime,... + % waves(line,Boundry,1),waves(line,Boundry,2),waves(line,Boundry,3),4); + refTime=refTime+180; + end + end + + fclose(fileID); + + + %% Modify MDF file to change reference date + + fileID = fopen('rt_base.mdf'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdf', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 15 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'Itdate = #%04d-%02d-%02d#\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 17 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % if FIRST_RUN==1 + if masterTime>=datetime(2019,09,05,00,00,00) + fprintf( fileID,['Tstart = %#.7e \n',... + 'Tstop = %#.7e \n'],refTime,refTime+2160); + else + fprintf( fileID,['Tstart = %#.7e \n',... + 'Tstop = %#.7e \n'],refTime,refTime+420); + end + % else + % fprintf( fileID,['Tstart = %#.7e \n',... + % 'Tstop = %#.7e \n'],refTime,refTime+2160); + % end + + + + for i = 20:29 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + if FIRST_RUN == 0 + restID = ['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000']; + % if masterTime~=datetime(2019,09,04,06,00,00) + if exist(restID)==2 + eval(['movefile ' restID ' tri-rst.6h_restart']) + end + + fprintf( fileID,['Commnt = initial conditions from restart file\n'... + 'Restid = #6h_restart#\n']); + delete tri-rst.rt* + + else +% fprintf( fileID,'Zeta0 = %#.7e \n',nanmean(nanmean(squeeze(waterLevels(1,:))))); + fprintf( fileID,'Zeta0 = %#.7e \n',0.127); + + end + + for i = 31:53 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % if FIRST_RUN==1 + % fprintf( fileID, 'Vicouv = 1.0000000e+002 \n'); + % else + fprintf( fileID, '%s\n', cac{1}{54} ); + % end + + for i = 55:64 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + if FIRST_RUN==1 + fprintf( fileID, 'Tlfsmo = 6.0000000e+001 \n'); + else + fprintf( fileID, 'Tlfsmo = 0.0000000e+000 \n'); + end + + for i = 66:94 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + + fprintf( fileID,[... + 'Flmap = %#.7e 60 %#.7e\n',... + 'Flhis = %#.7e 10 %#.7e\n',... + 'Flpp = %#.7e 60 %#.7e\n'],... + refTime,refTime+2160,refTime,refTime+2160,refTime,refTime+2160); + + for i = 98:109 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + clear cac + %% Modify MDW file to add times and change reference date + + fileID = fopen('rt_base.mdw'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdw', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 7 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'ReferenceDate = %04d-%02d-%02d\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 9 : 71 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % for i = 1 : records + % fprintf( fileID,'[TimePoint] \n Time = %#.7e \n',(i-1).*180); + % end + + bounOri{1}='East'; + bounOri{2}='North'; + bounOri{3}='South'; + bounRot{1}='counter-clockwise'; + bounRot{2}='counter-clockwise'; + bounRot{3}='clockwise'; + + + for Boundry = 1 : 3 + + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = orientation\n'... + 'Orientation = %s\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + 'DistanceDir = %s\n'... + ],Boundry,bounOri{Boundry},bounRot{Boundry}); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'CondSpecAtDist = %d\n',waveDistAlong(Segment)) + end + end + + clear cac + fclose( fileID ); + + + %% Met Files + % Create new UTM grid of the HRRR Data + [UTM1D(:,1),UTM1D(:,2)] = wgs2utm(reshape(windGridLAT,1,[]),reshape(windGridLON,1,[]),... + 18,'N'); + HRRR_UTM(:,:,1) = double(reshape(UTM1D(:,1),size(windGridLON,1),size(windGridLON,2))); + HRRR_UTM(:,:,2) = double(reshape(UTM1D(:,2),size(windGridLON,1),size(windGridLON,2))); + clear UTM1D + + G7LR = load('C7_1400_V2_C.mat'); + + % Remove land rainfall + % if FIRST_RUN == 1 + % landmask=zeros(size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % [HR_deg(:,1),HR_deg(:,2)] = utm2deg(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[]),reshape(G7LR.data.Y(1:end-1,1:end-1)',1,[]),repmat('18 S',length(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[])),1)); + % for ShoreLevel = 1:length(shoreline) + % landmask_Temp(:,:) = reshape(inpolygon(HR_deg(:,1),HR_deg(:,2),shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon),size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % + % landmask = landmask|landmask_Temp; + % clear landmask_Temp + % + % [shoreTempX,shoreTempY,shoreTempCell] = deg2utm(shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon); + % shoreUTM{ShoreLevel}(:,1) = shoreTempX(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % shoreUTM{ShoreLevel}(:,2) = shoreTempY(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % clear shoreTempX shoreTempY shoreTempCell + % disp(ShoreLevel) + % end + % save('shorelineInfo.mat','landmask','shoreUTM'); + % else + load('shorelineInfo.mat'); + % end + clear HR_deg ShoreLevel + + if masterTime>=datetime(2019,09,05,00,00,00) + runSteps = 37; + else + runSteps = 8; + end + + % Zero out met array + HRRR_INTER = zeros(4,runSteps,size(G7LR.data.X(1:end-1,1:end-1),2),size(G7LR.data.X(1:end-1,1:end-1),1)); + + % Interpolate against flowGrid for each time step + for TS = 1:runSteps + HRRR_INTER(1,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windU(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + HRRR_INTER(2,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windV(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + rainTemp = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(rain(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + rainTemp(landmask)=rainTemp(landmask)*0; % 100% infiltration + HRRR_INTER(3,TS,:,:) = rainTemp; % Convert to hours + clear rainTemp + + HRRR_INTER(4,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(pressure(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + end + + % Set nan to Delft3D zero value + HRRR_INTER(isnan(HRRR_INTER)==1)=-999.000; + + % Create input files + m = size(HRRR_INTER,3); + n = size(HRRR_INTER,4); + d3ddx = 5000; + d3ddy = 5000; + disp(m) + d3d_input_uvpFieldsCL_FUN(masterTime,m,n,... + squeeze(HRRR_INTER(4,:,:,:)),squeeze(HRRR_INTER(1,:,:,:)),squeeze(HRRR_INTER(2,:,:,:)),squeeze(HRRR_INTER(3,:,:,:)),1,'hrrr',runSteps) + + save(['ModelIn_6_HRRR' datestr(masterTime,'YYYY-MM-DD_hh') '.mat'],'-v7.3','windU','windV','pressure','rain','wind','temperature','waves','waterLevels') + + %% Run Delft3D FLOW/WAVE! + % system('. /home/cluster/D7545/enviorment.sh' + + + system('./runDuck_Wave.sh') + if exist('wavm-rt_run.dat')~=2 + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + delete swn-diag.* + + + system('./runDuck_Wave.sh') + end + + if exist('wavm-rt_run.dat')~=2 + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + elete FLOW2WAVE* + delete swn-diag.* + + + system('./runDuck_Wave.sh') + end + + if exist('wavm-rt_run.dat')~=2 + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + delete swn-diag.* + + + system('./runDuck_Wave.sh') + end + + + %% Move things + eval(['copyfile trim-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.dat']) + eval(['movefile trim-rt_run.dat /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.dat']) + + eval(['copyfile trim-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.def']) + eval(['movefile trim-rt_run.def /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.def']) + + eval(['copyfile wavm-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.dat']) + eval(['movefile wavm-rt_run.dat /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.dat']) + + eval(['copyfile wavm-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.def']) + eval(['movefile wavm-rt_run.def /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.def']) + + eval(['copyfile trih-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_histOut7.dat']) + eval(['movefile trih-rt_run.dat /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_histOut7.dat']) + + eval(['copyfile trih-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_histOut7.def']) + eval(['movefile trih-rt_run.def /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_histOut7.def']) + + + eval(['movefile hrrr.amu /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_hrrr7.amu']) + + eval(['movefile hrrr.amv /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_hrrr7.amv']) + + eval(['movefile hrrr.ampr /home/cluster/RT_Dec/CAD_OUT/' datestr(masterTime,'YYYY-MM-DD_hh') '_hrrr7.ampr']) + + eval(['copyfile ModelIn_6_HRRR' datestr(masterTime,'YYYY-MM-DD_hh') '.mat /home/cluster/RT_Dec/CAD_OUT/ModelIn_7' datestr(masterTime,'YYYY-MM-DD_hh') '.mat']) + eval(['copyfile tri-rst.rt* /home/cluster/RT_Dec/CAD_OUT/']) + + +end diff --git a/DelftInputsV2.m b/DelftInputsV2.m new file mode 100644 index 0000000..403709d --- /dev/null +++ b/DelftInputsV2.m @@ -0,0 +1,1058 @@ +%% Script to create inputs for Duck Delft3D + +%% Import +flowGrid = load('D:\Fateme_Alex\postRap\Hermine\C7HR100.mat'); + +% flowGrid = load('D:\Alexander\RT_25m\C7_25.mat'); +% flowGrid = load('D:\NCBathy\Cone7\C9S_50.mat'); + +% waveGrid = load('D:\Alexander\RealtimeHRRR.mat'); +% waveGrid = load('D:\NCBathy\Cone7\C9S_100.mat'); + + +load('D:\Temp\NC_Data.mat') +load('measuredNOAA.mat'); +load('D:\Fateme_Alex\postRap\Hermine\NCOM2016Final.mat') +clear NC_Data_PAR NC_Data_NOAA NC_Data_WQ + +%% Process +% axisLimits=[datetime(2016,10,07,00,00,00) datetime(2016,10,12)]; + +% axisLimits=[datetime(2016,08,27,00,00,00) datetime(2016,09,05)]; + +% axisLimits=[datetime(2016,08,15,00,00,00) datetime(2016,11,01)]; + +axisLimits=[datetime(2019,09,02) datetime(2019,09,09,18,00,00)]; + +dateStart = axisLimits(1); +dateEnd = axisLimits(2); + +delfTime = axisLimits(1):minutes(10):axisLimits(2); + +clear windIN windOut rainOut tempOut tideOut wlOut windOut_p_20 windOut_m_20 waveOut + +%% Process Wind +for Site=[1 3 4 5] + windIN(1,Site,:) = interp1(datenum(datetime(NC_Data_Wind{Site}(:,4),'ConvertFrom','posixtime')),... + NC_Data_Wind{Site}(:,5),... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + windIN(2,Site,:) = interp1(datenum(datetime(NC_Data_Wind{Site}(:,4),'ConvertFrom','posixtime')),... + NC_Data_Wind{Site}(:,9),... + datenum(axisLimits(1):minutes(10):axisLimits(2)),'nearest'); +end +windIN(windIN == 0) = NaN; + +delfTime = axisLimits(1):minutes(10):axisLimits(2); + +windOut(1,:) = nanmean(windIN(1,:,:),2); +windOut(2,:) = wrapTo360(rad2deg(circ_mean(deg2rad(windIN(2,:,:)), [], 2))); + + +windOut_p_20(1,:) = nanmean(windIN(1,:,:),2); +windOut_p_20(2,:) = wrapTo360(rad2deg(circ_mean(deg2rad(windIN(2,:,:)+20), [], 2))); + +windOut_m_20(1,:) = nanmean(windIN(1,:,:),2); +windOut_m_20(2,:) = wrapTo360(rad2deg(circ_mean(deg2rad(windIN(2,:,:)-20), [], 2))); + + + +%% Process Pier Wind + +[UA,~,idx] = unique(NC_Data_pierWind(:,4)); +windSpeedU = [accumarray(idx,NC_Data_pierWind(:,5),[],@mean)]; +windDirU = [accumarray(idx,NC_Data_pierWind(:,9),[],@mean)]; + +windIN_P(1,:) = interp1(datenum(datetime(UA,'ConvertFrom','posixtime')),... + windSpeedU,... + datenum(axisLimits(1):minutes(10):axisLimits(2)),'nearest'); +windIN_P(2,:) = interp1(datenum(datetime(UA,'ConvertFrom','posixtime')),... + windDirU,... + datenum(axisLimits(1):minutes(10):axisLimits(2)),'nearest'); + +delfTime = axisLimits(1):minutes(10):axisLimits(2); + +windOut_P(1,:) = windIN_P(1,:); +windOut_P(2,:) = windIN_P(2,:); + +clear UA windSpeedU windDirU windIN + +%% Process Rain +% Rain is given in total per 10 minutes, so multiplied by 6 to become +% hourly +rainOut = interp1(datenum(datetime(NC_Data_Rain(:,3),'ConvertFrom','posixtime')),... + NC_Data_Rain(:,5),... + datenum(axisLimits(1):minutes(10):axisLimits(2))).*6; + +%% Process Temperature +tempOut = interp1(datenum(datetime(NC_Data_Temp(:,1),'ConvertFrom','posixtime')),... + NC_Data_Temp(:,4),... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + +%% Process Tides +stations{6} = 8651370; %Dck +stations{9} = 8656483; %Beau +% monthDay = [31,30,31]; +for Stat=[6 9] + + for Month = 1:3 + if Month==1 + dateStartM=dateStart +((Month-1).*days(31)); + dateEndM=dateStart +((Month).*days(31)); + else + dateStartM=dateEndM + days(1); + dateEndM=dateStart +((Month).*days(31)); + end + + url = ['https://tidesandcurrents.noaa.gov/api/datagetter?product=water_level&application=NOS.COOPS.TAC.WL&'... + 'begin_date=' datestr(dateStartM,'yyyymmdd') '&end_date=' datestr(dateEndM,'yyyymmdd') '&datum=NAVD' '&station=' num2str(stations{Stat})... + '&time_zone=GMT&units=metric&format=csv']; + + wlIN = webread(url); + + if Month==1 + measuredWL_D = datenum(wlIN.DateTime); + measuredWL_W = wlIN.WaterLevel; + else + measuredWL_D = vertcat(measuredWL_D,datenum(wlIN.DateTime)); + measuredWL_W = vertcat(measuredWL_W,wlIN.WaterLevel); + end + + clear windIN wlIN + end + + switch Stat + case 6 + tideOutN = interp1(measuredWL_D,... + measuredWL_W,... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + + case 9 + tideOutS = interp1(measuredWL_D,... + measuredWL_W,... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + end +end + +%% Process Waves + +waveOut(:,1) = interp1(datenum(datetime(NC_Data_WAVE{3}(:,5),'ConvertFrom','posixtime')),... + NC_Data_WAVE{3}(:,6),... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + +waveOut(:,2) = interp1(datenum(datetime(NC_Data_WAVE{3}(:,5),'ConvertFrom','posixtime')),... + 1./NC_Data_WAVE{3}(:,7),... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + +waveOut(:,3) = windOut(2,:)'; + +waveOut(:,4) = ones(length(waveOut),1).*15; + +%% Import NDBC Waves +% py_addpath('D:\MATLAB4\Downloads\wave_buoys_exploit-master') +% py.importlib.import_module('utils_xuan') + +% py_addpath('D:\MATLAB4\Downloads\wave_buys_exploit-master\buoy_original_wanghe_source_code_buoystromassociator_31mai2018\buoy\utilos') +% py.importlib.import_module('wav_utils') + +py_addpath('D:\MATLAB4\Downloads\DirectionalSpectra-master') +mod = py.importlib.import_module('getmem'); + +addpath('Python') + +freqNDBC = [0.02 0.0325 0.0375 0.0425 0.0475 0.0525 0.0575 0.0625 0.0675 0.0725 0.0775 0.0825 0.0875 0.0925 0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.2 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.3 0.31 0.32 0.33 0.34 0.35 0.365 0.385 0.405 0.425 0.445 0.465 0.485]; +StatCount=1; +clear buoyIn dirSpec tmpSpc +% datesWW3=dateStart:minutes(20):dateEnd; + +for Station = [217 41025 44014 147] + VarCount=1; + + if ismember(Station,[44014,41025])==1 + for Var = [23 4 9 10 11] + [buoyIn{StatCount,1}(:,:,VarCount),buoyIn{StatCount,2}]... + = NDBCsave(['D:\WW3\' num2str(Station) alphabet(Var) '2016.txt']); +% [buoyIn{StatCount,1}(:,:,VarCount),buoyIn{StatCount,2}]... +% = NDBCsave(['D:\WW3\' num2str(Station) alphabet(Var) '2019.txt']); + + VarCount=VarCount+1; + end + + else + + url = ['http://thredds.cdip.ucsd.edu/thredds/dodsC/cdip/archive/' num2str(Station) 'p1/' num2str(Station) 'p1_historic.nc']; +% url = ['http://thredds.cdip.ucsd.edu/thredds/dodsC/cdip/realtime/' num2str(Station) 'p1_rt.nc']; + + waveTime = datetime(ncread(url,'waveTime'),'ConvertFrom','POSIX'); + cDipIDX(1) = NearestValue(datenum(dateStart),datenum(waveTime)); + cDipIDX(2) = NearestValue(datenum(dateEnd),datenum(waveTime)); + + freqCdip = ncread(url,'waveFrequency'); + + buoyIn{StatCount,1}(:,:,1) = ncread(url,'waveEnergyDensity',[1 cDipIDX(1)],[64 cDipIDX(2)-cDipIDX(1)])'; + buoyIn{StatCount,1}(:,:,2) = ncread(url,'waveA1Value',[1 cDipIDX(1)],[64 cDipIDX(2)-cDipIDX(1)])'; + buoyIn{StatCount,1}(:,:,3) = ncread(url,'waveA2Value',[1 cDipIDX(1)],[64 cDipIDX(2)-cDipIDX(1)])'; + buoyIn{StatCount,1}(:,:,4) = ncread(url,'waveB1Value',[1 cDipIDX(1)],[64 cDipIDX(2)-cDipIDX(1)])'; + buoyIn{StatCount,1}(:,:,5) = ncread(url,'waveB2Value',[1 cDipIDX(1)],[64 cDipIDX(2)-cDipIDX(1)])'; + + + buoyIn{StatCount,2} = datetime(ncread(url,'waveTime',[cDipIDX(1)],[cDipIDX(2)-cDipIDX(1)]),'ConvertFrom','POSIX'); + end + + + + DirCount=1; + directions = [5:5:360]; + directions2 = [1:1:360]; + directionsR = deg2rad(directions); + clear tmpSpc tmpSpc + if ismember(Station,[44014,41025])==1 + for Direction = directions + tmpSpc(:,:,DirCount) = buoyIn{StatCount,1}(:,:,1).*... + (1/180).*(0.5+0.01.*buoyIn{StatCount,1}(:,:,4).*cosd(1.*(Direction-buoyIn{StatCount,1}(:,:,2)))+... + (0.01.*buoyIn{StatCount,1}(:,:,5).*cosd(2.*(Direction-buoyIn{StatCount,1}(:,:,3))))); %https://www.ndbc.noaa.gov/measdes.shtml + DirCount=DirCount+1; + end + + else + tmpSpc = zeros(length(buoyIn{StatCount,2}),length(freqCdip),length(directions2)); + for Time = 1:length(buoyIn{StatCount,2}) + pySpc = mod.GetMem(py.numpy.array(squeeze(buoyIn{StatCount}(Time,:,2))),... + py.numpy.array(squeeze(buoyIn{StatCount}(Time,:,4))),py.numpy.array(squeeze(buoyIn{StatCount}(Time,:,3))),... + py.numpy.array(squeeze(buoyIn{StatCount}(Time,:,5)))); + tmpSpc(Time,:,:) = np2mat(pySpc).*repmat(squeeze(buoyIn{StatCount}(Time,:,1))',1,size(np2mat(pySpc),2)); + disp(Time) + end + clear pySpc + end + + if ismember(Station,[44014,41025])~=1 + [meshIN1,meshIN2] = meshgrid(freqCdip,directions2); + [meshOUT1,meshOUT2] = meshgrid(freqNDBC',directions); + meshIN1=double(meshIN1); + + dirSpec{StatCount,1} = zeros(length(buoyIn{StatCount,2}),length(freqNDBC),length(directions)); + + for Time = 1:length(buoyIn{StatCount,2}) + dirSpec{StatCount,1}(Time,:,:) = interp2(meshIN1,meshIN2,squeeze(tmpSpc(Time,:,:))',... + meshOUT1,meshOUT2)'; + end + + dirSpec{StatCount,1}(isnan(dirSpec{StatCount,1})==1)=0; + dirSpec{StatCount,2}=buoyIn{StatCount,2}; + + else + dirSpec{StatCount,1}=tmpSpc; + dirSpec{StatCount,2}=buoyIn{StatCount,2}; + + end + + + clear tmpSpc + StatCount=StatCount+1; + +end +clear Var Direction DirCount StatCount VarCount + + +%% Processs WW3 waves +% [meshDateQ,mesgFreqQ,meshDirQ] = meshgrid(freq,datenum(datesWW3),directions); +clear swanIN swanINTER +% for StatCount=1:2 +dateCount=1; + +% datesWW3=datetime(2016,09,02):minutes(20):datetime(2016,09,05); +datesWW3=datetime(2016,10,06):minutes(20):datetime(2016,10,11); +% datesWW3=datetime(2019,09,02):minutes(60):datetime(2019,09,05); + +swanINTER=zeros(length(datesWW3),length(freqNDBC),length(directions),7); +for dateWW3 = datesWW3 + [idx(1),waveDif(1)] = NearestValue(dateWW3,dirSpec{1,2}); + [idx(2),waveDif(2)] = NearestValue(dateWW3,dirSpec{2,2}); + [idx(3),waveDif(3)] = NearestValue(dateWW3,dirSpec{3,2}); + [idx(4),waveDif(4)] = NearestValue(dateWW3,dirSpec{4,2}); + + if max(waveDif)>hours(1) + disp(['noData for ' datestr(dateWW3)]) + end + % [meshDate,mesgFreq,meshDir] = meshgrid(freq,datenum(dirSpec{StatCount,2}),directions); + + % swanIN(:,:,:,StatCount) = interp3(meshDate,mesgFreq,meshDir,... + % dirSpec{StatCount,1},meshDateQ,mesgFreqQ,meshDirQ); + % swanIN(dateCount,:,:,StatCount) = dirSpec{StatCount,1}(idx,:,:); + + % [Xq,Yq,Zq] = meshgrid( 1:size(dirSpec{StatCount,1},3),1:size(dirSpec{StatCount,1},2),... + % linspace(1,2,size(flowGrid.data.Y,2)./2)); + % swanINTER(dateCount,:,:,:) = interp3(... + % cat(3,squeeze(dirSpec{1,1}(idx(1),:,:)),squeeze(dirSpec{2,1}(idx(2),:,:))),... + % Xq,Yq,Zq); + % swanINTER(dateCount,:,:,:) = linspaceNDim(squeeze(dirSpec{1,1}(idx(1),:,:)),... + % squeeze(dirSpec{2,1}(idx(2),:,:)),floor(size(flowGrid.data.Y,2)./25)); + swanINTER(dateCount,:,:,1:3) = linspaceNDim(squeeze(dirSpec{1,1}(idx(1),:,:)),... + squeeze(dirSpec{2,1}(idx(2),:,:)),3); + swanINTER(dateCount,:,:,3:7) = linspaceNDim(squeeze(dirSpec{2,1}(idx(2),:,:)),... + squeeze(dirSpec{3,1}(idx(3),:,:)),5); + swanINTER(dateCount,:,:,7:8) = linspaceNDim(squeeze(dirSpec{3,1}(idx(3),:,:)),... + squeeze(dirSpec{4,1}(idx(4),:,:)),2); + + dateCount=dateCount+1; + disp(dateWW3) +end + +% end +% xPts = [1300 2161 2161 1650]; +% yPts = [2 2 2641 2641]; +% xPts = [650 1081 1081 825]; +% yPts = [2 2 1321 1321]; +% xPts = [1300 1749lear akll 1749 1650]; +% yPts = [2 2 2641 2641]; +xPts = [490 874 874 740]; +yPts = [2 2 1321 1321]; + +xPtsSWAN(1:3) = floor(linspace(xPts(1),xPts(2),3)); +xPtsSWAN(3:7) = floor(linspace(xPts(2),xPts(3),5)); +xPtsSWAN(7:8) = floor(linspace(xPts(3),xPts(4),2)); + + +yPtsSWAN(1:3) = floor(linspace(yPts(1),yPts(2),3)); +yPtsSWAN(3:7) = floor(linspace(yPts(2),yPts(3),5)); +yPtsSWAN(7:8) = floor(linspace(yPts(3),yPts(4),2)); + +for i=1:8 + xPtsSWANutm(i) = waveGrid.data.X(xPtsSWAN(i),yPtsSWAN(i)); + yPtsSWANutm(i) = waveGrid.data.Y(xPtsSWAN(i),yPtsSWAN(i)); +end + + + +% dwr_2d_swan(freq,directions,swanIN(:,:,:,1),'ObsN',datesWW3,[5.1431e+05],[4.0512e+06],1,'NDBC_N.bcw') +dwr_2d_swanV2(freqNDBC,directions,swanINTER,'NDBC',datesWW3,... + [xPtsSWANutm],[yPtsSWANutm],1,'NDBC_2016Oct_C9S.bcw') +% dwr_2d_swan(freq,directions,swanIN(:,:,:,2),'ObsS',datesWW3,[4.6689e+05],[3.8759e+06],1,'NDBC_S.bcw') + +%% Process WL +for Site=[1 2 3 5] + wlIN(Site,:) = interp1(datenum(datetime(NC_Data_WL{Site}(:,4),'ConvertFrom','posixtime')),... + NC_Data_WL{Site}(:,5),... + datenum(axisLimits(1):minutes(10):axisLimits(2))); +end +wlIN(wlIN == 0) = NaN; + +delfTime = axisLimits(1):minutes(10):axisLimits(2); +wlOut = nanmean(wlIN(:,:)); + +%% load Measured NOAA WL +load('measuredNOAA.mat') + +tideOutN = interp1(measuredWL{6}(:,1),... + measuredWL{6}(:,2),... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + +tideOutS = interp1(measuredWL{9}(:,1),... + measuredWL{9}(:,2),... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + +%% Process Stream +% Designate Input Coordinates +% streamDelftLocation=[325409 4034751;... %1 +% 307140 3937494;... %2 +% 296176 3903604;... %3 +% 315241 3886276;... %4 +% 388920 4024591;... %5 +% 317623 3970513]; %6 +% streamDelftNum = [5 1 6 2 3 4 1 1 1]; + +streamDelftLocation=[325409 4034751;... %1 + 313151 3935550;... %2 + 296176 3903604;... %3 + 315241 3886276;... %4 + 388920 4024591;... %5 + 322564 3971902]; %6 +streamDelftNum = [5 1 6 2 3 4 1 1 1]; + + +for Stream=1:9 + streamIN(Stream,:) = interp1(measuredStream{Stream}(:,1),... + measuredStream{Stream}(:,2),... + datenum(axisLimits(1):minutes(10):axisLimits(2))); +end + +for Stream=1:6 + streamOut(:,Stream) = nansum(streamIN(streamDelftNum==Stream,:),1); +end +streamOut(streamOut<0)=0; + +%% Load Grid and find stream locations +grid = load('D:\Fateme_Alex\postRap\Hermine\C7HR100.mat'); + +for Stream=1:6 + [streamIDX(Stream,:)] = NearestValue(streamDelftLocation(Stream,:),grid.data.X,grid.data.Y); +end +%% Wind +fileID=fopen('D:\Fateme_Alex\CS2019\windOut_m_20.wnd','w'); + +refTime=0; +for line=1:length(delfTime) + fprintf(fileID,'%d. %2.1f %3.0f\n',refTime,windOut_m_20(1,line),windOut_m_20(2,line)); + refTime=refTime+10; +end +fclose(fileID) + +%% Wind P +fileID=fopen('D:\Fateme_Alex\CS2019\WindPH.wnd','w'); + +refTime=0; +for line=1:length(delfTime) + fprintf(fileID,'%d. %2.1f %3.0f\n',refTime,windOut_P(1,line),windOut_P(2,line)); + refTime=refTime+10; +end +fclose(fileID) + +%% Rain +fileID=fopen('D:\Fateme_Alex\CS2019\RainFull.eva','w'); + +refTime=0; + +for line=1:length(delfTime) + fprintf(fileID,'%d. %2.2f -999.0 %2.2f\n',refTime,rainOut(line),tempOut(line)); + refTime=refTime+10; +end + +fclose(fileID) + +%% Streams +fileID=fopen('D:\Fateme_Alex\CS2019\Stream_100.src','w'); +for line=1:length(streamIDX) + fprintf(fileID,'Stream_%d Y %d %d 0 N\n',line,streamIDX(line,1),streamIDX(line,2)); +end +fclose(fileID) + + + +fileID=fopen('D:\Fateme_Alex\CS2019\Stream_100.dis','w'); +refTime=0; +records=length(delfTime); + +for Stream=1:length(streamIDX) + refTime=0; + + header=[... + 'table-name ''Discharge : %d''\n'... + 'contents ''regular ''\n'... + 'location ''Stream_%d ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''flux/discharge rate'' unit ''[m3/s]''\n'... + 'records-in-table %d\n'... + ]; + + fprintf(fileID,header,Stream,Stream,str2num(datestr(axisLimits(1),'yyyymmdd')),records) + + + for line=1:length(delfTime) + fprintf(fileID,'%d %1.7f\n',refTime,streamOut(line,Stream)); + refTime=refTime+10; + end + +end +fclose(fileID) + + +%% Obs +%% Create Observation File +load('CSpoints.mat'); +locations = [36.606,-74.840;... + 36.260,-75.594;... + 36.001,-75.421;... + 35.750,-75.330;... + 35.025,-75.363; + 36.189244, -75.739155;... + 36.3205,-75.872;... + 36.1656,-75.8155;... + 36.0866, -75.76833;... + 35.8964389,-75.6220889;... + 34.7113528,-76.7368333;... + 36.20002, -75.7151]; + +locNames = {'Virginia Beach Wave',... + 'Duck 26 Wave',... + 'Nages Head Wave',... + 'Oregon Inlet Wave',... + 'Diamond Shoals Wave',... + 'Duck 11 AWAC',... + 'CS North',... + 'CS South',... + 'USGS CURRITUCK SOUND NR POINT HARBOR',... + 'USGS ROANOKE SOUND AT POND ISLAND',... + 'USGS BOGUE SOUND AT ATLANTIC BEACH',... + 'Duck 17 Wave'}; +% Realtime Points + +% Create Observation File +locations = [36.606,-74.840;... + 36.260,-75.594;... + 36.001,-75.421;... + 35.750,-75.330;... + 35.025,-75.363; + 36.189244, -75.739155;... + 36.3205,-75.872;... + 36.1656,-75.8155;... + 36.0866, -75.76833;... + 35.8964389,-75.6220889;... + 34.7113528,-76.7368333;... + 35.96176,-75.64163;... + 36.04318,-75.68936;... + 36.12932,-75.74501;... + 36.20002, -75.7151]; + +locNames = {'Virginia Beach Wave',... + 'Duck 26 Wave',... + 'Nages Head Wave',... + 'Oregon Inlet Wave',... + 'Diamond Shoals Wave',... + 'Duck 11 AWAC',... + 'CS North',... + 'CS South',... + 'USGS CURRITUCK SOUND NR POINT HARBOR',... + 'USGS ROANOKE SOUND AT POND ISLAND',... + 'USGS BOGUE SOUND AT ATLANTIC BEACH',... + 'Villa Dunes SW Dock Shoreline',... + 'Hayman St Dock SW Shoreline',... + 'Gunther Telephone Pole'... + 'Duck 17 Wave'}; + +% if FIRST_RUN == 0 + +for i = 1:length(locations) + pointsCS{i+11,1} = locNames{i}; + [pointsCS{i+11,2},pointsCS{i+11,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); +end + +pointsCS{27,1} = 'Beaufort 2'; +pointsCS{27,2} = 345563; +pointsCS{27,3} = 3842033; + +pointsCS{27,1} = 'Beaufort 3'; +pointsCS{27,2} = 346832; +pointsCS{27,3} = 3838721; + +pointsCS{8,3} = pointsCS{8,3} + 2500; +pointsCS{7,2} = pointsCS{7,2} - 500; + + +fileID=fopen('obs_f_RT.obs','w'); +for line=1:length(pointsCS) + obsIDX = NearestValue([pointsCS{line,2:3}],flowGrid.data.X,flowGrid.data.Y); + if length(pointsCS{line,1})>20 + fprintf(fileID,[pointsCS{line,1}(1:20) ' %d %d\n'],obsIDX(1),obsIDX(2)); + else + fprintf(fileID,[pointsCS{line,1}(1:end) ' %d %d\n'],obsIDX(1),obsIDX(2)); + end +end +fclose(fileID); + +fileID=fopen('obs_w_RT.loc','w'); + +for i = 1:length(pointsCS) + fprintf(fileID,' %1.7f %1.7f\n',pointsCS{i,2},pointsCS{i,3}); +end +fclose(fileID) +%end +%% Currents from NCOM + +idxCount=1; +for i = round(linspace(2,length(flowGrid.data.Y)-1,53)) % Every 5 km +% [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); +% [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(4322,i),flowGrid.data.Y(4322,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon +% crIDX(idxCount,:) = [1082,i]; +% crIDX(idxCount,:) = [2161,i]; + crIDX(idxCount,:) = [4322,i]; + + idxCount = idxCount + 1; +end + +crBoundCount(1) = 0; +crBoundCount(2) = idxCount -1; + +% for i = round(linspace(744,1080,14)) % Every 5 km +% for i = round(linspace(1488,2161,14)) % Every 5 km +for i = round(linspace(2976,2161,14)) % Every 5 km + +% [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); +% [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,5282),flowGrid.data.Y(i,5282),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon +% crIDX(idxCount,:) = [i,1321]; +% crIDX(idxCount,:) = [i,2641]; + crIDX(idxCount,:) = [i,5282]; + + idxCount = idxCount + 1; +end +crBoundCount(3) = idxCount -1; + +% for i = round(linspace(455,1080,26)) % Every 5 km +% for i = round(linspace(910,2161,26)) % Every 5 km +for i = round(linspace(1820,4322,26)) % Every 5 km +% [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon +% crIDX(idxCount,:) = [i,1]; + crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; +end +crBoundCount(4) = idxCount -1; + + +clear idxCount gridDeg + +%% Interpolate Water Level +for tStep = 1:length(tideOutN) + wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); + wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); + wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); +end +%% Match to grid +flowBed = load('D:\Fateme_Alex\postRap\Hermine\C7HR50_Bed.mat'); + +idxCount=1; +for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+0.112; + mag(:,idxCount) = vecmag(currX,currY); + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + +% disp(idxCount) + idxCount = idxCount + 1; + +end + +% fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); +% fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + +clear idxCount + +%% interpolate Currents +clear currentsOut +for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(hours(NCOM.time)+datetime(2013,04,05))); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(axisLimits(1):minutes(10):axisLimits(2))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + for j = 1:length(idxNCOM) + currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut)); + end + +end +idxCount=1; + +for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + RNOut_2(:,i) = currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + else + RNOut_2(:,i) = currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + + end + + + + idxCount = idxCount+1; +end +%% Combined Boundry Files +records=size(tideOutS,2); +boundryNames(1) = {'OceanE'}; + +for i = 2:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; +end + +boundryTypes(1) = {'water elevation (z)'}; +boundryTypes(2:crBoundCount(4)+1) = {'current (c)'}; +boundryUnits(1) = {'[m]'}; +boundryUnits(2:crBoundCount(4)+1) = {'[m/s]'}; + +fileID=fopen('NCOM_Tides2.bct','w'); + +for Boundry = [1 crBoundCount(2)+1:length(boundryNames)] + refTime=0; + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(dateStart,'yyyymmdd')),records); + if Boundry<2 + for line = 1:size(tideOutS,2) + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,tideOutS(line),tideOutN(line)); + refTime=refTime+10; + end + else + for line = 1:size(tideOutS,2) + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,currents2Out(line,Boundry-1),currents2Out(line,Boundry)); + + refTime=refTime+10; + end + end +end + +fclose(fileID); + +%% R Boundry Files +records=size(tideOutS,2); + +for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; +end + +% boundryTypes(1) = {'water elevation (z)'}; +boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; +boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + +fileID=fopen('NCOM_R1.bct','w'); + +for Boundry = [2:length(boundryNames)] + refTime=0; + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(dateStart,'yyyymmdd')),records); + for line = 1:size(tideOutS,2) + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_1(line,Boundry-1),RNOut_1(line,Boundry)); + + refTime=refTime+10; + end +end + +fclose(fileID); + + +%% Boundry definition file +fileID=fopen('NCOM_25m.bnd','w'); +crIDX2=crIDX; +crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+1; +for Boundry = [1 crBoundCount(2)+1:length(boundryNames)] + if Boundry == 1 + fprintf(fileID,[boundryNames{Boundry} ' Z T 1082 1320 1082 2 1.0000000e+004\n']); + + elseif ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' C T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 1.0000000e+004 Uniform \n']); + end +end +fclose(fileID); + +%% Boundry definition file-R +fileID=fopen('NCOM_R25.bnd','w'); +crIDX2=crIDX; +% crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+1; +for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end +end +fclose(fileID); + +%% Tides +refTime=0; +records=length(delfTime); +boundryNames = {'East','OceanN','OceanS'}; + +tideOutNSmooth=smooth(tideOutN,10); +tideOutSSmooth=smooth(tideOutS,10); + +fileID=fopen('D:\Fateme_Alex\CSBoundryTS_SmoothNS_NOAA_NS_100.bct','w'); + +for Boundry =[2 1 3] + refTime=0; + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''water elevation (z) end A'' unit ''[m]''\n'... + 'parameter ''water elevation (z) end B'' unit ''[m]''\n'... + 'records-in-table %d\n'... + ]; + + fprintf(fileID,header,Boundry,str2num(datestr(axisLimits(1),'yyyymmdd')),records) + + for line=1:length(delfTime) + switch Boundry + case 1 + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,tideOutN(line),tideOutS(line)); + case 2 + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,tideOutN(line),tideOutN(line)); + case 3 + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,tideOutS(line),tideOutS(line)); + end + refTime=refTime+10; + end + +end +fclose(fileID) + + +refTime=0; +records=length(delfTime); +boundryNames = {'East','OceanN','OceanS'}; +boundryTypes = {'water elevation (z)','neumann (n)','neumann (n)'}; + +tideOutNSmooth=zeros(length(tideOutN),3); +tideOutSSmooth=zeros(length(tideOutN),3); + +tideOutNSmooth(:,1)=smooth(tideOutN,10); +tideOutSSmooth(:,1)=smooth(tideOutS,10); + +fileID=fopen('D:\Fateme_Alex\CSBoundryTS_SmoothNS_NOAA_NS_Neu_100.bct','w'); +crBoundCount=1; + +for Boundry =[2 1 3] + refTime=0; + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''[m]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''[m]''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,crBoundCount,str2num(datestr(axisLimits(1),'yyyymmdd')),records) + + for line=1:length(delfTime) + switch Boundry + case 1 + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,tideOutN(line),tideOutS(line)); + case 2 + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,0,0); + case 3 + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,0,0); + end + refTime=refTime+10; + end + crBoundCount=crBoundCount+1; + +end +fclose(fileID) + +% +% refTime=0; +% records=length(delfTime); +% boundryNames = {'North','South'}; +% boundryTypes = {'water elevation (z)','water elevation (z)'}; +% +% tideOutSmooth(:,1)=smooth(wlIN(3,:),25); +% tideOutSmooth(:,2)=smooth(wlIN(1,:),25); +% +% fileID=fopen('D:\Fateme_Alex\CS2019\CS_Small_Bound.bct','w'); +% +% for Boundry =1:2 +% refTime=0; +% +% header=[... +% 'table-name ''Boundary Section : %d''\n'... +% 'contents ''Uniform ''\n'... +% 'location ''' boundryNames{Boundry} ' ''\n'... +% 'time-function ''non-equidistant''\n'... +% 'reference-time %d\n'... +% 'time-unit ''minutes''\n'... +% 'interpolation ''linear''\n'... +% 'parameter ''time '' unit ''[min]''\n'... +% 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''[m]''\n'... +% 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''[m]''\n'... +% 'records-in-table %d\n'... +% ]; +% +% +% fprintf(fileID,header,Boundry,str2num(datestr(axisLimits(1),'yyyymmdd')),records) +% +% for line=1:length(delfTime) +% fprintf(fileID,'%d %1.4f %1.4f\n',refTime,tideOutSmooth(line,Boundry),tideOutSmooth(line,Boundry)); +% refTime=refTime+10; +% end +% +% +% end +% fclose(fileID) + + +%% Waves + +refTime=0; +records=length(delfTime); +boundryNames = {'NorthWave'}; + +fileID=fopen('D:\Fateme_Alex\CS2019\CS_Wave_Bound.bcw','w'); + +for Boundry =1 + refTime=0; + + header=[... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time'' unit ''[min]''\n'... + 'parameter ''WaveHeight'' unit ''[m]''\n'... + 'parameter ''Period'' unit ''[s]''\n'... + 'parameter ''Direction'' unit ''[N^o]''\n'... + 'parameter ''DirSpreading'' unit ''[degrees]''\n'... + ]; + + + fprintf(fileID,header,str2num(datestr(axisLimits(1),'yyyymmdd'))) + + for line=1:length(delfTime) + if max(isnan(waveOut(line,:)))==0 + fprintf(fileID,'%d %1.2f %1.2f %3.0f %d\n',refTime,waveOut(line,1),waveOut(line,2),waveOut(line,3),waveOut(line,4)); + end + refTime=refTime+10; + end + + +end +fclose(fileID) + + diff --git a/Dunex_Operational_36h.m b/Dunex_Operational_36h.m new file mode 100644 index 0000000..35c9728 --- /dev/null +++ b/Dunex_Operational_36h.m @@ -0,0 +1,2322 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +% Moved to COASTLINES Feb 29, 2020 + +clear all +cd D:\DUNEX_RT\Operation +echo off; +addpath('NCtoolbox') +addpath('m_map') +setup_nctoolbox +flowGrid = load('Cone7W_100.mat'); +waveGrid = load('Cone7W_250.mat'); +load('LMSL_RT.mat') +addpath('D:\DUNEX_RT\Operation\abogaard-matlab2gsheets-6d76271') +setenv('PATH', [getenv('PATH') ';D:\DUNEX_RT\Windows_64']); + +%% Details for e-mail server +setpref('Internet','SMTP_Server','smtp.sendgrid.net'); +setpref('Internet','E_mail','mail@alexanderrey.ca'); +setpref('Internet','SMTP_Username','apikey'); +setpref('Internet','SMTP_Password','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'); +props = java.lang.System.getProperties; +props.setProperty('mail.smtp.auth','true'); +props.setProperty('mail.smtp.socketFactory.class', 'javax.net.ssl.SSLSocketFactory'); +props.setProperty('mail.smtp.socketFactory.port','465'); +props.setProperty('mail.smtp.starttls.enable','true'); + + +%% Master Model Time Step +% Every 6 hours + +nistTime = datetime(datevec(now())) - tzoffset(datetime(datevec(now()),'TimeZone','local')); +masterTime = dateshift(nistTime,'start','hour')-hours(2) % Assume script will run at 5 and a half hours after model start +clear nistTime +masterDate = datetime(year(masterTime),month(masterTime),day(masterTime)); + +if exist(['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000'])==2 + FIRST_RUN = 0; +else + FIRST_RUN = 1; +end + +%% Import +try + Import=0; + + + %% Clean files from previous run + system('taskkill /IM "d_hydro.exe" /F') + system('taskkill /IM "wave.exe" /F') + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + + clear HRRR_UTM + while Import==0 + try + %% Import data from NOMADS + %% Extratropical Surge and Tide Operational Forecast System for the Atlantic + % (ESTOFS Atlantic) for water levels + options = weboptions; + options.Timeout = 90; + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(6),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 7; + ESTrun = 6; + catch + % url = ['http://nomads.ncep.noaa.gov/dods/estofs_atl/'... + % datestr(masterTime-days(1),'yyyymmdd')... + % '/estofs_atl_conus_' datestr(masterTime-days(1),'hh') 'z']; + % ESTOFS = ncgeodataset(url); + % lonESTOFS=ESTOFS{'lon'}(:); + % latESTOFS=ESTOFS{'lat'}(:); + % ESTstart = 24+ESTstart; +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-days(1),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-days(1),'yyyymmdd')... + '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 25; + ESTrun = 24; + end + + + clear url + + % Find ESTOFS index for grid points along boundry + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); %Lat + wlIDX(idxCount,:) = [1082,i]; + + idxCount = idxCount + 1; + end + + wlBoundCount(1) = 0; + wlBoundCount(2) = idxCount -1; + + + for i = 750:11:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1322]; + idxCount = idxCount + 1; + end + + wlBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1]; + idxCount = idxCount + 1; + end + wlBoundCount(4) = idxCount -1; + + clear idxCount gridDeg + + % Extract ESTOFS Water Levels for 36 hours at indexes + % waterLevelsGRID = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(ESTstart:ESTstart+36,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + % min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + + % Find ESTOFS values from small grid + idxCount=1; + errorET = 0; + for i = ESTstart:ESTstart+72 + if errorET<10 + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... +% num2str(i,'%03d') '.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... + num2str(i,'%03d') '.grib2']; + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib'],url,options) + + if i<=ESTstart+36 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib']); + + waterLevelsGRID(idxCount,:,:) = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + end + idxCount = idxCount + 1; + catch + errorET = errorET+1; + end + else + error('ESTOFS ERROR') + end + + end + + idxCount=1; + for i = 1:length(idxESTOFS) + waterLevels(:,idxCount) = waterLevelsGRID(:,idxESTOFS(idxCount,1)-min(idxESTOFS(:,1))+1,... + idxESTOFS(idxCount,2)-min(idxESTOFS(:,2))+1); + + idxCount = idxCount + 1; + end + + + % Save ESTOFS Points +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_points.nc'],url,options) + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + disp('Loaded ESTOFS') + %% Multi-grid Wave model (WAVEWATCH III) + % 4 arc minute US East Coast grid for waves + + url = ['https://nomads.ncep.noaa.gov/dods/wave/gfswave/'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/gfswave.atlocn.0p16_' datestr(masterTime-hours(6),'hh') 'z']; + + MWW3 = ncgeodataset(url); + clear url + + lonMWW3=wrapTo180(MWW3{'lon'}(:)); + latMWW3=MWW3{'lat'}(:); + + % Find MWW3 index for grid points along boundry + idxCount=1; + for i = 1:25:length(waveGrid.data.Y)-25 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(end-2,i),waveGrid.data.Y(end-2,i),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(end-2,1:i)).^2+... + diff(waveGrid.data.Y(end-2,1:i)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(end-2,i); + waveUTM(idxCount,2) = waveGrid.data.Y(end-2,i); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + waveBoundCount(1) = 0; + waveBoundCount(2) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:350% Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,end-2),waveGrid.data.Y(i,end-2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,end-2)).^2+... + diff(waveGrid.data.Y(i:end-2,end-2)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,end-2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,end-2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + % 0 132 163 285 + + waveBoundCount(3) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:240 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,2),waveGrid.data.Y(i,2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,1)).^2+... + diff(waveGrid.data.Y(i:end-2,1)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(4) = idxCount -1; + + clear idxCount + + % Extract WW3 Hs for 36 hours at indexes + wavesGRID_Hs = MWW3{'htsgwsfc'}(7:19,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid htsgwsfc + %swell_1 + % Period + wavesGRID_P = MWW3{'perpwsfc'}(7:19,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... % + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid perpwsfc + %swper_1 + % Direction + wavesGRID_Dir = MWW3{'dirpwsfc'}(7:19,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid dirpwsfc + %swdir_1 + % Find WW3 values from small grid + idxCount=1; + for i = 1:length(idxMWW3) + waves(:,idxCount,1) = wavesGRID_Hs(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Hs + + waves(:,idxCount,2) = wavesGRID_P(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Tp + + waves(:,idxCount,3) = wavesGRID_Dir(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Dir + + idxCount = idxCount + 1; + end + clear idxCount + disp('Loaded WW3') + + + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; + delete(gcp('nocreate')) + parpool(8); + + parfor ForcastHour = 0:36 + % url = ['http://nomads.ncep.noaa.gov/pub/data/nccf/com/hrrr/prod/'... + % 'hrrr.' datestr(masterTime,'yyyymmdd')... + % '/conus/hrrr.t' num2str(hour(masterTime),'%02d') 'z.'... + % 'wrfsfcf' num2str(ForcastHour,'%02d') '.grib2']; + + url = ['https://nomads.ncep.noaa.gov/cgi-bin/filter_hrrr_2d.pl?file=hrrr.'... + 't' num2str(hour(masterTime),'%02d') 'z.wrfsfc'... + 'f' num2str(ForcastHour,'%02d') '.grib2&'... + 'lev_10_m_above_ground=on&lev_surface=on&var_APCP=on&var_PRES=on&var_UGRD=on&var_VGRD=on&var_TMP=on&subregion=&leftlon=-78&rightlon=-74&toplat=38&bottomlat=32.5&dir=%2F'... + 'hrrr.' datestr(masterTime,'yyyymmdd') '%2Fconus']; + + websave(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2'],url,options) + + [pCheck,gridParams] = system(['perl "D:\DUNEX_RT\Windows_64\grid_defn.pl" '... + 'D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + [wCheck,gridParams] = system(['wgrib2 D:\DUNEX_RT\Operation\HRRR\hrrrT' ... + num2str(ForcastHour,'%02d') '.grib2 -new_grid_winds earth -new_grid ' ... + gridParams ' D:\DUNEX_RT\Operation\HRRR\hrrrT'... + num2str(ForcastHour,'%02d') '.grib2.regrid']); + end + delete(gcp('nocreate')) + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(0,'%02d') '.grib2.regrid']); + clear url + + m_proj('lambert conformal conic','ori',[262.5 38.5],'clo',262.5,'par',[38.5 38.5],'ell','sphere');%,'lat',[20 55],'lon',[-60 -130] + [meshX,meshY] = meshgrid(HRRR{'x'}(:),HRRR{'y'}(:)); + [windGridLON,windGridLAT] = m_xy2ll(meshX.*1000,meshY.*1000); + windGridLON=wrapTo180(windGridLON); + clear meshX meshY + + % Extract MWW3 Hs for 36 hours at indexes + for ForcastHour = 0:36 + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2.regrid']); + windU(ForcastHour+1,:,:) = HRRR{'u-component_of_wind_height_above_ground'}(:,:,:); %U Winds @ 10m [m/s] + windV(ForcastHour+1,:,:) = HRRR{'v-component_of_wind_height_above_ground'}(:,:,:); %V Winds @ 10m [m/s] + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + pressure(ForcastHour+1,:,:) = HRRR{'Pressure_surface'}(:,:,:); %Surface Pressure [pa] + + if ForcastHour==0 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_0_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + elseif ForcastHour==1 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_1_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + else + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_Mixed_intervals_Accumulation'}(2,:,:); %Surface precipitation [kg/m^2] + end + temperature(ForcastHour+1) = squeeze(nanmean(nanmean(HRRR{'Temperature_surface'}(:,:,:)- 273.15,2),3)); %Surface Temperature [C] + end + % Extract Temp + + disp('Loaded HRRR') + + + %% IMPORT NCOM + + try + nComDate=masterDate; +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/20201220/coamps_ncom_useast_u_1_2020122000_00000000.nc']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; + +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + mkdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0025-0048.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); + % NCOM.Lat = ncom_grib{'lat',[331],[240]}; + % NCOM.Lon = ncom_grib{'lon',91,180}; + catch + try + if hour(masterTime) ~= 18 + nComDate=masterDate-days(1); + else + nComDate=masterDate; + end +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); +% ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\grids\operational\NCOM\regional\GRIB2\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2']; +% ncom_grib = ncgeodataset(ncom_downloadPath); + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); +% NCOM.Lat = ncom_grib{'lat',[331],[240]}; +% NCOM.Lon = ncom_grib{'lon',91,180}; + + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + end + + if FIRST_RUN == 1 + NCOM.depth = ncread('D:\Alexander\NCOM\2019090500_t000.nc','depth'); + end + + Noffset = hours(masterTime - nComDate); + tStep = Noffset; + tCount = 1; + + try + for Ni = masterTime:hours(3):masterTime+hours(36) + noData=1; + while noData==1 + try +% NCOMstep = tStep./3+1; + NCOMstep = 1; + +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(masterDate,'YYYYmmDD')],... +% 'water_u',[NCOMstep 1 331 91],[1 40 240 180],[1 1 1 1]); +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_u',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.water_v(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_v',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.surf_el(:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'surf_el',[91 331 NCOMstep],[180 240 1],[1 1 1]); +% NCOM.salinity(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'salinity',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); + NCOM.water_u(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_u',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.water_v(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_v',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.surf_el(:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'surf_el',[91 331 1],[180 240 1],[1 1 1]); + NCOM.salinity(:,:,:,tCount) =ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'salinity',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + + if (squeeze(NCOM.water_v(100,100,1,end))==0|squeeze(NCOM.water_u(100,100,1,end))==0|squeeze(NCOM.surf_el(100,100,end))==0|squeeze(NCOM.salinity(100,100,1,end))==0)==1 + noData=1; + else + noData=0; + end + catch + noData=1; + end + disp(Ni) + end + NCOM.time(tCount) = Ni; + tStep=tStep+3; + tCount = tCount+1; + end + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + + + + %% NCOM Process + NCOM.mag = vecmag(NCOM.water_u,NCOM.water_v); + + if FIRST_RUN == 1 + depthWeight = [diff(NCOM.depth)' 0]; + + for Layer = 1:40 + DAVfac(:,:,Layer,:) = ones(180,240,1,13).*depthWeight(Layer); + end + DAVtrue = DAVfac; + N_depth = NCOM.depth; + save('NCOMstuff.mat','DAVtrue','DAVfac','N_depth') + else + load('NCOMstuff.mat') + NCOM.depth = N_depth; + clear N_depth; + end + DAVtrue(isnan(NCOM.mag(:,:,1:40,:))==1) = 0; + DAVfac(isnan(NCOM.mag(:,:,1:40,:))==1) = nan; + DAVFac2 = sum(DAVtrue,3); + clear DAVtrue + NCOM.dav = nansum(DAVfac.*NCOM.mag(:,:,1:40,:),3)./DAVFac2; + NCOM.davX = nansum(DAVfac.*NCOM.water_u(:,:,1:40,:),3)./DAVFac2; + NCOM.davY = nansum(DAVfac.*NCOM.water_v(:,:,1:40,:),3)./DAVFac2; + + Import=1 + catch err + + clear waterLevels + + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + disp('FAILED TO IMPORT FROM NOMADS') + pause(600) + end + end + + + load('shoreline.mat'); + + %% Format data for Delft3D + %% Evap + fileID=fopen('TemperatureRT.eva','w'); + refTime=minutes(masterTime-masterDate); + records=37; + for i = 1 : records + fprintf(fileID,'%d. 0. 0. %2.2f\n',refTime,temperature(i)); + + refTime = refTime + 60;% 1 hour time steps for temperature + end + + fclose(fileID); + + %% NCOM ESTOFS + % Currents from NCOM + + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [1081,i]; + % crIDX(idxCount,:) = [2161,i]; + + idxCount = idxCount + 1; + end + + crBoundCount(1) = 0; + crBoundCount(2) = idxCount -1; + + for i = 750:11:1080 % Every 5 km + % for i = round(linspace(1488,2161,14)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1320]; + % crIDX(idxCount,:) = [i,2641]; + + idxCount = idxCount + 1; + end + crBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + % for i = round(linspace(910,2161,26)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1]; + % crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + crBoundCount(4) = idxCount -1; + + + clear idxCount + + %% Interpolate Water Level + % for tStep = 1:length(tideOutN) + % wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); + % wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); + % wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); + % end + + vDatOrder = [crBoundCount(3)+1:1:crBoundCount(4) ... + crBoundCount(1)+1:1:crBoundCount(2) ... + crBoundCount(3):-1:crBoundCount(2)+1]; + + crBoundCountOld = [0 27 34 46]; + vDatOrderOld = [crBoundCountOld(3)+1:1:crBoundCountOld(4) ... + crBoundCountOld(1)+1:1:crBoundCountOld(2) ... + crBoundCountOld(3):-1:crBoundCountOld(2)+1]; + + vDatNavD = LMSL_RT(:,3); + vDatNavD(vDatNavD==-999999)=nan; + + % interp1(vDatNavD(vDatOrder),1:46) + vDatNavDInter(vDatOrder) = naninterp(interp1(... + linspace(1,length(vDatOrder),length(vDatOrderOld)),... + vDatNavD(vDatOrderOld),1:length(vDatOrder))); + for i = 1:length(idxNCOM) + wlO(:,i) = interp1(masterTime:hours(1):masterTime+hours(36),waterLevels(:,i)+0,masterTime:minutes(10):masterTime+hours(36),'pchip'); + end + + %% Match to grid + flowBed = load('Dec6_100Bed.mat'); + clear wlN mag DM dirGrid currents RN_1 currents_2 currents_40 currDir currDir40 + idxCount=1; + for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+vDatNavDInter(i); + mag(:,idxCount) = vecmag(currX,currY); + + % if idxCount==1 + % DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount+1,1)-1,crIDX(idxCount+1,2))); + % else + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + % end + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + % currents(:,idxCount) = sind(dirGrid(i)-0)'.*vecmag(currY); + + RN_1(:,idxCount) = -currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + + % disp(idxCount) + idxCount = idxCount + 1; + + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + %% interpolate Currents + clear currentsOut + for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(NCOM.time)); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(masterTime:minutes(10):masterTime+hours(36))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + % for j = 1:length(idxNCOM) + % currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + % interp2(xIN,yIN,... + % squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1))),... + % xOut,yOut); + % end + + end + idxCount=1; + + + for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + if i<230 + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); +% RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 1.*sqrt(9.81./DM(idxCount)); + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 0.*sqrt(9.81./DM(idxCount)); + end + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = -1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + end + + + + idxCount = idxCount+1; + end + + %% R Boundry Files + records=size(RNOut_2,1); + + for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; + end + + % boundryTypes(1) = {'water elevation (z)'}; + boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; + boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + + fileID=fopen('NCOM_R2.bct','w'); + + for Boundry = [2:length(boundryNames)] + refTime=minutes(masterTime-masterDate); + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + for line = 1:records + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_2(line,Boundry-1),RNOut_2(line,Boundry)); + + refTime=refTime+10; + end + end + + fclose(fileID); + %% Boundry definition file-R + fileID=fopen('NCOM_R.bnd','w'); + crIDX2=crIDX; + crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+2; + crIDX2(crBoundCount(1)+1:crBoundCount(2),1) = 1082; + + for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end + end + fclose(fileID); + + + %% Waves + records = size(waves,1); + fileID=fopen('WW3.bcw','w'); + + for i = 1:3 + boundryNames(i) = {['East' num2str(i)]}; + end + + for Boundry = 1:3 + refTime=minutes(masterTime-masterDate); + + header=[... + 'location ''East%d''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterTime,'yyyymmdd'))); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''WaveHeight '' unit ''[m]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Period '' unit ''[s]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Direction '' unit ''[N^o]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''DirSpreading '' unit ''[-]''\n'); + end + + for line = 1:records + fprintf(fileID,'%d ',refTime); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,1)); %Hs + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,2)); %Period + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,3)); %Direction + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',4); %Spread + end + fprintf(fileID,'\n'); + + % fprintf(fileID,'%.2f %1.4f %1.4f %1.4f %1.4f\n',refTime,... + % waves(line,Boundry,1),waves(line,Boundry,2),waves(line,Boundry,3),4); + refTime=refTime+180; + end + end + + fclose(fileID); + + + %% Modify MDF file to change reference date + + fileID = fopen('rt_base.mdf'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdf', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 15 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'Itdate = #%04d-%02d-%02d#\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 17 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID,['Tstart = %#.7e \n','Tstop = %#.7e \n'],refTime,refTime+2160); + + + + for i = 20:29 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + if FIRST_RUN == 0 + restID = ['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000']; + if exist(restID)==2 + eval(['movefile ' restID ' tri-rst.6h_restart']) + end + + fprintf( fileID,['Commnt = initial conditions from restart file\n'... + 'Restid = #6h_restart#\n']); + % delete tri-rst.rt* + else + + % fprintf( fileID,['Commnt = initial conditions from map file\n'... + % 'Restid = #Jan16_06#\n']); + + % fprintf( fileID,'Zeta0 = %#.7e \n',nanmean(nanmean(squeeze(wlO(1,:))))); + fprintf( fileID,'Zeta0 = %#.7e \n',0); + + end + + for i = 31:53 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % if FIRST_RUN==1 + % fprintf( fileID, 'Vicouv = 1.0000000e+002 \n'); + % else + fprintf( fileID, '%s\n', cac{1}{54} ); + % end + + for i = 55:64 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + if FIRST_RUN==1 + fprintf( fileID, 'Tlfsmo = 0.0000000e+001 \n'); + else + fprintf( fileID, 'Tlfsmo = 0.0000000e+000 \n'); + end + + for i = 66:94 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + + fprintf( fileID,[... + 'Flmap = %#.7e 60 %#.7e\n',... + 'Flhis = %#.7e 10 %#.7e\n',... + 'Flpp = %#.7e 60 %#.7e\n'],... + refTime,refTime+2160,refTime,refTime+2160,refTime,refTime+2160); + + for i = 98:109 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + clear cac + %% Modify MDW file to add times and change reference date + + fileID = fopen('rt_base.mdw'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdw', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 7 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'ReferenceDate = %04d-%02d-%02d\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 9 : 71 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % for i = 1 : records + % fprintf( fileID,'[TimePoint] \n Time = %#.7e \n',(i-1).*180); + % end + + bounOri{1}='East'; + bounOri{2}='North'; + bounOri{3}='South'; + bounRot{1}='counter-clockwise'; + bounRot{2}='counter-clockwise'; + bounRot{3}='clockwise'; + bounDef{1}='grid-coordinates'; + bounDef{2}='orientation'; + bounDef{3}='orientation'; + + + for Boundry = 1 : 3 + + if Boundry ==1 + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'StartCoordM = %d\n'... + 'EndCoordM = %d\n'... + 'StartCoordN = %d\n'... + 'EndCoordN = %d\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + ],Boundry,bounDef{Boundry},432,432,2,528); + else + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'Orientation = %s\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + 'DistanceDir = %s\n'... + ],Boundry,bounDef{Boundry},bounOri{Boundry},bounRot{Boundry}); + end + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'CondSpecAtDist = %d\n',waveDistAlong(Segment)) + end + end + + clear cac + fclose( fileID ); + + + %% Met Files + % Create new UTM grid of the HRRR Data + [UTM1D(:,1),UTM1D(:,2)] = wgs2utm(reshape(windGridLAT,1,[]),reshape(windGridLON,1,[]),... + 18,'N'); + HRRR_UTM(:,:,1) = double(reshape(UTM1D(:,1),size(windGridLON,1),size(windGridLON,2))); + HRRR_UTM(:,:,2) = double(reshape(UTM1D(:,2),size(windGridLON,1),size(windGridLON,2))); + clear UTM1D + + G7LR = load('C7_1400_V2_C.mat'); + G7bath = load('C7_1400_V2_D.mat'); + % Remove land rainfall + % if FIRST_RUN == 1 + landmask=zeros(size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % [HR_deg(:,1),HR_deg(:,2)] = utm2deg(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[]),reshape(G7LR.data.Y(1:end-1,1:end-1)',1,[]),repmat('18 S',length(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[])),1)); + % for ShoreLevel = 1:length(shoreline) + % landmask_Temp(:,:) = reshape(inpolygon(HR_deg(:,1),HR_deg(:,2),shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon),size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % + % landmask = landmask|landmask_Temp; + % clear landmask_Temp + % + % [shoreTempX,shoreTempY,shoreTempCell] = deg2utm(shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon); + % shoreUTM{ShoreLevel}(:,1) = shoreTempX(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % shoreUTM{ShoreLevel}(:,2) = shoreTempY(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % clear shoreTempX shoreTempY shoreTempCell + % disp(ShoreLevel) + % end + % save('shorelineInfo.mat','landmask','shoreUTM'); + % else + % load('shorelineInfo.mat'); + % end + clear HR_deg ShoreLevel + landmask(G7bath.data.Val'<0)=1; + landmask=logical(landmask); + + if masterTime>=datetime(2019,09,05,00,00,00) + runSteps = 37; + else + runSteps = 8; + end + + % Zero out met array + HRRR_INTER = zeros(4,runSteps,size(G7LR.data.X(1:end-1,1:end-1),2),size(G7LR.data.X(1:end-1,1:end-1),1)); + + % Interpolate against flowGrid for each time step + for TS = 1:runSteps + HRRR_INTER(1,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windU(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + HRRR_INTER(2,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windV(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + rainTemp = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(rain(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + rainTemp(landmask)=rainTemp(landmask)*0; % 100% infiltration + HRRR_INTER(3,TS,:,:) = rainTemp; % Convert to hours + clear rainTemp + + HRRR_INTER(4,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(pressure(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + end + + % Set nan to Delft3D zero value + HRRR_INTER(isnan(HRRR_INTER)==1)=-999.000; + + % Create input files + m = size(HRRR_INTER,3); + n = size(HRRR_INTER,4); + d3ddx = 5000; + d3ddy = 5000; + disp(m) + d3d_input_uvpFieldsCL_FUN(masterTime,m,n,... + squeeze(HRRR_INTER(4,:,:,:)),squeeze(HRRR_INTER(1,:,:,:)),squeeze(HRRR_INTER(2,:,:,:)),squeeze(HRRR_INTER(3,:,:,:)),1,'hrrr',runSteps) + + save(['ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat'],'-v7.3','windU','windV','pressure','rain','temperature','waves','waterLevels','NCOM') + + %% Run Delft3D FLOW/WAVE! + % system('. /home/cluster/D7545/enviorment.sh' + + system('runcoast_flow2d3d_parallel_wave.bat') + if exist('wavm-rt_run.dat')~=2 + fid = fopen('errorFile.log','a+'); + fprintf(fid,'Delft Batch File Fallback\n'); + + % close file + fclose(fid) + disp('Run Fallback') + pause(60) + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + delete swn-diag.* + + system('runcoast_flow2d3d_parallel_wave.bat') + end + + %% Move things + pause(60) + + % eval(['copyfile trim-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.dat']) + % eval(['movefile trim-rt_run.dat D:\Alexander\RealtimeHRRR\' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.dat']) + eval(['copyfile trim-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.dat']) + + % eval(['copyfile trim-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.def']) + % eval(['movefile trim-rt_run.def D:\Alexander\RealtimeHRRR\' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.def']) + eval(['copyfile trim-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.def']) + + % eval(['copyfile wavm-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.dat']) + % eval(['movefile wavm-rt_run.dat D:\Alexander\RealtimeHRRR\' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.dat']) + eval(['copyfile wavm-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.dat']) + % eval(['copyfile wavm-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.def']) + % eval(['movefile wavm-rt_run.def D:\Alexander\RealtimeHRRR\' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.def']) + eval(['copyfile wavm-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.def']) + + % eval(['copyfile trih-rt_run.dat trih-rt_run.dat']) + eval(['copyfile trih-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.dat']) + + % eval(['copyfile trih-rt_run.def trih-rt_run.def']) + eval(['copyfile trih-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.def']) + + + eval(['copyfile hrrr.amu D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amu']) + + eval(['copyfile hrrr.amv D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amv']) + + eval(['copyfile hrrr.ampr D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.ampr']) + + eval(['copyfile hrrr.amp D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amp']) + + eval(['movefile ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat D:\DUNEX_RT\Archive\ModelIn_7' datestr(masterTime,'YYYY-mm-DD_HH') '.mat']) + % eval(['copyfile tri-rst.rt* D:\Alexander\RealtimeHRRR\']) + + + + + + %% Clear things not needed for plotting + clear HRRR_INTER flowGrid lonHRRR_Mesh windU windV rain pressure waveGrid + + + delete(gcp('nocreate')) + parpool(3); + %% Import Model Results + addpath(genpath('matlab/applications/delft3d_matlab'),'-begin') + + modelWater = qpread(qpfopen('trim-rt_run.dat'),1,'water level','griddata',0,0,0); + flowGrid = load('Cone7W_100.mat'); + waveGrid = load('Cone7W_250.mat'); + flowBed = load('Dec6_100Bed.mat'); + waveBed = load('Dec6_250Bed.mat'); + + %% Create GeoTIFF for water levels + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize + + timeIDX = [1 4 7 13 25 37]; + + yMinOffset = 75; + yMaxOffset = 25; + + parfor Time = 1:6 + % X{Time} = modelWater.X; + % Y{Time} = modelWater.Y; + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + + modelPlot_1 = squeeze(modelWater.Val(timeIDX(Time),1:end-1,1:end-1)); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['WL_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWater + + modelWaterDAV = qpread(qpfopen('trim-rt_run.dat'),1,'depth averaged velocity','griddata',0,0,0); + + %% Create GeoTIFF for DAVs + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoDat modelPlot_1 + + timeIDX = [1 4 7 13 25 37]; + if FIRST_RUN == 1 + Times = 2:6; + else + Times = 1:6; + end + + + for Time = Times + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + modelPlot_1 = sqrt(squeeze(modelWaterDAV.XComp(timeIDX(Time),1:end-1,1:end-1)).^2+... + squeeze(modelWaterDAV.YComp(timeIDX(Time),1:end-1,1:end-1)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['DAV_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + %% Quiver for DAV + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + vecScale(4) = 100000; + vecScale(3) = 50000; + vecScale(2) = 2500; + vecScale(1) = 1000; + + for Time = Times + + X{Time} = flowGrid.data.X(2:end,2:end); + Y{Time} = flowGrid.data.Y(2:end,2:end); + modelPlot_1 = squeeze(modelWaterDAV.XComp(timeIDX(Time),2:end,2:end)); + modelPlot_2 = squeeze(modelWaterDAV.YComp(timeIDX(Time),2:end,2:end)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(400:520,525:620)=nan; + + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + modelPlot_2(:,1:yMinOffset)=nan; + modelPlot_2(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + qSpace = [4 16 50 100] + + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + for i = 1:length(Xdat{Time}) + if ((Udat{Time}(i))==0 && (Vdat{Time}(i))==0) ||... + (isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1) ||... + ((isnan(Udat{Time}(i)))==1 && isnan(Vdat{Time}(i))==1) + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + + Xdat{Time}=[]; + Ydat{Time}=[]; + Udat{Time}=[]; + Vdat{Time}=[]; + q{Time}=[]; + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['DAV_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj DAV_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaterDAV + + %% Create GeoTIFF for HS + + modelWaves = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave height','griddata',0,0,0); + modelWavesDir = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave vector (mean direction)','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize GeoS + + timeIDX = [1 4 7 13 25 37]; + + parfor Time = 1:6 + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = (squeeze(modelWaves.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):250:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):250:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):250:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):250:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-0,1:end-0),1,[]),... + reshape(Y{Time}(1:end-0,1:end-0),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['HS_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for HS + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + vecScale(4) = 15000; + vecScale(3) = 5000; + vecScale(2) = 1000; + vecScale(1) = 500; + + for Time = 1:6 + + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = squeeze(modelWavesDir.XComp(timeIDX(Time),:,:)); + modelPlot_2 = squeeze(modelWavesDir.YComp(timeIDX(Time),:,:)); + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(155:205,210:265)=nan; + + + qSpace = [2 10 20 40] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + elseif isnan(Udat{Time}(i))==1 && isnan(Vdat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['HS_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj HS_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaves + clear modelWavesDIR + + %% Create GeoTIFF for Wind + modelWaterWind = qpread(qpfopen('trim-rt_run.dat'),1,'wind speed','griddata',0,0,0); + + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS ValX ValY + + timeIDX = [1 4 7 13 25 37]; + + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = sqrt(squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)).^2+... + squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):1000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):1000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):1000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):1000:R{Time}.YWorldLimits(2)); + + Val{Time}(Val{Time}==0)=nan; + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['Uw_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for Wind + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + + vecScale(4) = 3000; + vecScale(3) = 500; + vecScale(2) = 100; + vecScale(1) = 40; + + for Time = 1:6 + + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + ValX{Time} = squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)); + ValY{Time} = squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)); + + + qSpace = [5 25 50 100] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),Y{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),... + squeeze(ValX{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),squeeze(ValY{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['Uw_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj Uw_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaterWind + + %% Create GeoTIFF for Prep + + modelWaterPrep = qpread(qpfopen('trim-rt_run.dat'),1,'precipitation rate','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS + + timeIDX = [1 4 7 13 25 37]; + + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = (squeeze(modelWaterPrep.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):10000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):10000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):10000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):10000:R{Time}.YWorldLimits(2)); + + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geotiffwrite(['Prep_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWaterPrep + + %% Export to GEOSERVER + copyfile *.tif \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.dbf \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shx \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shp \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.prj \\geoserver.engineering.queensu.ca\TIFFS\ + + + %% Import Model forecast + modelWaterHist = qpread(qpfopen('trih-rt_run.dat'),1,'water level','data',0,0); + modelCurHist = qpread(qpfopen('trih-rt_run.dat'),1,'depth averaged velocity','data',0,0); + + %% Validation import ESTOFS + load('DUNEX_Nov20.mat') + clear ESTOFS lonESTOFS lonESTOFS + + wLIDX=[6 7 8 38]; + wlGrid = [5000 -4000 0 -2000]; + wlGridY = [0 0 2000 5000]; %7500 + ESTOFStimeOffset = [0 12 24 36]; + ESTOFSrunLength = [36 48 60 72]; + + for e = [1 4] + try + clear meshX meshY + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(0,'%03d') '.grib']); + + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTOFS_Val{e} = 1; + catch + ESTOFS_Val{e} = 0; + end + end + clear waterLevelsESTOFSINTER waterLevelsESTOFS + for e = [1 4] + for Stat = 1:4 + if ESTOFS_Val{e} == 0 + estofsWL(:,Stat,e) = zeros(37,1); + else + [wlDeg(2),wlDeg(1)] = utm2deg(pointsCS{wLIDX(Stat),2}+wlGrid(Stat),pointsCS{wLIDX(Stat),3}+wlGridY(Stat),'18 S'); + [estofIDX] = NearestValue(wlDeg,lonESTOFS,latESTOFS); %Lat + + for i = 1:ESTOFSrunLength(e)+1 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(i-1,'%03d') '.grib']); + + waterLevelsESTOFS{e}(i,Stat) = squeeze(ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,estofIDX(1),estofIDX(2))); + end + waterLevelsESTOFSINTER{e}(:,Stat) = interp1(masterTime-hours(ESTOFStimeOffset(e)):minutes(60):masterTime+hours(36),... + waterLevelsESTOFS{e}(:,Stat),masterTime-hours(ESTOFStimeOffset(e)):minutes(10):masterTime+hours(36),'spline'); + end + end + end + + + %% Validation import WL + % Duck + % Oregon Inlet + % Hatteras + % Beaufort + clear stations statWL + options = weboptions; + options.Timeout = 30; + + stations = {8651370,8652587,8654467,8656483}; + dateStartM = masterTime-hours(36); + dateEndM = masterTime+hours(5); + + for Stat = 1:4 + try + url = ['https://tidesandcurrents.noaa.gov/api/datagetter?product=water_level&application=NOS.COOPS.TAC.WL&'... + 'begin_date=' datestr(dateStartM,'yyyymmdd') '&end_date=' datestr(dateEndM,'yyyymmdd') '&datum=NAVD' '&station=' num2str(stations{Stat})... + '&time_zone=GMT&units=metric&format=csv']; + + wlIN = webread(url,options); + + statWL(:,Stat) = interp1(wlIN.DateTime,wlIN.WaterLevel,dateStartM:minutes(10):dateEndM); + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statWL(:,Stat) = 0; + end + + + clear wlIN + + end + %% Validation import Currents + % Duck + clear statCur + for Stat = 1 + % url = 'https://chlthredds.erdc.dren.mil/thredds/dodsC/frf/oceanography/currents/awac-11m/awac-11m.ncml'; + % curTime = ncread(url,'time'); + % curVal = ncread(url,'currentSpeed'); + try + if day(masterTime)<2 + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime-day(3),'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime-days(3),'YYYYmm') '.nc'],options); + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + curTime = vertcat(curTime,ncread('statCNC.nc','time')); + curVal = vertcat(curVal,ncread('statCNC.nc','currentSpeed')); + + else + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + end + + statCur(:) = interp1(datetime(curTime,'convertFrom','POSIX'),curVal,dateStartM:minutes(10):dateEndM); + clear wlIN + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statCur(:) = zeros(length(dateStartM:minutes(10):dateEndM),1); + end + end + + %% Validation import Waves + % Virginia Beach + % Duck 26 + % Nages Head + % Oregon Inlet + % Diamond Shoals + clear stations + + stations = {44014,44100,44086,44095,41025}; + dateStartM = masterTime-hours(36); + dateEndM = masterTime+hours(5); + + clear statWave + + for Stat = 1:5 + try + if ismember(Stat,[1,5]) == 1 + url = ['https://www.ndbc.noaa.gov/data/5day2/' num2str(stations{Stat}) '_5day.txt']; + + websave('NDBCdata.txt',url,options); + opts = delimitedTextImportOptions("NumVariables", 39); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, 15, "TrimNonNumeric", true); + opts = setvaropts(opts, 15, "ThousandsSeparator", ","); + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + else + url = ['https://www.ndbc.noaa.gov/data/realtime2/' num2str(stations{Stat}) '.txt']; + websave('NDBCdata.txt',url); + + opts = delimitedTextImportOptions("NumVariables", 52); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39", "Var40", "Var41", "Var42", "Var43", "Var44", "Var45", "Var46", "Var47", "Var48", "Var49", "Var50", "Var51", "Var52"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "categorical", "categorical", "categorical", "double", "double", "double", "double", "categorical", "categorical", "double", "double", "categorical", "categorical", "categorical", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "TrimNonNumeric", true); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "ThousandsSeparator", ","); + opts = setvaropts(opts, [6, 7, 8, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + end + + % Import the data + waveIN = readtable("NDBCdata.txt", opts); + waveNAN = isnan(waveIN.WVHT)==0; + % Hs + statWave(:,1,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.WVHT(waveNAN)),dateStartM:minutes(10):dateEndM); + % DPD + % statWave(:,2,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + % (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + % (waveIN.DPD(waveNAN)),dateStartM:minutes(10):dateEndM); + % APD + statWave(:,3,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.APD(waveNAN)),dateStartM:minutes(10):dateEndM); + %MWD + statWave(:,4,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.MWD(waveNAN)),dateStartM:minutes(10):dateEndM); + clear waveIN opts + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + %fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + %sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]); + + % close file + fclose(fid) + statWave(:,:,Stat) = zeros(size(dateStartM:minutes(10):dateEndM,2),4,1); + end + end + statWave(isnan(statWave))=0; + %% Import Model Waves + + for i = 1:37 + startRow = 8; + formatSpec = '%13f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%f%[^\n\r]'; + + fileID = fopen(['Dec28.loct00000' num2str(i,'%02d') '.tab'],'r'); + + % This call is based on the structure of the file used to generate this + % code. If an error occurs for a different file, try regenerating the code + % from the Import Tool. + dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines' ,startRow-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + + fclose(fileID); + modelWaveIN= table(dataArray{1:end-1}, 'VariableNames', {'Xp','Yp','Depth','Hsig','Dir','RTpea','kTm01','Dspr','Ubot','XWindv','YWindv','XVel','YVel'}); + + modelWave(:,1,i) = modelWaveIN.Hsig; + modelWave(:,3,i) = modelWaveIN.RTpea; + modelWave(:,4,i) = modelWaveIN.Dir; + + + clearvars filename startRow formatSpec fileID dataArray ans modelWaveIN; + + end + + %% Import Model WL + modelWL = modelWaterHist.Val; + modelCur = sqrt(modelCurHist.XComp.^2+modelCurHist.YComp.^2); + save(['ModelOut_' datestr(masterTime,'dd-mmm-yyyy_HH') 'Z.mat'],'modelWL','modelWave','statWL','statWave','modelCur','statCur'); + + %% Import Historic Model WL + try + H12 = load(['ModelOut_' datestr(masterTime-hours(12),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H24 = load(['ModelOut_' datestr(masterTime-hours(24),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H36 = load(['ModelOut_' datestr(masterTime-hours(36),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + + %% Save html for Currents + googleDates = days(masterTime-hours(36)+minutes((0:432)*10)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + locLine = 1:5:67; + locationsWave ={'FRF 11 m AWAC '}; + +% % for i = 1:433 +% % for j = 1:100 +% % modelDavDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,2],modelDavDel) + + davIDX=[17 161:172]; + + clear modelCurPlot curValLoc + for Loc = 1:13 + for Line=1:5 + switch Line + case 1 + curValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelCurPlot(1:433,locLine(Loc)+0) = num2cell(zeros(433,1)); + continue + end + modelCurPlot(1:216,locLine(Loc)+0) = {''}; + modelCurPlot(217:1:433,locLine(Loc)+0) = num2cell(modelCur(:,davIDX(Loc))); + case 2 + curValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelCurPlot(1:433,locLine(Loc)+1) = num2cell(zeros(433,1)); + continue + end + modelCurPlot(1:144,locLine(Loc)+1) = {''}; + modelCurPlot(362:433,locLine(Loc)+1) = {''}; + modelCurPlot(145:1:361,locLine(Loc)+1) = num2cell(H12.modelCur(:,davIDX(Loc))); + + case 3 + curValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelCurPlot(1:433,locLine(Loc)+2) = num2cell(zeros(433,1)); + continue + end + modelCurPlot(1:72,locLine(Loc)+2) = {''}; + modelCurPlot(290:433,locLine(Loc)+2) = {''}; + modelCurPlot(73:1:289,locLine(Loc)+2) = num2cell(H24.modelCur(:,davIDX(Loc))); + + case 4 + curValLoc{Line} = ['-36 Hour: ' datestr(masterTime-hours(36),'mm/dd HH') 'Z Run']; + if exist('H36','var') ==0 + modelCurPlot(1:433,locLine(Loc)+3) = num2cell(zeros(433,1)); + continue + end + modelCurPlot(218:433,locLine(Loc)+3) = {''}; + modelCurPlot(1:1:217,locLine(Loc)+3) = num2cell(H36.modelCur(:,davIDX(Loc))); + case 5 + curValLoc{Line} = ['Observed Velocity']; + if Loc> 1 || isnan(statCur(1,Loc)) + modelCurPlot(1:433,locLine(Loc)+4) = num2cell(zeros(433,1)); + continue + end + modelCurPlot(248:433,locLine(Loc)+4) = {''}; + modelCurPlot(1:247,locLine(Loc)+4) = num2cell(statCur); + + end + + end + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],modelCurPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],curValLoc) + curValLoc = repmat(curValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... + [1,1],horzcat(googleDatesCell',vertcat(curValLoc(1:size(modelCurPlot,2)),modelCurPlot))) + %% Save html for WL + googleDates = days(masterTime-hours(36)+minutes((0:432)*10)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% locLine = [2 7 12 17 22 27]; +% locLine = [2 9 16 23 30 37]; + locLine = 1:7:114; + + locationsWl ={'FRF Pier',... + 'Oregon Inlet',... + 'Hatteras',... + 'Beaufort'}; + +% % for i = 1:433 +% % for j = 1:121 +% % modelWlDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,2],modelWlDel) + + wLIDX=[6 7 8 38 161:172]; + clear modelWlPlot wlValLoc + for Loc = 1:length(wLIDX) +% modelwlPlot = cell(432,4); + for Line=[1:5 6 9] + switch Line + case 1 + wlValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelwlPlot(1:433,locLine(Loc)+0) = num2cell(zeros(433,1)); + continue + end + modelwlPlot(1:216,locLine(Loc)+0) = {''}; + modelwlPlot(217:1:433,locLine(Loc)+0) = num2cell(modelWL(:,wLIDX(Loc))); + case 2 + wlValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelwlPlot(1:433,locLine(Loc)+1) = num2cell(zeros(433,1)); + continue + end + modelwlPlot(1:144,locLine(Loc)+1) = {''}; + modelwlPlot(362:433,locLine(Loc)+1) = {''}; + modelwlPlot(145:1:361,locLine(Loc)+1) = num2cell(H12.modelWL(:,wLIDX(Loc))); + + case 3 + wlValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelwlPlot(1:433,locLine(Loc)+2) = num2cell(zeros(433,1)); + continue + end + modelwlPlot(1:72,locLine(Loc)+2) = {''}; + modelwlPlot(284:433,locLine(Loc)+2) = {''}; + modelwlPlot(73:1:289,locLine(Loc)+2) = num2cell(H24.modelWL(:,wLIDX(Loc))); + + case 4 + wlValLoc{Line} = ['-36 Hour: ' datestr(masterTime-hours(36),'mm/dd HH') 'Z Run']; + if exist('H36','var') ==0 + modelwlPlot(1:433,locLine(Loc)+3) = num2cell(zeros(433,1)); + continue + end + modelwlPlot(218:433,locLine(Loc)+3) = {''}; + modelwlPlot(1:1:217,locLine(Loc)+3) = num2cell(H36.modelWL(:,wLIDX(Loc))); + case 5 + wlValLoc{Line} = ['Observed Water Level']; + if Loc>4 || isnan(statWL(1,Loc)) + modelwlPlot(1:433,locLine(Loc)+4) = num2cell(zeros(433,1)); + continue + end + modelwlPlot(248:433,locLine(Loc)+4) = {''}; + modelwlPlot(1:247,locLine(Loc)+4) = num2cell(statWL(:,Loc)); + case 6 + wlValLoc{Line} = ['ESTOFS Forecast']; + if Loc>4 || ESTOFS_Val{1} == 0 + modelwlPlot(1:433,locLine(Loc)+5) = num2cell(zeros(433,1)); + continue + end + modelwlPlot(1:216,locLine(Loc)+5) = {''}; + modelwlPlot(217:1:433,locLine(Loc)+5) = num2cell(waterLevelsESTOFSINTER{1}(:,Loc)); + case 9 + wlValLoc{7} = ['-36 Hour ESTOFS']; + if Loc>4 || ESTOFS_Val{4} == 0 + modelwlPlot(1:433,locLine(Loc)+6) = num2cell(zeros(433,1)); + continue + end + modelwlPlot(1:1:433,locLine(Loc)+6) = num2cell(waterLevelsESTOFSINTER{4}(:,Loc)); + end + end + disp(Loc) + + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [2,locLine(Loc)],modelwlPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [1,locLine(Loc)],wlValLoc) + + wlValLoc = repmat(wlValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... + [1,1],horzcat(googleDatesCell',vertcat(wlValLoc(1:size(modelwlPlot,2)),modelwlPlot))) + + %% Save html for Waves + googleDates = days(masterTime-hours(36)+minutes((0:432)*10)-datetime(1899,12,30,00,00,00)); + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,1],googleDates') + +% locLine = [2 7 12 17 22 27]; + locLine = 1:5:114; + + locationsWave ={'Virginia Beach',... + 'FRF 26 m',... + 'Nags Head',... + 'Oregon Inlet',... + 'Diamond Shoals'}; + + clear waveValLoc modelwavePlot + + for i = 1:432 + for j = 1:85 + modelwavePlot(i,j)={''}; + end + end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,2],modelWaveDel) + + waveIDX = [12 13 14 15 16 161:172]; + for Loc = 1:length(waveIDX) +% modelwavePlot = cell(432,5); + for Line=1:5 + switch Line + case 1 + waveValLoc{Line} = ['Forecast']; + if exist('modelWave','var') ==0 + modelwavePlot(1:433,locLine(Loc)+0) = num2cell(zeros(433,1)); + continue + end + modelwavePlot(1:216,locLine(Loc)+0) = {''}; + modelwavePlot(216,locLine(Loc)+0) = {0}; + modelwavePlot(217:6:433,locLine(Loc)+0) = num2cell(modelWave(waveIDX(Loc),1,:)); + case 2 + waveValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 || size(H12.modelWave,1)5 || isnan(statWave(1,1,Loc)) + modelwavePlot(1:433,locLine(Loc)+4) = num2cell(zeros(433,1)); + continue + end + modelwavePlot(248:433,locLine(Loc)+4) = {''}; + modelwavePlot(248,locLine(Loc)+4) = {0}; + modelwavePlot(1:247,locLine(Loc)+4) = num2cell(statWave(:,1,Loc)); + + end + + end +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [2,locLine(Loc)],modelwavePlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [1,locLine(Loc)],waveValLoc) + end + + waveValLoc = repmat(waveValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... + [1,1],horzcat(googleDatesCell',vertcat(waveValLoc(1:size(modelwavePlot,2)),modelwavePlot))) + + + + + %% Import and modify times + modelHour = [0 3 6 12 24 36]; + for i = 1:6 + dateText(i) = {[datestr(masterTime+hours(modelHour(i)),'mmm dd, HH:MM') ' UTC (Hour '... + num2str(modelHour(i),'%d') ')']}; + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','0',[1,1],... + dateText) + +catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['ALL-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + +end + +%% +quit + + + + + + + + + + + + + + + + diff --git a/Dunex_Operational_48h.m b/Dunex_Operational_48h.m new file mode 100644 index 0000000..e393eee --- /dev/null +++ b/Dunex_Operational_48h.m @@ -0,0 +1,2333 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +% Moved to COASTLINES Feb 29, 2020 + +clear all +cd D:\DUNEX_RT\Operation +echo off; +addpath('NCtoolbox') +addpath('m_map') +setup_nctoolbox +flowGrid = load('Cone7W_100.mat'); +waveGrid = load('Cone7W_250.mat'); +load('LMSL_RT.mat') +addpath('D:\DUNEX_RT\Operation\abogaard-matlab2gsheets-6d76271') +setenv('PATH', [getenv('PATH') ';D:\DUNEX_RT\Windows_64']); + +%% Details for e-mail server +setpref('Internet','SMTP_Server','smtp.sendgrid.net'); +setpref('Internet','E_mail','mail@alexanderrey.ca'); +setpref('Internet','SMTP_Username','apikey'); +setpref('Internet','SMTP_Password','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'); +props = java.lang.System.getProperties; +props.setProperty('mail.smtp.auth','true'); +props.setProperty('mail.smtp.socketFactory.class', 'javax.net.ssl.SSLSocketFactory'); +props.setProperty('mail.smtp.socketFactory.port','465'); +props.setProperty('mail.smtp.starttls.enable','true'); + + +%% Master Model Time Step +% Every 6 hours + +nistTime = datetime(datevec(now())) - tzoffset(datetime(datevec(now()),'TimeZone','local')); +masterTime = dateshift(nistTime,'start','hour')-hours(2) % Assume script will run at 5 and a half hours after model start +clear nistTime +masterDate = datetime(year(masterTime),month(masterTime),day(masterTime)); + +if exist(['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000'])==2 + FIRST_RUN = 0; +else + FIRST_RUN = 1; +end + +%% Import +try + Import=0; + + + %% Clean files from previous run + system('taskkill /IM "d_hydro.exe" /F') + system('taskkill /IM "wave.exe" /F') + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + + clear HRRR_UTM + while Import==0 + try + %% Import data from NOMADS + %% Extratropical Surge and Tide Operational Forecast System for the Atlantic + % (ESTOFS Atlantic) for water levels + options = weboptions; + options.Timeout = 90; + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(6),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 7; + ESTrun = 6; + catch + % url = ['http://nomads.ncep.noaa.gov/dods/estofs_atl/'... + % datestr(masterTime-days(1),'yyyymmdd')... + % '/estofs_atl_conus_' datestr(masterTime-days(1),'hh') 'z']; + % ESTOFS = ncgeodataset(url); + % lonESTOFS=ESTOFS{'lon'}(:); + % latESTOFS=ESTOFS{'lat'}(:); + % ESTstart = 24+ESTstart; +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-days(1),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-days(1),'yyyymmdd')... + '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 25; + ESTrun = 24; + end + + + clear url + + % Find ESTOFS index for grid points along boundry + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); %Lat + wlIDX(idxCount,:) = [1082,i]; + + idxCount = idxCount + 1; + end + + wlBoundCount(1) = 0; + wlBoundCount(2) = idxCount -1; + + + for i = 750:11:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1322]; + idxCount = idxCount + 1; + end + + wlBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1]; + idxCount = idxCount + 1; + end + wlBoundCount(4) = idxCount -1; + + clear idxCount gridDeg + + % Extract ESTOFS Water Levels for 36 hours at indexes + % waterLevelsGRID = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(ESTstart:ESTstart+36,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + % min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + + % Find ESTOFS values from small grid + idxCount=1; + errorET = 0; + for i = ESTstart:ESTstart+96 + if errorET<10 + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... +% num2str(i,'%03d') '.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... + num2str(i,'%03d') '.grib2']; + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib'],url,options) + + if i<=ESTstart+48 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib']); + + waterLevelsGRID(idxCount,:,:) = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + end + idxCount = idxCount + 1; + catch + errorET = errorET+1; + end + else + error('ESTOFS ERROR') + end + + end + + idxCount=1; + for i = 1:length(idxESTOFS) + waterLevels(:,idxCount) = waterLevelsGRID(:,idxESTOFS(idxCount,1)-min(idxESTOFS(:,1))+1,... + idxESTOFS(idxCount,2)-min(idxESTOFS(:,2))+1); + + idxCount = idxCount + 1; + end + + + % Save ESTOFS Points +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_points.nc'],url,options) + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + disp('Loaded ESTOFS') + %% Multi-grid Wave model (WAVEWATCH III) + % 4 arc minute US East Coast grid for waves + + url = ['https://nomads.ncep.noaa.gov/dods/wave/gfswave/'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/gfswave.atlocn.0p16_' datestr(masterTime-hours(6),'hh') 'z']; + + MWW3 = ncgeodataset(url); + clear url + + lonMWW3=wrapTo180(MWW3{'lon'}(:)); + latMWW3=MWW3{'lat'}(:); + + % Find MWW3 index for grid points along boundry + idxCount=1; + for i = 1:25:length(waveGrid.data.Y)-25 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(end-2,i),waveGrid.data.Y(end-2,i),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(end-2,1:i)).^2+... + diff(waveGrid.data.Y(end-2,1:i)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(end-2,i); + waveUTM(idxCount,2) = waveGrid.data.Y(end-2,i); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + waveBoundCount(1) = 0; + waveBoundCount(2) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:350% Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,end-2),waveGrid.data.Y(i,end-2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,end-2)).^2+... + diff(waveGrid.data.Y(i:end-2,end-2)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,end-2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,end-2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + % 0 132 163 285 + + waveBoundCount(3) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:240 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,2),waveGrid.data.Y(i,2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,1)).^2+... + diff(waveGrid.data.Y(i:end-2,1)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(4) = idxCount -1; + + clear idxCount + + % Extract WW3 Hs for 36 hours at indexes + wavesGRID_Hs = MWW3{'htsgwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid htsgwsfc + %swell_1 + % Period + wavesGRID_P = MWW3{'perpwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... % + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid perpwsfc + %swper_1 + % Direction + wavesGRID_Dir = MWW3{'dirpwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid dirpwsfc + %swdir_1 + % Find WW3 values from small grid + idxCount=1; + for i = 1:length(idxMWW3) + waves(:,idxCount,1) = wavesGRID_Hs(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Hs + + waves(:,idxCount,2) = wavesGRID_P(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Tp + + waves(:,idxCount,3) = wavesGRID_Dir(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Dir + + idxCount = idxCount + 1; + end + clear idxCount + disp('Loaded WW3') + + + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; +% delete(gcp('nocreate')) +% parpool(8); + + for ForcastHour = 0:48 + % url = ['http://nomads.ncep.noaa.gov/pub/data/nccf/com/hrrr/prod/'... + % 'hrrr.' datestr(masterTime,'yyyymmdd')... + % '/conus/hrrr.t' num2str(hour(masterTime),'%02d') 'z.'... + % 'wrfsfcf' num2str(ForcastHour,'%02d') '.grib2']; + + url = ['https://nomads.ncep.noaa.gov/cgi-bin/filter_hrrr_2d.pl?file=hrrr.'... + 't' num2str(hour(masterTime),'%02d') 'z.wrfsfc'... + 'f' num2str(ForcastHour,'%02d') '.grib2&'... + 'lev_10_m_above_ground=on&lev_surface=on&var_APCP=on&var_PRES=on&var_UGRD=on&var_VGRD=on&var_TMP=on&subregion=&leftlon=-78&rightlon=-74&toplat=38&bottomlat=32.5&dir=%2F'... + 'hrrr.' datestr(masterTime,'yyyymmdd') '%2Fconus']; + + websave(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2'],url,options) + + [pCheck,gridParams] = system(['perl "D:\DUNEX_RT\Windows_64\grid_defn.pl" '... + 'D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + [wCheck,gridParams] = system(['wgrib2 D:\DUNEX_RT\Operation\HRRR\hrrrT' ... + num2str(ForcastHour,'%02d') '.grib2 -new_grid_winds earth -new_grid ' ... + gridParams ' D:\DUNEX_RT\Operation\HRRR\hrrrT'... + num2str(ForcastHour,'%02d') '.grib2.regrid']); + end +% delete(gcp('nocreate')) + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(0,'%02d') '.grib2.regrid']); + clear url + + m_proj('lambert conformal conic','ori',[262.5 38.5],'clo',262.5,'par',[38.5 38.5],'ell','sphere');%,'lat',[20 55],'lon',[-60 -130] + [meshX,meshY] = meshgrid(HRRR{'x'}(:),HRRR{'y'}(:)); + [windGridLON,windGridLAT] = m_xy2ll(meshX.*1000,meshY.*1000); + windGridLON=wrapTo180(windGridLON); + clear meshX meshY + + % Extract MWW3 Hs for 48 hours at indexes + for ForcastHour = 0:48 + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2.regrid']); + windU(ForcastHour+1,:,:) = HRRR{'u-component_of_wind_height_above_ground'}(:,:,:); %U Winds @ 10m [m/s] + windV(ForcastHour+1,:,:) = HRRR{'v-component_of_wind_height_above_ground'}(:,:,:); %V Winds @ 10m [m/s] + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + pressure(ForcastHour+1,:,:) = HRRR{'Pressure_surface'}(:,:,:); %Surface Pressure [pa] + + if ForcastHour==0 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_0_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + elseif ForcastHour==1 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_1_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + else + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_Mixed_intervals_Accumulation'}(2,:,:); %Surface precipitation [kg/m^2] + end + temperature(ForcastHour+1) = squeeze(nanmean(nanmean(HRRR{'Temperature_surface'}(:,:,:)- 273.15,2),3)); %Surface Temperature [C] + end + % Extract Temp + + disp('Loaded HRRR') + + + %% IMPORT NCOM + + try + nComDate=masterDate; +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/20201220/coamps_ncom_useast_u_1_2020122000_00000000.nc']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; + +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + mkdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0025-0048.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0073-0096.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0073-0096.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); + % NCOM.Lat = ncom_grib{'lat',[331],[240]}; + % NCOM.Lon = ncom_grib{'lon',91,180}; + catch + try + if hour(masterTime) ~= 18 + nComDate=masterDate-days(1); + else + nComDate=masterDate; + end +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); +% ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\grids\operational\NCOM\regional\GRIB2\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2']; +% ncom_grib = ncgeodataset(ncom_downloadPath); + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0073-0096.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0073-0096.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); +% NCOM.Lat = ncom_grib{'lat',[331],[240]}; +% NCOM.Lon = ncom_grib{'lon',91,180}; + + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + end + + if FIRST_RUN == 1 + NCOM.depth = ncread('D:\Alexander\NCOM\2019090500_t000.nc','depth'); + end + + Noffset = hours(masterTime - nComDate); + tStep = Noffset; + tCount = 1; + + try + for Ni = masterTime:hours(3):masterTime+hours(48) + noData=1; + while noData==1 + try +% NCOMstep = tStep./3+1; + NCOMstep = 1; + +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(masterDate,'YYYYmmDD')],... +% 'water_u',[NCOMstep 1 331 91],[1 40 240 180],[1 1 1 1]); +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_u',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.water_v(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_v',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.surf_el(:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'surf_el',[91 331 NCOMstep],[180 240 1],[1 1 1]); +% NCOM.salinity(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'salinity',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); + NCOM.water_u(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_u',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.water_v(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_v',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.surf_el(:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'surf_el',[91 331 1],[180 240 1],[1 1 1]); + NCOM.salinity(:,:,:,tCount) =ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'salinity',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + + if (squeeze(NCOM.water_v(100,100,1,end))==0|squeeze(NCOM.water_u(100,100,1,end))==0|squeeze(NCOM.surf_el(100,100,end))==0|squeeze(NCOM.salinity(100,100,1,end))==0)==1 + noData=1; + else + noData=0; + end + catch + noData=1; + end + disp(Ni) + end + NCOM.time(tCount) = Ni; + tStep=tStep+3; + tCount = tCount+1; + end + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + + + + %% NCOM Process + NCOM.mag = vecmag(NCOM.water_u,NCOM.water_v); + + if FIRST_RUN == 1 + depthWeight = [diff(NCOM.depth)' 0]; + + for Layer = 1:40 + DAVfac(:,:,Layer,:) = ones(180,240,1,17).*depthWeight(Layer); + end + DAVtrue = DAVfac; + N_depth = NCOM.depth; + save('NCOMstuff.mat','DAVtrue','DAVfac','N_depth') + else + load('NCOMstuff.mat') + NCOM.depth = N_depth; + clear N_depth; + end + DAVtrue(isnan(NCOM.mag(:,:,1:40,:))==1) = 0; + DAVfac(isnan(NCOM.mag(:,:,1:40,:))==1) = nan; + DAVFac2 = sum(DAVtrue,3); + clear DAVtrue + NCOM.dav = nansum(DAVfac.*NCOM.mag(:,:,1:40,:),3)./DAVFac2; + NCOM.davX = nansum(DAVfac.*NCOM.water_u(:,:,1:40,:),3)./DAVFac2; + NCOM.davY = nansum(DAVfac.*NCOM.water_v(:,:,1:40,:),3)./DAVFac2; + + Import=1 + catch err + + clear waterLevels + + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + disp('FAILED TO IMPORT FROM NOMADS') + pause(600) + end + end + + + load('shoreline.mat'); + + %% Format data for Delft3D + %% Evap + fileID=fopen('TemperatureRT.eva','w'); + refTime=minutes(masterTime-masterDate); + records=49; + for i = 1 : records + fprintf(fileID,'%d. 0. 0. %2.2f\n',refTime,temperature(i)); + + refTime = refTime + 60;% 1 hour time steps for temperature + end + + fclose(fileID); + + %% NCOM ESTOFS + % Currents from NCOM + + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [1081,i]; + % crIDX(idxCount,:) = [2161,i]; + + idxCount = idxCount + 1; + end + + crBoundCount(1) = 0; + crBoundCount(2) = idxCount -1; + + for i = 750:11:1080 % Every 5 km + % for i = round(linspace(1488,2161,14)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1320]; + % crIDX(idxCount,:) = [i,2641]; + + idxCount = idxCount + 1; + end + crBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + % for i = round(linspace(910,2161,26)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1]; + % crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + crBoundCount(4) = idxCount -1; + + + clear idxCount + + %% Interpolate Water Level + % for tStep = 1:length(tideOutN) + % wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); + % wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); + % wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); + % end + + vDatOrder = [crBoundCount(3)+1:1:crBoundCount(4) ... + crBoundCount(1)+1:1:crBoundCount(2) ... + crBoundCount(3):-1:crBoundCount(2)+1]; + + crBoundCountOld = [0 27 34 46]; + vDatOrderOld = [crBoundCountOld(3)+1:1:crBoundCountOld(4) ... + crBoundCountOld(1)+1:1:crBoundCountOld(2) ... + crBoundCountOld(3):-1:crBoundCountOld(2)+1]; + + vDatNavD = LMSL_RT(:,3); + vDatNavD(vDatNavD==-999999)=nan; + + % interp1(vDatNavD(vDatOrder),1:46) + vDatNavDInter(vDatOrder) = naninterp(interp1(... + linspace(1,length(vDatOrder),length(vDatOrderOld)),... + vDatNavD(vDatOrderOld),1:length(vDatOrder))); + for i = 1:length(idxNCOM) + wlO(:,i) = interp1(masterTime:hours(1):masterTime+hours(48),waterLevels(:,i)+0,masterTime:minutes(10):masterTime+hours(48),'pchip'); + end + + %% Match to grid + flowBed = load('Dec6_100Bed.mat'); + clear wlN mag DM dirGrid currents RN_1 currents_2 currents_40 currDir currDir40 + idxCount=1; + for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+vDatNavDInter(i); + mag(:,idxCount) = vecmag(currX,currY); + + % if idxCount==1 + % DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount+1,1)-1,crIDX(idxCount+1,2))); + % else + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + % end + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + % currents(:,idxCount) = sind(dirGrid(i)-0)'.*vecmag(currY); + + RN_1(:,idxCount) = -currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + + % disp(idxCount) + idxCount = idxCount + 1; + + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + %% interpolate Currents + clear currentsOut + for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(NCOM.time)); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(masterTime:minutes(10):masterTime+hours(48))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + % for j = 1:length(idxNCOM) + % currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + % interp2(xIN,yIN,... + % squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1))),... + % xOut,yOut); + % end + + end + idxCount=1; + + + for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + if i<230 + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); +% RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 1.*sqrt(9.81./DM(idxCount)); + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 0.*sqrt(9.81./DM(idxCount)); + end + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = -1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + end + + + + idxCount = idxCount+1; + end + + %% R Boundry Files + records=size(RNOut_2,1); + + for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; + end + + % boundryTypes(1) = {'water elevation (z)'}; + boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; + boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + + fileID=fopen('NCOM_R2.bct','w'); + + for Boundry = [2:length(boundryNames)] + refTime=minutes(masterTime-masterDate); + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + for line = 1:records + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_2(line,Boundry-1),RNOut_2(line,Boundry)); + + refTime=refTime+10; + end + end + + fclose(fileID); + %% Boundry definition file-R + fileID=fopen('NCOM_R.bnd','w'); + crIDX2=crIDX; + crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+2; + crIDX2(crBoundCount(1)+1:crBoundCount(2),1) = 1082; + + for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end + end + fclose(fileID); + + + %% Waves + records = size(waves,1); + fileID=fopen('WW3.bcw','w'); + + for i = 1:3 + boundryNames(i) = {['East' num2str(i)]}; + end + + for Boundry = 1:3 + refTime=minutes(masterTime-masterDate); + + header=[... + 'location ''East%d''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterTime,'yyyymmdd'))); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''WaveHeight '' unit ''[m]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Period '' unit ''[s]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Direction '' unit ''[N^o]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''DirSpreading '' unit ''[-]''\n'); + end + + for line = 1:records + fprintf(fileID,'%d ',refTime); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,1)); %Hs + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,2)); %Period + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,3)); %Direction + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',4); %Spread + end + fprintf(fileID,'\n'); + + % fprintf(fileID,'%.2f %1.4f %1.4f %1.4f %1.4f\n',refTime,... + % waves(line,Boundry,1),waves(line,Boundry,2),waves(line,Boundry,3),4); + refTime=refTime+180; + end + end + + fclose(fileID); + + + %% Modify MDF file to change reference date + + fileID = fopen('rt_base.mdf'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdf', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 15 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'Itdate = #%04d-%02d-%02d#\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 17 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID,['Tstart = %#.7e \n','Tstop = %#.7e \n'],refTime,refTime+2880); + + + + for i = 20:29 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + if FIRST_RUN == 0 + restID = ['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000']; + if exist(restID)==2 + eval(['movefile ' restID ' tri-rst.6h_restart']) + end + + fprintf( fileID,['Commnt = initial conditions from restart file\n'... + 'Restid = #6h_restart#\n']); + % delete tri-rst.rt* + else + + % fprintf( fileID,['Commnt = initial conditions from map file\n'... + % 'Restid = #Jan16_06#\n']); + + % fprintf( fileID,'Zeta0 = %#.7e \n',nanmean(nanmean(squeeze(wlO(1,:))))); + fprintf( fileID,'Zeta0 = %#.7e \n',0); + + end + + for i = 31:53 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % if FIRST_RUN==1 + % fprintf( fileID, 'Vicouv = 1.0000000e+002 \n'); + % else + fprintf( fileID, '%s\n', cac{1}{54} ); + % end + + for i = 55:64 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + if FIRST_RUN==1 + fprintf( fileID, 'Tlfsmo = 0.0000000e+001 \n'); + else + fprintf( fileID, 'Tlfsmo = 0.0000000e+000 \n'); + end + + for i = 66:94 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + + fprintf( fileID,[... + 'Flmap = %#.7e 60 %#.7e\n',... + 'Flhis = %#.7e 10 %#.7e\n',... + 'Flpp = %#.7e 60 %#.7e\n'],... + refTime,refTime+2880,refTime,refTime+2880,refTime,refTime+2880); + + for i = 98:109 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + clear cac + %% Modify MDW file to add times and change reference date + + fileID = fopen('rt_base.mdw'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdw', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 7 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'ReferenceDate = %04d-%02d-%02d\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 9 : 71 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % for i = 1 : records + % fprintf( fileID,'[TimePoint] \n Time = %#.7e \n',(i-1).*180); + % end + + bounOri{1}='East'; + bounOri{2}='North'; + bounOri{3}='South'; + bounRot{1}='counter-clockwise'; + bounRot{2}='counter-clockwise'; + bounRot{3}='clockwise'; + bounDef{1}='grid-coordinates'; + bounDef{2}='orientation'; + bounDef{3}='orientation'; + + + for Boundry = 1 : 3 + + if Boundry ==1 + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'StartCoordM = %d\n'... + 'EndCoordM = %d\n'... + 'StartCoordN = %d\n'... + 'EndCoordN = %d\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + ],Boundry,bounDef{Boundry},432,432,2,528); + else + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'Orientation = %s\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + 'DistanceDir = %s\n'... + ],Boundry,bounDef{Boundry},bounOri{Boundry},bounRot{Boundry}); + end + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'CondSpecAtDist = %d\n',waveDistAlong(Segment)); + end + end + + clear cac + fclose( fileID ); + + + %% Met Files + % Create new UTM grid of the HRRR Data + [UTM1D(:,1),UTM1D(:,2)] = wgs2utm(reshape(windGridLAT,1,[]),reshape(windGridLON,1,[]),... + 18,'N'); + HRRR_UTM(:,:,1) = double(reshape(UTM1D(:,1),size(windGridLON,1),size(windGridLON,2))); + HRRR_UTM(:,:,2) = double(reshape(UTM1D(:,2),size(windGridLON,1),size(windGridLON,2))); + clear UTM1D + + G7LR = load('C7_1400_V2_C.mat'); + G7bath = load('C7_1400_V2_D.mat'); + % Remove land rainfall + % if FIRST_RUN == 1 + landmask=zeros(size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % [HR_deg(:,1),HR_deg(:,2)] = utm2deg(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[]),reshape(G7LR.data.Y(1:end-1,1:end-1)',1,[]),repmat('18 S',length(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[])),1)); + % for ShoreLevel = 1:length(shoreline) + % landmask_Temp(:,:) = reshape(inpolygon(HR_deg(:,1),HR_deg(:,2),shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon),size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % + % landmask = landmask|landmask_Temp; + % clear landmask_Temp + % + % [shoreTempX,shoreTempY,shoreTempCell] = deg2utm(shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon); + % shoreUTM{ShoreLevel}(:,1) = shoreTempX(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % shoreUTM{ShoreLevel}(:,2) = shoreTempY(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % clear shoreTempX shoreTempY shoreTempCell + % disp(ShoreLevel) + % end + % save('shorelineInfo.mat','landmask','shoreUTM'); + % else + % load('shorelineInfo.mat'); + % end + clear HR_deg ShoreLevel + landmask(G7bath.data.Val'<0)=1; + landmask=logical(landmask); + + if masterTime>=datetime(2019,09,05,00,00,00) + runSteps = 49; + else + runSteps = 8; + end + + % Zero out met array + HRRR_INTER = zeros(4,runSteps,size(G7LR.data.X(1:end-1,1:end-1),2),size(G7LR.data.X(1:end-1,1:end-1),1)); + + % Interpolate against flowGrid for each time step + for TS = 1:runSteps + HRRR_INTER(1,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windU(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + HRRR_INTER(2,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windV(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + rainTemp = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(rain(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + rainTemp(landmask)=rainTemp(landmask)*0; % 100% infiltration + HRRR_INTER(3,TS,:,:) = rainTemp; % Convert to hours + clear rainTemp + + HRRR_INTER(4,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(pressure(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + end + + % Set nan to Delft3D zero value + HRRR_INTER(isnan(HRRR_INTER)==1)=-999.000; + + % Create input files + m = size(HRRR_INTER,3); + n = size(HRRR_INTER,4); + d3ddx = 5000; + d3ddy = 5000; + disp(m) + d3d_input_uvpFieldsCL_FUN(masterTime,m,n,... + squeeze(HRRR_INTER(4,:,:,:)),squeeze(HRRR_INTER(1,:,:,:)),squeeze(HRRR_INTER(2,:,:,:)),squeeze(HRRR_INTER(3,:,:,:)),1,'hrrr',runSteps) + + save(['ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat'],'-v7.3','windU','windV','pressure','rain','temperature','waves','waterLevels','NCOM') + + %% Run Delft3D FLOW/WAVE! + % system('. /home/cluster/D7545/enviorment.sh' + + system('runcoast_flow2d3d_parallel_wave.bat') + if exist('wavm-rt_run.dat')~=2 + fid = fopen('errorFile.log','a+'); + fprintf(fid,'Delft Batch File Fallback\n'); + + % close file + fclose(fid) + disp('Run Fallback') + pause(60) + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + delete swn-diag.* + + system('runcoast_flow2d3d_parallel_wave.bat') + end + + %% Move things + pause(60) + + eval(['copyfile trih-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.dat']) + eval(['copyfile trih-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.def']) + + eval(['movefile ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat D:\DUNEX_RT\Archive\ModelIn_7' datestr(masterTime,'YYYY-mm-DD_HH') '.mat']) + % eval(['copyfile tri-rst.rt* D:\Alexander\RealtimeHRRR\']) + + + eval(['copyfile hrrr.amu D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amu']) + eval(['copyfile hrrr.amv D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amv']) + eval(['copyfile hrrr.ampr D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.ampr']) + eval(['copyfile hrrr.amp D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amp']) + eval(['copyfile trim-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.dat']) + eval(['copyfile trim-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.def']) + eval(['copyfile wavm-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.dat']) + eval(['copyfile wavm-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.def']) + + + + %% Clear things not needed for plotting + clear HRRR_INTER flowGrid lonHRRR_Mesh windU windV rain pressure waveGrid + + + delete(gcp('nocreate')) + parpool(3); + %% Import Model Results + addpath(genpath('matlab/applications/delft3d_matlab'),'-begin') + + modelWater = qpread(qpfopen('trim-rt_run.dat'),1,'water level','griddata',0,0,0); + flowGrid = load('Cone7W_100.mat'); + waveGrid = load('Cone7W_250.mat'); + flowBed = load('Dec6_100Bed.mat'); + waveBed = load('Dec6_250Bed.mat'); + + %% Create GeoTIFF for water levels + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + + yMinOffset = 75; + yMaxOffset = 25; + + parfor Time = 1:6 + % X{Time} = modelWater.X; + % Y{Time} = modelWater.Y; + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + + modelPlot_1 = squeeze(modelWater.Val(timeIDX(Time),1:end-1,1:end-1)); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['WL_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWater + + modelWaterDAV = qpread(qpfopen('trim-rt_run.dat'),1,'depth averaged velocity','griddata',0,0,0); + + %% Create GeoTIFF for DAVs + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoDat modelPlot_1 + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + if FIRST_RUN == 1 + Times = 2:6; + else + Times = 1:6; + end + + + parfor Time = Times + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + modelPlot_1 = sqrt(squeeze(modelWaterDAV.XComp(timeIDX(Time),1:end-1,1:end-1)).^2+... + squeeze(modelWaterDAV.YComp(timeIDX(Time),1:end-1,1:end-1)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['DAV_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + %% Quiver for DAV + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + vecScale(4) = 100000; + vecScale(3) = 50000; + vecScale(2) = 2500; + vecScale(1) = 1000; + + for Time = Times + + X{Time} = flowGrid.data.X(2:end,2:end); + Y{Time} = flowGrid.data.Y(2:end,2:end); + modelPlot_1 = squeeze(modelWaterDAV.XComp(timeIDX(Time),2:end,2:end)); + modelPlot_2 = squeeze(modelWaterDAV.YComp(timeIDX(Time),2:end,2:end)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(400:520,525:620)=nan; + + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + modelPlot_2(:,1:yMinOffset)=nan; + modelPlot_2(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + qSpace = [4 16 50 100] + + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + for i = 1:length(Xdat{Time}) + if ((Udat{Time}(i))==0 && (Vdat{Time}(i))==0) ||... + (isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1) ||... + ((isnan(Udat{Time}(i)))==1 && isnan(Vdat{Time}(i))==1) + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + + Xdat{Time}=[]; + Ydat{Time}=[]; + Udat{Time}=[]; + Vdat{Time}=[]; + q{Time}=[]; + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['DAV_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj DAV_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaterDAV + + %% Create GeoTIFF for HS + + modelWaves = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave height','griddata',0,0,0); + modelWavesDir = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave vector (mean direction)','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize GeoS + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = (squeeze(modelWaves.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):250:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):250:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):250:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):250:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-0,1:end-0),1,[]),... + reshape(Y{Time}(1:end-0,1:end-0),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['HS_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for HS + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + vecScale(4) = 15000; + vecScale(3) = 5000; + vecScale(2) = 1000; + vecScale(1) = 500; + + for Time = 1:6 + + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = squeeze(modelWavesDir.XComp(timeIDX(Time),:,:)); + modelPlot_2 = squeeze(modelWavesDir.YComp(timeIDX(Time),:,:)); + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(155:205,210:265)=nan; + + + qSpace = [2 10 20 40] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + elseif isnan(Udat{Time}(i))==1 && isnan(Vdat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['HS_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj HS_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaves + clear modelWavesDIR + + %% Create GeoTIFF for Wind + modelWaterWind = qpread(qpfopen('trim-rt_run.dat'),1,'wind speed','griddata',0,0,0); + + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS ValX ValY + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = sqrt(squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)).^2+... + squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):1000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):1000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):1000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):1000:R{Time}.YWorldLimits(2)); + + Val{Time}(Val{Time}==0)=nan; + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['Uw_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for Wind + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + + vecScale(4) = 3000; + vecScale(3) = 500; + vecScale(2) = 100; + vecScale(1) = 40; + + for Time = 1:6 + + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + ValX{Time} = squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)); + ValY{Time} = squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)); + + + qSpace = [5 25 50 100] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),Y{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),... + squeeze(ValX{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),squeeze(ValY{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['Uw_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj Uw_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaterWind + + %% Create GeoTIFF for Prep + + modelWaterPrep = qpread(qpfopen('trim-rt_run.dat'),1,'precipitation rate','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = (squeeze(modelWaterPrep.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):10000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):10000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):10000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):10000:R{Time}.YWorldLimits(2)); + + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geotiffwrite(['Prep_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWaterPrep + + %% Export to GEOSERVER + copyfile *.tif \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.dbf \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shx \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shp \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.prj \\geoserver.engineering.queensu.ca\TIFFS\ + + + %% Import Model forecast + modelWaterHist = qpread(qpfopen('trih-rt_run.dat'),1,'water level','data',0,0); + modelCurHist = qpread(qpfopen('trih-rt_run.dat'),1,'depth averaged velocity','data',0,0); + + %% Validation import ESTOFS + load('DUNEX_Nov20.mat') + clear ESTOFS lonESTOFS lonESTOFS + + wLIDX=[6 7 8 38]; + wlGrid = [5000 -4000 0 -2000]; + wlGridY = [0 0 2000 5000]; %7500 + ESTOFStimeOffset = [0 12 24 48]; + ESTOFSrunLength = [48 60 72 96]; + + for e = [1 4] + try + clear meshX meshY + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(0,'%03d') '.grib']); + + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTOFS_Val{e} = 1; + catch + ESTOFS_Val{e} = 0; + end + end + clear waterLevelsESTOFSINTER waterLevelsESTOFS + for e = [1 4] + try + for Stat = 1:4 + if ESTOFS_Val{e} == 0 + estofsWL(:,Stat,e) = zeros(49,1); + else + [wlDeg(2),wlDeg(1)] = utm2deg(pointsCS{wLIDX(Stat),2}+wlGrid(Stat),pointsCS{wLIDX(Stat),3}+wlGridY(Stat),'18 S'); + [estofIDX] = NearestValue(wlDeg,lonESTOFS,latESTOFS); %Lat + + for i = 1:ESTOFSrunLength(e)+1 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(i-1,'%03d') '.grib']); + + waterLevelsESTOFS{e}(i,Stat) = squeeze(ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,estofIDX(1),estofIDX(2))); + end + waterLevelsESTOFSINTER{e}(:,Stat) = interp1(masterTime-hours(ESTOFStimeOffset(e)):minutes(60):masterTime+hours(48),... + waterLevelsESTOFS{e}(:,Stat),masterTime-hours(ESTOFStimeOffset(e)):minutes(15):masterTime+hours(48),'spline'); + end + end + catch + waterLevelsESTOFSINTER{e}(:,Stat) = zeros(1,385); + end + end + + + %% Validation import WL + % Duck + % Oregon Inlet + % Hatteras + % Beaufort + clear stations statWL + options = weboptions; + options.Timeout = 30; + + stations = {8651370,8652587,8654467,8656483}; + dateStartM = masterTime-hours(48); + dateEndM = masterTime+hours(5); + + for Stat = 1:4 + try + url = ['https://tidesandcurrents.noaa.gov/api/datagetter?product=water_level&application=NOS.COOPS.TAC.WL&'... + 'begin_date=' datestr(dateStartM,'yyyymmdd') '&end_date=' datestr(dateEndM,'yyyymmdd') '&datum=NAVD' '&station=' num2str(stations{Stat})... + '&time_zone=GMT&units=metric&format=csv']; + + wlIN = webread(url,options); + + statWL(:,Stat) = interp1(wlIN.DateTime,wlIN.WaterLevel,dateStartM:minutes(15):dateEndM); + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statWL(:,Stat) = 0; + end + + + clear wlIN + + end + %% Validation import Currents + % Duck + clear statCur + for Stat = 1 + % url = 'https://chlthredds.erdc.dren.mil/thredds/dodsC/frf/oceanography/currents/awac-11m/awac-11m.ncml'; + % curTime = ncread(url,'time'); + % curVal = ncread(url,'currentSpeed'); + try + if day(masterTime)<2 + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime-day(3),'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime-days(3),'YYYYmm') '.nc'],options); + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + curTime = vertcat(curTime,ncread('statCNC.nc','time')); + curVal = vertcat(curVal,ncread('statCNC.nc','currentSpeed')); + + else + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + end + + statCur(:) = interp1(datetime(curTime,'convertFrom','POSIX'),curVal,dateStartM:minutes(15):dateEndM); + clear wlIN + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statCur(:) = zeros(length(dateStartM:minutes(10):dateEndM),1); + end + end + + %% Validation import Waves + % Virginia Beach + % Duck 26 + % Nages Head + % Oregon Inlet + % Diamond Shoals + clear stations + + stations = {44014,44100,44086,44095,41025}; + dateStartM = masterTime-hours(48); + dateEndM = masterTime+hours(5); + + clear statWave + + for Stat = 1:5 + try + if ismember(Stat,[1,5]) == 1 + url = ['https://www.ndbc.noaa.gov/data/5day2/' num2str(stations{Stat}) '_5day.txt']; + + websave('NDBCdata.txt',url,options); + opts = delimitedTextImportOptions("NumVariables", 39); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, 15, "TrimNonNumeric", true); + opts = setvaropts(opts, 15, "ThousandsSeparator", ","); + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + else + url = ['https://www.ndbc.noaa.gov/data/realtime2/' num2str(stations{Stat}) '.txt']; + websave('NDBCdata.txt',url); + + opts = delimitedTextImportOptions("NumVariables", 52); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39", "Var40", "Var41", "Var42", "Var43", "Var44", "Var45", "Var46", "Var47", "Var48", "Var49", "Var50", "Var51", "Var52"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "categorical", "categorical", "categorical", "double", "double", "double", "double", "categorical", "categorical", "double", "double", "categorical", "categorical", "categorical", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "TrimNonNumeric", true); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "ThousandsSeparator", ","); + opts = setvaropts(opts, [6, 7, 8, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + end + + % Import the data + waveIN = readtable("NDBCdata.txt", opts); + waveNAN = isnan(waveIN.WVHT)==0; + % Hs + statWave(:,1,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.WVHT(waveNAN)),dateStartM:minutes(15):dateEndM); + % DPD + % statWave(:,2,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + % (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + % (waveIN.DPD(waveNAN)),dateStartM:minutes(10):dateEndM); + % APD + statWave(:,3,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.APD(waveNAN)),dateStartM:minutes(15):dateEndM); + %MWD + statWave(:,4,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.MWD(waveNAN)),dateStartM:minutes(15):dateEndM); + clear waveIN opts + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + %fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + %sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]); + + % close file + fclose(fid) + statWave(:,:,Stat) = zeros(size(dateStartM:minutes(10):dateEndM,2),4,1); + end + end + statWave(isnan(statWave))=0; + %% Import Model Waves + + for i = 1:49 + startRow = 8; + formatSpec = '%13f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%f%[^\n\r]'; + + fileID = fopen(['Dec28.loct00000' num2str(i,'%02d') '.tab'],'r'); + + % This call is based on the structure of the file used to generate this + % code. If an error occurs for a different file, try regenerating the code + % from the Import Tool. + dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines' ,startRow-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + + fclose(fileID); + modelWaveIN= table(dataArray{1:end-1}, 'VariableNames', {'Xp','Yp','Depth','Hsig','Dir','RTpea','kTm01','Dspr','Ubot','XWindv','YWindv','XVel','YVel'}); + + modelWave(:,1,i) = modelWaveIN.Hsig; + modelWave(:,3,i) = modelWaveIN.RTpea; + modelWave(:,4,i) = modelWaveIN.Dir; + + + clearvars filename startRow formatSpec fileID dataArray ans modelWaveIN; + + end + + %% Import Model WL + modelWL = modelWaterHist.Val; + modelCur = sqrt(modelCurHist.XComp.^2+modelCurHist.YComp.^2); + + for idx = 1:size(modelWL,2) + modelWLInter(:,idx) = interp1(modelWaterHist.Time,modelWL(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))); + end + for idx = 1:size(modelCur,2) + modelCurInter(:,idx) = sqrt(interp1(modelCurHist.Time,modelCurHist.XComp(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))).^2+... + interp1(modelCurHist.Time,modelCurHist.YComp(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))).^2); + end + + save(['ModelOut_' datestr(masterTime,'dd-mmm-yyyy_HH') 'Z.mat'],'modelWL','modelWave','statWL','statWave','modelCur','statCur','modelWLInter','modelCurInter'); + + %% Import Historic Model WL + if masterTime>=datetime(2021,07,08) + try + H12 = load(['ModelOut_' datestr(masterTime-hours(12),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H24 = load(['ModelOut_' datestr(masterTime-hours(24),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H48 = load(['ModelOut_' datestr(masterTime-hours(48),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + end + %% Save html for Currents + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + locLine = 1:5:67; + locationsWave ={'FRF 11 m AWAC '}; + +% % for i = 1:433 +% % for j = 1:100 +% % modelDavDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,2],modelDavDel) + + davIDX=[17 161:172]; + + clear modelCurPlot curValLoc + for Loc = 1:13 + for Line=1:5 + switch Line + case 1 + curValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelCurPlot(1:385,locLine(Loc)+0) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:192,locLine(Loc)+0) = {''}; + modelCurPlot(193:1:385,locLine(Loc)+0) = num2cell(modelCurInter(:,davIDX(Loc))); + case 2 + curValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelCurPlot(1:385,locLine(Loc)+1) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:143,locLine(Loc)+1) = {''}; + modelCurPlot(337:385,locLine(Loc)+1) = {''}; + modelCurPlot(144:1:336,locLine(Loc)+1) = num2cell(H12.modelCurInter(:,davIDX(Loc))); + + case 3 + curValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelCurPlot(1:385,locLine(Loc)+2) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:96,locLine(Loc)+2) = {''}; + modelCurPlot(290:385,locLine(Loc)+2) = {''}; + modelCurPlot(97:1:289,locLine(Loc)+2) = num2cell(H24.modelCurInter(:,davIDX(Loc))); + + case 4 + curValLoc{Line} = ['-48 Hour: ' datestr(masterTime-hours(48),'mm/dd HH') 'Z Run']; + if exist('H48','var') ==0 + modelCurPlot(1:385,locLine(Loc)+3) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(193:385,locLine(Loc)+3) = {''}; + modelCurPlot(1:1:192,locLine(Loc)+3) = num2cell(H48.modelCurInter(:,davIDX(Loc))); + case 5 + curValLoc{Line} = ['Observed Velocity']; + if Loc> 1 || isnan(statCur(1,Loc)) + modelCurPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(214:385,locLine(Loc)+4) = {''}; + modelCurPlot(1:213,locLine(Loc)+4) = num2cell(statCur); + + end + + end + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],modelCurPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],curValLoc) + curValLoc = repmat(curValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... + [1,1],horzcat(googleDatesCell',vertcat(curValLoc(1:size(modelCurPlot,2)),modelCurPlot))) + %% Save html for WL + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% locLine = [2 7 12 17 22 27]; +% locLine = [2 9 16 23 30 37]; + locLine = 1:7:114; + + locationsWl ={'FRF Pier',... + 'Oregon Inlet',... + 'Hatteras',... + 'Beaufort'}; + +% % for i = 1:433 +% % for j = 1:121 +% % modelWlDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,2],modelWlDel) + + wLIDX=[6 7 8 38 161:172]; + clear modelWlPlot wlValLoc + for Loc = 1:length(wLIDX) +% modelwlPlot = cell(432,4); + for Line=[1:5 6 9] + switch Line + case 1 + wlValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelwlPlot(1:385,locLine(Loc)+0) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:192,locLine(Loc)+0) = {''}; + modelwlPlot(193:1:385,locLine(Loc)+0) = num2cell(modelWLInter(:,wLIDX(Loc))); + case 2 + wlValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelwlPlot(1:385,locLine(Loc)+1) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:143,locLine(Loc)+1) = {''}; + modelwlPlot(337:385,locLine(Loc)+1) = {''}; + modelwlPlot(144:1:336,locLine(Loc)+1) = num2cell(H12.modelWLInter(:,wLIDX(Loc))); + + case 3 + wlValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelwlPlot(1:385,locLine(Loc)+2) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:96,locLine(Loc)+2) = {''}; + modelwlPlot(290:385,locLine(Loc)+2) = {''}; + modelwlPlot(97:1:289,locLine(Loc)+2) = num2cell(H24.modelWLInter(:,wLIDX(Loc))); + + case 4 + wlValLoc{Line} = ['-48 Hour: ' datestr(masterTime-hours(48),'mm/dd HH') 'Z Run']; + if exist('H48','var') ==0 + modelwlPlot(1:385,locLine(Loc)+3) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(218:385,locLine(Loc)+3) = {''}; + modelwlPlot(1:1:217,locLine(Loc)+3) = num2cell(H48.modelWLInter(:,wLIDX(Loc))); + case 5 + wlValLoc{Line} = ['Observed Water Level']; + if Loc>4 || isnan(statWL(1,Loc)) + modelwlPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(214:385,locLine(Loc)+4) = {''}; + modelwlPlot(1:213,locLine(Loc)+4) = num2cell(statWL(:,Loc)); + case 6 + wlValLoc{Line} = ['ESTOFS Forecast']; + if Loc>4 || ESTOFS_Val{1} == 0 + modelwlPlot(1:385,locLine(Loc)+5) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:192,locLine(Loc)+5) = {''}; + modelwlPlot(193:385,locLine(Loc)+5) = num2cell(waterLevelsESTOFSINTER{1}(:,Loc)); + case 9 + wlValLoc{7} = ['-48 Hour ESTOFS']; + if Loc>4 || ESTOFS_Val{4} == 0 || size(ESTOFS_Val{4},2) == 1 + modelwlPlot(1:385,locLine(Loc)+6) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:1:385,locLine(Loc)+6) = num2cell(waterLevelsESTOFSINTER{4}(:,Loc)); + end + end + disp(Loc) + + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [2,locLine(Loc)],modelwlPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [1,locLine(Loc)],wlValLoc) + + wlValLoc = repmat(wlValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... + [1,1],horzcat(googleDatesCell',vertcat(wlValLoc(1:size(modelwlPlot,2)),modelwlPlot))) + + %% Save html for Waves + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,1],googleDates') + +% locLine = [2 7 12 17 22 27]; + locLine = 1:5:114; + + locationsWave ={'Virginia Beach',... + 'FRF 26 m',... + 'Nags Head',... + 'Oregon Inlet',... + 'Diamond Shoals'}; + + clear waveValLoc modelwavePlot + + for i = 1:385 + for j = 1:85 + modelwavePlot(i,j)={''}; + end + end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,2],modelWaveDel) + + waveIDX = [12 13 14 15 16 161:172]; + for Loc = 1:length(waveIDX) +% modelwavePlot = cell(432,5); + for Line=1:5 + switch Line + case 1 + waveValLoc{Line} = ['Forecast']; + if exist('modelWave','var') ==0 + modelwavePlot(1:385,locLine(Loc)+0) = num2cell(zeros(433,1)); + continue + end + modelwavePlot(1:191,locLine(Loc)+0) = {''}; + modelwavePlot(192,locLine(Loc)+0) = {0}; + modelwavePlot(193:4:385,locLine(Loc)+0) = num2cell(modelWave(waveIDX(Loc),1,:)); + case 2 + waveValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 || size(H12.modelWave,1)5 || isnan(statWave(1,1,Loc)) + modelwavePlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelwavePlot(215:385,locLine(Loc)+4) = {''}; + modelwavePlot(214,locLine(Loc)+4) = {0}; + modelwavePlot(1:1:213,locLine(Loc)+4) = num2cell(statWave(:,1,Loc)); + + end + + end +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [2,locLine(Loc)],modelwavePlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [1,locLine(Loc)],waveValLoc) + end + + waveValLoc = repmat(waveValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... + [1,1],horzcat(googleDatesCell',vertcat(waveValLoc(1:size(modelwavePlot,2)),modelwavePlot))) + + + + + %% Import and modify times +% modelHour = [0 3 6 12 24 48]; + modelHour = [0 6 12 24 36 48]; + for i = 1:6 + dateText(i) = {[datestr(masterTime+hours(modelHour(i)),'mmm dd, HH:MM') ' UTC (Hour '... + num2str(modelHour(i),'%d') ')']}; + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','0',[1,1],... + dateText) + +catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['ALL-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + +end + +%% +% quit + + + + + + + + + + + + + + + + diff --git a/Dunex_Operational_Feb28.m b/Dunex_Operational_Feb28.m new file mode 100644 index 0000000..0718575 --- /dev/null +++ b/Dunex_Operational_Feb28.m @@ -0,0 +1,2414 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +% Moved to COASTLINES Feb 29, 2020 + +clear all +cd D:\DUNEX_RT\Operation +echo off; +addpath('NCtoolbox') +addpath('m_map') +setup_nctoolbox +flowGrid = load('Cone7W_100.mat'); +waveGrid = load('Cone7W_250.mat'); +load('LMSL_RT.mat') +addpath('D:\DUNEX_RT\Operation\abogaard-matlab2gsheets-6d76271') +setenv('PATH', [getenv('PATH') ';D:\DUNEX_RT\Windows_64']); + +%% Details for e-mail server +setpref('Internet','SMTP_Server','smtp.sendgrid.net'); +setpref('Internet','E_mail','mail@alexanderrey.ca'); +setpref('Internet','SMTP_Username','apikey'); +setpref('Internet','SMTP_Password','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'); +props = java.lang.System.getProperties; +props.setProperty('mail.smtp.auth','true'); +props.setProperty('mail.smtp.socketFactory.class', 'javax.net.ssl.SSLSocketFactory'); +props.setProperty('mail.smtp.socketFactory.port','465'); +props.setProperty('mail.smtp.starttls.enable','true'); + + +%% Master Model Time Step +% Every 6 hours + +nistTime = datetime(datevec(now())) - tzoffset(datetime(datevec(now()),'TimeZone','local')); +masterTime = dateshift(nistTime,'start','hour')-hours(2) % Assume script will run at 5 and a half hours after model start +clear nistTime +masterDate = datetime(year(masterTime),month(masterTime),day(masterTime)); + +if exist(['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000'])==2 + FIRST_RUN = 0; +else + FIRST_RUN = 1; +end + +%% Import +try + Import=0; + + + %% Clean files from previous run + system('taskkill /IM "d_hydro.exe" /F') + system('taskkill /IM "wave.exe" /F') + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + + clear HRRR_UTM + while Import==0 + try + %% Import data from NOMADS + %% Extratropical Surge and Tide Operational Forecast System for the Atlantic + % (ESTOFS Atlantic) for water levels + options = weboptions; + options.Timeout = 90; + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(6),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 6; %7 + ESTrun = 6; + catch + % url = ['http://nomads.ncep.noaa.gov/dods/estofs_atl/'... + % datestr(masterTime-days(1),'yyyymmdd')... + % '/estofs_atl_conus_' datestr(masterTime-days(1),'hh') 'z']; + % ESTOFS = ncgeodataset(url); + % lonESTOFS=ESTOFS{'lon'}(:); + % latESTOFS=ESTOFS{'lat'}(:); + % ESTstart = 24+ESTstart; +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-days(1),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-days(1),'yyyymmdd')... + '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 24; %25 + ESTrun = 24; + end + + + clear url + + % Find ESTOFS index for grid points along boundry + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); %Lat + wlIDX(idxCount,:) = [1082,i]; + + idxCount = idxCount + 1; + end + + wlBoundCount(1) = 0; + wlBoundCount(2) = idxCount -1; + + + for i = 750:11:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1322]; + idxCount = idxCount + 1; + end + + wlBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1]; + idxCount = idxCount + 1; + end + wlBoundCount(4) = idxCount -1; + + clear idxCount gridDeg + + % Extract ESTOFS Water Levels for 36 hours at indexes + % waterLevelsGRID = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(ESTstart:ESTstart+36,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + % min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + + % Find ESTOFS values from small grid + idxCount=1; + errorET = 0; + for i = ESTstart:ESTstart+96 + if errorET<10 + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... +% num2str(i,'%03d') '.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... + num2str(i,'%03d') '.grib2']; + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib'],url,options) + + if i<=ESTstart+48 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib']); + + waterLevelsGRID(idxCount,:,:) = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + end + idxCount = idxCount + 1; + catch + errorET = errorET+1; + end + else + error('ESTOFS ERROR') + end + + end + + idxCount=1; + for i = 1:length(idxESTOFS) + waterLevels(:,idxCount) = waterLevelsGRID(:,idxESTOFS(idxCount,1)-min(idxESTOFS(:,1))+1,... + idxESTOFS(idxCount,2)-min(idxESTOFS(:,2))+1); + + idxCount = idxCount + 1; + end + + + % Save ESTOFS Points +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_points.nc'],url,options) + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + disp('Loaded ESTOFS') + %% Multi-grid Wave model (WAVEWATCH III) + % 4 arc minute US East Coast grid for waves + + url = ['https://nomads.ncep.noaa.gov/dods/wave/gfswave/'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/gfswave.atlocn.0p16_' datestr(masterTime-hours(6),'hh') 'z']; + + MWW3 = ncgeodataset(url); + clear url + + lonMWW3=wrapTo180(MWW3{'lon'}(:)); + latMWW3=MWW3{'lat'}(:); + + % Find MWW3 index for grid points along boundry + idxCount=1; + for i = 1:25:length(waveGrid.data.Y)-25 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(end-2,i),waveGrid.data.Y(end-2,i),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(end-2,1:i)).^2+... + diff(waveGrid.data.Y(end-2,1:i)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(end-2,i); + waveUTM(idxCount,2) = waveGrid.data.Y(end-2,i); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + waveBoundCount(1) = 0; + waveBoundCount(2) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:350% Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,end-2),waveGrid.data.Y(i,end-2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,end-2)).^2+... + diff(waveGrid.data.Y(i:end-2,end-2)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,end-2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,end-2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + % 0 132 163 285 + + waveBoundCount(3) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:240 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,2),waveGrid.data.Y(i,2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,1)).^2+... + diff(waveGrid.data.Y(i:end-2,1)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(4) = idxCount -1; + + clear idxCount + + % Extract WW3 Hs for 36 hours at indexes + wavesGRID_Hs = MWW3{'htsgwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid htsgwsfc + %swell_1 + % Period + wavesGRID_P = MWW3{'perpwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... % + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid perpwsfc + %swper_1 + % Direction + wavesGRID_Dir = MWW3{'dirpwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid dirpwsfc + %swdir_1 + % Find WW3 values from small grid + idxCount=1; + for i = 1:length(idxMWW3) + waves(:,idxCount,1) = wavesGRID_Hs(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Hs + + waves(:,idxCount,2) = wavesGRID_P(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Tp + + waves(:,idxCount,3) = wavesGRID_Dir(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Dir + + idxCount = idxCount + 1; + end + clear idxCount + disp('Loaded WW3') + + + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; +% delete(gcp('nocreate')) +% parpool(8); + + for ForcastHour = 0:48 + % url = ['http://nomads.ncep.noaa.gov/pub/data/nccf/com/hrrr/prod/'... + % 'hrrr.' datestr(masterTime,'yyyymmdd')... + % '/conus/hrrr.t' num2str(hour(masterTime),'%02d') 'z.'... + % 'wrfsfcf' num2str(ForcastHour,'%02d') '.grib2']; + + url = ['https://nomads.ncep.noaa.gov/cgi-bin/filter_hrrr_2d.pl?file=hrrr.'... + 't' num2str(hour(masterTime),'%02d') 'z.wrfsfc'... + 'f' num2str(ForcastHour,'%02d') '.grib2&'... + 'lev_10_m_above_ground=on&lev_surface=on&var_APCP=on&var_PRES=on&var_UGRD=on&var_VGRD=on&var_TMP=on&subregion=&leftlon=-78&rightlon=-74&toplat=38&bottomlat=32.5&dir=%2F'... + 'hrrr.' datestr(masterTime,'yyyymmdd') '%2Fconus']; + + websave(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2'],url,options) + + [pCheck,gridParams] = system(['perl "D:\DUNEX_RT\Windows_64\grid_defn.pl" '... + 'D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + [wCheck,gridParams] = system(['wgrib2 D:\DUNEX_RT\Operation\HRRR\hrrrT' ... + num2str(ForcastHour,'%02d') '.grib2 -new_grid_winds earth -new_grid ' ... + gridParams ' D:\DUNEX_RT\Operation\HRRR\hrrrT'... + num2str(ForcastHour,'%02d') '.grib2.regrid']); + end +% delete(gcp('nocreate')) + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(0,'%02d') '.grib2.regrid']); + clear url + + m_proj('lambert conformal conic','ori',[262.5 38.5],'clo',262.5,'par',[38.5 38.5],'ell','sphere');%,'lat',[20 55],'lon',[-60 -130] + [meshX,meshY] = meshgrid(HRRR{'x'}(:),HRRR{'y'}(:)); + [windGridLON,windGridLAT] = m_xy2ll(meshX.*1000,meshY.*1000); + windGridLON=wrapTo180(windGridLON); + clear meshX meshY + + % Extract MWW3 Hs for 48 hours at indexes + for ForcastHour = 0:48 + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2.regrid']); + windU(ForcastHour+1,:,:) = HRRR{'u-component_of_wind_height_above_ground'}(:,:,:); %U Winds @ 10m [m/s] + windV(ForcastHour+1,:,:) = HRRR{'v-component_of_wind_height_above_ground'}(:,:,:); %V Winds @ 10m [m/s] + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + pressure(ForcastHour+1,:,:) = HRRR{'Pressure_surface'}(:,:,:); %Surface Pressure [pa] + + if ForcastHour==0 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_0_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + elseif ForcastHour==1 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_1_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + else + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_Mixed_intervals_Accumulation'}(2,:,:); %Surface precipitation [kg/m^2] + end + temperature(ForcastHour+1) = squeeze(nanmean(nanmean(HRRR{'Temperature_surface'}(:,:,:)- 273.15,2),3)); %Surface Temperature [C] + end + % Extract Temp + + disp('Loaded HRRR') + + + %% IMPORT NCOM + + try + nComDate=masterDate; +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/20201220/coamps_ncom_useast_u_1_2020122000_00000000.nc']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; + +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + mkdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0025-0048.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0073-0096.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0073-0096.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); + % NCOM.Lat = ncom_grib{'lat',[331],[240]}; + % NCOM.Lon = ncom_grib{'lon',91,180}; + catch + try + if hour(masterTime) ~= 18 + nComDate=masterDate-days(1); + else + nComDate=masterDate; + end +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); +% ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\grids\operational\NCOM\regional\GRIB2\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2']; +% ncom_grib = ncgeodataset(ncom_downloadPath); + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0073-0096.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0073-0096.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); +% NCOM.Lat = ncom_grib{'lat',[331],[240]}; +% NCOM.Lon = ncom_grib{'lon',91,180}; + + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + end + + if FIRST_RUN == 1 + NCOM.depth = ncread('D:\Alexander\NCOM\2019090500_t000.nc','depth'); + end + + Noffset = hours(masterTime - nComDate); + tStep = Noffset; + tCount = 1; + + try + for Ni = masterTime:hours(3):masterTime+hours(48) + noData=1; + while noData==1 + try +% NCOMstep = tStep./3+1; + NCOMstep = 1; + +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(masterDate,'YYYYmmDD')],... +% 'water_u',[NCOMstep 1 331 91],[1 40 240 180],[1 1 1 1]); +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_u',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.water_v(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_v',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.surf_el(:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'surf_el',[91 331 NCOMstep],[180 240 1],[1 1 1]); +% NCOM.salinity(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'salinity',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); + NCOM.water_u(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_u',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.water_v(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_v',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.surf_el(:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'surf_el',[91 331 1],[180 240 1],[1 1 1]); + NCOM.salinity(:,:,:,tCount) =ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'salinity',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + + if (squeeze(NCOM.water_v(100,100,1,end))==0|squeeze(NCOM.water_u(100,100,1,end))==0|squeeze(NCOM.surf_el(100,100,end))==0|squeeze(NCOM.salinity(100,100,1,end))==0)==1 + noData=1; + else + noData=0; + end + catch + noData=1; + end + disp(Ni) + end + NCOM.time(tCount) = Ni; + tStep=tStep+3; + tCount = tCount+1; + end + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + + + + %% NCOM Process + NCOM.mag = vecmag(NCOM.water_u,NCOM.water_v); + + if FIRST_RUN == 1 + depthWeight = [diff(NCOM.depth)' 0]; + + for Layer = 1:40 + DAVfac(:,:,Layer,:) = ones(180,240,1,17).*depthWeight(Layer); + end + DAVtrue = DAVfac; + N_depth = NCOM.depth; + save('NCOMstuff.mat','DAVtrue','DAVfac','N_depth') + else + load('NCOMstuff.mat') + NCOM.depth = N_depth; + clear N_depth; + end + DAVtrue(isnan(NCOM.mag(:,:,1:40,:))==1) = 0; + DAVfac(isnan(NCOM.mag(:,:,1:40,:))==1) = nan; + DAVFac2 = sum(DAVtrue,3); + clear DAVtrue + NCOM.dav = nansum(DAVfac.*NCOM.mag(:,:,1:40,:),3)./DAVFac2; + NCOM.davX = nansum(DAVfac.*NCOM.water_u(:,:,1:40,:),3)./DAVFac2; + NCOM.davY = nansum(DAVfac.*NCOM.water_v(:,:,1:40,:),3)./DAVFac2; + + Import=1 + catch err + + clear waterLevels + + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + disp('FAILED TO IMPORT FROM NOMADS') + pause(600) + end + end + + + load('shoreline.mat'); + + %% Format data for Delft3D + %% Evap + fileID=fopen('TemperatureRT.eva','w'); + refTime=minutes(masterTime-masterDate); + records=49; + for i = 1 : records + fprintf(fileID,'%d. 0. 0. %2.2f\n',refTime,temperature(i)); + + refTime = refTime + 60;% 1 hour time steps for temperature + end + + fclose(fileID); + + %% NCOM ESTOFS + % Currents from NCOM + + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [1081,i]; + % crIDX(idxCount,:) = [2161,i]; + + idxCount = idxCount + 1; + end + + crBoundCount(1) = 0; + crBoundCount(2) = idxCount -1; + + for i = 750:11:1080 % Every 5 km + % for i = round(linspace(1488,2161,14)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1320]; + % crIDX(idxCount,:) = [i,2641]; + + idxCount = idxCount + 1; + end + crBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + % for i = round(linspace(910,2161,26)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1]; + % crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + crBoundCount(4) = idxCount -1; + + + clear idxCount + + %% Interpolate Water Level + % for tStep = 1:length(tideOutN) + % wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); + % wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); + % wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); + % end + + vDatOrder = [crBoundCount(3)+1:1:crBoundCount(4) ... + crBoundCount(1)+1:1:crBoundCount(2) ... + crBoundCount(3):-1:crBoundCount(2)+1]; + + crBoundCountOld = [0 27 34 46]; + vDatOrderOld = [crBoundCountOld(3)+1:1:crBoundCountOld(4) ... + crBoundCountOld(1)+1:1:crBoundCountOld(2) ... + crBoundCountOld(3):-1:crBoundCountOld(2)+1]; + + vDatNavD = LMSL_RT(:,3); + vDatNavD(vDatNavD==-999999)=nan; + + % interp1(vDatNavD(vDatOrder),1:46) + vDatNavDInter(vDatOrder) = naninterp(interp1(... + linspace(1,length(vDatOrder),length(vDatOrderOld)),... + vDatNavD(vDatOrderOld),1:length(vDatOrder))); + for i = 1:length(idxNCOM) + wlO(:,i) = interp1(masterTime:hours(1):masterTime+hours(48),waterLevels(:,i)+0,masterTime:minutes(10):masterTime+hours(48),'pchip'); + end + + %% Match to grid + flowBed = load('Dec6_100Bed.mat'); + clear wlN mag DM dirGrid currents RN_1 currents_2 currents_40 currDir currDir40 + idxCount=1; + for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+vDatNavDInter(i); + mag(:,idxCount) = vecmag(currX,currY); + + % if idxCount==1 + % DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount+1,1)-1,crIDX(idxCount+1,2))); + % else + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + % end + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + % currents(:,idxCount) = sind(dirGrid(i)-0)'.*vecmag(currY); + + RN_1(:,idxCount) = -currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + + % disp(idxCount) + idxCount = idxCount + 1; + + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + %% interpolate Currents + clear currentsOut + for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(NCOM.time)); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(masterTime:minutes(10):masterTime+hours(48))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + % for j = 1:length(idxNCOM) + % currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + % interp2(xIN,yIN,... + % squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1))),... + % xOut,yOut); + % end + + end + idxCount=1; + + + for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + if i<230 + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); +% RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 1.*sqrt(9.81./DM(idxCount)); + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 0.*sqrt(9.81./DM(idxCount)); + end + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = -1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + end + + + + idxCount = idxCount+1; + end + + %% R Boundry Files + records=size(RNOut_2,1); + + for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; + end + + % boundryTypes(1) = {'water elevation (z)'}; + boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; + boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + + fileID=fopen('NCOM_R2.bct','w'); + + for Boundry = [2:length(boundryNames)] + refTime=minutes(masterTime-masterDate); + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + for line = 1:records + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_2(line,Boundry-1),RNOut_2(line,Boundry)); + + refTime=refTime+10; + end + end + + fclose(fileID); + %% Boundry definition file-R + fileID=fopen('NCOM_R.bnd','w'); + crIDX2=crIDX; + crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+2; + crIDX2(crBoundCount(1)+1:crBoundCount(2),1) = 1082; + + for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end + end + fclose(fileID); + + + %% Waves + records = size(waves,1); + fileID=fopen('WW3.bcw','w'); + + for i = 1:3 + boundryNames(i) = {['East' num2str(i)]}; + end + + for Boundry = 1:3 + refTime=minutes(masterTime-masterDate); + + header=[... + 'location ''East%d''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterTime,'yyyymmdd'))); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''WaveHeight '' unit ''[m]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Period '' unit ''[s]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Direction '' unit ''[N^o]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''DirSpreading '' unit ''[-]''\n'); + end + + for line = 1:records + fprintf(fileID,'%d ',refTime); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,1)); %Hs + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,2)); %Period + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,3)); %Direction + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',4); %Spread + end + fprintf(fileID,'\n'); + + % fprintf(fileID,'%.2f %1.4f %1.4f %1.4f %1.4f\n',refTime,... + % waves(line,Boundry,1),waves(line,Boundry,2),waves(line,Boundry,3),4); + refTime=refTime+180; + end + end + + fclose(fileID); + + + %% Modify MDF file to change reference date + + fileID = fopen('rt_base.mdf'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdf', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 15 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'Itdate = #%04d-%02d-%02d#\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 17 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID,['Tstart = %#.7e \n','Tstop = %#.7e \n'],refTime,refTime+2880); + + + + for i = 20:29 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + if FIRST_RUN == 0 + restID = ['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000']; + if exist(restID)==2 + eval(['movefile ' restID ' tri-rst.6h_restart']) + end + + fprintf( fileID,['Commnt = initial conditions from restart file\n'... + 'Restid = #6h_restart#\n']); + % delete tri-rst.rt* + else + + % fprintf( fileID,['Commnt = initial conditions from map file\n'... + % 'Restid = #Jan16_06#\n']); + + % fprintf( fileID,'Zeta0 = %#.7e \n',nanmean(nanmean(squeeze(wlO(1,:))))); + fprintf( fileID,'Zeta0 = %#.7e \n',0); + + end + + for i = 31:53 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % if FIRST_RUN==1 + % fprintf( fileID, 'Vicouv = 1.0000000e+002 \n'); + % else + fprintf( fileID, '%s\n', cac{1}{54} ); + % end + + for i = 55:64 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + if FIRST_RUN==1 + fprintf( fileID, 'Tlfsmo = 0.0000000e+001 \n'); + else + fprintf( fileID, 'Tlfsmo = 0.0000000e+000 \n'); + end + + for i = 66:94 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + + fprintf( fileID,[... + 'Flmap = %#.7e 60 %#.7e\n',... + 'Flhis = %#.7e 10 %#.7e\n',... + 'Flpp = %#.7e 60 %#.7e\n'],... + refTime,refTime+2880,refTime,refTime+2880,refTime,refTime+2880); + + for i = 98:109 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + clear cac + %% Modify MDW file to add times and change reference date + + fileID = fopen('rt_base.mdw'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdw', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 7 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'ReferenceDate = %04d-%02d-%02d\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 9 : 71 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % for i = 1 : records + % fprintf( fileID,'[TimePoint] \n Time = %#.7e \n',(i-1).*180); + % end + + bounOri{1}='East'; + bounOri{2}='North'; + bounOri{3}='South'; + bounRot{1}='counter-clockwise'; + bounRot{2}='counter-clockwise'; + bounRot{3}='clockwise'; + bounDef{1}='grid-coordinates'; + bounDef{2}='orientation'; + bounDef{3}='orientation'; + + + for Boundry = 1 : 3 + + if Boundry ==1 + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'StartCoordM = %d\n'... + 'EndCoordM = %d\n'... + 'StartCoordN = %d\n'... + 'EndCoordN = %d\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + ],Boundry,bounDef{Boundry},432,432,2,528); + else + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'Orientation = %s\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + 'DistanceDir = %s\n'... + ],Boundry,bounDef{Boundry},bounOri{Boundry},bounRot{Boundry}); + end + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'CondSpecAtDist = %d\n',waveDistAlong(Segment)); + end + end + + clear cac + fclose( fileID ); + + + %% Met Files + % Create new UTM grid of the HRRR Data + [UTM1D(:,1),UTM1D(:,2)] = wgs2utm(reshape(windGridLAT,1,[]),reshape(windGridLON,1,[]),... + 18,'N'); + HRRR_UTM(:,:,1) = double(reshape(UTM1D(:,1),size(windGridLON,1),size(windGridLON,2))); + HRRR_UTM(:,:,2) = double(reshape(UTM1D(:,2),size(windGridLON,1),size(windGridLON,2))); + clear UTM1D + + G7LR = load('C7_1400_V2_C.mat'); + G7bath = load('C7_1400_V2_D.mat'); + % Remove land rainfall + % if FIRST_RUN == 1 + landmask=zeros(size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % [HR_deg(:,1),HR_deg(:,2)] = utm2deg(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[]),reshape(G7LR.data.Y(1:end-1,1:end-1)',1,[]),repmat('18 S',length(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[])),1)); + % for ShoreLevel = 1:length(shoreline) + % landmask_Temp(:,:) = reshape(inpolygon(HR_deg(:,1),HR_deg(:,2),shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon),size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % + % landmask = landmask|landmask_Temp; + % clear landmask_Temp + % + % [shoreTempX,shoreTempY,shoreTempCell] = deg2utm(shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon); + % shoreUTM{ShoreLevel}(:,1) = shoreTempX(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % shoreUTM{ShoreLevel}(:,2) = shoreTempY(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % clear shoreTempX shoreTempY shoreTempCell + % disp(ShoreLevel) + % end + % save('shorelineInfo.mat','landmask','shoreUTM'); + % else + % load('shorelineInfo.mat'); + % end + clear HR_deg ShoreLevel + landmask(G7bath.data.Val'<0)=1; + landmask=logical(landmask); + + if masterTime>=datetime(2019,09,05,00,00,00) + runSteps = 49; + else + runSteps = 8; + end + + % Zero out met array + HRRR_INTER = zeros(4,runSteps,size(G7LR.data.X(1:end-1,1:end-1),2),size(G7LR.data.X(1:end-1,1:end-1),1)); + + % Interpolate against flowGrid for each time step + for TS = 1:runSteps + HRRR_INTER(1,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windU(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + HRRR_INTER(2,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windV(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + rainTemp = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(rain(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + rainTemp(landmask)=rainTemp(landmask)*0; % 100% infiltration + HRRR_INTER(3,TS,:,:) = rainTemp; % Convert to hours + clear rainTemp + + HRRR_INTER(4,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(pressure(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + end + + % Set nan to Delft3D zero value + HRRR_INTER(isnan(HRRR_INTER)==1)=-999.000; + + % Create input files + m = size(HRRR_INTER,3); + n = size(HRRR_INTER,4); + d3ddx = 5000; + d3ddy = 5000; + disp(m) + d3d_input_uvpFieldsCL_FUN(masterTime,m,n,... + squeeze(HRRR_INTER(4,:,:,:)),squeeze(HRRR_INTER(1,:,:,:)),squeeze(HRRR_INTER(2,:,:,:)),squeeze(HRRR_INTER(3,:,:,:)),1,'hrrr',runSteps) + + save(['ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat'],'windU','windV','pressure','rain','temperature','waves','waterLevels','NCOM','-v7.3') + + %% Run Delft3D FLOW/WAVE! + % system('. /home/cluster/D7545/enviorment.sh' + + system('runcoast_flow2d3d_parallel_wave.bat') + if exist('wavm-rt_run.dat')~=2 + fid = fopen('errorFile.log','a+'); + fprintf(fid,'Delft Batch File Fallback\n'); + + % close file + fclose(fid) + disp('Run Fallback') + pause(60) + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + delete swn-diag.* + + system('runcoast_flow2d3d_parallel_wave.bat') + end + + %% Move things + pause(60) + + eval(['copyfile trih-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.dat']) + eval(['copyfile trih-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.def']) + + eval(['movefile ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat D:\DUNEX_RT\Archive\ModelIn_7' datestr(masterTime,'YYYY-mm-DD_HH') '.mat']) + % eval(['copyfile tri-rst.rt* D:\Alexander\RealtimeHRRR\']) + + +% eval(['copyfile hrrr.amu D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amu']) +% eval(['copyfile hrrr.amv D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amv']) +% eval(['copyfile hrrr.ampr D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.ampr']) +% eval(['copyfile hrrr.amp D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amp']) +% eval(['copyfile trim-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.dat']) +% eval(['copyfile trim-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.def']) +% eval(['copyfile wavm-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.dat']) +% eval(['copyfile wavm-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.def']) + + + + %% Clear things not needed for plotting + clear HRRR_INTER flowGrid lonHRRR_Mesh windU windV rain pressure waveGrid + + + delete(gcp('nocreate')) + parpool(3); + %% Import Model Results + addpath(genpath('matlab/applications/delft3d_matlab'),'-begin') + + modelWater = qpread(qpfopen('trim-rt_run.dat'),1,'water level','griddata',0,0,0); + flowGrid = load('Cone7W_100.mat'); + waveGrid = load('Cone7W_250.mat'); + flowBed = load('Dec6_100Bed.mat'); + waveBed = load('Dec6_250Bed.mat'); + + %% Create GeoTIFF for water levels + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + timeIDXNames = [1 4 7 13 25 37]; % For Geoserver + + yMinOffset = 75; + yMaxOffset = 25; + + parfor Time = 1:6 + % X{Time} = modelWater.X; + % Y{Time} = modelWater.Y; + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + + modelPlot_1 = squeeze(modelWater.Val(timeIDX(Time),1:end-1,1:end-1)); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['WL_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWater + + modelWaterDAV = qpread(qpfopen('trim-rt_run.dat'),1,'depth averaged velocity','griddata',0,0,0); + + %% Create GeoTIFF for DAVs + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoDat modelPlot_1 + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + if FIRST_RUN == 1 + Times = 2:6; + else + Times = 1:6; + end + + + parfor Time = Times + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + modelPlot_1 = sqrt(squeeze(modelWaterDAV.XComp(timeIDX(Time),1:end-1,1:end-1)).^2+... + squeeze(modelWaterDAV.YComp(timeIDX(Time),1:end-1,1:end-1)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['DAV_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + %% Quiver for DAV + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + vecScale(4) = 100000; + vecScale(3) = 50000; + vecScale(2) = 2500; + vecScale(1) = 1000; + + for Time = Times + + X{Time} = flowGrid.data.X(2:end,2:end); + Y{Time} = flowGrid.data.Y(2:end,2:end); + modelPlot_1 = squeeze(modelWaterDAV.XComp(timeIDX(Time),2:end,2:end)); + modelPlot_2 = squeeze(modelWaterDAV.YComp(timeIDX(Time),2:end,2:end)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(400:520,525:620)=nan; + + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + modelPlot_2(:,1:yMinOffset)=nan; + modelPlot_2(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + qSpace = [4 16 50 100] + + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + for i = 1:length(Xdat{Time}) + if ((Udat{Time}(i))==0 && (Vdat{Time}(i))==0) ||... + (isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1) ||... + ((isnan(Udat{Time}(i)))==1 && isnan(Vdat{Time}(i))==1) + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + + Xdat{Time}=[]; + Ydat{Time}=[]; + Udat{Time}=[]; + Vdat{Time}=[]; + q{Time}=[]; + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['DAV_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj DAV_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaterDAV + + %% Create GeoTIFF for HS + + modelWaves = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave height','griddata',0,0,0); + modelWavesDir = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave vector (mean direction)','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize GeoS + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = (squeeze(modelWaves.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):250:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):250:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):250:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):250:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-0,1:end-0),1,[]),... + reshape(Y{Time}(1:end-0,1:end-0),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['HS_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for HS + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + vecScale(4) = 15000; + vecScale(3) = 5000; + vecScale(2) = 1000; + vecScale(1) = 500; + + for Time = 1:6 + + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = squeeze(modelWavesDir.XComp(timeIDX(Time),:,:)); + modelPlot_2 = squeeze(modelWavesDir.YComp(timeIDX(Time),:,:)); + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(155:205,210:265)=nan; + + + qSpace = [2 10 20 40] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + elseif isnan(Udat{Time}(i))==1 && isnan(Vdat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['HS_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj HS_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaves + clear modelWavesDIR + + %% Create GeoTIFF for Wind + modelWaterWind = qpread(qpfopen('trim-rt_run.dat'),1,'wind speed','griddata',0,0,0); + + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS ValX ValY + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = sqrt(squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)).^2+... + squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):1000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):1000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):1000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):1000:R{Time}.YWorldLimits(2)); + + Val{Time}(Val{Time}==0)=nan; + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['Uw_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for Wind + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + + vecScale(4) = 3000; + vecScale(3) = 500; + vecScale(2) = 100; + vecScale(1) = 40; + + for Time = 1:6 + + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + ValX{Time} = squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)); + ValY{Time} = squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)); + + + qSpace = [5 25 50 100] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),Y{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),... + squeeze(ValX{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),squeeze(ValY{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['Uw_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj Uw_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaterWind + + %% Create GeoTIFF for Prep + + modelWaterPrep = qpread(qpfopen('trim-rt_run.dat'),1,'precipitation rate','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = (squeeze(modelWaterPrep.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):10000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):10000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):10000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):10000:R{Time}.YWorldLimits(2)); + + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geotiffwrite(['Prep_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWaterPrep + + %% Export to GEOSERVER + try + copyfile *.tif \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.dbf \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shx \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shp \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.prj \\geoserver.engineering.queensu.ca\TIFFS\ + catch + end + + %% Import Model forecast + modelWaterHist = qpread(qpfopen('trih-rt_run.dat'),1,'water level','data',0,0); + modelCurHist = qpread(qpfopen('trih-rt_run.dat'),1,'depth averaged velocity','data',0,0); + + %% Validation import ESTOFS + %load('DUNEX_Nov20.mat') + load('DUNEX_Sept7.mat') %hohonu pts + + clear ESTOFS lonESTOFS lonESTOFS + + wLIDX=[6 7 8 38]; + wlGrid = [5000 -4000 0 -2000]; + wlGridY = [0 0 2000 5000]; %7500 + ESTOFStimeOffset = [0 12 24 48]; + ESTOFSrunLength = [48 60 72 96]; + + for e = [1 4] + try + clear meshX meshY + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(0,'%03d') '.grib']); + + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTOFS_Val{e} = 1; + catch + ESTOFS_Val{e} = 0; + end + end + clear waterLevelsESTOFSINTER waterLevelsESTOFS + for e = [1 4] + try + for Stat = 1:4 + if ESTOFS_Val{e} == 0 + estofsWL(:,Stat,e) = zeros(49,1); + else + [wlDeg(2),wlDeg(1)] = utm2deg(pointsCS{wLIDX(Stat),2}+wlGrid(Stat),pointsCS{wLIDX(Stat),3}+wlGridY(Stat),'18 S'); + [estofIDX] = NearestValue(wlDeg,lonESTOFS,latESTOFS); %Lat + + for i = 1:ESTOFSrunLength(e)+1 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(i-1,'%03d') '.grib']); + + waterLevelsESTOFS{e}(i,Stat) = squeeze(ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,estofIDX(1),estofIDX(2))); + end + waterLevelsESTOFSINTER{e}(:,Stat) = interp1(masterTime-hours(ESTOFStimeOffset(e)):minutes(60):masterTime+hours(48),... + waterLevelsESTOFS{e}(:,Stat),masterTime-hours(ESTOFStimeOffset(e)):minutes(15):masterTime+hours(48),'spline'); + end + end + catch + waterLevelsESTOFSINTER{e}(:,Stat) = zeros(1,385); + end + end + + + %% Validation import WL + % Duck + % Oregon Inlet + % Hatteras + % Beaufort + clear stations statWL + options = weboptions; + options.Timeout = 30; + + stations = {8651370,8652587,8654467,8656483}; + dateStartM = masterTime-hours(48); + dateEndM = masterTime+hours(5); + + for Stat = 1:4 + try + url = ['https://tidesandcurrents.noaa.gov/api/datagetter?product=water_level&application=NOS.COOPS.TAC.WL&'... + 'begin_date=' datestr(dateStartM,'yyyymmdd') '&end_date=' datestr(dateEndM,'yyyymmdd') '&datum=NAVD' '&station=' num2str(stations{Stat})... + '&time_zone=GMT&units=metric&format=csv']; + + wlIN = webread(url,options); + + statWL(:,Stat) = interp1(wlIN.DateTime,wlIN.WaterLevel,dateStartM:minutes(15):dateEndM); + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statWL(:,Stat) = 0; + end + + + clear wlIN + + end + + %% Validate Import Hohonu + + hohonuBase = 'https://dashboard.hohonu.io/api/stations/node-'; + + hohonuStation(5:10) = [ + 10015; %Duck, Dare County, NC + 10020; %Southern Shores, NC + 10011; %Collington Creek Inn Dock, Kill Devil Hills + 10012; %Jennette's Pier, Nags Head + 10009; %Hwy 64, Little Bridge + 10010]; %Coastal Studies Institute, Wanchese, NC + + hohonuDatums(5:10) = [ + 6.03; + 6.41; + 5.777; + 25.742; + 6.889; + 8.3]*304.8; % In feet, convert to mm + + + for Stat = 5:10 + fname = ['D:\DUNEX_RT\Operation\Hohonu\' num2str(hohonuStation(Stat)) '.json']; + try + websave(fname,... + [hohonuBase num2str(hohonuStation(Stat)) '/statistic/?cleaned=true&format=json&from='... + datestr(dateStartM,'yyyy-mm-dd') '+00%3A00&to=' datestr(dateEndM,'yyyy-mm-dd')... + '+23%3A59']); + + fid = fopen(fname); + raw = fread(fid,inf); + str = char(raw'); + fclose(fid); + + hohonuIN = jsondecode(str); + + % Filter out data more than 1 standard deviation + hmean = mean((hohonuDatums(Stat) - hohonuIN.data{2}) * 0.001); + hstd = std((hohonuDatums(Stat) - hohonuIN.data{2}) * 0.001); + hohonuFilt = abs((hohonuDatums(Stat) - hohonuIN.data{2}) * 0.001)>(abs(hmean)+hstd); + + statWL(:,Stat) = interp1(datetime(hohonuIN.data{1}(~hohonuFilt),'InputFormat','yyyy-MM-dd''T''HH:mm:SS'),... + (hohonuDatums(Stat) - hohonuIN.data{2}(~hohonuFilt)) * 0.001,dateStartM:minutes(15):dateEndM); + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statWL(:,Stat) = 0; + end + clear fid raw str hohonuIN fname + end + + + + + %% Validation import Currents + % Duck + clear statCur + for Stat = 1 + % url = 'https://chlthredds.erdc.dren.mil/thredds/dodsC/frf/oceanography/currents/awac-11m/awac-11m.ncml'; + % curTime = ncread(url,'time'); + % curVal = ncread(url,'currentSpeed'); + try + if day(masterTime)<2 + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime-day(3),'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime-days(3),'YYYYmm') '.nc'],options); + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + curTime = vertcat(curTime,ncread('statCNC.nc','time')); + curVal = vertcat(curVal,ncread('statCNC.nc','currentSpeed')); + + else + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + end + + statCur(:) = interp1(datetime(curTime,'convertFrom','POSIX'),curVal,dateStartM:minutes(15):dateEndM); + clear wlIN + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statCur(:) = zeros(length(dateStartM:minutes(15):dateEndM),1); + end + end + + %% Validation import Waves + % Virginia Beach + % Duck 26 + % Nages Head + % Oregon Inlet + % Diamond Shoals + clear stations + + stations = {44014,44100,44086,44095,41025}; + dateStartM = masterTime-hours(48); + dateEndM = masterTime+hours(5); + + clear statWave + + for Stat = 1:5 + try + if ismember(Stat,[1,5]) == 1 + url = ['https://www.ndbc.noaa.gov/data/5day2/' num2str(stations{Stat}) '_5day.txt']; + + websave('NDBCdata.txt',url,options); + opts = delimitedTextImportOptions("NumVariables", 39); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, 15, "TrimNonNumeric", true); + opts = setvaropts(opts, 15, "ThousandsSeparator", ","); + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + else + url = ['https://www.ndbc.noaa.gov/data/realtime2/' num2str(stations{Stat}) '.txt']; + websave('NDBCdata.txt',url); + + opts = delimitedTextImportOptions("NumVariables", 52); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39", "Var40", "Var41", "Var42", "Var43", "Var44", "Var45", "Var46", "Var47", "Var48", "Var49", "Var50", "Var51", "Var52"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "categorical", "categorical", "categorical", "double", "double", "double", "double", "categorical", "categorical", "double", "double", "categorical", "categorical", "categorical", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "TrimNonNumeric", true); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "ThousandsSeparator", ","); + opts = setvaropts(opts, [6, 7, 8, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + end + + % Import the data + waveIN = readtable("NDBCdata.txt", opts); + waveNAN = isnan(waveIN.WVHT)==0; + % Hs + statWave(:,1,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.WVHT(waveNAN)),dateStartM:minutes(15):dateEndM); + % DPD + % statWave(:,2,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + % (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + % (waveIN.DPD(waveNAN)),dateStartM:minutes(10):dateEndM); + % APD + statWave(:,3,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.APD(waveNAN)),dateStartM:minutes(15):dateEndM); + %MWD + statWave(:,4,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.MWD(waveNAN)),dateStartM:minutes(15):dateEndM); + clear waveIN opts + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + %fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + %sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]); + + % close file + fclose(fid) + statWave(:,:,Stat) = zeros(size(dateStartM:minutes(15):dateEndM,2),4,1); + end + end + statWave(isnan(statWave))=0; + %% Import Model Waves + + for i = 1:49 + startRow = 8; + formatSpec = '%13f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%f%[^\n\r]'; + + fileID = fopen(['Sept7.loct00000' num2str(i,'%02d') '.tab'],'r'); + + % This call is based on the structure of the file used to generate this + % code. If an error occurs for a different file, try regenerating the code + % from the Import Tool. + dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines' ,startRow-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + + fclose(fileID); + modelWaveIN= table(dataArray{1:end-1}, 'VariableNames', {'Xp','Yp','Depth','Hsig','Dir','RTpea','kTm01','Dspr','Ubot','XWindv','YWindv','XVel','YVel'}); + + modelWave(:,1,i) = modelWaveIN.Hsig; + modelWave(:,3,i) = modelWaveIN.RTpea; + modelWave(:,4,i) = modelWaveIN.Dir; + + + clearvars filename startRow formatSpec fileID dataArray ans modelWaveIN; + + end + + %% Import Model WL + modelWL = modelWaterHist.Val; + modelCur = sqrt(modelCurHist.XComp.^2+modelCurHist.YComp.^2); + + for idx = 1:size(modelWL,2) + modelWLInter(:,idx) = interp1(modelWaterHist.Time,modelWL(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))); + end + for idx = 1:size(modelCur,2) + modelCurInter(:,idx) = sqrt(interp1(modelCurHist.Time,modelCurHist.XComp(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))).^2+... + interp1(modelCurHist.Time,modelCurHist.YComp(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))).^2); + end + + save(['ModelOut_' datestr(masterTime,'dd-mmm-yyyy_HH') 'Z.mat'],'modelWL','modelWave','statWL','statWave','modelCur','statCur','modelWLInter','modelCurInter','-v7.3'); + + %% Import Historic Model WL + if masterTime>=datetime(2021,07,08) + try + H12 = load(['ModelOut_' datestr(masterTime-hours(12),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H24 = load(['ModelOut_' datestr(masterTime-hours(24),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H48 = load(['ModelOut_' datestr(masterTime-hours(48),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + end + %% Save html for Currents + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + locLine = 1:5:67; + locationsWave ={'FRF 11 m AWAC '}; + +% % for i = 1:433 +% % for j = 1:100 +% % modelDavDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,2],modelDavDel) + + davIDX=[17 161:172]; + + clear modelCurPlot curValLoc + for Loc = 1:13 + for Line=1:5 + switch Line + case 1 + curValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelCurPlot(1:385,locLine(Loc)+0) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:192,locLine(Loc)+0) = {''}; + modelCurPlot(193:1:385,locLine(Loc)+0) = num2cell(modelCurInter(:,davIDX(Loc))); + case 2 + curValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelCurPlot(1:385,locLine(Loc)+1) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:143,locLine(Loc)+1) = {''}; + modelCurPlot(337:385,locLine(Loc)+1) = {''}; + modelCurPlot(144:1:336,locLine(Loc)+1) = num2cell(H12.modelCurInter(:,davIDX(Loc))); + + case 3 + curValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelCurPlot(1:385,locLine(Loc)+2) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:96,locLine(Loc)+2) = {''}; + modelCurPlot(290:385,locLine(Loc)+2) = {''}; + modelCurPlot(97:1:289,locLine(Loc)+2) = num2cell(H24.modelCurInter(:,davIDX(Loc))); + + case 4 + curValLoc{Line} = ['-48 Hour: ' datestr(masterTime-hours(48),'mm/dd HH') 'Z Run']; + if exist('H48','var') ==0 + modelCurPlot(1:385,locLine(Loc)+3) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(194:385,locLine(Loc)+3) = {''}; + modelCurPlot(1:1:193,locLine(Loc)+3) = num2cell(H48.modelCurInter(:,davIDX(Loc))); + case 5 + curValLoc{Line} = ['Observed Velocity']; + if Loc> 1 || isnan(statCur(1,Loc)) + modelCurPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(214:385,locLine(Loc)+4) = {''}; + modelCurPlot(1:213,locLine(Loc)+4) = num2cell(statCur); + + end + + end + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],modelCurPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],curValLoc) + curValLoc = repmat(curValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... + [1,1],horzcat(googleDatesCell',vertcat(curValLoc(1:size(modelCurPlot,2)),modelCurPlot))) + %% Save html for WL + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + + clear wlValLoc + +% locLine = [2 7 12 17 22 27]; +% locLine = [2 9 16 23 30 37]; +% locLine = 1:7:114; + locLine = 1:7:156; % Hohonu locations + + locationsWl ={'FRF Pier',... + 'Oregon Inlet',... + 'Hatteras',... + 'Beaufort'}; + +% % for i = 1:433 +% % for j = 1:121 +% % modelWlDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,2],modelWlDel) + + wLIDX=[6 7 8 38 161:172 181:186]; + clear modelWlPlot wlValLoc + for Loc = 1:length(wLIDX) +% modelwlPlot = cell(432,4); + for Line=[1:5 6 9] + switch Line + case 1 + wlValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelwlPlot(1:385,locLine(Loc)+0) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:192,locLine(Loc)+0) = {''}; + modelwlPlot(193:1:385,locLine(Loc)+0) = num2cell(modelWLInter(:,wLIDX(Loc))); + case 2 + wlValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelwlPlot(1:385,locLine(Loc)+1) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:143,locLine(Loc)+1) = {''}; + modelwlPlot(337:385,locLine(Loc)+1) = {''}; + modelwlPlot(144:1:336,locLine(Loc)+1) = num2cell(H12.modelWLInter(:,wLIDX(Loc))); + + case 3 + wlValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelwlPlot(1:385,locLine(Loc)+2) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:96,locLine(Loc)+2) = {''}; + modelwlPlot(290:385,locLine(Loc)+2) = {''}; + modelwlPlot(97:1:289,locLine(Loc)+2) = num2cell(H24.modelWLInter(:,wLIDX(Loc))); + + case 4 + wlValLoc{Line} = ['-48 Hour: ' datestr(masterTime-hours(48),'mm/dd HH') 'Z Run']; + if exist('H48','var') ==0 + modelwlPlot(1:385,locLine(Loc)+3) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(194:385,locLine(Loc)+3) = {''}; + modelwlPlot(1:1:193,locLine(Loc)+3) = num2cell(H48.modelWLInter(:,wLIDX(Loc))); + case 5 + wlValLoc{Line} = ['Observed Water Level']; + modelwlPlot(214:385,locLine(Loc)+4) = {''}; + if Loc <5 + if isnan(statWL(1,Loc)) + modelwlPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + else + modelwlPlot(1:213,locLine(Loc)+4) = num2cell(statWL(:,Loc)); + end + elseif Loc>=17 % Hohonu starts at 17 + if isnan(statWL(1,Loc-12)) %-12 to get to Hohonu IDX + modelwlPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + else + modelwlPlot(1:213,locLine(Loc)+4) = num2cell(statWL(:,Loc-12)); + end + else + modelwlPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + end + case 6 + wlValLoc{Line} = ['ESTOFS Forecast']; +% % if Loc>4 || ESTOFS_Val{1} == 0 + modelwlPlot(1:385,locLine(Loc)+5) = num2cell(zeros(385,1)); +% % continue +% % end +% % modelwlPlot(1:192,locLine(Loc)+5) = {''}; +% % modelwlPlot(193:385,locLine(Loc)+5) = num2cell(waterLevelsESTOFSINTER{1}(:,Loc)); + case 9 + wlValLoc{7} = ['-48 Hour ESTOFS']; +% if Loc>4 || ESTOFS_Val{4} == 0 + modelwlPlot(1:385,locLine(Loc)+6) = num2cell(zeros(385,1)); +% % continue +% % end +% % modelwlPlot(1:1:385,locLine(Loc)+6) = num2cell(waterLevelsESTOFSINTER{4}(:,Loc)); + end + end + disp(Loc) + + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [2,locLine(Loc)],modelwlPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [1,locLine(Loc)],wlValLoc) + + wlValLoc = repmat(wlValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... + [1,1],horzcat(googleDatesCell',vertcat(wlValLoc(1:size(modelwlPlot,2)),modelwlPlot))) + + %% Save html for Waves + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,1],googleDates') + +% locLine = [2 7 12 17 22 27]; + locLine = 1:5:114; + + locationsWave ={'Virginia Beach',... + 'FRF 26 m',... + 'Nags Head',... + 'Oregon Inlet',... + 'Diamond Shoals'}; + + clear waveValLoc modelwavePlot + + for i = 1:385 + for j = 1:85 + modelwavePlot(i,j)={''}; + end + end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,2],modelWaveDel) + + waveIDX = [12 13 14 15 16 161:172]; + for Loc = 1:length(waveIDX) +% modelwavePlot = cell(432,5); + for Line=1:5 + switch Line + case 1 + waveValLoc{Line} = ['Forecast']; + if exist('modelWave','var') ==0 + modelwavePlot(1:385,locLine(Loc)+0) = num2cell(zeros(433,1)); + continue + end + modelwavePlot(1:191,locLine(Loc)+0) = {''}; + modelwavePlot(192,locLine(Loc)+0) = {0}; + modelwavePlot(193:4:385,locLine(Loc)+0) = num2cell(modelWave(waveIDX(Loc),1,:)); + case 2 + waveValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 || size(H12.modelWave,1)5 || isnan(statWave(1,1,Loc)) + modelwavePlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelwavePlot(215:385,locLine(Loc)+4) = {''}; + modelwavePlot(214,locLine(Loc)+4) = {0}; + modelwavePlot(1:1:213,locLine(Loc)+4) = num2cell(statWave(:,1,Loc)); + + end + + end +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [2,locLine(Loc)],modelwavePlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [1,locLine(Loc)],waveValLoc) + end + + waveValLoc = repmat(waveValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... + [1,1],horzcat(googleDatesCell',vertcat(waveValLoc(1:size(modelwavePlot,2)),modelwavePlot))) + + + + + %% Import and modify times +% modelHour = [0 3 6 12 24 48]; + modelHour = [0 6 12 24 36 48]; + for i = 1:6 + dateText(i) = {[datestr(masterTime+hours(modelHour(i)),'mmm dd, HH:MM') ' UTC (Hour '... + num2str(modelHour(i),'%d') ')']}; + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','0',[1,1],... + dateText) + +catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['ALL-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + +end + +%% +quit + + + + + + + + + + + + + + + + diff --git a/Dunex_Operational_Feb28_Backup.m b/Dunex_Operational_Feb28_Backup.m new file mode 100644 index 0000000..9787d82 --- /dev/null +++ b/Dunex_Operational_Feb28_Backup.m @@ -0,0 +1,2139 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +% Moved to COASTLINES Feb 29, 2020 + +clear all +cd D:\DUNEX_RT\Operation +echo off; +addpath('NCtoolbox') +addpath('m_map') +setup_nctoolbox +flowGrid = load('Cone7W_100.mat'); +waveGrid = load('Cone7W_250.mat'); +load('LMSL_RT.mat') +addpath('D:\DUNEX_RT\Operation\abogaard-matlab2gsheets-6d76271') +setenv('PATH', [getenv('PATH') ';D:\DUNEX_RT\Windows_64']); + +%% Details for e-mail server +setpref('Internet','SMTP_Server','smtp.sendgrid.net'); +setpref('Internet','E_mail','mail@alexanderrey.ca'); +setpref('Internet','SMTP_Username','apikey'); +setpref('Internet','SMTP_Password','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'); +props = java.lang.System.getProperties; +props.setProperty('mail.smtp.auth','true'); +props.setProperty('mail.smtp.socketFactory.class', 'javax.net.ssl.SSLSocketFactory'); +props.setProperty('mail.smtp.socketFactory.port','465'); +props.setProperty('mail.smtp.starttls.enable','true'); + + +%% Master Model Time Step +% Every 6 hours + +nistTime = datetime(datevec(now())) - tzoffset(datetime(datevec(now()),'TimeZone','local')); +masterTime = dateshift(nistTime,'start','hour')-hours(2) % Assume script will run at 5 and a half hours after model start +clear nistTime +masterDate = datetime(year(masterTime),month(masterTime),day(masterTime)); + +if exist(['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000'])==2 + FIRST_RUN = 0; +else + FIRST_RUN = 1; +end + +%% Import +try + Import=0; + + + %% Clean files from previous run + system('taskkill /IM "d_hydro.exe" /F') + system('taskkill /IM "wave.exe" /F') + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + + clear HRRR_UTM + while Import==0 + try + %% Import data from NOMADS + %% Extratropical Surge and Tide Operational Forecast System for the Atlantic + % (ESTOFS Atlantic) for water levels + options = weboptions; + options.Timeout = 90; + try + url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs_atl.'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/estofs.atl.t' datestr(masterTime-hours(6),'hh') 'z.conus.f000.grib2']; + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 6; + catch + % url = ['http://nomads.ncep.noaa.gov/dods/estofs_atl/'... + % datestr(masterTime-days(1),'yyyymmdd')... + % '/estofs_atl_conus_' datestr(masterTime-days(1),'hh') 'z']; + % ESTOFS = ncgeodataset(url); + % lonESTOFS=ESTOFS{'lon'}(:); + % latESTOFS=ESTOFS{'lat'}(:); + % ESTstart = 24+ESTstart; + url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs_atl.'... + datestr(masterTime-days(1),'yyyymmdd')... + '/estofs.atl.t' datestr(masterTime-days(1),'hh') 'z.conus.f000.grib2']; + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 24; + end + + + clear url + + % Find ESTOFS index for grid points along boundry + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); %Lat + wlIDX(idxCount,:) = [1082,i]; + + idxCount = idxCount + 1; + end + + wlBoundCount(1) = 0; + wlBoundCount(2) = idxCount -1; + + + for i = 750:11:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1322]; + idxCount = idxCount + 1; + end + + wlBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1]; + idxCount = idxCount + 1; + end + wlBoundCount(4) = idxCount -1; + + clear idxCount gridDeg + + % Extract ESTOFS Water Levels for 36 hours at indexes + % waterLevelsGRID = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(ESTstart:ESTstart+36,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + % min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + + % Find ESTOFS values from small grid + idxCount=1; + errorET = 0; + for i = ESTstart:ESTstart+72 + if errorET<10 + try + url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs_atl.'... + datestr(masterTime-hours(ESTstart),'yyyymmdd')... + '/estofs.atl.t' datestr(masterTime-hours(ESTstart),'hh') 'z.conus.f'... + num2str(i,'%03d') '.grib2']; + + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib'],url,options) + + if i<=ESTstart+36 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib']); + + waterLevelsGRID(idxCount,:,:) = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + end + idxCount = idxCount + 1; + catch + errorET = errorET+1; + end + else + error('ESTOFS ERROR') + end + + end + + idxCount=1; + for i = 1:length(idxESTOFS) + waterLevels(:,idxCount) = waterLevelsGRID(:,idxESTOFS(idxCount,1)-min(idxESTOFS(:,1))+1,... + idxESTOFS(idxCount,2)-min(idxESTOFS(:,2))+1); + + idxCount = idxCount + 1; + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + disp('Loaded ESTOFS') + %% Multi-grid Wave model (WAVEWATCH III) + % 4 arc minute US East Coast grid for waves + + url = ['http://nomads.ncep.noaa.gov/dods/wave/mww3/'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/multi_1.at_4m' datestr(masterTime-hours(6),'yyyymmdd') '_' datestr(masterTime-hours(6),'hh') 'z']; + + MWW3 = ncgeodataset(url); + clear url + + lonMWW3=wrapTo180(MWW3{'lon'}(:)); + latMWW3=MWW3{'lat'}(:); + + % Find MWW3 index for grid points along boundry + idxCount=1; + for i = 1:25:length(waveGrid.data.Y)-25 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(end-2,i),waveGrid.data.Y(end-2,i),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(end-2,1:i)).^2+... + diff(waveGrid.data.Y(end-2,1:i)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(end-2,i); + waveUTM(idxCount,2) = waveGrid.data.Y(end-2,i); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + waveBoundCount(1) = 0; + waveBoundCount(2) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:350% Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,end-2),waveGrid.data.Y(i,end-2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,end-2)).^2+... + diff(waveGrid.data.Y(i:end-2,end-2)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,end-2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,end-2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + % 0 132 163 285 + + waveBoundCount(3) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:240 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,2),waveGrid.data.Y(i,2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,1)).^2+... + diff(waveGrid.data.Y(i:end-2,1)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(4) = idxCount -1; + + clear idxCount + + % Extract WW3 Hs for 36 hours at indexes + wavesGRID_Hs = MWW3{'htsgwsfc'}(7:19,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid htsgwsfc + %swell_1 + % Period + wavesGRID_P = MWW3{'perpwsfc'}(7:19,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... % + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid perpwsfc + %swper_1 + % Direction + wavesGRID_Dir = MWW3{'dirpwsfc'}(7:19,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid dirpwsfc + %swdir_1 + % Find WW3 values from small grid + idxCount=1; + for i = 1:length(idxMWW3) + waves(:,idxCount,1) = wavesGRID_Hs(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Hs + + waves(:,idxCount,2) = wavesGRID_P(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Tp + + waves(:,idxCount,3) = wavesGRID_Dir(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Dir + + idxCount = idxCount + 1; + end + clear idxCount + disp('Loaded WW3') + + + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; + delete(gcp('nocreate')) + parpool(8); + + parfor ForcastHour = 0:36 + % url = ['http://nomads.ncep.noaa.gov/pub/data/nccf/com/hrrr/prod/'... + % 'hrrr.' datestr(masterTime,'yyyymmdd')... + % '/conus/hrrr.t' num2str(hour(masterTime),'%02d') 'z.'... + % 'wrfsfcf' num2str(ForcastHour,'%02d') '.grib2']; + + url = ['https://nomads.ncep.noaa.gov/cgi-bin/filter_hrrr_2d.pl?file=hrrr.'... + 't' num2str(hour(masterTime),'%02d') 'z.wrfsfc'... + 'f' num2str(ForcastHour,'%02d') '.grib2&'... + 'lev_10_m_above_ground=on&lev_surface=on&var_APCP=on&var_PRES=on&var_UGRD=on&var_VGRD=on&var_TMP=on&subregion=&leftlon=-78&rightlon=-74&toplat=38&bottomlat=32.5&dir=%2F'... + 'hrrr.' datestr(masterTime,'yyyymmdd') '%2Fconus']; + + websave(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2'],url) + + [pCheck,gridParams] = system(['perl "D:\DUNEX_RT\Windows_64\grid_defn.pl" '... + 'D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + [wCheck,gridParams] = system(['wgrib2 D:\DUNEX_RT\Operation\HRRR\hrrrT' ... + num2str(ForcastHour,'%02d') '.grib2 -new_grid_winds earth -new_grid ' ... + gridParams ' D:\DUNEX_RT\Operation\HRRR\hrrrT'... + num2str(ForcastHour,'%02d') '.grib2.regrid']); + end + delete(gcp('nocreate')) + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(0,'%02d') '.grib2.regrid']); + clear url + + m_proj('lambert conformal conic','ori',[262.5 38.5],'clo',262.5,'par',[38.5 38.5],'ell','sphere');%,'lat',[20 55],'lon',[-60 -130] + [meshX,meshY] = meshgrid(HRRR{'x'}(:),HRRR{'y'}(:)); + [windGridLON,windGridLAT] = m_xy2ll(meshX.*1000,meshY.*1000); + windGridLON=wrapTo180(windGridLON); + clear meshX meshY + + % Extract MWW3 Hs for 36 hours at indexes + for ForcastHour = 0:36 + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2.regrid']); + windU(ForcastHour+1,:,:) = HRRR{'u-component_of_wind_height_above_ground'}(:,:,:); %U Winds @ 10m [m/s] + windV(ForcastHour+1,:,:) = HRRR{'v-component_of_wind_height_above_ground'}(:,:,:); %V Winds @ 10m [m/s] + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + pressure(ForcastHour+1,:,:) = HRRR{'Pressure_surface'}(:,:,:); %Surface Pressure [pa] + + if ForcastHour==0 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_0_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + elseif ForcastHour==1 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_1_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + else + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_Mixed_intervals_Accumulation'}(2,:,:); %Surface precipitation [kg/m^2] + end + temperature(ForcastHour+1) = squeeze(nanmean(nanmean(HRRR{'Temperature_surface'}(:,:,:)- 273.15,2),3)); %Surface Temperature [C] + end + % Extract Temp + + disp('Loaded HRRR') + + + %% IMPORT NCOM + try + nComDate=masterDate + ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; + NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); + NCOM.Lon = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lon',91,180); + catch + try + if hour(masterTime) ~= 18 + nComDate=masterDate-days(1); + else + nComDate=masterDate; + end + ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; + NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); + NCOM.Lon = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lon',91,180); + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + end + + if FIRST_RUN == 1 + NCOM.depth = ncread('D:\Alexander\NCOM\2019090500_t000.nc','depth'); + end + + Noffset = hours(masterTime - nComDate); + tStep = Noffset; + tCount = 1; + + try + for Ni = masterTime:hours(3):masterTime+hours(36) + noData=1; + while noData==1 + try + NCOMstep = tStep./3+1; + % NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(masterDate,'YYYYmmDD')],... + % 'water_u',[NCOMstep 1 331 91],[1 40 240 180],[1 1 1 1]); + NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],... + 'water_u',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); + NCOM.water_v(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],... + 'water_v',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); + NCOM.surf_el(:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],... + 'surf_el',[91 331 NCOMstep],[180 240 1],[1 1 1]); + NCOM.salinity(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],... + 'salinity',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); + if (squeeze(NCOM.water_v(100,100,1,end))==0|squeeze(NCOM.water_u(100,100,1,end))==0|squeeze(NCOM.surf_el(100,100,end))==0|squeeze(NCOM.salinity(100,100,1,end))==0)==1 + noData=1; + else + noData=0; + end + catch + noData=1; + end + disp(Ni) + end + NCOM.time(tCount) = Ni; + tStep=tStep+3; + tCount = tCount+1; + end + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + + + + %% NCOM Process + NCOM.mag = vecmag(NCOM.water_u,NCOM.water_v); + + if FIRST_RUN == 1 + depthWeight = [diff(NCOM.depth)' 0]; + + for Layer = 1:40 + DAVfac(:,:,Layer,:) = ones(180,240,1,13).*depthWeight(Layer); + end + DAVtrue = DAVfac; + N_depth = NCOM.depth; + save('NCOMstuff.mat','DAVtrue','DAVfac','N_depth') + else + load('NCOMstuff.mat') + NCOM.depth = N_depth; + clear N_depth; + end + DAVtrue(isnan(NCOM.mag(:,:,1:40,:))==1) = 0; + DAVfac(isnan(NCOM.mag(:,:,1:40,:))==1) = nan; + DAVFac2 = sum(DAVtrue,3); + clear DAVtrue + NCOM.dav = nansum(DAVfac.*NCOM.mag(:,:,1:40,:),3)./DAVFac2; + NCOM.davX = nansum(DAVfac.*NCOM.water_u(:,:,1:40,:),3)./DAVFac2; + NCOM.davY = nansum(DAVfac.*NCOM.water_v(:,:,1:40,:),3)./DAVFac2; + + Import=1 + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + disp('FAILED TO IMPORT FROM NOMADS') + pause(600) + end + end + + + load('shoreline.mat'); + + %% Format data for Delft3D + %% Evap + fileID=fopen('TemperatureRT.eva','w'); + refTime=minutes(masterTime-masterDate); + records=37; + for i = 1 : records + fprintf(fileID,'%d. 0. 0. %2.2f\n',refTime,temperature(i)); + + refTime = refTime + 60;% 1 hour time steps for temperature + end + + fclose(fileID); + + %% NCOM ESTOFS + % Currents from NCOM + + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [1081,i]; + % crIDX(idxCount,:) = [2161,i]; + + idxCount = idxCount + 1; + end + + crBoundCount(1) = 0; + crBoundCount(2) = idxCount -1; + + for i = 750:11:1080 % Every 5 km + % for i = round(linspace(1488,2161,14)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1320]; + % crIDX(idxCount,:) = [i,2641]; + + idxCount = idxCount + 1; + end + crBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + % for i = round(linspace(910,2161,26)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1]; + % crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + crBoundCount(4) = idxCount -1; + + + clear idxCount + + %% Interpolate Water Level + % for tStep = 1:length(tideOutN) + % wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); + % wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); + % wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); + % end + + vDatOrder = [crBoundCount(3)+1:1:crBoundCount(4) ... + crBoundCount(1)+1:1:crBoundCount(2) ... + crBoundCount(3):-1:crBoundCount(2)+1]; + + crBoundCountOld = [0 27 34 46]; + vDatOrderOld = [crBoundCountOld(3)+1:1:crBoundCountOld(4) ... + crBoundCountOld(1)+1:1:crBoundCountOld(2) ... + crBoundCountOld(3):-1:crBoundCountOld(2)+1]; + + vDatNavD = LMSL_RT(:,3); + vDatNavD(vDatNavD==-999999)=nan; + + % interp1(vDatNavD(vDatOrder),1:46) + vDatNavDInter(vDatOrder) = naninterp(interp1(... + linspace(1,length(vDatOrder),length(vDatOrderOld)),... + vDatNavD(vDatOrderOld),1:length(vDatOrder))); + for i = 1:length(idxNCOM) + wlO(:,i) = interp1(masterTime:hours(1):masterTime+hours(36),waterLevels(:,i)+0,masterTime:minutes(10):masterTime+hours(36),'pchip'); + end + + %% Match to grid + flowBed = load('Dec6_100Bed.mat'); + clear wlN mag DM dirGrid currents RN_1 currents_2 currents_40 currDir currDir40 + idxCount=1; + for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+vDatNavDInter(i); + mag(:,idxCount) = vecmag(currX,currY); + + % if idxCount==1 + % DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount+1,1)-1,crIDX(idxCount+1,2))); + % else + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + % end + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + % currents(:,idxCount) = sind(dirGrid(i)-0)'.*vecmag(currY); + + RN_1(:,idxCount) = -currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + + % disp(idxCount) + idxCount = idxCount + 1; + + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + %% interpolate Currents + clear currentsOut + for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(NCOM.time)); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(masterTime:minutes(10):masterTime+hours(36))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + % for j = 1:length(idxNCOM) + % currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + % interp2(xIN,yIN,... + % squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1))),... + % xOut,yOut); + % end + + end + idxCount=1; + + + for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + if i<230 + % RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 1.*sqrt(9.81./DM(idxCount)); + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 0.*sqrt(9.81./DM(idxCount)); + end + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = -1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + end + + + + idxCount = idxCount+1; + end + + %% R Boundry Files + records=size(RNOut_2,1); + + for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; + end + + % boundryTypes(1) = {'water elevation (z)'}; + boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; + boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + + fileID=fopen('NCOM_R2.bct','w'); + + for Boundry = [2:length(boundryNames)] + refTime=minutes(masterTime-masterDate); + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + for line = 1:records + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_2(line,Boundry-1),RNOut_2(line,Boundry)); + + refTime=refTime+10; + end + end + + fclose(fileID); + %% Boundry definition file-R + fileID=fopen('NCOM_R.bnd','w'); + crIDX2=crIDX; + crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+2; + crIDX2(crBoundCount(1)+1:crBoundCount(2),1) = 1082; + + for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end + end + fclose(fileID); + + + %% Waves + records = size(waves,1); + fileID=fopen('WW3.bcw','w'); + + for i = 1:3 + boundryNames(i) = {['East' num2str(i)]}; + end + + for Boundry = 1:3 + refTime=minutes(masterTime-masterDate); + + header=[... + 'location ''East%d''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterTime,'yyyymmdd'))); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''WaveHeight '' unit ''[m]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Period '' unit ''[s]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Direction '' unit ''[N^o]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''DirSpreading '' unit ''[-]''\n'); + end + + for line = 1:records + fprintf(fileID,'%d ',refTime); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,1)); %Hs + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,2)); %Period + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,3)); %Direction + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',4); %Spread + end + fprintf(fileID,'\n'); + + % fprintf(fileID,'%.2f %1.4f %1.4f %1.4f %1.4f\n',refTime,... + % waves(line,Boundry,1),waves(line,Boundry,2),waves(line,Boundry,3),4); + refTime=refTime+180; + end + end + + fclose(fileID); + + + %% Modify MDF file to change reference date + + fileID = fopen('rt_base.mdf'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdf', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 15 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'Itdate = #%04d-%02d-%02d#\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 17 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID,['Tstart = %#.7e \n','Tstop = %#.7e \n'],refTime,refTime+2160); + + + + for i = 20:29 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + if FIRST_RUN == 0 + restID = ['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000']; + if exist(restID)==2 + eval(['movefile ' restID ' tri-rst.6h_restart']) + end + + fprintf( fileID,['Commnt = initial conditions from restart file\n'... + 'Restid = #6h_restart#\n']); + % delete tri-rst.rt* + else + + % fprintf( fileID,['Commnt = initial conditions from map file\n'... + % 'Restid = #Jan16_06#\n']); + + % fprintf( fileID,'Zeta0 = %#.7e \n',nanmean(nanmean(squeeze(wlO(1,:))))); + fprintf( fileID,'Zeta0 = %#.7e \n',0); + + end + + for i = 31:53 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % if FIRST_RUN==1 + % fprintf( fileID, 'Vicouv = 1.0000000e+002 \n'); + % else + fprintf( fileID, '%s\n', cac{1}{54} ); + % end + + for i = 55:64 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + if FIRST_RUN==1 + fprintf( fileID, 'Tlfsmo = 0.0000000e+001 \n'); + else + fprintf( fileID, 'Tlfsmo = 0.0000000e+000 \n'); + end + + for i = 66:94 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + + fprintf( fileID,[... + 'Flmap = %#.7e 60 %#.7e\n',... + 'Flhis = %#.7e 10 %#.7e\n',... + 'Flpp = %#.7e 60 %#.7e\n'],... + refTime,refTime+2160,refTime,refTime+2160,refTime,refTime+2160); + + for i = 98:109 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + clear cac + %% Modify MDW file to add times and change reference date + + fileID = fopen('rt_base.mdw'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdw', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 7 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'ReferenceDate = %04d-%02d-%02d\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 9 : 71 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % for i = 1 : records + % fprintf( fileID,'[TimePoint] \n Time = %#.7e \n',(i-1).*180); + % end + + bounOri{1}='East'; + bounOri{2}='North'; + bounOri{3}='South'; + bounRot{1}='counter-clockwise'; + bounRot{2}='counter-clockwise'; + bounRot{3}='clockwise'; + bounDef{1}='grid-coordinates'; + bounDef{2}='orientation'; + bounDef{3}='orientation'; + + + for Boundry = 1 : 3 + + if Boundry ==1 + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'StartCoordM = %d\n'... + 'EndCoordM = %d\n'... + 'StartCoordN = %d\n'... + 'EndCoordN = %d\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + ],Boundry,bounDef{Boundry},432,432,2,528); + else + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'Orientation = %s\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + 'DistanceDir = %s\n'... + ],Boundry,bounDef{Boundry},bounOri{Boundry},bounRot{Boundry}); + end + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'CondSpecAtDist = %d\n',waveDistAlong(Segment)) + end + end + + clear cac + fclose( fileID ); + + + %% Met Files + % Create new UTM grid of the HRRR Data + [UTM1D(:,1),UTM1D(:,2)] = wgs2utm(reshape(windGridLAT,1,[]),reshape(windGridLON,1,[]),... + 18,'N'); + HRRR_UTM(:,:,1) = double(reshape(UTM1D(:,1),size(windGridLON,1),size(windGridLON,2))); + HRRR_UTM(:,:,2) = double(reshape(UTM1D(:,2),size(windGridLON,1),size(windGridLON,2))); + clear UTM1D + + G7LR = load('C7_1400_V2_C.mat'); + G7bath = load('C7_1400_V2_D.mat'); + % Remove land rainfall + % if FIRST_RUN == 1 + landmask=zeros(size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % [HR_deg(:,1),HR_deg(:,2)] = utm2deg(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[]),reshape(G7LR.data.Y(1:end-1,1:end-1)',1,[]),repmat('18 S',length(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[])),1)); + % for ShoreLevel = 1:length(shoreline) + % landmask_Temp(:,:) = reshape(inpolygon(HR_deg(:,1),HR_deg(:,2),shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon),size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % + % landmask = landmask|landmask_Temp; + % clear landmask_Temp + % + % [shoreTempX,shoreTempY,shoreTempCell] = deg2utm(shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon); + % shoreUTM{ShoreLevel}(:,1) = shoreTempX(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % shoreUTM{ShoreLevel}(:,2) = shoreTempY(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % clear shoreTempX shoreTempY shoreTempCell + % disp(ShoreLevel) + % end + % save('shorelineInfo.mat','landmask','shoreUTM'); + % else + % load('shorelineInfo.mat'); + % end + clear HR_deg ShoreLevel + landmask(G7bath.data.Val'<0)=1; + landmask=logical(landmask); + + if masterTime>=datetime(2019,09,05,00,00,00) + runSteps = 37; + else + runSteps = 8; + end + + % Zero out met array + HRRR_INTER = zeros(4,runSteps,size(G7LR.data.X(1:end-1,1:end-1),2),size(G7LR.data.X(1:end-1,1:end-1),1)); + + % Interpolate against flowGrid for each time step + for TS = 1:runSteps + HRRR_INTER(1,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windU(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + HRRR_INTER(2,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windV(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + rainTemp = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(rain(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + rainTemp(landmask)=rainTemp(landmask)*0; % 100% infiltration + HRRR_INTER(3,TS,:,:) = rainTemp; % Convert to hours + clear rainTemp + + HRRR_INTER(4,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(pressure(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + end + + % Set nan to Delft3D zero value + HRRR_INTER(isnan(HRRR_INTER)==1)=-999.000; + + % Create input files + m = size(HRRR_INTER,3); + n = size(HRRR_INTER,4); + d3ddx = 5000; + d3ddy = 5000; + disp(m) + d3d_input_uvpFieldsCL_FUN(masterTime,m,n,... + squeeze(HRRR_INTER(4,:,:,:)),squeeze(HRRR_INTER(1,:,:,:)),squeeze(HRRR_INTER(2,:,:,:)),squeeze(HRRR_INTER(3,:,:,:)),1,'hrrr',runSteps) + + save(['ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat'],'-v7.3','windU','windV','pressure','rain','temperature','waves','waterLevels','NCOM') + + %% Run Delft3D FLOW/WAVE! + % system('. /home/cluster/D7545/enviorment.sh' + + system('runcoast_flow2d3d_parallel_wave.bat') + if exist('wavm-rt_run.dat')~=2 + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + delete swn-diag.* + + system('runcoast_flow2d3d_parallel_wave.bat') + end + + %% Move things + pause(60) + + % eval(['copyfile trim-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.dat']) + % eval(['movefile trim-rt_run.dat D:\Alexander\RealtimeHRRR\' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.dat']) + eval(['copyfile trim-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.dat']) + + % eval(['copyfile trim-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.def']) + % eval(['movefile trim-rt_run.def D:\Alexander\RealtimeHRRR\' datestr(masterTime,'YYYY-MM-DD_hh') '_mapOut7.def']) + eval(['copyfile trim-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.def']) + + % eval(['copyfile wavm-rt_run.dat ' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.dat']) + % eval(['movefile wavm-rt_run.dat D:\Alexander\RealtimeHRRR\' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.dat']) + eval(['copyfile wavm-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.dat']) + % eval(['copyfile wavm-rt_run.def ' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.def']) + % eval(['movefile wavm-rt_run.def D:\Alexander\RealtimeHRRR\' datestr(masterTime,'YYYY-MM-DD_hh') '_waveOut7.def']) + eval(['copyfile wavm-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.def']) + + % eval(['copyfile trih-rt_run.dat trih-rt_run.dat']) + eval(['copyfile trih-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.dat']) + + % eval(['copyfile trih-rt_run.def trih-rt_run.def']) + eval(['copyfile trih-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.def']) + + + eval(['copyfile hrrr.amu D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amu']) + + eval(['copyfile hrrr.amv D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amv']) + + eval(['copyfile hrrr.ampr D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.ampr']) + + eval(['copyfile hrrr.amp D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amp']) + + eval(['movefile ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat D:\DUNEX_RT\Archive\ModelIn_7' datestr(masterTime,'YYYY-mm-DD_HH') '.mat']) + % eval(['copyfile tri-rst.rt* D:\Alexander\RealtimeHRRR\']) + + + + + + %% Clear things not needed for plotting + clear HRRR_INTER flowGrid lonHRRR_Mesh windU windV rain pressure waveGrid + + + delete(gcp('nocreate')) + parpool(3); + %% Import Model Results + addpath(genpath('matlab/applications/delft3d_matlab'),'-begin') + + modelWater = qpread(qpfopen('trim-rt_run.dat'),1,'water level','griddata',0,0,0); + flowGrid = load('Cone7W_100.mat'); + waveGrid = load('Cone7W_250.mat'); + flowBed = load('Dec6_100Bed.mat'); + waveBed = load('Dec6_250Bed.mat'); + + %% Create GeoTIFF for water levels + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize + + timeIDX = [1 4 7 13 25 37]; + + parfor Time = 1:6 + % X{Time} = modelWater.X; + % Y{Time} = modelWater.Y; + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + + modelPlot_1 = squeeze(modelWater.Val(timeIDX(Time),1:end-1,1:end-1)); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['WL_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWater + + modelWaterDAV = qpread(qpfopen('trim-rt_run.dat'),1,'depth averaged velocity','griddata',0,0,0); + + %% Create GeoTIFF for DAVs + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoDat modelPlot_1 + + timeIDX = [1 4 7 13 25 37]; + if FIRST_RUN == 1 + Times = 2:6; + else + Times = 1:6; + end + for Time = Times + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + modelPlot_1 = sqrt(squeeze(modelWaterDAV.XComp(timeIDX(Time),1:end-1,1:end-1)).^2+... + squeeze(modelWaterDAV.YComp(timeIDX(Time),1:end-1,1:end-1)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['DAV_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + %% Quiver for DAV + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + vecScale(4) = 100000; + vecScale(3) = 50000; + vecScale(2) = 2500; + vecScale(1) = 1000; + + for Time = Times + + X{Time} = flowGrid.data.X(2:end,2:end); + Y{Time} = flowGrid.data.Y(2:end,2:end); + modelPlot_1 = squeeze(modelWaterDAV.XComp(timeIDX(Time),2:end,2:end)); + modelPlot_2 = squeeze(modelWaterDAV.YComp(timeIDX(Time),2:end,2:end)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(400:520,525:620)=nan; + + qSpace = [4 16 50 100] + + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + for i = 1:length(Xdat{Time}) + if ((Udat{Time}(i))==0 && (Vdat{Time}(i))==0) ||... + (isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1) ||... + ((isnan(Udat{Time}(i)))==1 && isnan(Vdat{Time}(i))==1) + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + + Xdat{Time}=[]; + Ydat{Time}=[]; + Udat{Time}=[]; + Vdat{Time}=[]; + q{Time}=[]; + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['DAV_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj DAV_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaterDAV + + %% Create GeoTIFF for HS + + modelWaves = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave height','griddata',0,0,0); + modelWavesDir = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave vector (mean direction)','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize GeoS + + timeIDX = [1 4 7 13 25 37]; + + parfor Time = 1:6 + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = (squeeze(modelWaves.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):250:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):250:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):250:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):250:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-0,1:end-0),1,[]),... + reshape(Y{Time}(1:end-0,1:end-0),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['HS_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for HS + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + vecScale(4) = 15000; + vecScale(3) = 5000; + vecScale(2) = 1000; + vecScale(1) = 500; + + for Time = 1:6 + + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = squeeze(modelWavesDir.XComp(timeIDX(Time),:,:)); + modelPlot_2 = squeeze(modelWavesDir.YComp(timeIDX(Time),:,:)); + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(155:205,210:265)=nan; + + + qSpace = [2 10 20 40] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + elseif isnan(Udat{Time}(i))==1 && isnan(Vdat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['HS_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj HS_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaves + clear modelWavesDIR + + %% Create GeoTIFF for Wind + modelWaterWind = qpread(qpfopen('trim-rt_run.dat'),1,'wind speed','griddata',0,0,0); + + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS ValX ValY + + timeIDX = [1 4 7 13 25 37]; + + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = sqrt(squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)).^2+... + squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):1000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):1000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):1000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):1000:R{Time}.YWorldLimits(2)); + + Val{Time}(Val{Time}==0)=nan; + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['Uw_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for Wind + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + + vecScale(4) = 3000; + vecScale(3) = 500; + vecScale(2) = 100; + vecScale(1) = 40; + + for Time = 1:6 + + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + ValX{Time} = squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)); + ValY{Time} = squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)); + + + qSpace = [5 25 50 100] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),Y{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),... + squeeze(ValX{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),squeeze(ValY{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['Uw_' num2str(timeIDX(Time)) '_D.shp']) + eval(['copyfile vector.prj Uw_' num2str(timeIDX(Time)) '_D.prj']) + + end + + clear modelWaterWind + + %% Create GeoTIFF for Prep + + modelWaterPrep = qpread(qpfopen('trim-rt_run.dat'),1,'precipitation rate','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS + + timeIDX = [1 4 7 13 25 37]; + + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = (squeeze(modelWaterPrep.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):10000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):10000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):10000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):10000:R{Time}.YWorldLimits(2)); + + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geotiffwrite(['Prep_' num2str(timeIDX(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWaterPrep + + %% Export to GEOSERVER + copyfile *.tif \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.dbf \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shx \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shp \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.prj \\geoserver.engineering.queensu.ca\TIFFS\ + + + %% Import Model forecast + modelWaterHist = qpread(qpfopen('trih-rt_run.dat'),1,'water level','data',0,0); + modelCurHist = qpread(qpfopen('trih-rt_run.dat'),1,'depth averaged velocity','data',0,0); + + %% Validation import ESTOFS + load('NWS_CS_DUNEX_M15.mat') + clear ESTOFS lonESTOFS lonESTOFS + + wLIDX=[6 7 8 38]; + wlGrid = [5000 -4000 0 0]; + wlGridY = [0 0 2000 -7500]; + ESTOFStimeOffset = [0 12 24 36]; + ESTOFSrunLength = [36 48 60 72]; + + for e = [1 4] + try + clear meshX meshY + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(0,'%03d') '.grib']); + + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTOFS_Val{e} = 1; + catch + ESTOFS_Val{e} = 0; + end + end + clear waterLevelsESTOFSINTER waterLevelsESTOFS + for e = [1 4] + for Stat = 1:4 + if ESTOFS_Val{e} == 0 + estofsWL(:,Stat,e) = zeros(37,1); + else + [wlDeg(2),wlDeg(1)] = utm2deg(pointsCS{wLIDX(Stat),2}+wlGrid(Stat),pointsCS{wLIDX(Stat),3}+wlGridY(Stat),'18 S'); + [estofIDX] = NearestValue(wlDeg,lonESTOFS,latESTOFS); %Lat + + for i = 1:ESTOFSrunLength(e)+1 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(i-1,'%03d') '.grib']); + + waterLevelsESTOFS{e}(i,Stat) = squeeze(ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,estofIDX(1),estofIDX(2))); + end + waterLevelsESTOFSINTER{e}(:,Stat) = interp1(masterTime-hours(ESTOFStimeOffset(e)):minutes(60):masterTime+hours(36),... + waterLevelsESTOFS{e}(:,Stat),masterTime-hours(ESTOFStimeOffset(e)):minutes(10):masterTime+hours(36),'spline'); + end + end + end + + + %% Validation import WL + + + % Duck + % Oregon Inlet + % Hatteras + % Beaufort + clear stations statWL + options = weboptions; + options.Timeout = 30; + + stations = {8651370,8652587,8654467,8656483}; + dateStartM = masterTime-hours(36); + dateEndM = masterTime+hours(5); + + for Stat = 1:4 + try + url = ['https://tidesandcurrents.noaa.gov/api/datagetter?product=water_level&application=NOS.COOPS.TAC.WL&'... + 'begin_date=' datestr(dateStartM,'yyyymmdd') '&end_date=' datestr(dateEndM,'yyyymmdd') '&datum=NAVD' '&station=' num2str(stations{Stat})... + '&time_zone=GMT&units=metric&format=csv']; + + wlIN = webread(url,options); + + statWL(:,Stat) = interp1(wlIN.DateTime,wlIN.WaterLevel,dateStartM:minutes(10):dateEndM); + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statWL(:,Stat) = 0; + end + + + clear wlIN + + end + %% Validation import Currents + % Duck + clear statCur + for Stat = 1 + % url = 'https://chlthredds.erdc.dren.mil/thredds/dodsC/frf/oceanography/currents/awac-11m/awac-11m.ncml'; + % curTime = ncread(url,'time'); + % curVal = ncread(url,'currentSpeed'); + try + if day(masterTime)<2 + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime-day(3),'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime-days(3),'YYYYmm') '.nc'],options); + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + curTime = vertcat(curTime,ncread('statCNC.nc','time')); + curVal = vertcat(curVal,ncread('statCNC.nc','currentSpeed')); + + else + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + end + + statCur(:) = interp1(datetime(curTime,'convertFrom','POSIX'),curVal,dateStartM:minutes(10):dateEndM); + clear wlIN + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statCur(:) = zeros(length(dateStartM:minutes(10):dateEndM),1); + end + end + + %% Validation import Waves + % Virginia Beach + % Duck 26 + % Nages Head + % Oregon Inlet + % Diamond Shoals + clear stations + + stations = {44014,44100,44086,44095,41025}; + dateStartM = masterTime-hours(36); + dateEndM = masterTime+hours(5); + + clear statWave + + for Stat = 1:5 + try + if ismember(Stat,[1,5]) == 1 + url = ['https://www.ndbc.noaa.gov/data/5day2/' num2str(stations{Stat}) '_5day.txt']; + + websave('NDBCdata.txt',url,options); + opts = delimitedTextImportOptions("NumVariables", 39); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, 15, "TrimNonNumeric", true); + opts = setvaropts(opts, 15, "ThousandsSeparator", ","); + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + else + url = ['https://www.ndbc.noaa.gov/data/realtime2/' num2str(stations{Stat}) '.txt']; + websave('NDBCdata.txt',url); + + opts = delimitedTextImportOptions("NumVariables", 52); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39", "Var40", "Var41", "Var42", "Var43", "Var44", "Var45", "Var46", "Var47", "Var48", "Var49", "Var50", "Var51", "Var52"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "categorical", "categorical", "categorical", "double", "double", "double", "double", "categorical", "categorical", "double", "double", "categorical", "categorical", "categorical", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "TrimNonNumeric", true); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "ThousandsSeparator", ","); + opts = setvaropts(opts, [6, 7, 8, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + end + + % Import the data + waveIN = readtable("NDBCdata.txt", opts); + waveNAN = isnan(waveIN.WVHT)==0; + % Hs + statWave(:,1,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.WVHT(waveNAN)),dateStartM:minutes(10):dateEndM); + % DPD + % statWave(:,2,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + % (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + % (waveIN.DPD(waveNAN)),dateStartM:minutes(10):dateEndM); + % APD + statWave(:,3,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.APD(waveNAN)),dateStartM:minutes(10):dateEndM); + %MWD + statWave(:,4,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.MWD(waveNAN)),dateStartM:minutes(10):dateEndM); + clear waveIN opts + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]); + + % close file + fclose(fid) + statWave(:,:,Stat) = zeros(size(dateStartM:minutes(10):dateEndM,2),4,1); + end + end + statWave(isnan(statWave))=0; + %% Import Model Waves + + for i = 1:37 + startRow = 8; + formatSpec = '%13f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%f%[^\n\r]'; + + fileID = fopen(['C7_100_D_M15.loct00000' num2str(i,'%02d') '.tab'],'r'); + + % This call is based on the structure of the file used to generate this + % code. If an error occurs for a different file, try regenerating the code + % from the Import Tool. + dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines' ,startRow-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + + fclose(fileID); + modelWaveIN= table(dataArray{1:end-1}, 'VariableNames', {'Xp','Yp','Depth','Hsig','Dir','RTpea','kTm01','Dspr','Ubot','XWindv','YWindv','XVel','YVel'}); + + modelWave(:,1,i) = modelWaveIN.Hsig; + modelWave(:,3,i) = modelWaveIN.RTpea; + modelWave(:,4,i) = modelWaveIN.Dir; + + + clearvars filename startRow formatSpec fileID dataArray ans modelWaveIN; + + end + + %% Import Model WL + modelWL = modelWaterHist.Val; + modelCur = sqrt(modelCurHist.XComp.^2+modelCurHist.YComp.^2); + save(['ModelOut_' datestr(masterTime,'dd-mmm-yyyy_HH') 'Z.mat'],'modelWL','modelWave','statWL','statWave','modelCur','statCur'); + + %% Import Historic Model WL + try + H12 = load(['ModelOut_' datestr(masterTime-hours(12),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H24 = load(['ModelOut_' datestr(masterTime-hours(24),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H36 = load(['ModelOut_' datestr(masterTime-hours(36),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + + %% Save html for Currents + googleDates = days(masterTime-hours(36)+minutes((0:432)*10)-datetime(1899,12,30,00,00,00)); + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,1],googleDates') + + locLine = [2 7 12 17 22 27]; + + locationsWave ={'FRF 11 m AWAC '}; + + for i = 1:432 + for j = 1:5 + modelDavDel(i,j)={''}; + end + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,2],modelDavDel) + + clear modelCurPlot + for Loc = 1 + modeldavPlot = cell(432,5); + for Line=1:5 + switch Line + case 1 + curValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + continue + end + % modelCurPlot(1:216,1) = {0}; + modelCurPlot(217:1:433,1) = num2cell(modelCur(:,Loc+16)); + case 2 + curValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + continue + end + % modelCurPlot(1:144,2) = {0}; + % modelCurPlot(362:433,2) = {0}; + modelCurPlot(145:1:361,2) = num2cell(H12.modelCur(:,Loc+16)); + + case 3 + curValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + continue + end + % modelCurPlot(1:72,3) = {0}; + % modelCurPlot(290:433,3) = {0}; + modelCurPlot(73:1:289,3) = num2cell(H24.modelCur(:,Loc+16)); + + case 4 + curValLoc{Line} = ['-36 Hour: ' datestr(masterTime-hours(36),'mm/dd HH') 'Z Run']; + if exist('H36','var') ==0 + continue + end + % modelCurPlot(218:433,4) = {0}; + modelCurPlot(1:1:217,4) = num2cell(H36.modelCur(:,Loc+16)); + case 5 + curValLoc{Line} = ['Observed Velocity']; + if isnan(statCur(1,Loc)) + continue + end + % modelCurPlot(248:433,5) = {0}; + modelCurPlot(1:247,5) = num2cell(statCur); + + end + + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... + [2,locLine(Loc)],modelCurPlot) + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... + [1,locLine(Loc)],curValLoc) + end + + + %% Save html for WL + googleDates = days(masterTime-hours(36)+minutes((0:432)*10)-datetime(1899,12,30,00,00,00)); + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,1],googleDates') + +% locLine = [2 7 12 17 22 27]; + locLine = [2 9 16 23 30 37]; + + locationsWl ={'FRF Pier',... + 'Oregon Inlet',... + 'Hatteras',... + 'Beaufort'}; + + for i = 1:432 + for j = 1:20 + modelWlDel(i,j)={''}; + end + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,2],modelWlDel) + + wLIDX=[6 7 8 38]; + clear modelWlPlot + for Loc = 1:4 + modelwlPlot = cell(432,4); + for Line=[1:5 6 9] + switch Line + case 1 + wlValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + continue + end + % modelwlPlot(1:216,1) = {0}; + modelwlPlot(217:1:433,1) = num2cell(modelWL(:,wLIDX(Loc))); + case 2 + wlValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + continue + end + % modelwlPlot(1:144,2) = {0}; + % modelwlPlot(362:433,2) = {0}; + modelwlPlot(145:1:361,2) = num2cell(H12.modelWL(:,wLIDX(Loc))); + + case 3 + wlValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + continue + end + % modelwlPlot(1:72,3) = {0}; + % modelwlPlot(284:433,3) = {0}; + modelwlPlot(73:1:289,3) = num2cell(H24.modelWL(:,wLIDX(Loc))); + + case 4 + wlValLoc{Line} = ['-36 Hour: ' datestr(masterTime-hours(36),'mm/dd HH') 'Z Run']; + if exist('H36','var') ==0 + continue + end + % modelwlPlot(218:433,4) = {0}; + modelwlPlot(1:1:217,4) = num2cell(H36.modelWL(:,wLIDX(Loc))); + case 5 + wlValLoc{Line} = ['Observed Water Level']; + if isnan(statWL(1,Loc)) + continue + end + % modelwlPlot(248:433,5) = {0}; + modelwlPlot(1:247,5) = num2cell(statWL(:,Loc)); + case 6 + wlValLoc{Line} = ['ESTOFS Forecast']; + if ESTOFS_Val{1} == 0 + continue + end + modelwlPlot(217:1:433,6) = num2cell(waterLevelsESTOFSINTER{1}(:,Loc)); + case 9 + wlValLoc{Line} = ['-36 Hour ESTOFS']; + if ESTOFS_Val{4} == 0 + continue + end + modelwlPlot(1:1:433,7) = num2cell(waterLevelsESTOFSINTER{4}(:,Loc)); + + + end + + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... + [2,locLine(Loc)],modelwlPlot) + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... + [1,locLine(Loc)],wlValLoc) + end + + %% Save html for Waves + googleDates = days(masterTime-hours(36)+minutes((0:432)*10)-datetime(1899,12,30,00,00,00)); + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,1],googleDates') + + locLine = [2 7 12 17 22 27]; + + locationsWave ={'Virginia Beach',... + 'FRF 26 m',... + 'Nags Head',... + 'Oregon Inlet',... + 'Diamond Shoals'}; + + for i = 1:432 + for j = 1:25 + modelWaveDel(i,j)={''}; + end + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,2],modelWaveDel) + + for Loc = 1:5 + modelwavePlot = cell(432,5); + for Line=1:5 + switch Line + case 1 + waveValLoc{Line} = ['Forecast']; + if exist('modelWave','var') ==0 + continue + end + modelwavePlot(216,1) = {0}; + modelwavePlot(217:6:433,1) = num2cell(modelWave(Loc+11,1,:)); + case 2 + waveValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + continue + end + modelwavePlot(144,2) = {0}; + modelwavePlot(362,2) = {0}; + modelwavePlot(145:6:361,2) = num2cell(H12.modelWave(Loc+11,1,:)); + + case 3 + waveValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + continue + end + modelwavePlot(72,3) = {0}; + modelwavePlot(290,3) = {0}; + modelwavePlot(73:6:289,3) = num2cell(H24.modelWave(Loc+11,1,:)); + + case 4 + waveValLoc{Line} = ['-36 Hour: ' datestr(masterTime-hours(36),'mm/dd HH') 'Z Run']; + if exist('H36','var') ==0 + continue + end + modelwavePlot(218,4) = {0}; + modelwavePlot(1:6:217,4) = num2cell(H36.modelWave(Loc+11,1,:)); + case 5 + waveValLoc{Line} = ['Observed Wave']; + if isnan(statWave(1,1,Loc)) + continue + end + modelwavePlot(248,5) = {0}; + modelwavePlot(1:247,5) = num2cell(statWave(:,1,Loc)); + + end + + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... + [2,locLine(Loc)],modelwavePlot) + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... + [1,locLine(Loc)],waveValLoc) + end + + + + + + %% Import and modify times + modelHour = [0 3 6 12 24 36]; + for i = 1:6 + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','0',[1,i],... + {[datestr(masterTime+hours(modelHour(i)),'mmm dd, HH:MM') ' UTC (Hour '... + num2str(modelHour(i),'%d') ')']}) + end + +catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['ALL-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + +end + +%% +quit + + + + + + + + + + + + + + + + diff --git a/Dunex_Operational_Feb28_BackupSept7.m b/Dunex_Operational_Feb28_BackupSept7.m new file mode 100644 index 0000000..17b7880 --- /dev/null +++ b/Dunex_Operational_Feb28_BackupSept7.m @@ -0,0 +1,2336 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +% Moved to COASTLINES Feb 29, 2020 + +clear all +cd D:\DUNEX_RT\Operation +echo off; +addpath('NCtoolbox') +addpath('m_map') +setup_nctoolbox +flowGrid = load('Cone7W_100.mat'); +waveGrid = load('Cone7W_250.mat'); +load('LMSL_RT.mat') +addpath('D:\DUNEX_RT\Operation\abogaard-matlab2gsheets-6d76271') +setenv('PATH', [getenv('PATH') ';D:\DUNEX_RT\Windows_64']); + +%% Details for e-mail server +setpref('Internet','SMTP_Server','smtp.sendgrid.net'); +setpref('Internet','E_mail','mail@alexanderrey.ca'); +setpref('Internet','SMTP_Username','apikey'); +setpref('Internet','SMTP_Password','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'); +props = java.lang.System.getProperties; +props.setProperty('mail.smtp.auth','true'); +props.setProperty('mail.smtp.socketFactory.class', 'javax.net.ssl.SSLSocketFactory'); +props.setProperty('mail.smtp.socketFactory.port','465'); +props.setProperty('mail.smtp.starttls.enable','true'); + + +%% Master Model Time Step +% Every 6 hours + +nistTime = datetime(datevec(now())) - tzoffset(datetime(datevec(now()),'TimeZone','local')); +masterTime = dateshift(nistTime,'start','hour')-hours(2) % Assume script will run at 5 and a half hours after model start +clear nistTime +masterDate = datetime(year(masterTime),month(masterTime),day(masterTime)); + +if exist(['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000'])==2 + FIRST_RUN = 0; +else + FIRST_RUN = 1; +end + +%% Import +try + Import=0; + + + %% Clean files from previous run + system('taskkill /IM "d_hydro.exe" /F') + system('taskkill /IM "wave.exe" /F') + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + + clear HRRR_UTM + while Import==0 + try + %% Import data from NOMADS + %% Extratropical Surge and Tide Operational Forecast System for the Atlantic + % (ESTOFS Atlantic) for water levels + options = weboptions; + options.Timeout = 90; + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(6),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 7; + ESTrun = 6; + catch + % url = ['http://nomads.ncep.noaa.gov/dods/estofs_atl/'... + % datestr(masterTime-days(1),'yyyymmdd')... + % '/estofs_atl_conus_' datestr(masterTime-days(1),'hh') 'z']; + % ESTOFS = ncgeodataset(url); + % lonESTOFS=ESTOFS{'lon'}(:); + % latESTOFS=ESTOFS{'lat'}(:); + % ESTstart = 24+ESTstart; +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-days(1),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-days(1),'yyyymmdd')... + '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 25; + ESTrun = 24; + end + + + clear url + + % Find ESTOFS index for grid points along boundry + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); %Lat + wlIDX(idxCount,:) = [1082,i]; + + idxCount = idxCount + 1; + end + + wlBoundCount(1) = 0; + wlBoundCount(2) = idxCount -1; + + + for i = 750:11:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1322]; + idxCount = idxCount + 1; + end + + wlBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1]; + idxCount = idxCount + 1; + end + wlBoundCount(4) = idxCount -1; + + clear idxCount gridDeg + + % Extract ESTOFS Water Levels for 36 hours at indexes + % waterLevelsGRID = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(ESTstart:ESTstart+36,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + % min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + + % Find ESTOFS values from small grid + idxCount=1; + errorET = 0; + for i = ESTstart:ESTstart+96 + if errorET<10 + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... +% num2str(i,'%03d') '.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... + num2str(i,'%03d') '.grib2']; + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib'],url,options) + + if i<=ESTstart+48 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib']); + + waterLevelsGRID(idxCount,:,:) = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + end + idxCount = idxCount + 1; + catch + errorET = errorET+1; + end + else + error('ESTOFS ERROR') + end + + end + + idxCount=1; + for i = 1:length(idxESTOFS) + waterLevels(:,idxCount) = waterLevelsGRID(:,idxESTOFS(idxCount,1)-min(idxESTOFS(:,1))+1,... + idxESTOFS(idxCount,2)-min(idxESTOFS(:,2))+1); + + idxCount = idxCount + 1; + end + + + % Save ESTOFS Points +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_points.nc'],url,options) + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + disp('Loaded ESTOFS') + %% Multi-grid Wave model (WAVEWATCH III) + % 4 arc minute US East Coast grid for waves + + url = ['https://nomads.ncep.noaa.gov/dods/wave/gfswave/'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/gfswave.atlocn.0p16_' datestr(masterTime-hours(6),'hh') 'z']; + + MWW3 = ncgeodataset(url); + clear url + + lonMWW3=wrapTo180(MWW3{'lon'}(:)); + latMWW3=MWW3{'lat'}(:); + + % Find MWW3 index for grid points along boundry + idxCount=1; + for i = 1:25:length(waveGrid.data.Y)-25 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(end-2,i),waveGrid.data.Y(end-2,i),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(end-2,1:i)).^2+... + diff(waveGrid.data.Y(end-2,1:i)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(end-2,i); + waveUTM(idxCount,2) = waveGrid.data.Y(end-2,i); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + waveBoundCount(1) = 0; + waveBoundCount(2) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:350% Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,end-2),waveGrid.data.Y(i,end-2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,end-2)).^2+... + diff(waveGrid.data.Y(i:end-2,end-2)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,end-2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,end-2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + % 0 132 163 285 + + waveBoundCount(3) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:240 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,2),waveGrid.data.Y(i,2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,1)).^2+... + diff(waveGrid.data.Y(i:end-2,1)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(4) = idxCount -1; + + clear idxCount + + % Extract WW3 Hs for 36 hours at indexes + wavesGRID_Hs = MWW3{'htsgwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid htsgwsfc + %swell_1 + % Period + wavesGRID_P = MWW3{'perpwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... % + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid perpwsfc + %swper_1 + % Direction + wavesGRID_Dir = MWW3{'dirpwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid dirpwsfc + %swdir_1 + % Find WW3 values from small grid + idxCount=1; + for i = 1:length(idxMWW3) + waves(:,idxCount,1) = wavesGRID_Hs(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Hs + + waves(:,idxCount,2) = wavesGRID_P(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Tp + + waves(:,idxCount,3) = wavesGRID_Dir(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Dir + + idxCount = idxCount + 1; + end + clear idxCount + disp('Loaded WW3') + + + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; +% delete(gcp('nocreate')) +% parpool(8); + + for ForcastHour = 0:48 + % url = ['http://nomads.ncep.noaa.gov/pub/data/nccf/com/hrrr/prod/'... + % 'hrrr.' datestr(masterTime,'yyyymmdd')... + % '/conus/hrrr.t' num2str(hour(masterTime),'%02d') 'z.'... + % 'wrfsfcf' num2str(ForcastHour,'%02d') '.grib2']; + + url = ['https://nomads.ncep.noaa.gov/cgi-bin/filter_hrrr_2d.pl?file=hrrr.'... + 't' num2str(hour(masterTime),'%02d') 'z.wrfsfc'... + 'f' num2str(ForcastHour,'%02d') '.grib2&'... + 'lev_10_m_above_ground=on&lev_surface=on&var_APCP=on&var_PRES=on&var_UGRD=on&var_VGRD=on&var_TMP=on&subregion=&leftlon=-78&rightlon=-74&toplat=38&bottomlat=32.5&dir=%2F'... + 'hrrr.' datestr(masterTime,'yyyymmdd') '%2Fconus']; + + websave(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2'],url,options) + + [pCheck,gridParams] = system(['perl "D:\DUNEX_RT\Windows_64\grid_defn.pl" '... + 'D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + [wCheck,gridParams] = system(['wgrib2 D:\DUNEX_RT\Operation\HRRR\hrrrT' ... + num2str(ForcastHour,'%02d') '.grib2 -new_grid_winds earth -new_grid ' ... + gridParams ' D:\DUNEX_RT\Operation\HRRR\hrrrT'... + num2str(ForcastHour,'%02d') '.grib2.regrid']); + end +% delete(gcp('nocreate')) + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(0,'%02d') '.grib2.regrid']); + clear url + + m_proj('lambert conformal conic','ori',[262.5 38.5],'clo',262.5,'par',[38.5 38.5],'ell','sphere');%,'lat',[20 55],'lon',[-60 -130] + [meshX,meshY] = meshgrid(HRRR{'x'}(:),HRRR{'y'}(:)); + [windGridLON,windGridLAT] = m_xy2ll(meshX.*1000,meshY.*1000); + windGridLON=wrapTo180(windGridLON); + clear meshX meshY + + % Extract MWW3 Hs for 48 hours at indexes + for ForcastHour = 0:48 + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2.regrid']); + windU(ForcastHour+1,:,:) = HRRR{'u-component_of_wind_height_above_ground'}(:,:,:); %U Winds @ 10m [m/s] + windV(ForcastHour+1,:,:) = HRRR{'v-component_of_wind_height_above_ground'}(:,:,:); %V Winds @ 10m [m/s] + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + pressure(ForcastHour+1,:,:) = HRRR{'Pressure_surface'}(:,:,:); %Surface Pressure [pa] + + if ForcastHour==0 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_0_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + elseif ForcastHour==1 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_1_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + else + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_Mixed_intervals_Accumulation'}(2,:,:); %Surface precipitation [kg/m^2] + end + temperature(ForcastHour+1) = squeeze(nanmean(nanmean(HRRR{'Temperature_surface'}(:,:,:)- 273.15,2),3)); %Surface Temperature [C] + end + % Extract Temp + + disp('Loaded HRRR') + + + %% IMPORT NCOM + + try + nComDate=masterDate; +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/20201220/coamps_ncom_useast_u_1_2020122000_00000000.nc']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; + +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + mkdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0025-0048.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0073-0096.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0073-0096.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); + % NCOM.Lat = ncom_grib{'lat',[331],[240]}; + % NCOM.Lon = ncom_grib{'lon',91,180}; + catch + try + if hour(masterTime) ~= 18 + nComDate=masterDate-days(1); + else + nComDate=masterDate; + end +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); +% ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\grids\operational\NCOM\regional\GRIB2\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2']; +% ncom_grib = ncgeodataset(ncom_downloadPath); + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0073-0096.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0073-0096.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); +% NCOM.Lat = ncom_grib{'lat',[331],[240]}; +% NCOM.Lon = ncom_grib{'lon',91,180}; + + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + end + + if FIRST_RUN == 1 + NCOM.depth = ncread('D:\Alexander\NCOM\2019090500_t000.nc','depth'); + end + + Noffset = hours(masterTime - nComDate); + tStep = Noffset; + tCount = 1; + + try + for Ni = masterTime:hours(3):masterTime+hours(48) + noData=1; + while noData==1 + try +% NCOMstep = tStep./3+1; + NCOMstep = 1; + +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(masterDate,'YYYYmmDD')],... +% 'water_u',[NCOMstep 1 331 91],[1 40 240 180],[1 1 1 1]); +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_u',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.water_v(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_v',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.surf_el(:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'surf_el',[91 331 NCOMstep],[180 240 1],[1 1 1]); +% NCOM.salinity(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'salinity',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); + NCOM.water_u(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_u',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.water_v(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_v',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.surf_el(:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'surf_el',[91 331 1],[180 240 1],[1 1 1]); + NCOM.salinity(:,:,:,tCount) =ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'salinity',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + + if (squeeze(NCOM.water_v(100,100,1,end))==0|squeeze(NCOM.water_u(100,100,1,end))==0|squeeze(NCOM.surf_el(100,100,end))==0|squeeze(NCOM.salinity(100,100,1,end))==0)==1 + noData=1; + else + noData=0; + end + catch + noData=1; + end + disp(Ni) + end + NCOM.time(tCount) = Ni; + tStep=tStep+3; + tCount = tCount+1; + end + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + + + + %% NCOM Process + NCOM.mag = vecmag(NCOM.water_u,NCOM.water_v); + + if FIRST_RUN == 1 + depthWeight = [diff(NCOM.depth)' 0]; + + for Layer = 1:40 + DAVfac(:,:,Layer,:) = ones(180,240,1,17).*depthWeight(Layer); + end + DAVtrue = DAVfac; + N_depth = NCOM.depth; + save('NCOMstuff.mat','DAVtrue','DAVfac','N_depth') + else + load('NCOMstuff.mat') + NCOM.depth = N_depth; + clear N_depth; + end + DAVtrue(isnan(NCOM.mag(:,:,1:40,:))==1) = 0; + DAVfac(isnan(NCOM.mag(:,:,1:40,:))==1) = nan; + DAVFac2 = sum(DAVtrue,3); + clear DAVtrue + NCOM.dav = nansum(DAVfac.*NCOM.mag(:,:,1:40,:),3)./DAVFac2; + NCOM.davX = nansum(DAVfac.*NCOM.water_u(:,:,1:40,:),3)./DAVFac2; + NCOM.davY = nansum(DAVfac.*NCOM.water_v(:,:,1:40,:),3)./DAVFac2; + + Import=1 + catch err + + clear waterLevels + + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + disp('FAILED TO IMPORT FROM NOMADS') + pause(600) + end + end + + + load('shoreline.mat'); + + %% Format data for Delft3D + %% Evap + fileID=fopen('TemperatureRT.eva','w'); + refTime=minutes(masterTime-masterDate); + records=49; + for i = 1 : records + fprintf(fileID,'%d. 0. 0. %2.2f\n',refTime,temperature(i)); + + refTime = refTime + 60;% 1 hour time steps for temperature + end + + fclose(fileID); + + %% NCOM ESTOFS + % Currents from NCOM + + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [1081,i]; + % crIDX(idxCount,:) = [2161,i]; + + idxCount = idxCount + 1; + end + + crBoundCount(1) = 0; + crBoundCount(2) = idxCount -1; + + for i = 750:11:1080 % Every 5 km + % for i = round(linspace(1488,2161,14)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1320]; + % crIDX(idxCount,:) = [i,2641]; + + idxCount = idxCount + 1; + end + crBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + % for i = round(linspace(910,2161,26)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1]; + % crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + crBoundCount(4) = idxCount -1; + + + clear idxCount + + %% Interpolate Water Level + % for tStep = 1:length(tideOutN) + % wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); + % wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); + % wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); + % end + + vDatOrder = [crBoundCount(3)+1:1:crBoundCount(4) ... + crBoundCount(1)+1:1:crBoundCount(2) ... + crBoundCount(3):-1:crBoundCount(2)+1]; + + crBoundCountOld = [0 27 34 46]; + vDatOrderOld = [crBoundCountOld(3)+1:1:crBoundCountOld(4) ... + crBoundCountOld(1)+1:1:crBoundCountOld(2) ... + crBoundCountOld(3):-1:crBoundCountOld(2)+1]; + + vDatNavD = LMSL_RT(:,3); + vDatNavD(vDatNavD==-999999)=nan; + + % interp1(vDatNavD(vDatOrder),1:46) + vDatNavDInter(vDatOrder) = naninterp(interp1(... + linspace(1,length(vDatOrder),length(vDatOrderOld)),... + vDatNavD(vDatOrderOld),1:length(vDatOrder))); + for i = 1:length(idxNCOM) + wlO(:,i) = interp1(masterTime:hours(1):masterTime+hours(48),waterLevels(:,i)+0,masterTime:minutes(10):masterTime+hours(48),'pchip'); + end + + %% Match to grid + flowBed = load('Dec6_100Bed.mat'); + clear wlN mag DM dirGrid currents RN_1 currents_2 currents_40 currDir currDir40 + idxCount=1; + for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+vDatNavDInter(i); + mag(:,idxCount) = vecmag(currX,currY); + + % if idxCount==1 + % DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount+1,1)-1,crIDX(idxCount+1,2))); + % else + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + % end + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + % currents(:,idxCount) = sind(dirGrid(i)-0)'.*vecmag(currY); + + RN_1(:,idxCount) = -currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + + % disp(idxCount) + idxCount = idxCount + 1; + + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + %% interpolate Currents + clear currentsOut + for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(NCOM.time)); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(masterTime:minutes(10):masterTime+hours(48))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + % for j = 1:length(idxNCOM) + % currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + % interp2(xIN,yIN,... + % squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1))),... + % xOut,yOut); + % end + + end + idxCount=1; + + + for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + if i<230 + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); +% RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 1.*sqrt(9.81./DM(idxCount)); + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 0.*sqrt(9.81./DM(idxCount)); + end + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = -1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + end + + + + idxCount = idxCount+1; + end + + %% R Boundry Files + records=size(RNOut_2,1); + + for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; + end + + % boundryTypes(1) = {'water elevation (z)'}; + boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; + boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + + fileID=fopen('NCOM_R2.bct','w'); + + for Boundry = [2:length(boundryNames)] + refTime=minutes(masterTime-masterDate); + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + for line = 1:records + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_2(line,Boundry-1),RNOut_2(line,Boundry)); + + refTime=refTime+10; + end + end + + fclose(fileID); + %% Boundry definition file-R + fileID=fopen('NCOM_R.bnd','w'); + crIDX2=crIDX; + crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+2; + crIDX2(crBoundCount(1)+1:crBoundCount(2),1) = 1082; + + for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end + end + fclose(fileID); + + + %% Waves + records = size(waves,1); + fileID=fopen('WW3.bcw','w'); + + for i = 1:3 + boundryNames(i) = {['East' num2str(i)]}; + end + + for Boundry = 1:3 + refTime=minutes(masterTime-masterDate); + + header=[... + 'location ''East%d''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterTime,'yyyymmdd'))); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''WaveHeight '' unit ''[m]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Period '' unit ''[s]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Direction '' unit ''[N^o]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''DirSpreading '' unit ''[-]''\n'); + end + + for line = 1:records + fprintf(fileID,'%d ',refTime); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,1)); %Hs + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,2)); %Period + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,3)); %Direction + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',4); %Spread + end + fprintf(fileID,'\n'); + + % fprintf(fileID,'%.2f %1.4f %1.4f %1.4f %1.4f\n',refTime,... + % waves(line,Boundry,1),waves(line,Boundry,2),waves(line,Boundry,3),4); + refTime=refTime+180; + end + end + + fclose(fileID); + + + %% Modify MDF file to change reference date + + fileID = fopen('rt_base.mdf'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdf', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 15 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'Itdate = #%04d-%02d-%02d#\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 17 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID,['Tstart = %#.7e \n','Tstop = %#.7e \n'],refTime,refTime+2880); + + + + for i = 20:29 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + if FIRST_RUN == 0 + restID = ['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000']; + if exist(restID)==2 + eval(['movefile ' restID ' tri-rst.6h_restart']) + end + + fprintf( fileID,['Commnt = initial conditions from restart file\n'... + 'Restid = #6h_restart#\n']); + % delete tri-rst.rt* + else + + % fprintf( fileID,['Commnt = initial conditions from map file\n'... + % 'Restid = #Jan16_06#\n']); + + % fprintf( fileID,'Zeta0 = %#.7e \n',nanmean(nanmean(squeeze(wlO(1,:))))); + fprintf( fileID,'Zeta0 = %#.7e \n',0); + + end + + for i = 31:53 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % if FIRST_RUN==1 + % fprintf( fileID, 'Vicouv = 1.0000000e+002 \n'); + % else + fprintf( fileID, '%s\n', cac{1}{54} ); + % end + + for i = 55:64 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + if FIRST_RUN==1 + fprintf( fileID, 'Tlfsmo = 0.0000000e+001 \n'); + else + fprintf( fileID, 'Tlfsmo = 0.0000000e+000 \n'); + end + + for i = 66:94 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + + fprintf( fileID,[... + 'Flmap = %#.7e 60 %#.7e\n',... + 'Flhis = %#.7e 10 %#.7e\n',... + 'Flpp = %#.7e 60 %#.7e\n'],... + refTime,refTime+2880,refTime,refTime+2880,refTime,refTime+2880); + + for i = 98:109 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + clear cac + %% Modify MDW file to add times and change reference date + + fileID = fopen('rt_base.mdw'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdw', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 7 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'ReferenceDate = %04d-%02d-%02d\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 9 : 71 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % for i = 1 : records + % fprintf( fileID,'[TimePoint] \n Time = %#.7e \n',(i-1).*180); + % end + + bounOri{1}='East'; + bounOri{2}='North'; + bounOri{3}='South'; + bounRot{1}='counter-clockwise'; + bounRot{2}='counter-clockwise'; + bounRot{3}='clockwise'; + bounDef{1}='grid-coordinates'; + bounDef{2}='orientation'; + bounDef{3}='orientation'; + + + for Boundry = 1 : 3 + + if Boundry ==1 + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'StartCoordM = %d\n'... + 'EndCoordM = %d\n'... + 'StartCoordN = %d\n'... + 'EndCoordN = %d\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + ],Boundry,bounDef{Boundry},432,432,2,528); + else + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'Orientation = %s\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + 'DistanceDir = %s\n'... + ],Boundry,bounDef{Boundry},bounOri{Boundry},bounRot{Boundry}); + end + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'CondSpecAtDist = %d\n',waveDistAlong(Segment)); + end + end + + clear cac + fclose( fileID ); + + + %% Met Files + % Create new UTM grid of the HRRR Data + [UTM1D(:,1),UTM1D(:,2)] = wgs2utm(reshape(windGridLAT,1,[]),reshape(windGridLON,1,[]),... + 18,'N'); + HRRR_UTM(:,:,1) = double(reshape(UTM1D(:,1),size(windGridLON,1),size(windGridLON,2))); + HRRR_UTM(:,:,2) = double(reshape(UTM1D(:,2),size(windGridLON,1),size(windGridLON,2))); + clear UTM1D + + G7LR = load('C7_1400_V2_C.mat'); + G7bath = load('C7_1400_V2_D.mat'); + % Remove land rainfall + % if FIRST_RUN == 1 + landmask=zeros(size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % [HR_deg(:,1),HR_deg(:,2)] = utm2deg(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[]),reshape(G7LR.data.Y(1:end-1,1:end-1)',1,[]),repmat('18 S',length(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[])),1)); + % for ShoreLevel = 1:length(shoreline) + % landmask_Temp(:,:) = reshape(inpolygon(HR_deg(:,1),HR_deg(:,2),shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon),size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % + % landmask = landmask|landmask_Temp; + % clear landmask_Temp + % + % [shoreTempX,shoreTempY,shoreTempCell] = deg2utm(shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon); + % shoreUTM{ShoreLevel}(:,1) = shoreTempX(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % shoreUTM{ShoreLevel}(:,2) = shoreTempY(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % clear shoreTempX shoreTempY shoreTempCell + % disp(ShoreLevel) + % end + % save('shorelineInfo.mat','landmask','shoreUTM'); + % else + % load('shorelineInfo.mat'); + % end + clear HR_deg ShoreLevel + landmask(G7bath.data.Val'<0)=1; + landmask=logical(landmask); + + if masterTime>=datetime(2019,09,05,00,00,00) + runSteps = 49; + else + runSteps = 8; + end + + % Zero out met array + HRRR_INTER = zeros(4,runSteps,size(G7LR.data.X(1:end-1,1:end-1),2),size(G7LR.data.X(1:end-1,1:end-1),1)); + + % Interpolate against flowGrid for each time step + for TS = 1:runSteps + HRRR_INTER(1,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windU(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + HRRR_INTER(2,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windV(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + rainTemp = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(rain(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + rainTemp(landmask)=rainTemp(landmask)*0; % 100% infiltration + HRRR_INTER(3,TS,:,:) = rainTemp; % Convert to hours + clear rainTemp + + HRRR_INTER(4,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(pressure(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + end + + % Set nan to Delft3D zero value + HRRR_INTER(isnan(HRRR_INTER)==1)=-999.000; + + % Create input files + m = size(HRRR_INTER,3); + n = size(HRRR_INTER,4); + d3ddx = 5000; + d3ddy = 5000; + disp(m) + d3d_input_uvpFieldsCL_FUN(masterTime,m,n,... + squeeze(HRRR_INTER(4,:,:,:)),squeeze(HRRR_INTER(1,:,:,:)),squeeze(HRRR_INTER(2,:,:,:)),squeeze(HRRR_INTER(3,:,:,:)),1,'hrrr',runSteps) + + save(['ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat'],'-v7.3','windU','windV','pressure','rain','temperature','waves','waterLevels','NCOM') + + %% Run Delft3D FLOW/WAVE! + % system('. /home/cluster/D7545/enviorment.sh' + + system('runcoast_flow2d3d_parallel_wave.bat') + if exist('wavm-rt_run.dat')~=2 + fid = fopen('errorFile.log','a+'); + fprintf(fid,'Delft Batch File Fallback\n'); + + % close file + fclose(fid) + disp('Run Fallback') + pause(60) + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + delete swn-diag.* + + system('runcoast_flow2d3d_parallel_wave.bat') + end + + %% Move things + pause(60) + + eval(['copyfile trih-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.dat']) + eval(['copyfile trih-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.def']) + + eval(['movefile ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat D:\DUNEX_RT\Archive\ModelIn_7' datestr(masterTime,'YYYY-mm-DD_HH') '.mat']) + % eval(['copyfile tri-rst.rt* D:\Alexander\RealtimeHRRR\']) + + + eval(['copyfile hrrr.amu D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amu']) + eval(['copyfile hrrr.amv D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amv']) + eval(['copyfile hrrr.ampr D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.ampr']) + eval(['copyfile hrrr.amp D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amp']) + eval(['copyfile trim-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.dat']) + eval(['copyfile trim-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.def']) + eval(['copyfile wavm-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.dat']) + eval(['copyfile wavm-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.def']) + + + + %% Clear things not needed for plotting + clear HRRR_INTER flowGrid lonHRRR_Mesh windU windV rain pressure waveGrid + + + delete(gcp('nocreate')) + parpool(3); + %% Import Model Results + addpath(genpath('matlab/applications/delft3d_matlab'),'-begin') + + modelWater = qpread(qpfopen('trim-rt_run.dat'),1,'water level','griddata',0,0,0); + flowGrid = load('Cone7W_100.mat'); + waveGrid = load('Cone7W_250.mat'); + flowBed = load('Dec6_100Bed.mat'); + waveBed = load('Dec6_250Bed.mat'); + + %% Create GeoTIFF for water levels + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + timeIDXNames = [1 4 7 13 25 37]; % For Geoserver + + yMinOffset = 75; + yMaxOffset = 25; + + parfor Time = 1:6 + % X{Time} = modelWater.X; + % Y{Time} = modelWater.Y; + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + + modelPlot_1 = squeeze(modelWater.Val(timeIDX(Time),1:end-1,1:end-1)); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['WL_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWater + + modelWaterDAV = qpread(qpfopen('trim-rt_run.dat'),1,'depth averaged velocity','griddata',0,0,0); + + %% Create GeoTIFF for DAVs + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoDat modelPlot_1 + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + if FIRST_RUN == 1 + Times = 2:6; + else + Times = 1:6; + end + + + parfor Time = Times + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + modelPlot_1 = sqrt(squeeze(modelWaterDAV.XComp(timeIDX(Time),1:end-1,1:end-1)).^2+... + squeeze(modelWaterDAV.YComp(timeIDX(Time),1:end-1,1:end-1)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['DAV_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + %% Quiver for DAV + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + vecScale(4) = 100000; + vecScale(3) = 50000; + vecScale(2) = 2500; + vecScale(1) = 1000; + + for Time = Times + + X{Time} = flowGrid.data.X(2:end,2:end); + Y{Time} = flowGrid.data.Y(2:end,2:end); + modelPlot_1 = squeeze(modelWaterDAV.XComp(timeIDX(Time),2:end,2:end)); + modelPlot_2 = squeeze(modelWaterDAV.YComp(timeIDX(Time),2:end,2:end)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(400:520,525:620)=nan; + + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + modelPlot_2(:,1:yMinOffset)=nan; + modelPlot_2(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + qSpace = [4 16 50 100] + + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + for i = 1:length(Xdat{Time}) + if ((Udat{Time}(i))==0 && (Vdat{Time}(i))==0) ||... + (isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1) ||... + ((isnan(Udat{Time}(i)))==1 && isnan(Vdat{Time}(i))==1) + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + + Xdat{Time}=[]; + Ydat{Time}=[]; + Udat{Time}=[]; + Vdat{Time}=[]; + q{Time}=[]; + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['DAV_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj DAV_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaterDAV + + %% Create GeoTIFF for HS + + modelWaves = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave height','griddata',0,0,0); + modelWavesDir = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave vector (mean direction)','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize GeoS + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = (squeeze(modelWaves.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):250:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):250:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):250:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):250:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-0,1:end-0),1,[]),... + reshape(Y{Time}(1:end-0,1:end-0),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['HS_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for HS + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + vecScale(4) = 15000; + vecScale(3) = 5000; + vecScale(2) = 1000; + vecScale(1) = 500; + + for Time = 1:6 + + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = squeeze(modelWavesDir.XComp(timeIDX(Time),:,:)); + modelPlot_2 = squeeze(modelWavesDir.YComp(timeIDX(Time),:,:)); + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(155:205,210:265)=nan; + + + qSpace = [2 10 20 40] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + elseif isnan(Udat{Time}(i))==1 && isnan(Vdat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['HS_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj HS_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaves + clear modelWavesDIR + + %% Create GeoTIFF for Wind + modelWaterWind = qpread(qpfopen('trim-rt_run.dat'),1,'wind speed','griddata',0,0,0); + + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS ValX ValY + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = sqrt(squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)).^2+... + squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):1000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):1000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):1000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):1000:R{Time}.YWorldLimits(2)); + + Val{Time}(Val{Time}==0)=nan; + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['Uw_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for Wind + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + + vecScale(4) = 3000; + vecScale(3) = 500; + vecScale(2) = 100; + vecScale(1) = 40; + + for Time = 1:6 + + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + ValX{Time} = squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)); + ValY{Time} = squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)); + + + qSpace = [5 25 50 100] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),Y{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),... + squeeze(ValX{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),squeeze(ValY{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['Uw_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj Uw_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaterWind + + %% Create GeoTIFF for Prep + + modelWaterPrep = qpread(qpfopen('trim-rt_run.dat'),1,'precipitation rate','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = (squeeze(modelWaterPrep.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):10000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):10000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):10000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):10000:R{Time}.YWorldLimits(2)); + + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geotiffwrite(['Prep_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWaterPrep + + %% Export to GEOSERVER + try + copyfile *.tif \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.dbf \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shx \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shp \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.prj \\geoserver.engineering.queensu.ca\TIFFS\ + catch + end + + %% Import Model forecast + modelWaterHist = qpread(qpfopen('trih-rt_run.dat'),1,'water level','data',0,0); + modelCurHist = qpread(qpfopen('trih-rt_run.dat'),1,'depth averaged velocity','data',0,0); + + %% Validation import ESTOFS + load('DUNEX_Nov20.mat') + clear ESTOFS lonESTOFS lonESTOFS + + wLIDX=[6 7 8 38]; + wlGrid = [5000 -4000 0 -2000]; + wlGridY = [0 0 2000 5000]; %7500 + ESTOFStimeOffset = [0 12 24 48]; + ESTOFSrunLength = [48 60 72 96]; + + for e = [1 4] + try + clear meshX meshY + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(0,'%03d') '.grib']); + + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTOFS_Val{e} = 1; + catch + ESTOFS_Val{e} = 0; + end + end + clear waterLevelsESTOFSINTER waterLevelsESTOFS + for e = [1 4] + try + for Stat = 1:4 + if ESTOFS_Val{e} == 0 + estofsWL(:,Stat,e) = zeros(49,1); + else + [wlDeg(2),wlDeg(1)] = utm2deg(pointsCS{wLIDX(Stat),2}+wlGrid(Stat),pointsCS{wLIDX(Stat),3}+wlGridY(Stat),'18 S'); + [estofIDX] = NearestValue(wlDeg,lonESTOFS,latESTOFS); %Lat + + for i = 1:ESTOFSrunLength(e)+1 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(i-1,'%03d') '.grib']); + + waterLevelsESTOFS{e}(i,Stat) = squeeze(ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,estofIDX(1),estofIDX(2))); + end + waterLevelsESTOFSINTER{e}(:,Stat) = interp1(masterTime-hours(ESTOFStimeOffset(e)):minutes(60):masterTime+hours(48),... + waterLevelsESTOFS{e}(:,Stat),masterTime-hours(ESTOFStimeOffset(e)):minutes(15):masterTime+hours(48),'spline'); + end + end + catch + waterLevelsESTOFSINTER{e}(:,Stat) = zeros(1,385); + end + end + + + %% Validation import WL + % Duck + % Oregon Inlet + % Hatteras + % Beaufort + clear stations statWL + options = weboptions; + options.Timeout = 30; + + stations = {8651370,8652587,8654467,8656483}; + dateStartM = masterTime-hours(48); + dateEndM = masterTime+hours(5); + + for Stat = 1:4 + try + url = ['https://tidesandcurrents.noaa.gov/api/datagetter?product=water_level&application=NOS.COOPS.TAC.WL&'... + 'begin_date=' datestr(dateStartM,'yyyymmdd') '&end_date=' datestr(dateEndM,'yyyymmdd') '&datum=NAVD' '&station=' num2str(stations{Stat})... + '&time_zone=GMT&units=metric&format=csv']; + + wlIN = webread(url,options); + + statWL(:,Stat) = interp1(wlIN.DateTime,wlIN.WaterLevel,dateStartM:minutes(15):dateEndM); + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statWL(:,Stat) = 0; + end + + + clear wlIN + + end + %% Validation import Currents + % Duck + clear statCur + for Stat = 1 + % url = 'https://chlthredds.erdc.dren.mil/thredds/dodsC/frf/oceanography/currents/awac-11m/awac-11m.ncml'; + % curTime = ncread(url,'time'); + % curVal = ncread(url,'currentSpeed'); + try + if day(masterTime)<2 + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime-day(3),'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime-days(3),'YYYYmm') '.nc'],options); + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + curTime = vertcat(curTime,ncread('statCNC.nc','time')); + curVal = vertcat(curVal,ncread('statCNC.nc','currentSpeed')); + + else + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + end + + statCur(:) = interp1(datetime(curTime,'convertFrom','POSIX'),curVal,dateStartM:minutes(15):dateEndM); + clear wlIN + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statCur(:) = zeros(length(dateStartM:minutes(15):dateEndM),1); + end + end + + %% Validation import Waves + % Virginia Beach + % Duck 26 + % Nages Head + % Oregon Inlet + % Diamond Shoals + clear stations + + stations = {44014,44100,44086,44095,41025}; + dateStartM = masterTime-hours(48); + dateEndM = masterTime+hours(5); + + clear statWave + + for Stat = 1:5 + try + if ismember(Stat,[1,5]) == 1 + url = ['https://www.ndbc.noaa.gov/data/5day2/' num2str(stations{Stat}) '_5day.txt']; + + websave('NDBCdata.txt',url,options); + opts = delimitedTextImportOptions("NumVariables", 39); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, 15, "TrimNonNumeric", true); + opts = setvaropts(opts, 15, "ThousandsSeparator", ","); + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + else + url = ['https://www.ndbc.noaa.gov/data/realtime2/' num2str(stations{Stat}) '.txt']; + websave('NDBCdata.txt',url); + + opts = delimitedTextImportOptions("NumVariables", 52); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39", "Var40", "Var41", "Var42", "Var43", "Var44", "Var45", "Var46", "Var47", "Var48", "Var49", "Var50", "Var51", "Var52"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "categorical", "categorical", "categorical", "double", "double", "double", "double", "categorical", "categorical", "double", "double", "categorical", "categorical", "categorical", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "TrimNonNumeric", true); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "ThousandsSeparator", ","); + opts = setvaropts(opts, [6, 7, 8, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + end + + % Import the data + waveIN = readtable("NDBCdata.txt", opts); + waveNAN = isnan(waveIN.WVHT)==0; + % Hs + statWave(:,1,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.WVHT(waveNAN)),dateStartM:minutes(15):dateEndM); + % DPD + % statWave(:,2,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + % (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + % (waveIN.DPD(waveNAN)),dateStartM:minutes(10):dateEndM); + % APD + statWave(:,3,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.APD(waveNAN)),dateStartM:minutes(15):dateEndM); + %MWD + statWave(:,4,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.MWD(waveNAN)),dateStartM:minutes(15):dateEndM); + clear waveIN opts + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + %fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + %sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]); + + % close file + fclose(fid) + statWave(:,:,Stat) = zeros(size(dateStartM:minutes(15):dateEndM,2),4,1); + end + end + statWave(isnan(statWave))=0; + %% Import Model Waves + + for i = 1:49 + startRow = 8; + formatSpec = '%13f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%f%[^\n\r]'; + + fileID = fopen(['Dec28.loct00000' num2str(i,'%02d') '.tab'],'r'); + + % This call is based on the structure of the file used to generate this + % code. If an error occurs for a different file, try regenerating the code + % from the Import Tool. + dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines' ,startRow-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + + fclose(fileID); + modelWaveIN= table(dataArray{1:end-1}, 'VariableNames', {'Xp','Yp','Depth','Hsig','Dir','RTpea','kTm01','Dspr','Ubot','XWindv','YWindv','XVel','YVel'}); + + modelWave(:,1,i) = modelWaveIN.Hsig; + modelWave(:,3,i) = modelWaveIN.RTpea; + modelWave(:,4,i) = modelWaveIN.Dir; + + + clearvars filename startRow formatSpec fileID dataArray ans modelWaveIN; + + end + + %% Import Model WL + modelWL = modelWaterHist.Val; + modelCur = sqrt(modelCurHist.XComp.^2+modelCurHist.YComp.^2); + + for idx = 1:size(modelWL,2) + modelWLInter(:,idx) = interp1(modelWaterHist.Time,modelWL(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))); + end + for idx = 1:size(modelCur,2) + modelCurInter(:,idx) = sqrt(interp1(modelCurHist.Time,modelCurHist.XComp(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))).^2+... + interp1(modelCurHist.Time,modelCurHist.YComp(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))).^2); + end + + save(['ModelOut_' datestr(masterTime,'dd-mmm-yyyy_HH') 'Z.mat'],'modelWL','modelWave','statWL','statWave','modelCur','statCur','modelWLInter','modelCurInter'); + + %% Import Historic Model WL + if masterTime>=datetime(2021,07,08) + try + H12 = load(['ModelOut_' datestr(masterTime-hours(12),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H24 = load(['ModelOut_' datestr(masterTime-hours(24),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H48 = load(['ModelOut_' datestr(masterTime-hours(48),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + end + %% Save html for Currents + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + locLine = 1:5:67; + locationsWave ={'FRF 11 m AWAC '}; + +% % for i = 1:433 +% % for j = 1:100 +% % modelDavDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,2],modelDavDel) + + davIDX=[17 161:172]; + + clear modelCurPlot curValLoc + for Loc = 1:13 + for Line=1:5 + switch Line + case 1 + curValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelCurPlot(1:385,locLine(Loc)+0) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:192,locLine(Loc)+0) = {''}; + modelCurPlot(193:1:385,locLine(Loc)+0) = num2cell(modelCurInter(:,davIDX(Loc))); + case 2 + curValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelCurPlot(1:385,locLine(Loc)+1) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:143,locLine(Loc)+1) = {''}; + modelCurPlot(337:385,locLine(Loc)+1) = {''}; + modelCurPlot(144:1:336,locLine(Loc)+1) = num2cell(H12.modelCurInter(:,davIDX(Loc))); + + case 3 + curValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelCurPlot(1:385,locLine(Loc)+2) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:96,locLine(Loc)+2) = {''}; + modelCurPlot(290:385,locLine(Loc)+2) = {''}; + modelCurPlot(97:1:289,locLine(Loc)+2) = num2cell(H24.modelCurInter(:,davIDX(Loc))); + + case 4 + curValLoc{Line} = ['-48 Hour: ' datestr(masterTime-hours(48),'mm/dd HH') 'Z Run']; + if exist('H48','var') ==0 + modelCurPlot(1:385,locLine(Loc)+3) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(194:385,locLine(Loc)+3) = {''}; + modelCurPlot(1:1:193,locLine(Loc)+3) = num2cell(H48.modelCurInter(:,davIDX(Loc))); + case 5 + curValLoc{Line} = ['Observed Velocity']; + if Loc> 1 || isnan(statCur(1,Loc)) + modelCurPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(214:385,locLine(Loc)+4) = {''}; + modelCurPlot(1:213,locLine(Loc)+4) = num2cell(statCur); + + end + + end + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],modelCurPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],curValLoc) + curValLoc = repmat(curValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... + [1,1],horzcat(googleDatesCell',vertcat(curValLoc(1:size(modelCurPlot,2)),modelCurPlot))) + %% Save html for WL + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% locLine = [2 7 12 17 22 27]; +% locLine = [2 9 16 23 30 37]; + locLine = 1:7:114; + + locationsWl ={'FRF Pier',... + 'Oregon Inlet',... + 'Hatteras',... + 'Beaufort'}; + +% % for i = 1:433 +% % for j = 1:121 +% % modelWlDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,2],modelWlDel) + + wLIDX=[6 7 8 38 161:172]; + clear modelWlPlot wlValLoc + for Loc = 1:length(wLIDX) +% modelwlPlot = cell(432,4); + for Line=[1:5 6 9] + switch Line + case 1 + wlValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelwlPlot(1:385,locLine(Loc)+0) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:192,locLine(Loc)+0) = {''}; + modelwlPlot(193:1:385,locLine(Loc)+0) = num2cell(modelWLInter(:,wLIDX(Loc))); + case 2 + wlValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelwlPlot(1:385,locLine(Loc)+1) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:143,locLine(Loc)+1) = {''}; + modelwlPlot(337:385,locLine(Loc)+1) = {''}; + modelwlPlot(144:1:336,locLine(Loc)+1) = num2cell(H12.modelWLInter(:,wLIDX(Loc))); + + case 3 + wlValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelwlPlot(1:385,locLine(Loc)+2) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:96,locLine(Loc)+2) = {''}; + modelwlPlot(290:385,locLine(Loc)+2) = {''}; + modelwlPlot(97:1:289,locLine(Loc)+2) = num2cell(H24.modelWLInter(:,wLIDX(Loc))); + + case 4 + wlValLoc{Line} = ['-48 Hour: ' datestr(masterTime-hours(48),'mm/dd HH') 'Z Run']; + if exist('H48','var') ==0 + modelwlPlot(1:385,locLine(Loc)+3) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(194:385,locLine(Loc)+3) = {''}; + modelwlPlot(1:1:193,locLine(Loc)+3) = num2cell(H48.modelWLInter(:,wLIDX(Loc))); + case 5 + wlValLoc{Line} = ['Observed Water Level']; + if Loc>4 || isnan(statWL(1,Loc)) + modelwlPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(214:385,locLine(Loc)+4) = {''}; + modelwlPlot(1:213,locLine(Loc)+4) = num2cell(statWL(:,Loc)); + case 6 + wlValLoc{Line} = ['ESTOFS Forecast']; +% % if Loc>4 || ESTOFS_Val{1} == 0 + modelwlPlot(1:385,locLine(Loc)+5) = num2cell(zeros(385,1)); +% % continue +% % end +% % modelwlPlot(1:192,locLine(Loc)+5) = {''}; +% % modelwlPlot(193:385,locLine(Loc)+5) = num2cell(waterLevelsESTOFSINTER{1}(:,Loc)); + case 9 + wlValLoc{7} = ['-48 Hour ESTOFS']; +% if Loc>4 || ESTOFS_Val{4} == 0 + modelwlPlot(1:385,locLine(Loc)+6) = num2cell(zeros(385,1)); +% % continue +% % end +% % modelwlPlot(1:1:385,locLine(Loc)+6) = num2cell(waterLevelsESTOFSINTER{4}(:,Loc)); + end + end + disp(Loc) + + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [2,locLine(Loc)],modelwlPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [1,locLine(Loc)],wlValLoc) + + wlValLoc = repmat(wlValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... + [1,1],horzcat(googleDatesCell',vertcat(wlValLoc(1:size(modelwlPlot,2)),modelwlPlot))) + + %% Save html for Waves + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,1],googleDates') + +% locLine = [2 7 12 17 22 27]; + locLine = 1:5:114; + + locationsWave ={'Virginia Beach',... + 'FRF 26 m',... + 'Nags Head',... + 'Oregon Inlet',... + 'Diamond Shoals'}; + + clear waveValLoc modelwavePlot + + for i = 1:385 + for j = 1:85 + modelwavePlot(i,j)={''}; + end + end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,2],modelWaveDel) + + waveIDX = [12 13 14 15 16 161:172]; + for Loc = 1:length(waveIDX) +% modelwavePlot = cell(432,5); + for Line=1:5 + switch Line + case 1 + waveValLoc{Line} = ['Forecast']; + if exist('modelWave','var') ==0 + modelwavePlot(1:385,locLine(Loc)+0) = num2cell(zeros(433,1)); + continue + end + modelwavePlot(1:191,locLine(Loc)+0) = {''}; + modelwavePlot(192,locLine(Loc)+0) = {0}; + modelwavePlot(193:4:385,locLine(Loc)+0) = num2cell(modelWave(waveIDX(Loc),1,:)); + case 2 + waveValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 || size(H12.modelWave,1)5 || isnan(statWave(1,1,Loc)) + modelwavePlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelwavePlot(215:385,locLine(Loc)+4) = {''}; + modelwavePlot(214,locLine(Loc)+4) = {0}; + modelwavePlot(1:1:213,locLine(Loc)+4) = num2cell(statWave(:,1,Loc)); + + end + + end +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [2,locLine(Loc)],modelwavePlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [1,locLine(Loc)],waveValLoc) + end + + waveValLoc = repmat(waveValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... + [1,1],horzcat(googleDatesCell',vertcat(waveValLoc(1:size(modelwavePlot,2)),modelwavePlot))) + + + + + %% Import and modify times +% modelHour = [0 3 6 12 24 48]; + modelHour = [0 6 12 24 36 48]; + for i = 1:6 + dateText(i) = {[datestr(masterTime+hours(modelHour(i)),'mmm dd, HH:MM') ' UTC (Hour '... + num2str(modelHour(i),'%d') ')']}; + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','0',[1,1],... + dateText) + +catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['ALL-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + +end + +%% +quit + + + + + + + + + + + + + + + + diff --git a/Dunex_Operational_Sept_7.m b/Dunex_Operational_Sept_7.m new file mode 100644 index 0000000..ff02cd4 --- /dev/null +++ b/Dunex_Operational_Sept_7.m @@ -0,0 +1,2382 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +% Moved to COASTLINES Feb 29, 2020 + +clear all +cd D:\DUNEX_RT\Operation +echo off; +addpath('NCtoolbox') +addpath('m_map') +setup_nctoolbox +flowGrid = load('Cone7W_100.mat'); +waveGrid = load('Cone7W_250.mat'); +load('LMSL_RT.mat') +addpath('D:\DUNEX_RT\Operation\abogaard-matlab2gsheets-6d76271') +setenv('PATH', [getenv('PATH') ';D:\DUNEX_RT\Windows_64']); + +%% Details for e-mail server +setpref('Internet','SMTP_Server','smtp.sendgrid.net'); +setpref('Internet','E_mail','mail@alexanderrey.ca'); +setpref('Internet','SMTP_Username','apikey'); +setpref('Internet','SMTP_Password','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'); +props = java.lang.System.getProperties; +props.setProperty('mail.smtp.auth','true'); +props.setProperty('mail.smtp.socketFactory.class', 'javax.net.ssl.SSLSocketFactory'); +props.setProperty('mail.smtp.socketFactory.port','465'); +props.setProperty('mail.smtp.starttls.enable','true'); + + +%% Master Model Time Step +% Every 6 hours + +nistTime = datetime(datevec(now())) - tzoffset(datetime(datevec(now()),'TimeZone','local')); +masterTime = dateshift(nistTime,'start','hour')-hours(2) % Assume script will run at 5 and a half hours after model start +clear nistTime +masterDate = datetime(year(masterTime),month(masterTime),day(masterTime)); + +if exist(['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000'])==2 + FIRST_RUN = 0; +else + FIRST_RUN = 1; +end + +%% Import +try + Import=0; + + + %% Clean files from previous run + system('taskkill /IM "d_hydro.exe" /F') + system('taskkill /IM "wave.exe" /F') + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + + clear HRRR_UTM + while Import==0 + try + %% Import data from NOMADS + %% Extratropical Surge and Tide Operational Forecast System for the Atlantic + % (ESTOFS Atlantic) for water levels + options = weboptions; + options.Timeout = 90; + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(6),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(6),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 7; + ESTrun = 6; + catch + % url = ['http://nomads.ncep.noaa.gov/dods/estofs_atl/'... + % datestr(masterTime-days(1),'yyyymmdd')... + % '/estofs_atl_conus_' datestr(masterTime-days(1),'hh') 'z']; + % ESTOFS = ncgeodataset(url); + % lonESTOFS=ESTOFS{'lon'}(:); + % latESTOFS=ESTOFS{'lat'}(:); + % ESTstart = 24+ESTstart; +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-days(1),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-days(1),'yyyymmdd')... + '/estofs.t' datestr(masterTime-days(1),'hh') 'z.conus.east.f000.grib2']; + + websave('ESTOFS.grib',url,options) + ESTOFS = ncgeodataset('ESTOFS.grib'); + + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTstart = 25; + ESTrun = 24; + end + + + clear url + + % Find ESTOFS index for grid points along boundry + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); %Lat + wlIDX(idxCount,:) = [1082,i]; + + idxCount = idxCount + 1; + end + + wlBoundCount(1) = 0; + wlBoundCount(2) = idxCount -1; + + + for i = 750:11:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1322]; + idxCount = idxCount + 1; + end + + wlBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [idxESTOFS(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latESTOFS); %Lat + % [idxESTOFS(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonESTOFS); %Lon + [idxESTOFS(idxCount,:)] = ... + NearestValue([gridDeg(idxCount,:)],latESTOFS,lonESTOFS); + wlIDX(idxCount,:) = [i,1]; + idxCount = idxCount + 1; + end + wlBoundCount(4) = idxCount -1; + + clear idxCount gridDeg + + % Extract ESTOFS Water Levels for 36 hours at indexes + % waterLevelsGRID = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(ESTstart:ESTstart+36,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + % min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + + % Find ESTOFS values from small grid + idxCount=1; + errorET = 0; + for i = ESTstart:ESTstart+96 + if errorET<10 + try +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... +% num2str(i,'%03d') '.grib2']; + + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.conus.east.f'... + num2str(i,'%03d') '.grib2']; + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib'],url,options) + + if i<=ESTstart+48 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_f' num2str(idxCount-1,'%03d') '.grib']); + + waterLevelsGRID(idxCount,:,:) = ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,min(idxESTOFS(:,1)):max(idxESTOFS(:,1)),... + min(idxESTOFS(:,2)):max(idxESTOFS(:,2))); % Extract small grid + end + idxCount = idxCount + 1; + catch + errorET = errorET+1; + end + else + error('ESTOFS ERROR') + end + + end + + idxCount=1; + for i = 1:length(idxESTOFS) + waterLevels(:,idxCount) = waterLevelsGRID(:,idxESTOFS(idxCount,1)-min(idxESTOFS(:,1))+1,... + idxESTOFS(idxCount,2)-min(idxESTOFS(:,2))+1); + + idxCount = idxCount + 1; + end + + + % Save ESTOFS Points +% url = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/estofs/prod/estofs.'... +% datestr(masterTime-hours(ESTrun),'yyyymmdd')... +% '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + url = ['https://noaa-gestofs-pds.s3.amazonaws.com/estofs.'... + datestr(masterTime-hours(ESTrun),'yyyymmdd')... + '/estofs.t' datestr(masterTime-hours(ESTrun),'hh') 'z.points.cwl.nc']; + + websave(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime,'YYYY-mm-DD_HH') '_points.nc'],url,options) + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + disp('Loaded ESTOFS') + %% Multi-grid Wave model (WAVEWATCH III) + % 4 arc minute US East Coast grid for waves + + url = ['https://nomads.ncep.noaa.gov/dods/wave/gfswave/'... + datestr(masterTime-hours(6),'yyyymmdd')... + '/gfswave.atlocn.0p16_' datestr(masterTime-hours(6),'hh') 'z']; + + MWW3 = ncgeodataset(url); + clear url + + lonMWW3=wrapTo180(MWW3{'lon'}(:)); + latMWW3=MWW3{'lat'}(:); + + % Find MWW3 index for grid points along boundry + idxCount=1; + for i = 1:25:length(waveGrid.data.Y)-25 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(end-2,i),waveGrid.data.Y(end-2,i),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(end-2,1:i)).^2+... + diff(waveGrid.data.Y(end-2,1:i)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(end-2,i); + waveUTM(idxCount,2) = waveGrid.data.Y(end-2,i); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + waveBoundCount(1) = 0; + waveBoundCount(2) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:350% Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,end-2),waveGrid.data.Y(i,end-2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,end-2)).^2+... + diff(waveGrid.data.Y(i:end-2,end-2)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,end-2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,end-2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + % 0 132 163 285 + + waveBoundCount(3) = idxCount -1; + + for i = size(waveGrid.data.X,1)-25:-25:240 % Every ~200 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(waveGrid.data.X(i,2),waveGrid.data.Y(i,2),'18 S'); + waveDistAlong(idxCount) = sum(sqrt(diff(waveGrid.data.X(i:end-2,1)).^2+... + diff(waveGrid.data.Y(i:end-2,1)).^2)); + + waveUTM(idxCount,1) = waveGrid.data.X(i,2); + waveUTM(idxCount,2) = waveGrid.data.Y(i,2); + + [idxMWW3(idxCount,1)] = NearestValue(gridDeg(idxCount,1),latMWW3); %Lat + [idxMWW3(idxCount,2)] = NearestValue(gridDeg(idxCount,2),lonMWW3); %Lon + + idxCount = idxCount + 1; + end + + waveBoundCount(4) = idxCount -1; + + clear idxCount + + % Extract WW3 Hs for 36 hours at indexes + wavesGRID_Hs = MWW3{'htsgwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid htsgwsfc + %swell_1 + % Period + wavesGRID_P = MWW3{'perpwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... % + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid perpwsfc + %swper_1 + % Direction + wavesGRID_Dir = MWW3{'dirpwsfc'}(7:23,min(idxMWW3(:,1)):max(idxMWW3(:,1)),... + min(idxMWW3(:,2)):max(idxMWW3(:,2))); % Extract small grid dirpwsfc + %swdir_1 + % Find WW3 values from small grid + idxCount=1; + for i = 1:length(idxMWW3) + waves(:,idxCount,1) = wavesGRID_Hs(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Hs + + waves(:,idxCount,2) = wavesGRID_P(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Tp + + waves(:,idxCount,3) = wavesGRID_Dir(:,idxMWW3(idxCount,1)-min(idxMWW3(:,1))+1,... + idxMWW3(idxCount,2)-min(idxMWW3(:,2))+1); %Dir + + idxCount = idxCount + 1; + end + clear idxCount + disp('Loaded WW3') + + + %% HRRR (High-Resolution Rapid Refresh) + % Wind Speeds, Directions, Pressures, Precipitations + % url = ['http://nomads.ncep.noaa.gov/dods/hrrr/hrrr'... + % datestr(masterTime,'yyyymmdd')... + % '/hrrr_sfc.t' datestr(masterTime,'hh') 'z']; +% delete(gcp('nocreate')) +% parpool(8); + + for ForcastHour = 0:48 + % url = ['http://nomads.ncep.noaa.gov/pub/data/nccf/com/hrrr/prod/'... + % 'hrrr.' datestr(masterTime,'yyyymmdd')... + % '/conus/hrrr.t' num2str(hour(masterTime),'%02d') 'z.'... + % 'wrfsfcf' num2str(ForcastHour,'%02d') '.grib2']; + + url = ['https://nomads.ncep.noaa.gov/cgi-bin/filter_hrrr_2d.pl?file=hrrr.'... + 't' num2str(hour(masterTime),'%02d') 'z.wrfsfc'... + 'f' num2str(ForcastHour,'%02d') '.grib2&'... + 'lev_10_m_above_ground=on&lev_surface=on&var_APCP=on&var_PRES=on&var_UGRD=on&var_VGRD=on&var_TMP=on&subregion=&leftlon=-78&rightlon=-74&toplat=38&bottomlat=32.5&dir=%2F'... + 'hrrr.' datestr(masterTime,'yyyymmdd') '%2Fconus']; + + websave(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2'],url,options) + + [pCheck,gridParams] = system(['perl "D:\DUNEX_RT\Windows_64\grid_defn.pl" '... + 'D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + [wCheck,gridParams] = system(['wgrib2 D:\DUNEX_RT\Operation\HRRR\hrrrT' ... + num2str(ForcastHour,'%02d') '.grib2 -new_grid_winds earth -new_grid ' ... + gridParams ' D:\DUNEX_RT\Operation\HRRR\hrrrT'... + num2str(ForcastHour,'%02d') '.grib2.regrid']); + end +% delete(gcp('nocreate')) + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(0,'%02d') '.grib2.regrid']); + clear url + + m_proj('lambert conformal conic','ori',[262.5 38.5],'clo',262.5,'par',[38.5 38.5],'ell','sphere');%,'lat',[20 55],'lon',[-60 -130] + [meshX,meshY] = meshgrid(HRRR{'x'}(:),HRRR{'y'}(:)); + [windGridLON,windGridLAT] = m_xy2ll(meshX.*1000,meshY.*1000); + windGridLON=wrapTo180(windGridLON); + clear meshX meshY + + % Extract MWW3 Hs for 48 hours at indexes + for ForcastHour = 0:48 + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2.regrid']); + windU(ForcastHour+1,:,:) = HRRR{'u-component_of_wind_height_above_ground'}(:,:,:); %U Winds @ 10m [m/s] + windV(ForcastHour+1,:,:) = HRRR{'v-component_of_wind_height_above_ground'}(:,:,:); %V Winds @ 10m [m/s] + + HRRR = ncgeodataset(['D:\DUNEX_RT\Operation\HRRR\hrrrT' num2str(ForcastHour,'%02d') '.grib2']); + pressure(ForcastHour+1,:,:) = HRRR{'Pressure_surface'}(:,:,:); %Surface Pressure [pa] + + if ForcastHour==0 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_0_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + elseif ForcastHour==1 + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_1_Hour_Accumulation'}(1,:,:); %Surface precipitation [kg/m^2] + else + rain(ForcastHour+1,:,:) = HRRR{'Total_precipitation_surface_Mixed_intervals_Accumulation'}(2,:,:); %Surface precipitation [kg/m^2] + end + temperature(ForcastHour+1) = squeeze(nanmean(nanmean(HRRR{'Temperature_surface'}(:,:,:)- 273.15,2),3)); %Surface Temperature [C] + end + % Extract Temp + + disp('Loaded HRRR') + + + %% IMPORT NCOM + + try + nComDate=masterDate; +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/20201220/coamps_ncom_useast_u_1_2020122000_00000000.nc']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; + +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + mkdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0025-0048.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0073-0096.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0073-0096.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); + % NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); + % NCOM.Lat = ncom_grib{'lat',[331],[240]}; + % NCOM.Lon = ncom_grib{'lon',91,180}; + catch + try + if hour(masterTime) ~= 18 + nComDate=masterDate-days(1); + else + nComDate=masterDate; + end +% ncomeURL = ['http://nomads.ncep.noaa.gov:80/dods/ncom/ncom' datestr(nComDate,'YYYYmmDD') '/ncom_useast_']; +% ncomeURL = ['https://www.ncei.noaa.gov/thredds-coastal/dodsC/us_east/us_east_20201218_to_current/' datestr(nComDate,'YYYYmmDD')... +% '/coamps_ncom_useast_u_1_']; +% mget(ncom_ftp,['grids/operational/NCOM/regional/GRIB2/ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2'],['D:\DUNEX_RT\Operation\NCOM\']); +% ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\grids\operational\NCOM\regional\GRIB2\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.grb2']; +% ncom_grib = ncgeodataset(ncom_downloadPath); + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + if exist(ncom_downloadPath) ~= 2 + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0025-0048.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '00.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0000-0024.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0000-0024.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0049-0072.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0049-0072.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + ncomURL = ['https://nomads.ncep.noaa.gov/pub/data/nccf/com/ncom/prod/ncom.' datestr(nComDate,'YYYYmmDD') '/' 'useast_u_ocn_ncout_grid1_'... + datestr(nComDate,'YYYYmmDD') '00_t0073-0096.tgz']; + ncom_downloadPath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\ncom_useast_' datestr(nComDate,'YYYYmmDD') '0073-0096.tgz']; + websave(ncom_downloadPath,ncomURL,options) + untar(ncom_downloadPath,['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD')]) + + end + + if exist(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')]) == 7 + rmdir(['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate-days(2),'YYYYmmDD')], 's') + end + ncom_filePath = ['D:\DUNEX_RT\Operation\NCOM\' datestr(masterDate,'YYYYmmDD') '\coamps_ncom_useast_u_1_' datestr(nComDate,'YYYYmmDD') '00_00']; +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD')],'lat',[331],[240]); +% NCOM.Lat = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00000000.nc'],'lat',[331],[240]); + NCOM.Lat = ncread([ncom_filePath '48' '0000.nc'],'lat',[331],[240]); + NCOM.Lon = ncread([ncom_filePath '48' '0000.nc'],'lon',91,180); +% NCOM.Lat = ncom_grib{'lat',[331],[240]}; +% NCOM.Lon = ncom_grib{'lon',91,180}; + + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + end + + if FIRST_RUN == 1 + NCOM.depth = ncread('D:\Alexander\NCOM\2019090500_t000.nc','depth'); + end + + Noffset = hours(masterTime - nComDate); + tStep = Noffset; + tCount = 1; + + try + for Ni = masterTime:hours(3):masterTime+hours(48) + noData=1; + while noData==1 + try +% NCOMstep = tStep./3+1; + NCOMstep = 1; + +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(masterDate,'YYYYmmDD')],... +% 'water_u',[NCOMstep 1 331 91],[1 40 240 180],[1 1 1 1]); +% NCOM.water_u(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_u',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.water_v(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'water_v',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); +% NCOM.surf_el(:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'surf_el',[91 331 NCOMstep],[180 240 1],[1 1 1]); +% NCOM.salinity(:,:,:,tCount) = ncread([ncomeURL datestr(nComDate,'YYYYmmDD') '00_00' num2str(tStep) '0000.nc'],... +% 'salinity',[91 331 1 NCOMstep],[180 240 inf 1],[1 1 1 1]); + NCOM.water_u(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_u',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.water_v(:,:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'water_v',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + NCOM.surf_el(:,:,tCount) = ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'surf_el',[91 331 1],[180 240 1],[1 1 1]); + NCOM.salinity(:,:,:,tCount) =ncread([ncom_filePath num2str(tStep,'%02d') '0000.nc'],... + 'salinity',[91 331 1 1],[180 240 inf 1],[1 1 1 1]); + + if (squeeze(NCOM.water_v(100,100,1,end))==0|squeeze(NCOM.water_u(100,100,1,end))==0|squeeze(NCOM.surf_el(100,100,end))==0|squeeze(NCOM.salinity(100,100,1,end))==0)==1 + noData=1; + else + noData=0; + end + catch + noData=1; + end + disp(Ni) + end + NCOM.time(tCount) = Ni; + tStep=tStep+3; + tCount = tCount+1; + end + catch + load(['ModelOut_03-Mar-2020_18Z'],'NCOM'); + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'%s : %s\n',datestr(masterTime),'NCOM Fallback'); + sendmail('alexander.rey@queensu.ca',[datestr(masterTime) ': NCOM Fallback']) ; + + % close file + fclose(fid) + end + + + + %% NCOM Process + NCOM.mag = vecmag(NCOM.water_u,NCOM.water_v); + + if FIRST_RUN == 1 + depthWeight = [diff(NCOM.depth)' 0]; + + for Layer = 1:40 + DAVfac(:,:,Layer,:) = ones(180,240,1,17).*depthWeight(Layer); + end + DAVtrue = DAVfac; + N_depth = NCOM.depth; + save('NCOMstuff.mat','DAVtrue','DAVfac','N_depth') + else + load('NCOMstuff.mat') + NCOM.depth = N_depth; + clear N_depth; + end + DAVtrue(isnan(NCOM.mag(:,:,1:40,:))==1) = 0; + DAVfac(isnan(NCOM.mag(:,:,1:40,:))==1) = nan; + DAVFac2 = sum(DAVtrue,3); + clear DAVtrue + NCOM.dav = nansum(DAVfac.*NCOM.mag(:,:,1:40,:),3)./DAVFac2; + NCOM.davX = nansum(DAVfac.*NCOM.water_u(:,:,1:40,:),3)./DAVFac2; + NCOM.davY = nansum(DAVfac.*NCOM.water_v(:,:,1:40,:),3)./DAVFac2; + + Import=1 + catch err + + clear waterLevels + + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + disp('FAILED TO IMPORT FROM NOMADS') + pause(600) + end + end + + + load('shoreline.mat'); + + %% Format data for Delft3D + %% Evap + fileID=fopen('TemperatureRT.eva','w'); + refTime=minutes(masterTime-masterDate); + records=49; + for i = 1 : records + fprintf(fileID,'%d. 0. 0. %2.2f\n',refTime,temperature(i)); + + refTime = refTime + 60;% 1 hour time steps for temperature + end + + fclose(fileID); + + %% NCOM ESTOFS + % Currents from NCOM + + idxCount=1; + for i = 2:10:length(flowGrid.data.Y)-1 % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(1081,i),flowGrid.data.Y(1081,i),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(2161,i),flowGrid.data.Y(2161,i),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [1081,i]; + % crIDX(idxCount,:) = [2161,i]; + + idxCount = idxCount + 1; + end + + crBoundCount(1) = 0; + crBoundCount(2) = idxCount -1; + + for i = 750:11:1080 % Every 5 km + % for i = round(linspace(1488,2161,14)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1321),flowGrid.data.Y(i,1321),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,2641),flowGrid.data.Y(i,2641),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1320]; + % crIDX(idxCount,:) = [i,2641]; + + idxCount = idxCount + 1; + end + crBoundCount(3) = idxCount -1; + + for i = 475:5:1080 % Every 5 km + % for i = round(linspace(910,2161,26)) % Every 5 km + [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + % [gridDeg(idxCount,1),gridDeg(idxCount,2)] = utm2deg(flowGrid.data.X(i,1),flowGrid.data.Y(i,1),'18 S'); + + [idxNCOM(idxCount,1)] = NearestValue(gridDeg(idxCount,1),NCOM.Lat); %Lat + [idxNCOM(idxCount,2)] = NearestValue(gridDeg(idxCount,2),wrapTo180(NCOM.Lon)); %Lon + crIDX(idxCount,:) = [i,1]; + % crIDX(idxCount,:) = [i,1]; + + idxCount = idxCount + 1; + end + crBoundCount(4) = idxCount -1; + + + clear idxCount + + %% Interpolate Water Level + % for tStep = 1:length(tideOutN) + % wlO(tStep,1:crBoundCount(2)) = linspace(tideOutS(tStep),tideOutN(tStep),crBoundCount(2)); + % wlO(tStep,crBoundCount(2)+1:crBoundCount(3)) = linspace(tideOutN(tStep),tideOutN(tStep),crBoundCount(3)-crBoundCount(2)); + % wlO(tStep,crBoundCount(3)+1:crBoundCount(4)) = linspace(tideOutS(tStep),tideOutS(tStep),crBoundCount(4)-crBoundCount(3)); + % end + + vDatOrder = [crBoundCount(3)+1:1:crBoundCount(4) ... + crBoundCount(1)+1:1:crBoundCount(2) ... + crBoundCount(3):-1:crBoundCount(2)+1]; + + crBoundCountOld = [0 27 34 46]; + vDatOrderOld = [crBoundCountOld(3)+1:1:crBoundCountOld(4) ... + crBoundCountOld(1)+1:1:crBoundCountOld(2) ... + crBoundCountOld(3):-1:crBoundCountOld(2)+1]; + + vDatNavD = LMSL_RT(:,3); + vDatNavD(vDatNavD==-999999)=nan; + + % interp1(vDatNavD(vDatOrder),1:46) + vDatNavDInter(vDatOrder) = naninterp(interp1(... + linspace(1,length(vDatOrder),length(vDatOrderOld)),... + vDatNavD(vDatOrderOld),1:length(vDatOrder))); + for i = 1:length(idxNCOM) + wlO(:,i) = interp1(masterTime:hours(1):masterTime+hours(48),waterLevels(:,i)+0,masterTime:minutes(10):masterTime+hours(48),'pchip'); + end + + %% Match to grid + flowBed = load('Dec6_100Bed.mat'); + clear wlN mag DM dirGrid currents RN_1 currents_2 currents_40 currDir currDir40 + idxCount=1; + for i = 1:length(idxNCOM) + currX = squeeze(NCOM.davX(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + currY = squeeze(NCOM.davY(idxNCOM(idxCount,2),idxNCOM(idxCount,1),1,:)); + + currX40 = squeeze(NCOM.water_u(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + currY40 = squeeze(NCOM.water_v(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:,:)); + + + currDir(i,:) = wrapTo360(atan2d(-currY,currX)+90); + currDir40(i,:,:) = wrapTo360(atan2d(-currY40,currX40)+90); + + xGridDir(i,:) = ([flowGrid.data.X(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.X(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + yGridDir(i,:) = ([flowGrid.data.Y(crIDX(idxCount,1)-2,crIDX(idxCount,2)-0) flowGrid.data.Y(crIDX(idxCount,1)-1,crIDX(idxCount,2)-0)]); + wlN(:,idxCount) = squeeze(NCOM.surf_el(idxNCOM(idxCount,2),idxNCOM(idxCount,1),:))+vDatNavDInter(i); + mag(:,idxCount) = vecmag(currX,currY); + + % if idxCount==1 + % DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount+1,1)-1,crIDX(idxCount+1,2))); + % else + DM(idxCount) = -squeeze(flowBed.data.Val(crIDX(idxCount,1)-1,crIDX(idxCount,2))); + % end + + if i>crBoundCount(2) && i<=crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + elseif i>crBoundCount(3) + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))+90); + currents(:,idxCount) = sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + RN_1(:,idxCount) = currents(:,idxCount) + wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currY; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + else + dirGrid(i) = wrapTo360(atan2d(-diff(yGridDir(i,:)),diff(xGridDir(i,:)))); + currents(:,idxCount) = -sind(dirGrid(i)-currDir(i,:))'.*vecmag(currX,currY); + % currents(:,idxCount) = sind(dirGrid(i)-0)'.*vecmag(currY); + + RN_1(:,idxCount) = -currents(:,idxCount) - wlN(:,idxCount).*sqrt(9.81./DM(idxCount)); + currents_2(:,idxCount) = currX; + + for j=1:40 + currents_40(:,j,idxCount) = squeeze(-sind(dirGrid(i)-squeeze(currDir40(i,j,:))).*vecmag(currX40(j,:),currY40(j,:))'); + end + + end + + % disp(idxCount) + idxCount = idxCount + 1; + + end + + % fprintf(fileID,[boundryNames{Boundry} ' N T 750 1322 1081 1322 0.0000000e+000\n']); + % fprintf(fileID,[boundryNames{Boundry} ' N T 475 1 1081 1 0.0000000e+000\n']); + + clear idxCount + + %% interpolate Currents + clear currentsOut + for i = 1:3 + [xIN,yIN] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(NCOM.time)); + + [xOut,yOut] = meshgrid([crBoundCount(i)+1:crBoundCount(i+1)],... + datenum(masterTime:minutes(10):masterTime+hours(48))); + + + currentsOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + currents2Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + currents_2(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + wlNOut(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + wlN(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + RNOut_1(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + interp2(xIN,yIN,... + RN_1(:,crBoundCount(i)+1:crBoundCount(i+1)),... + xOut,yOut); + + % for j = 1:length(idxNCOM) + % currents40Out(:,crBoundCount(i)+1:crBoundCount(i+1)) = ... + % interp2(xIN,yIN,... + % squeeze(currents_40(:,j,crBoundCount(i)+1:crBoundCount(i+1))),... + % xOut,yOut); + % end + + end + idxCount=1; + + + for i = 1:length(idxNCOM) + if i>crBoundCount(2) && i<=crBoundCount(3) + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + + elseif i>crBoundCount(3) + if i<230 + RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); +% RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 1.*sqrt(9.81./DM(idxCount)); + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) + wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = 1.0.*currentsOut(:,idxCount) + 0.*sqrt(9.81./DM(idxCount)); + end + else + RNOut_2(:,i) = 0.0.*currentsOut(:,idxCount) - wlO(:,idxCount).*sqrt(9.81./DM(idxCount)); + % RNOut_2(:,i) = -1.0.*currentsOut(:,idxCount) - 0.*sqrt(9.81./DM(idxCount)); + end + + + + idxCount = idxCount+1; + end + + %% R Boundry Files + records=size(RNOut_2,1); + + for i = 1:crBoundCount(4) + boundryNames(i) = {['NCOM' num2str(i)]}; + end + + % boundryTypes(1) = {'water elevation (z)'}; + boundryTypes(1:crBoundCount(4)) = {'riemann (r)'}; + boundryUnits(1:crBoundCount(4)) = {'[m/s]'}; + + fileID=fopen('NCOM_R2.bct','w'); + + for Boundry = [2:length(boundryNames)] + refTime=minutes(masterTime-masterDate); + if Boundry==1 + elseif ismember(Boundry-1,crBoundCount)==1 + continue + end + + header=[... + 'table-name ''Boundary Section : %d''\n'... + 'contents ''Uniform ''\n'... + 'location ''' boundryNames{Boundry} ' ''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + 'parameter ''' boundryTypes{Boundry} ' end A'' unit ''' boundryUnits{Boundry} '''\n'... + 'parameter ''' boundryTypes{Boundry} ' end B'' unit ''' boundryUnits{Boundry} '''\n'... + 'records-in-table %d\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterDate,'yyyymmdd')),records); + for line = 1:records + fprintf(fileID,'%d %1.4f %1.4f\n',refTime,RNOut_2(line,Boundry-1),RNOut_2(line,Boundry)); + + refTime=refTime+10; + end + end + + fclose(fileID); + %% Boundry definition file-R + fileID=fopen('NCOM_R.bnd','w'); + crIDX2=crIDX; + crIDX2(crBoundCount(2)+1:crBoundCount(3),2) = crIDX(crBoundCount(2)+1:crBoundCount(3),2)+2; + crIDX2(crBoundCount(1)+1:crBoundCount(2),1) = 1082; + + for Boundry = [2:length(boundryNames)] + if ismember(Boundry-1,crBoundCount)==1 + continue + else + + boundStart = crIDX2(Boundry-1,:); + boundEnd = crIDX2(Boundry,:); + + fprintf(fileID,[boundryNames{Boundry} ' R T ' num2str(boundStart(1)) ' ' num2str(boundStart(2)) ' '... + num2str(boundEnd(1)) ' ' num2str(boundEnd(2)) ' 0.0000000e+000 Uniform \n']); + end + end + fclose(fileID); + + + %% Waves + records = size(waves,1); + fileID=fopen('WW3.bcw','w'); + + for i = 1:3 + boundryNames(i) = {['East' num2str(i)]}; + end + + for Boundry = 1:3 + refTime=minutes(masterTime-masterDate); + + header=[... + 'location ''East%d''\n'... + 'time-function ''non-equidistant''\n'... + 'reference-time %d\n'... + 'time-unit ''minutes''\n'... + 'interpolation ''linear''\n'... + 'parameter ''time '' unit ''[min]''\n'... + ]; + + + fprintf(fileID,header,Boundry,str2num(datestr(masterTime,'yyyymmdd'))); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''WaveHeight '' unit ''[m]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Period '' unit ''[s]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''Direction '' unit ''[N^o]''\n'); + end + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'parameter ''DirSpreading '' unit ''[-]''\n'); + end + + for line = 1:records + fprintf(fileID,'%d ',refTime); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,1)); %Hs + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,2)); %Period + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',waves(line,Segment,3)); %Direction + end + fprintf(fileID,'\n '); + + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'%1.4f ',4); %Spread + end + fprintf(fileID,'\n'); + + % fprintf(fileID,'%.2f %1.4f %1.4f %1.4f %1.4f\n',refTime,... + % waves(line,Boundry,1),waves(line,Boundry,2),waves(line,Boundry,3),4); + refTime=refTime+180; + end + end + + fclose(fileID); + + + %% Modify MDF file to change reference date + + fileID = fopen('rt_base.mdf'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdf', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 15 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'Itdate = #%04d-%02d-%02d#\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 17 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID,['Tstart = %#.7e \n','Tstop = %#.7e \n'],refTime,refTime+2880); + + + + for i = 20:29 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + if FIRST_RUN == 0 + restID = ['tri-rst.rt_run.' datestr(masterTime,'yyyymmdd.HH') '0000']; + if exist(restID)==2 + eval(['movefile ' restID ' tri-rst.6h_restart']) + end + + fprintf( fileID,['Commnt = initial conditions from restart file\n'... + 'Restid = #6h_restart#\n']); + % delete tri-rst.rt* + else + + % fprintf( fileID,['Commnt = initial conditions from map file\n'... + % 'Restid = #Jan16_06#\n']); + + % fprintf( fileID,'Zeta0 = %#.7e \n',nanmean(nanmean(squeeze(wlO(1,:))))); + fprintf( fileID,'Zeta0 = %#.7e \n',0); + + end + + for i = 31:53 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % if FIRST_RUN==1 + % fprintf( fileID, 'Vicouv = 1.0000000e+002 \n'); + % else + fprintf( fileID, '%s\n', cac{1}{54} ); + % end + + for i = 55:64 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + if FIRST_RUN==1 + fprintf( fileID, 'Tlfsmo = 0.0000000e+001 \n'); + else + fprintf( fileID, 'Tlfsmo = 0.0000000e+000 \n'); + end + + for i = 66:94 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + + + fprintf( fileID,[... + 'Flmap = %#.7e 60 %#.7e\n',... + 'Flhis = %#.7e 10 %#.7e\n',... + 'Flpp = %#.7e 60 %#.7e\n'],... + refTime,refTime+2880,refTime,refTime+2880,refTime,refTime+2880); + + for i = 98:109 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + clear cac + %% Modify MDW file to add times and change reference date + + fileID = fopen('rt_base.mdw'); + cac = textscan( fileID, '%s', 'Delimiter','\n', 'CollectOutput',true ); + fclose( fileID ); + fileID = fopen('rt_run.mdw', 'w' ); + + refTime=minutes(masterTime-masterDate); + + for i = 1 : 7 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + fprintf( fileID, 'ReferenceDate = %04d-%02d-%02d\n',... + year(masterTime),month(masterTime),day(masterTime)); + + for i = 9 : 71 + fprintf( fileID, '%s\n', cac{1}{i} ); + end + + % for i = 1 : records + % fprintf( fileID,'[TimePoint] \n Time = %#.7e \n',(i-1).*180); + % end + + bounOri{1}='East'; + bounOri{2}='North'; + bounOri{3}='South'; + bounRot{1}='counter-clockwise'; + bounRot{2}='counter-clockwise'; + bounRot{3}='clockwise'; + bounDef{1}='grid-coordinates'; + bounDef{2}='orientation'; + bounDef{3}='orientation'; + + + for Boundry = 1 : 3 + + if Boundry ==1 + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'StartCoordM = %d\n'... + 'EndCoordM = %d\n'... + 'StartCoordN = %d\n'... + 'EndCoordN = %d\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + ],Boundry,bounDef{Boundry},432,432,2,528); + else + fprintf(fileID,['[Boundary]\n'... + 'Name = East%d\n'... + 'Definition = %s\n'... + 'Orientation = %s\n'... + 'SpectrumSpec = parametric\n'... + 'SpShapeType = pierson-moskowitz\n'... + 'GaussSpread = 9.9999998e-003\n'... + 'PeriodType = peak\n'... + 'DirSpreadType = power\n'... + 'PeakEnhanceFac = 3.3000000e+000\n'... + 'DistanceDir = %s\n'... + ],Boundry,bounDef{Boundry},bounOri{Boundry},bounRot{Boundry}); + end + for Segment = waveBoundCount(Boundry)+1:waveBoundCount(Boundry+1) + fprintf(fileID,'CondSpecAtDist = %d\n',waveDistAlong(Segment)); + end + end + + clear cac + fclose( fileID ); + + + %% Met Files + % Create new UTM grid of the HRRR Data + [UTM1D(:,1),UTM1D(:,2)] = wgs2utm(reshape(windGridLAT,1,[]),reshape(windGridLON,1,[]),... + 18,'N'); + HRRR_UTM(:,:,1) = double(reshape(UTM1D(:,1),size(windGridLON,1),size(windGridLON,2))); + HRRR_UTM(:,:,2) = double(reshape(UTM1D(:,2),size(windGridLON,1),size(windGridLON,2))); + clear UTM1D + + G7LR = load('C7_1400_V2_C.mat'); + G7bath = load('C7_1400_V2_D.mat'); + % Remove land rainfall + % if FIRST_RUN == 1 + landmask=zeros(size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % [HR_deg(:,1),HR_deg(:,2)] = utm2deg(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[]),reshape(G7LR.data.Y(1:end-1,1:end-1)',1,[]),repmat('18 S',length(reshape(G7LR.data.X(1:end-1,1:end-1)',1,[])),1)); + % for ShoreLevel = 1:length(shoreline) + % landmask_Temp(:,:) = reshape(inpolygon(HR_deg(:,1),HR_deg(:,2),shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon),size(G7LR.data.X(1:end-1,1:end-1)',1),size(G7LR.data.X(1:end-1,1:end-1)',2)); + % + % landmask = landmask|landmask_Temp; + % clear landmask_Temp + % + % [shoreTempX,shoreTempY,shoreTempCell] = deg2utm(shoreline(ShoreLevel).Lat,shoreline(ShoreLevel).Lon); + % shoreUTM{ShoreLevel}(:,1) = shoreTempX(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % shoreUTM{ShoreLevel}(:,2) = shoreTempY(all((shoreTempCell==repmat('18 S',length(shoreTempCell),1))')); + % clear shoreTempX shoreTempY shoreTempCell + % disp(ShoreLevel) + % end + % save('shorelineInfo.mat','landmask','shoreUTM'); + % else + % load('shorelineInfo.mat'); + % end + clear HR_deg ShoreLevel + landmask(G7bath.data.Val'<0)=1; + landmask=logical(landmask); + + if masterTime>=datetime(2019,09,05,00,00,00) + runSteps = 49; + else + runSteps = 8; + end + + % Zero out met array + HRRR_INTER = zeros(4,runSteps,size(G7LR.data.X(1:end-1,1:end-1),2),size(G7LR.data.X(1:end-1,1:end-1),1)); + + % Interpolate against flowGrid for each time step + for TS = 1:runSteps + HRRR_INTER(1,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windU(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + HRRR_INTER(2,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(windV(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + + rainTemp = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(rain(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + rainTemp(landmask)=rainTemp(landmask)*0; % 100% infiltration + HRRR_INTER(3,TS,:,:) = rainTemp; % Convert to hours + clear rainTemp + + HRRR_INTER(4,TS,:,:) = griddata(HRRR_UTM(:,:,1),HRRR_UTM(:,:,2),... + double(squeeze(pressure(TS,:,:))),G7LR.data.X(1:end-1,1:end-1)',G7LR.data.Y(1:end-1,1:end-1)','natural'); + end + + % Set nan to Delft3D zero value + HRRR_INTER(isnan(HRRR_INTER)==1)=-999.000; + + % Create input files + m = size(HRRR_INTER,3); + n = size(HRRR_INTER,4); + d3ddx = 5000; + d3ddy = 5000; + disp(m) + d3d_input_uvpFieldsCL_FUN(masterTime,m,n,... + squeeze(HRRR_INTER(4,:,:,:)),squeeze(HRRR_INTER(1,:,:,:)),squeeze(HRRR_INTER(2,:,:,:)),squeeze(HRRR_INTER(3,:,:,:)),1,'hrrr',runSteps) + + save(['ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat'],'windU','windV','pressure','rain','temperature','waves','waterLevels','NCOM','-v7.3') + + %% Run Delft3D FLOW/WAVE! + % system('. /home/cluster/D7545/enviorment.sh' + + system('runcoast_flow2d3d_parallel_wave.bat') + if exist('wavm-rt_run.dat')~=2 + fid = fopen('errorFile.log','a+'); + fprintf(fid,'Delft Batch File Fallback\n'); + + % close file + fclose(fid) + disp('Run Fallback') + pause(60) + + delete com-* + delete hot* + delete rt_run.prt* + delete tri-diag.* + delete TMP_* + + delete trim-* + delete wavm-* + delete trih-* + delete obs.loct00* + delete WNDNOW + delete swan.inp + delete PRINT* + delete hot* + delete SWANOUT* + delete Errfile* + delete WAVE2FLOW* + delete FLOW2WAVE* + delete swn-diag.* + + system('runcoast_flow2d3d_parallel_wave.bat') + end + + %% Move things + pause(60) + + eval(['copyfile trih-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.dat']) + eval(['copyfile trih-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_histOut7.def']) + + eval(['movefile ModelIn_6_HRRR' datestr(masterTime,'YYYY-mm-DD_HH') '.mat D:\DUNEX_RT\Archive\ModelIn_7' datestr(masterTime,'YYYY-mm-DD_HH') '.mat']) + % eval(['copyfile tri-rst.rt* D:\Alexander\RealtimeHRRR\']) + + +% eval(['copyfile hrrr.amu D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amu']) +% eval(['copyfile hrrr.amv D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amv']) +% eval(['copyfile hrrr.ampr D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.ampr']) +% eval(['copyfile hrrr.amp D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_hrrr7.amp']) +% eval(['copyfile trim-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.dat']) +% eval(['copyfile trim-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_mapOut7.def']) +% eval(['copyfile wavm-rt_run.dat D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.dat']) +% eval(['copyfile wavm-rt_run.def D:\DUNEX_RT\Archive\' datestr(masterTime,'YYYY-mm-DD_HH') '_waveOut7.def']) + + + + %% Clear things not needed for plotting + clear HRRR_INTER flowGrid lonHRRR_Mesh windU windV rain pressure waveGrid + + + delete(gcp('nocreate')) + parpool(3); + %% Import Model Results + addpath(genpath('matlab/applications/delft3d_matlab'),'-begin') + + modelWater = qpread(qpfopen('trim-rt_run.dat'),1,'water level','griddata',0,0,0); + flowGrid = load('Cone7W_100.mat'); + waveGrid = load('Cone7W_250.mat'); + flowBed = load('Dec6_100Bed.mat'); + waveBed = load('Dec6_250Bed.mat'); + + %% Create GeoTIFF for water levels + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + timeIDXNames = [1 4 7 13 25 37]; % For Geoserver + + yMinOffset = 75; + yMaxOffset = 25; + + parfor Time = 1:6 + % X{Time} = modelWater.X; + % Y{Time} = modelWater.Y; + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + + modelPlot_1 = squeeze(modelWater.Val(timeIDX(Time),1:end-1,1:end-1)); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['WL_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWater + + modelWaterDAV = qpread(qpfopen('trim-rt_run.dat'),1,'depth averaged velocity','griddata',0,0,0); + + %% Create GeoTIFF for DAVs + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoDat modelPlot_1 + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + if FIRST_RUN == 1 + Times = 2:6; + else + Times = 1:6; + end + + + parfor Time = Times + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + modelPlot_1 = sqrt(squeeze(modelWaterDAV.XComp(timeIDX(Time),1:end-1,1:end-1)).^2+... + squeeze(modelWaterDAV.YComp(timeIDX(Time),1:end-1,1:end-1)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):100:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):100:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):100:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):100:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-1,1:end-1),1,[]),... + reshape(Y{Time}(1:end-1,1:end-1),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['DAV_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + %% Quiver for DAV + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + vecScale(4) = 100000; + vecScale(3) = 50000; + vecScale(2) = 2500; + vecScale(1) = 1000; + + for Time = Times + + X{Time} = flowGrid.data.X(2:end,2:end); + Y{Time} = flowGrid.data.Y(2:end,2:end); + modelPlot_1 = squeeze(modelWaterDAV.XComp(timeIDX(Time),2:end,2:end)); + modelPlot_2 = squeeze(modelWaterDAV.YComp(timeIDX(Time),2:end,2:end)); + + modelMask = squeeze(flowBed.data.Val>1); + modelPlot_1(modelMask)=nan; + modelPlot_1(400:520,525:620)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(400:520,525:620)=nan; + + modelPlot_1(:,1:yMinOffset)=nan; + modelPlot_1(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + modelPlot_2(:,1:yMinOffset)=nan; + modelPlot_2(:,size(modelMask,2)-yMaxOffset:size(modelMask,2))=nan; + + + qSpace = [4 16 50 100] + + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + for i = 1:length(Xdat{Time}) + if ((Udat{Time}(i))==0 && (Vdat{Time}(i))==0) ||... + (isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1) ||... + ((isnan(Udat{Time}(i)))==1 && isnan(Vdat{Time}(i))==1) + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + + Xdat{Time}=[]; + Ydat{Time}=[]; + Udat{Time}=[]; + Vdat{Time}=[]; + q{Time}=[]; + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['DAV_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj DAV_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaterDAV + + %% Create GeoTIFF for HS + + modelWaves = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave height','griddata',0,0,0); + modelWavesDir = qpread(qpfopen('wavm-rt_run.dat'),1,'hsig wave vector (mean direction)','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize GeoS + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = (squeeze(modelWaves.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):250:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):250:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):250:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):250:R{Time}.YWorldLimits(2)); + + modelPlot_1(modelPlot_1==0)=nan; + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + + geoDat{Time} = -griddata(reshape(X{Time}(1:end-0,1:end-0),1,[]),... + reshape(Y{Time}(1:end-0,1:end-0),1,[]),... + reshape(modelPlot_1,1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['HS_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for HS + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + vecScale(4) = 15000; + vecScale(3) = 5000; + vecScale(2) = 1000; + vecScale(1) = 500; + + for Time = 1:6 + + X{Time} = waveGrid.data.X(1:end-1,1:end-1); + Y{Time} = waveGrid.data.Y(1:end-1,1:end-1); + modelPlot_1 = squeeze(modelWavesDir.XComp(timeIDX(Time),:,:)); + modelPlot_2 = squeeze(modelWavesDir.YComp(timeIDX(Time),:,:)); + + modelMask = squeeze(waveBed.data.Val<-1); + modelPlot_1(modelMask)=nan; + modelPlot_1(155:205,210:265)=nan; + modelPlot_2(modelMask)=nan; + modelPlot_2(155:205,210:265)=nan; + + + qSpace = [2 10 20 40] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),Y{Time}(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0),... + squeeze(modelPlot_1(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),squeeze(modelPlot_2(1:qSpace(Detail):end-0,1:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + elseif isnan(Udat{Time}(i))==1 && isnan(Vdat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['HS_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj HS_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaves + clear modelWavesDIR + + %% Create GeoTIFF for Wind + modelWaterWind = qpread(qpfopen('trim-rt_run.dat'),1,'wind speed','griddata',0,0,0); + + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS ValX ValY + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = sqrt(squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)).^2+... + squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)).^2); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):1000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):1000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):1000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):1000:R{Time}.YWorldLimits(2)); + + Val{Time}(Val{Time}==0)=nan; + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + geoDat{Time}(isnan(geoDat{Time})==1) = -999; + + geotiffwrite(['Uw_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + + + %% Quiver for Wind + clear X Y ValX ValY XXd YYd geoS XdatE YdatE Xdat Ydat Udat Vdat geoDat + + + vecScale(4) = 3000; + vecScale(3) = 500; + vecScale(2) = 100; + vecScale(1) = 40; + + for Time = 1:6 + + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + ValX{Time} = squeeze(modelWaterWind.XComp(timeIDX(Time),:,:)); + ValY{Time} = squeeze(modelWaterWind.YComp(timeIDX(Time),:,:)); + + + qSpace = [5 25 50 100] + Count{Time}=1; + + for Detail = 1:4 + q{Time} = quiver(X{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),Y{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0),... + squeeze(ValX{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),squeeze(ValY{Time}(2:qSpace(Detail):end-0,2:qSpace(Detail):end-0)),'color','k'); + + Xdat{Time} = reshape(q{Time}.XData,1,[]); + Ydat{Time} = reshape(q{Time}.YData,1,[]); + + Udat{Time} = reshape(q{Time}.UData,1,[]); + Vdat{Time} = reshape(q{Time}.VData,1,[]); + + + for i = 1:length(Xdat{Time}) + if (Udat{Time}(i))==0 && (Vdat{Time}(i))==0 + continue + elseif isnan(Xdat{Time}(i))==1 || isnan(Ydat{Time}(i))==1 + continue + end + + geoS{Time}(Count{Time}).Geometry = 'Line'; + + geoS{Time}(Count{Time}).Detail = Detail; + XdatE{Time} = Xdat{Time}(i)+Udat{Time}(i).*vecScale(Detail); + YdatE{Time} = Ydat{Time}(i)+Vdat{Time}(i).*vecScale(Detail); + [XXd{Time}(1),YYd{Time}(1)] = utm2deg(Xdat{Time}(i),Ydat{Time}(i),'18 S'); + [XXd{Time}(2),YYd{Time}(2)] = utm2deg(XdatE{Time}',YdatE{Time}','18 S'); + geoS{Time}(Count{Time}).BoundingBox = [min(XXd{Time}) min(YYd{Time});... + max(XXd{Time}) max(YYd{Time})]; + geoS{Time}(Count{Time}).Lat = [XXd{Time}(1) XXd{Time}(2)]; + geoS{Time}(Count{Time}).Lon = [YYd{Time}(1) YYd{Time}(2)]; + + + Count{Time}=Count{Time}+1; + end + close all + end + disp(Time) + + shapewrite(geoS{Time}(1:end-1),['Uw_' num2str(timeIDXNames(Time)) '_D.shp']) + eval(['copyfile vector.prj Uw_' num2str(timeIDXNames(Time)) '_D.prj']) + + end + + clear modelWaterWind + + %% Create GeoTIFF for Prep + + modelWaterPrep = qpread(qpfopen('trim-rt_run.dat'),1,'precipitation rate','griddata',0,0,0); + + clear X Y Val geoDat geoMeshX geoMeshY R xWorldLimits yWorldLimits rasterSize geoS + +% timeIDX = [1 4 7 13 25 37]; + timeIDX = [1 7 13 25 37 49]; + parfor Time = 1:6 + X{Time} = flowGrid.data.X; + Y{Time} = flowGrid.data.Y; + Val{Time} = (squeeze(modelWaterPrep.Val(timeIDX(Time),:,:))); + + xWorldLimits{Time} = [min(min(X{Time}(1:end,1:end))) max(max(X{Time}(1:end,1:end)))]; + yWorldLimits{Time} = [min(min(Y{Time}(1:end,1:end))) max(max(Y{Time}(1:end,1:end)))]; + % rasterSize = [(size(data.X,1)-2).*2 (size(data.X,2)-2).*2]; + rasterSize{Time} = [length(xWorldLimits{Time}(1):10000:xWorldLimits{Time}(2)) length(yWorldLimits{Time}(1):10000:yWorldLimits{Time}(2))]; + + R{Time} = maprefpostings(xWorldLimits{Time},yWorldLimits{Time},[rasterSize{Time}(2) rasterSize{Time}(1)]) + [geoMeshX{Time},geoMeshY{Time}] = meshgrid(R{Time}.XWorldLimits(1):10000:R{Time}.XWorldLimits(2),... + R{Time}.YWorldLimits(1):10000:R{Time}.YWorldLimits(2)); + + geoDat{Time} = -griddata(reshape(X{Time}(2:end-2,2:end-2),1,[]),... + reshape(Y{Time}(2:end-2,2:end-2),1,[]),... + reshape(Val{Time}(2:end-2,2:end-2),1,[]),... + geoMeshX{Time},geoMeshY{Time},'natural'); + + geotiffwrite(['Prep_' num2str(timeIDXNames(Time)) '.tif'],geoDat{Time},... + R{Time},'CoordRefSysCode',32618) + disp(Time) + % clear X Y Val geoDat geoMeshX geoMeshY + end + + clear modelWaterPrep + + %% Export to GEOSERVER + try + copyfile *.tif \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.dbf \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shx \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.shp \\geoserver.engineering.queensu.ca\TIFFS\ + copyfile *.prj \\geoserver.engineering.queensu.ca\TIFFS\ + catch + end + + %% Import Model forecast + modelWaterHist = qpread(qpfopen('trih-rt_run.dat'),1,'water level','data',0,0); + modelCurHist = qpread(qpfopen('trih-rt_run.dat'),1,'depth averaged velocity','data',0,0); + + %% Validation import ESTOFS + load('DUNEX_Nov20.mat') + clear ESTOFS lonESTOFS lonESTOFS + + wLIDX=[6 7 8 38]; + wlGrid = [5000 -4000 0 -2000]; + wlGridY = [0 0 2000 5000]; %7500 + ESTOFStimeOffset = [0 12 24 48]; + ESTOFSrunLength = [48 60 72 96]; + + for e = [1 4] + try + clear meshX meshY + m_proj('lambert conformal conic','ori',[-95 25.0],'clo',-95,'par',[25 25],'ell','sphere'); + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(0,'%03d') '.grib']); + + [meshX,meshY] = meshgrid(ESTOFS{'x'}(:),ESTOFS{'y'}(:)); + [lonESTOFS,latESTOFS] = m_xy2ll(meshX.*1000,meshY.*1000); + clear meshX meshY + ESTOFS_Val{e} = 1; + catch + ESTOFS_Val{e} = 0; + end + end + clear waterLevelsESTOFSINTER waterLevelsESTOFS + for e = [1 4] + try + for Stat = 1:4 + if ESTOFS_Val{e} == 0 + estofsWL(:,Stat,e) = zeros(49,1); + else + [wlDeg(2),wlDeg(1)] = utm2deg(pointsCS{wLIDX(Stat),2}+wlGrid(Stat),pointsCS{wLIDX(Stat),3}+wlGridY(Stat),'18 S'); + [estofIDX] = NearestValue(wlDeg,lonESTOFS,latESTOFS); %Lat + + for i = 1:ESTOFSrunLength(e)+1 + ESTOFS = ncgeodataset(['D:\DUNEX_RT\Archive\ESTOFS\ESTOFS_' ... + datestr(masterTime-hours(ESTOFStimeOffset(e)),'YYYY-mm-DD_HH') '_f' num2str(i-1,'%03d') '.grib']); + + waterLevelsESTOFS{e}(i,Stat) = squeeze(ESTOFS{'Ocean_Surface_Elevation_Relative_to_Geoid_surface'}(1,estofIDX(1),estofIDX(2))); + end + waterLevelsESTOFSINTER{e}(:,Stat) = interp1(masterTime-hours(ESTOFStimeOffset(e)):minutes(60):masterTime+hours(48),... + waterLevelsESTOFS{e}(:,Stat),masterTime-hours(ESTOFStimeOffset(e)):minutes(15):masterTime+hours(48),'spline'); + end + end + catch + waterLevelsESTOFSINTER{e}(:,Stat) = zeros(1,385); + end + end + + + %% Validation import WL + % Duck + % Oregon Inlet + % Hatteras + % Beaufort + clear stations statWL + options = weboptions; + options.Timeout = 30; + + stations = {8651370,8652587,8654467,8656483}; + dateStartM = masterTime-hours(48); + dateEndM = masterTime+hours(5); + + for Stat = 1:4 + try + url = ['https://tidesandcurrents.noaa.gov/api/datagetter?product=water_level&application=NOS.COOPS.TAC.WL&'... + 'begin_date=' datestr(dateStartM,'yyyymmdd') '&end_date=' datestr(dateEndM,'yyyymmdd') '&datum=NAVD' '&station=' num2str(stations{Stat})... + '&time_zone=GMT&units=metric&format=csv']; + + wlIN = webread(url,options); + + statWL(:,Stat) = interp1(wlIN.DateTime,wlIN.WaterLevel,dateStartM:minutes(15):dateEndM); + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statWL(:,Stat) = 0; + end + + + clear wlIN + + end + + %% Validate Import Hohonu + + hohonuBase = 'https://dashboard.hohonu.io/api/stations/node-'; + + hohonuStation(5:10) = [ + 10015; %Duck, Dare County, NC + 10020; %Southern Shores, NC + 10011; %Collington Creek Inn Dock, Kill Devil Hills + 10012; %Jennette's Pier, Nags Head + 10009; %Hwy 64, Little Bridge + 10010]; %Coastal Studies Institute, Wanchese, NC + + hohonuDatums(5:10) = [ + 6.03; + 6.41; + 5.777; + 25.742; + 6.889; + 8.3]*304.8; % In feet, convert to mm + + + for Stat = 5:10 + fname = ['D:\DUNEX_RT\Operation\Hohonu\' num2str(hohonuStation(Stat)) '.json']; + + websave(fname,... + [hohonuBase num2str(hohonuStation(Stat)) '/statistic/?cleaned=true&format=json&from='... + datestr(dateStartM,'yyyy-mm-dd') '+00%3A00&to=' datestr(dateEndM,'yyyy-mm-dd')... + '+23%3A59']); + + fid = fopen(fname); + raw = fread(fid,inf); + str = char(raw'); + fclose(fid); + + hohonuIN = jsondecode(str); + + statWL(:,Stat) = interp1(datetime(hohonuIN.data{1},'InputFormat','yyyy-MM-dd''T''HH:mm:SS'),... + (hohonuDatums(Stat) - hohonuIN.data{2}) * 0.001,dateStartM:minutes(15):dateEndM); + + clear fid raw str hohonuIN fname + end + + + + + %% Validation import Currents + % Duck + clear statCur + for Stat = 1 + % url = 'https://chlthredds.erdc.dren.mil/thredds/dodsC/frf/oceanography/currents/awac-11m/awac-11m.ncml'; + % curTime = ncread(url,'time'); + % curVal = ncread(url,'currentSpeed'); + try + if day(masterTime)<2 + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime-day(3),'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime-days(3),'YYYYmm') '.nc'],options); + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + curTime = vertcat(curTime,ncread('statCNC.nc','time')); + curVal = vertcat(curVal,ncread('statCNC.nc','currentSpeed')); + + else + websave('statCNC.nc',['https://chlthredds.erdc.dren.mil/thredds/fileServer/frf/oceanography/currents/awac-11m/' datestr(masterTime,'YYYY') '/FRF-ocean_currents_awac-11m_' ... + datestr(masterTime,'YYYYmm') '.nc'],options); + + curTime = ncread('statCNC.nc','time'); + curVal = ncread('statCNC.nc','currentSpeed'); + end + + statCur(:) = interp1(datetime(curTime,'convertFrom','POSIX'),curVal,dateStartM:minutes(15):dateEndM); + clear wlIN + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + + statCur(:) = zeros(length(dateStartM:minutes(15):dateEndM),1); + end + end + + %% Validation import Waves + % Virginia Beach + % Duck 26 + % Nages Head + % Oregon Inlet + % Diamond Shoals + clear stations + + stations = {44014,44100,44086,44095,41025}; + dateStartM = masterTime-hours(48); + dateEndM = masterTime+hours(5); + + clear statWave + + for Stat = 1:5 + try + if ismember(Stat,[1,5]) == 1 + url = ['https://www.ndbc.noaa.gov/data/5day2/' num2str(stations{Stat}) '_5day.txt']; + + websave('NDBCdata.txt',url,options); + opts = delimitedTextImportOptions("NumVariables", 39); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, 15, "TrimNonNumeric", true); + opts = setvaropts(opts, 15, "ThousandsSeparator", ","); + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + else + url = ['https://www.ndbc.noaa.gov/data/realtime2/' num2str(stations{Stat}) '.txt']; + websave('NDBCdata.txt',url); + + opts = delimitedTextImportOptions("NumVariables", 52); + + % Specify range and delimiter + opts.DataLines = [3, Inf]; + opts.Delimiter = " "; + + % Specify column names and types + opts.VariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE", "Var20", "Var21", "Var22", "Var23", "Var24", "Var25", "Var26", "Var27", "Var28", "Var29", "Var30", "Var31", "Var32", "Var33", "Var34", "Var35", "Var36", "Var37", "Var38", "Var39", "Var40", "Var41", "Var42", "Var43", "Var44", "Var45", "Var46", "Var47", "Var48", "Var49", "Var50", "Var51", "Var52"]; + opts.SelectedVariableNames = ["YY", "MM", "DD", "hh", "mm", "WDIR", "WSPD", "GST", "WVHT", "DPD", "APD", "MWD", "PRES", "ATMP", "WTMP", "DEWP", "VIS", "PTDY", "TIDE"]; + opts.VariableTypes = ["double", "double", "double", "double", "double", "categorical", "categorical", "categorical", "double", "double", "double", "double", "categorical", "categorical", "double", "double", "categorical", "categorical", "categorical", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string"]; + opts = setvaropts(opts, [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "WhitespaceRule", "preserve"); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "TrimNonNumeric", true); + opts = setvaropts(opts, [9, 10, 11, 12, 15], "ThousandsSeparator", ","); + opts = setvaropts(opts, [6, 7, 8, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], "EmptyFieldRule", "auto"); + opts.ExtraColumnsRule = "ignore"; + opts.EmptyLineRule = "read"; + opts.ConsecutiveDelimitersRule = "join"; + opts.LeadingDelimitersRule = "ignore"; + + end + + % Import the data + waveIN = readtable("NDBCdata.txt", opts); + waveNAN = isnan(waveIN.WVHT)==0; + % Hs + statWave(:,1,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.WVHT(waveNAN)),dateStartM:minutes(15):dateEndM); + % DPD + % statWave(:,2,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + % (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + % (waveIN.DPD(waveNAN)),dateStartM:minutes(10):dateEndM); + % APD + statWave(:,3,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.APD(waveNAN)),dateStartM:minutes(15):dateEndM); + %MWD + statWave(:,4,Stat) = interp1(datetime(waveIN.YY(waveNAN),(waveIN.MM(waveNAN)),(waveIN.DD(waveNAN)),... + (waveIN.hh(waveNAN)),(waveIN.mm(waveNAN)),zeros(length(waveIN.YY(waveNAN)),1)),... + (waveIN.MWD(waveNAN)),dateStartM:minutes(15):dateEndM); + clear waveIN opts + catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + %fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + %sendmail('alexander.rey@queensu.ca',['Ext-DUNEX-RT: ' datestr(masterTime) err.message]); + + % close file + fclose(fid) + statWave(:,:,Stat) = zeros(size(dateStartM:minutes(15):dateEndM,2),4,1); + end + end + statWave(isnan(statWave))=0; + %% Import Model Waves + + for i = 1:49 + startRow = 8; + formatSpec = '%13f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%14f%f%[^\n\r]'; + + fileID = fopen(['Dec28.loct00000' num2str(i,'%02d') '.tab'],'r'); + + % This call is based on the structure of the file used to generate this + % code. If an error occurs for a different file, try regenerating the code + % from the Import Tool. + dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines' ,startRow-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + + fclose(fileID); + modelWaveIN= table(dataArray{1:end-1}, 'VariableNames', {'Xp','Yp','Depth','Hsig','Dir','RTpea','kTm01','Dspr','Ubot','XWindv','YWindv','XVel','YVel'}); + + modelWave(:,1,i) = modelWaveIN.Hsig; + modelWave(:,3,i) = modelWaveIN.RTpea; + modelWave(:,4,i) = modelWaveIN.Dir; + + + clearvars filename startRow formatSpec fileID dataArray ans modelWaveIN; + + end + + %% Import Model WL + modelWL = modelWaterHist.Val; + modelCur = sqrt(modelCurHist.XComp.^2+modelCurHist.YComp.^2); + + for idx = 1:size(modelWL,2) + modelWLInter(:,idx) = interp1(modelWaterHist.Time,modelWL(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))); + end + for idx = 1:size(modelCur,2) + modelCurInter(:,idx) = sqrt(interp1(modelCurHist.Time,modelCurHist.XComp(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))).^2+... + interp1(modelCurHist.Time,modelCurHist.YComp(:,idx),datenum(masterTime:minutes(15):masterTime+hours(48))).^2); + end + + save(['ModelOut_' datestr(masterTime,'dd-mmm-yyyy_HH') 'Z.mat'],'modelWL','modelWave','statWL','statWave','modelCur','statCur','modelWLInter','modelCurInter','-v7.3'); + + %% Import Historic Model WL + if masterTime>=datetime(2021,07,08) + try + H12 = load(['ModelOut_' datestr(masterTime-hours(12),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H24 = load(['ModelOut_' datestr(masterTime-hours(24),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + try + H48 = load(['ModelOut_' datestr(masterTime-hours(48),'dd-mmm-yyyy_HH') 'Z.mat']); + catch + end + end + %% Save html for Currents + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + locLine = 1:5:67; + locationsWave ={'FRF 11 m AWAC '}; + +% % for i = 1:433 +% % for j = 1:100 +% % modelDavDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',[2,2],modelDavDel) + + davIDX=[17 161:172]; + + clear modelCurPlot curValLoc + for Loc = 1:13 + for Line=1:5 + switch Line + case 1 + curValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelCurPlot(1:385,locLine(Loc)+0) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:192,locLine(Loc)+0) = {''}; + modelCurPlot(193:1:385,locLine(Loc)+0) = num2cell(modelCurInter(:,davIDX(Loc))); + case 2 + curValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelCurPlot(1:385,locLine(Loc)+1) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:143,locLine(Loc)+1) = {''}; + modelCurPlot(337:385,locLine(Loc)+1) = {''}; + modelCurPlot(144:1:336,locLine(Loc)+1) = num2cell(H12.modelCurInter(:,davIDX(Loc))); + + case 3 + curValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelCurPlot(1:385,locLine(Loc)+2) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(1:96,locLine(Loc)+2) = {''}; + modelCurPlot(290:385,locLine(Loc)+2) = {''}; + modelCurPlot(97:1:289,locLine(Loc)+2) = num2cell(H24.modelCurInter(:,davIDX(Loc))); + + case 4 + curValLoc{Line} = ['-48 Hour: ' datestr(masterTime-hours(48),'mm/dd HH') 'Z Run']; + if exist('H48','var') ==0 + modelCurPlot(1:385,locLine(Loc)+3) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(194:385,locLine(Loc)+3) = {''}; + modelCurPlot(1:1:193,locLine(Loc)+3) = num2cell(H48.modelCurInter(:,davIDX(Loc))); + case 5 + curValLoc{Line} = ['Observed Velocity']; + if Loc> 1 || isnan(statCur(1,Loc)) + modelCurPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelCurPlot(214:385,locLine(Loc)+4) = {''}; + modelCurPlot(1:213,locLine(Loc)+4) = num2cell(statCur); + + end + + end + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],modelCurPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... +% [1,locLine(Loc)],curValLoc) + curValLoc = repmat(curValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1763350398',... + [1,1],horzcat(googleDatesCell',vertcat(curValLoc(1:size(modelCurPlot,2)),modelCurPlot))) + %% Save html for WL + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,1],googleDates') + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% locLine = [2 7 12 17 22 27]; +% locLine = [2 9 16 23 30 37]; + locLine = 1:7:114; + + locationsWl ={'FRF Pier',... + 'Oregon Inlet',... + 'Hatteras',... + 'Beaufort'}; + +% % for i = 1:433 +% % for j = 1:121 +% % modelWlDel(i,j)={''}; +% % end +% % end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',[2,2],modelWlDel) + + wLIDX=[6 7 8 38 161:172]; + clear modelWlPlot wlValLoc + for Loc = 1:length(wLIDX) +% modelwlPlot = cell(432,4); + for Line=[1:5 6 9] + switch Line + case 1 + wlValLoc{Line} = ['Forecast']; + if exist('modelCur','var') ==0 + modelwlPlot(1:385,locLine(Loc)+0) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:192,locLine(Loc)+0) = {''}; + modelwlPlot(193:1:385,locLine(Loc)+0) = num2cell(modelWLInter(:,wLIDX(Loc))); + case 2 + wlValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 + modelwlPlot(1:385,locLine(Loc)+1) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:143,locLine(Loc)+1) = {''}; + modelwlPlot(337:385,locLine(Loc)+1) = {''}; + modelwlPlot(144:1:336,locLine(Loc)+1) = num2cell(H12.modelWLInter(:,wLIDX(Loc))); + + case 3 + wlValLoc{Line} = ['-24 Hour: ' datestr(masterTime-hours(24),'mm/dd HH') 'Z Run']; + if exist('H24','var') ==0 + modelwlPlot(1:385,locLine(Loc)+2) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(1:96,locLine(Loc)+2) = {''}; + modelwlPlot(290:385,locLine(Loc)+2) = {''}; + modelwlPlot(97:1:289,locLine(Loc)+2) = num2cell(H24.modelWLInter(:,wLIDX(Loc))); + + case 4 + wlValLoc{Line} = ['-48 Hour: ' datestr(masterTime-hours(48),'mm/dd HH') 'Z Run']; + if exist('H48','var') ==0 + modelwlPlot(1:385,locLine(Loc)+3) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(194:385,locLine(Loc)+3) = {''}; + modelwlPlot(1:1:193,locLine(Loc)+3) = num2cell(H48.modelWLInter(:,wLIDX(Loc))); + case 5 + wlValLoc{Line} = ['Observed Water Level']; + if Loc>4 || isnan(statWL(1,Loc)) + modelwlPlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelwlPlot(214:385,locLine(Loc)+4) = {''}; + modelwlPlot(1:213,locLine(Loc)+4) = num2cell(statWL(:,Loc)); + case 6 + wlValLoc{Line} = ['ESTOFS Forecast']; +% % if Loc>4 || ESTOFS_Val{1} == 0 + modelwlPlot(1:385,locLine(Loc)+5) = num2cell(zeros(385,1)); +% % continue +% % end +% % modelwlPlot(1:192,locLine(Loc)+5) = {''}; +% % modelwlPlot(193:385,locLine(Loc)+5) = num2cell(waterLevelsESTOFSINTER{1}(:,Loc)); + case 9 + wlValLoc{7} = ['-48 Hour ESTOFS']; +% if Loc>4 || ESTOFS_Val{4} == 0 + modelwlPlot(1:385,locLine(Loc)+6) = num2cell(zeros(385,1)); +% % continue +% % end +% % modelwlPlot(1:1:385,locLine(Loc)+6) = num2cell(waterLevelsESTOFSINTER{4}(:,Loc)); + end + end + disp(Loc) + + end + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [2,locLine(Loc)],modelwlPlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... +% [1,locLine(Loc)],wlValLoc) + + wlValLoc = repmat(wlValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','1102090436',... + [1,1],horzcat(googleDatesCell',vertcat(wlValLoc(1:size(modelwlPlot,2)),modelwlPlot))) + + %% Save html for Waves + googleDates = days(masterTime-hours(48)+minutes((0:384)*15)-datetime(1899,12,30,00,00,00)); + googleDatesCell(2:length(googleDates)+1) = num2cell(googleDates); + googleDatesCell{1} = 'Time'; + +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,1],googleDates') + +% locLine = [2 7 12 17 22 27]; + locLine = 1:5:114; + + locationsWave ={'Virginia Beach',... + 'FRF 26 m',... + 'Nags Head',... + 'Oregon Inlet',... + 'Diamond Shoals'}; + + clear waveValLoc modelwavePlot + + for i = 1:385 + for j = 1:85 + modelwavePlot(i,j)={''}; + end + end +% % mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',[2,2],modelWaveDel) + + waveIDX = [12 13 14 15 16 161:172]; + for Loc = 1:length(waveIDX) +% modelwavePlot = cell(432,5); + for Line=1:5 + switch Line + case 1 + waveValLoc{Line} = ['Forecast']; + if exist('modelWave','var') ==0 + modelwavePlot(1:385,locLine(Loc)+0) = num2cell(zeros(433,1)); + continue + end + modelwavePlot(1:191,locLine(Loc)+0) = {''}; + modelwavePlot(192,locLine(Loc)+0) = {0}; + modelwavePlot(193:4:385,locLine(Loc)+0) = num2cell(modelWave(waveIDX(Loc),1,:)); + case 2 + waveValLoc{Line} = ['-12 Hour: ' datestr(masterTime-hours(12),'mm/dd HH') 'Z Run']; + if exist('H12','var') ==0 || size(H12.modelWave,1)5 || isnan(statWave(1,1,Loc)) + modelwavePlot(1:385,locLine(Loc)+4) = num2cell(zeros(385,1)); + continue + end + modelwavePlot(215:385,locLine(Loc)+4) = {''}; + modelwavePlot(214,locLine(Loc)+4) = {0}; + modelwavePlot(1:1:213,locLine(Loc)+4) = num2cell(statWave(:,1,Loc)); + + end + + end +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [2,locLine(Loc)],modelwavePlot) +% +% mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... +% [1,locLine(Loc)],waveValLoc) + end + + waveValLoc = repmat(waveValLoc,1,Loc); + + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','319734265',... + [1,1],horzcat(googleDatesCell',vertcat(waveValLoc(1:size(modelwavePlot,2)),modelwavePlot))) + + + + + %% Import and modify times +% modelHour = [0 3 6 12 24 48]; + modelHour = [0 6 12 24 36 48]; + for i = 1:6 + dateText(i) = {[datestr(masterTime+hours(modelHour(i)),'mmm dd, HH:MM') ' UTC (Hour '... + num2str(modelHour(i),'%d') ')']}; + end + mat2sheets('1K6toMh7L8nL3rtoPLJxD1Ebfqaty0wkPJSUGXNAbhoU','0',[1,1],... + dateText) + +catch err + %open file + fid = fopen('errorFile.log','a+'); + % write the error to file + % first line: message + fprintf(fid,'Line %d on %s : %s\n',err.stack.line,datestr(masterTime),err.message); + sendmail('alexander.rey@queensu.ca',['ALL-DUNEX-RT: ' datestr(masterTime) err.message]) ; + + % close file + fclose(fid) + +end + +%% +quit + + + + + + + + + + + + + + + + diff --git a/MatlabTest.m b/MatlabTest.m new file mode 100644 index 0000000..d331963 --- /dev/null +++ b/MatlabTest.m @@ -0,0 +1,55 @@ +%% NC DUNEX Realtime script +% Alexander Rey, August 12, 2019 +clear all +cd D:\DUNEX_RT\Operation +echo off; + +%% Master Model Time Step +% Every 6 hours + +% Download the current UTC time from NIST +% s1 = webread('https://nist.time.gov/actualtime.cgi?lzbc=siqm9b'); +% s2 = regexp(s1,'\12 || timezone<-12 + error('Invalid TIMEZONE:Timezone should be in the range of [-12,12].') +end +floor(timezone); +timeServer = 'https://time.is/UTC'; +o = weboptions('CertificateFilename',''); +uniTime = str2double(regexp(webread(timeServer,o),'\d{13}','match','once'))/1000; % Retrieve the universal time and convert it to seconds +localTime = uniTime+timezone*60*60; +ml = [1970,1,1,0,0,localTime]; %Matlab datenum is defied relative to Jan-01,1970,00:00:00, +utctime = datenum(ml); \ No newline at end of file diff --git a/google_tokens.mat b/google_tokens.mat index 691c485..3f1727c 100644 Binary files a/google_tokens.mat and b/google_tokens.mat differ diff --git a/importASOS.m b/importASOS.m new file mode 100644 index 0000000..81eac01 --- /dev/null +++ b/importASOS.m @@ -0,0 +1,50 @@ +function asos = importASOS(filename, dataLines) +%IMPORTFILE Import data from a text file +% ASOS = IMPORTFILE(FILENAME) reads data from text file FILENAME for +% the default selection. Returns the data as a table. +% +% ASOS = IMPORTFILE(FILE, DATALINES) reads data for the specified row +% interval(s) of text file FILENAME. Specify DATALINES as a positive +% scalar integer or a N-by-2 array of positive scalar integers for +% dis-contiguous row intervals. +% +% Example: +% asos = importASOS("D:\DorianRP\asos.txt", [1, Inf]); +% +% See also READTABLE. +% +% Auto-generated by MATLAB on 11-Dec-2019 13:04:36 + +%% Input handling + +% If dataLines is not specified, define defaults +if nargin < 2 + dataLines = [2, Inf]; +end + +%% Setup the Import Options and import the data +opts = delimitedTextImportOptions("NumVariables", 31); + +% Specify range and delimiter +opts.DataLines = dataLines; +opts.Delimiter = ","; + +% Specify column names and types +opts.VariableNames = ["station", "valid", "lon", "lat", "tmpf", "dwpf", "relh", "drct", "sknt", "p01i", "alti", "mslp", "vsby", "gust", "skyc1", "skyc2", "skyc3", "skyc4", "skyl1", "skyl2", "skyl3", "skyl4", "wxcodes", "ice_accretion_1hr", "ice_accretion_3hr", "ice_accretion_6hr", "peak_wind_gust", "peak_wind_drct", "peak_wind_time", "feel", "metar"]; +opts.VariableTypes = ["categorical", "datetime", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "categorical", "categorical", "categorical", "categorical", "double", "double", "double", "double", "categorical", "double", "double", "double", "double", "double", "double", "double", "string"]; + +% Specify file level properties +opts.ExtraColumnsRule = "ignore"; +opts.EmptyLineRule = "read"; + +% Specify variable properties +opts = setvaropts(opts, "metar", "WhitespaceRule", "preserve"); +opts = setvaropts(opts, ["station", "skyc1", "skyc2", "skyc3", "skyc4", "wxcodes", "metar"], "EmptyFieldRule", "auto"); +opts = setvaropts(opts, "valid", "InputFormat", "yyyy-MM-dd HH:mm"); +opts = setvaropts(opts, ["tmpf", "dwpf", "relh", "p01i", "mslp", "gust", "skyl1", "skyl2", "skyl3", "skyl4", "ice_accretion_1hr", "ice_accretion_3hr", "ice_accretion_6hr", "peak_wind_gust", "peak_wind_drct", "peak_wind_time", "feel"], "TrimNonNumeric", true); +opts = setvaropts(opts, ["tmpf", "dwpf", "relh", "p01i", "mslp", "gust", "skyl1", "skyl2", "skyl3", "skyl4", "ice_accretion_1hr", "ice_accretion_3hr", "ice_accretion_6hr", "peak_wind_gust", "peak_wind_drct", "peak_wind_time", "feel"], "ThousandsSeparator", ","); + +% Import the data +asos = readtable(filename, opts); + +end \ No newline at end of file diff --git a/makeCSptsDUNEXR_Dec28.m b/makeCSptsDUNEXR_Dec28.m new file mode 100644 index 0000000..2cf5011 --- /dev/null +++ b/makeCSptsDUNEXR_Dec28.m @@ -0,0 +1,771 @@ +%% Make CS Points +clear pointsCS + +load('CSpoints.mat'); +% Realtime Points +% Create Observation File +locations = [36.606,-74.840;... + 36.260,-75.594;... + 36.001,-75.421;... + 35.750,-75.330;... + 35.025,-75.363; + 36.189244, -75.739155;... + 36.3205,-75.872;... + 36.1656,-75.8155;... + 36.0866, -75.76833;... + 35.8964389,-75.6220889;... + 34.7113528,-76.7368333;... + 35.96176,-75.64163;... + 36.04318,-75.68936;... + 36.12932,-75.74501;... + 36.20002, -75.7151]; + +locNames = {'Virginia Beach Wave',... + 'Duck 26 Wave',... + 'Nages Head Wave',... + 'Oregon Inlet Wave',... + 'Diamond Shoals Wave',... + 'Duck 11 AWAC',... + 'CS North',... + 'CS South',... + 'USGS CURRITUCK SOUND NR POINT HARBOR',... + 'USGS ROANOKE SOUND AT POND ISLAND',... + 'USGS BOGUE SOUND AT ATLANTIC BEACH',... + 'Villa Dunes SW Dock Shoreline',... + 'Hayman St Dock SW Shoreline',... + 'Gunther Telephone Pole'... + 'Duck 17 Wave'}; + +for i = 1:length(locations) + pointsCS{i+11,1} = locNames{i}; + [pointsCS{i+11,2},pointsCS{i+11,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); +end + + +pointsCS{8,3} = pointsCS{8,3} + 2500; +pointsCS{7,2} = pointsCS{7,2} - 500; +[pointsCS{30,2},pointsCS{30,3}]= wgs2utm(34.213,-76.946,18,'N'); +[pointsCS{31,2},pointsCS{31,3}]= wgs2utm(36.914,-75.720,18,'N'); +pointsCS{30,1} = 'Onslow Bay Wave'; +pointsCS{31,1} = 'Cape Henry Wave'; +[pointsCS{32,2},pointsCS{32,3}]= wgs2utm(36.0175833,-75.6715833,18,'N'); +pointsCS{32,1} = 'Kitty Hawk Airport'; +[pointsCS{33,2},pointsCS{33,3}]= wgs2utm(36.20002,-75.7151,18,'N'); +pointsCS{33,1} = 'FRF 17m'; +pointsCS(33,4) = {'F17'}; +pointsCS{10,1} = 'Currituck Sound @ Corolla'; +pointsCS(1:21,4) = {'CS 1','CS 2','CS 3','CS 4','CS 5','FP','OI','HT','BF','CC','AS','VB','F26','NH','O18','DS','F11','CN','CS','PH','PI'}; +pointsCS(22,4) = {'AB'}; +pointsCS(23,4) = {'VD'}; +pointsCS(24,4) = {'HD'}; +pointsCS(25,4) = {'JC'}; +pointsCS(30,4) = {'OB'}; +pointsCS(31,4) = {'CH'}; +pointsCS(32,4) = {'KH'}; + + +pointsCS{27,1} = 'FRF 6m AWAC'; +[pointsCS{27,2},pointsCS{27,3}]= wgs2utm(36.187328,-75.7465267,18,'N'); +pointsCS{27,4} = 'F6'; +pointsCS(26,4) = {'F17'}; + + +for i = 1:length(locations) + pointsCS{i+11,1} = locNames{i}; + [pointsCS{i+11,2},pointsCS{i+11,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); +end + +pointsCS(28,:) = pointsCS(18,:); +pointsCS(29,:) = pointsCS(19,:); +pointsCS{28,1} = 'CS North 2'; +pointsCS{29,1} = 'CS South 2'; + +% NDBC + +[pointsCS{34,2},pointsCS{34,3}] = deg2utm(36.778,-76.302); +pointsCS{34,1} = 'Money Point'; + +[pointsCS{35,2},pointsCS{35,3}] = deg2utm(34.622,-76.525); +pointsCS{35,1} = 'Cape Lookout'; + +[pointsCS{36,2},pointsCS{36,3}] = deg2utm(36.962,-76.424); +pointsCS{36,1} = 'Dominion Terminal'; + +pointsCS(34,4) = {'MP'}; +pointsCS(35,4) = {'CPL'}; +pointsCS(36,4) = {'DV'}; + +% StatNum +pointsCS{6,5} = 8651370; %Dck +pointsCS{7,5} = 8652587; %OI +pointsCS{8,5} = 8654467; %Hat +pointsCS{9,5} = 8656483; %Beau + +pointsCS{12,5} = '44014'; %VB +pointsCS{16,5} = '41025'; %DS +pointsCS{30,5} = '41159'; %OB +pointsCS{31,5} = '44099'; %CH +pointsCS{34,5} = 'MNPV2'; %MP +pointsCS{35,5} = 'CLKN7'; %CL +pointsCS{36,5} = 'DOMV2'; %DV + +% Import Winds from NWS + +opts = delimitedTextImportOptions("NumVariables", 124); + +% Specify range and delimiter +opts.DataLines = [1, Inf]; +opts.Delimiter = ","; + +% Specify column names and types +opts.VariableNames = ["STATION", "DATE", "REPORT_TYPE", "SOURCE", "AWND", "BackupDirection", "BackupDistance", "BackupDistanceUnit", "BackupElements", "BackupElevation", "BackupElevationUnit", "BackupEquipment", "BackupLatitude", "BackupLongitude", "BackupName", "CDSD", "CLDD", "DSNW", "DailyAverageDewPointTemperature", "DailyAverageDryBulbTemperature", "DailyAverageRelativeHumidity", "DailyAverageSeaLevelPressure", "DailyAverageStationPressure", "DailyAverageWetBulbTemperature", "DailyAverageWindSpeed", "DailyCoolingDegreeDays", "DailyDepartureFromNormalAverageTemperature", "DailyHeatingDegreeDays", "DailyMaximumDryBulbTemperature", "DailyMinimumDryBulbTemperature", "DailyPeakWindDirection", "DailyPeakWindSpeed", "DailyPrecipitation", "DailySnowDepth", "DailySnowfall", "DailySustainedWindDirection", "DailySustainedWindSpeed", "DailyWeather", "HDSD", "HTDD", "HeavyFog", "HourlyAltimeterSetting", "HourlyDewPointTemperature", "HourlyDryBulbTemperature", "HourlyPrecipitation", "HourlyPresentWeatherType", "HourlyPressureChange", "HourlyPressureTendency", "HourlyRelativeHumidity", "HourlySeaLevelPressure", "HourlySkyConditions", "HourlyStationPressure", "HourlyVisibility", "HourlyWetBulbTemperature", "HourlyWindDirection", "HourlyWindGustSpeed", "HourlyWindSpeed", "MonthlyAverageRH", "MonthlyDaysWithGT001Precip", "MonthlyDaysWithGT010Precip", "MonthlyDaysWithGT32Temp", "MonthlyDaysWithGT90Temp", "MonthlyDaysWithLT0Temp", "MonthlyDaysWithLT32Temp", "MonthlyDepartureFromNormalAverageTemperature", "MonthlyDepartureFromNormalCoolingDegreeDays", "MonthlyDepartureFromNormalHeatingDegreeDays", "MonthlyDepartureFromNormalMaximumTemperature", "MonthlyDepartureFromNormalMinimumTemperature", "MonthlyDepartureFromNormalPrecipitation", "MonthlyDewpointTemperature", "MonthlyGreatestPrecip", "MonthlyGreatestPrecipDate", "MonthlyGreatestSnowDepth", "MonthlyGreatestSnowDepthDate", "MonthlyGreatestSnowfall", "MonthlyGreatestSnowfallDate", "MonthlyMaxSeaLevelPressureValue", "MonthlyMaxSeaLevelPressureValueDate", "MonthlyMaxSeaLevelPressureValueTime", "MonthlyMaximumTemperature", "MonthlyMeanTemperature", "MonthlyMinSeaLevelPressureValue", "MonthlyMinSeaLevelPressureValueDate", "MonthlyMinSeaLevelPressureValueTime", "MonthlyMinimumTemperature", "MonthlySeaLevelPressure", "MonthlyStationPressure", "MonthlyTotalLiquidPrecipitation", "MonthlyTotalSnowfall", "MonthlyWetBulb", "NormalsCoolingDegreeDay", "NormalsHeatingDegreeDay", "REM", "REPORT_TYPE1", "SOURCE1", "ShortDurationEndDate005", "ShortDurationEndDate010", "ShortDurationEndDate015", "ShortDurationEndDate020", "ShortDurationEndDate030", "ShortDurationEndDate045", "ShortDurationEndDate060", "ShortDurationEndDate080", "ShortDurationEndDate100", "ShortDurationEndDate120", "ShortDurationEndDate150", "ShortDurationEndDate180", "ShortDurationPrecipitationValue005", "ShortDurationPrecipitationValue010", "ShortDurationPrecipitationValue015", "ShortDurationPrecipitationValue020", "ShortDurationPrecipitationValue030", "ShortDurationPrecipitationValue045", "ShortDurationPrecipitationValue060", "ShortDurationPrecipitationValue080", "ShortDurationPrecipitationValue100", "ShortDurationPrecipitationValue120", "ShortDurationPrecipitationValue150", "ShortDurationPrecipitationValue180", "Sunrise", "Sunset", "TStorms", "WindEquipmentChangeDate"]; +opts.VariableTypes = ["string", "string", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "string", "double", "double", "string", "string", "string", "string", "double", "double", "double", "double", "string", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "double", "double", "double", "double", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "datetime"]; +opts = setvaropts(opts, 124, "InputFormat", "yyyy-MM-dd"); +opts = setvaropts(opts, [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 34, 35, 38, 39, 40, 41, 46, 58, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 123], "WhitespaceRule", "preserve"); +opts = setvaropts(opts, [3, 51, 59, 60, 61, 62, 63, 64, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "TrimNonNumeric", true); +opts = setvaropts(opts, [3, 51, 59, 60, 61, 62, 63, 64, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "ThousandsSeparator", ","); +opts = setvaropts(opts, [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 34, 35, 38, 39, 40, 41, 46, 58, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 123], "EmptyFieldRule", "auto"); +opts.ExtraColumnsRule = "ignore"; +opts.EmptyLineRule = "read"; + +% Import the data +tbl = readtable("NWS.csv", opts); + +% Convert to output type +STATION = tbl.STATION; +DATE = tbl.DATE; +REPORT_TYPE = tbl.REPORT_TYPE; +HourlyAltimeterSetting = tbl.HourlyAltimeterSetting; +HourlyPrecipitation = tbl.HourlyPrecipitation; +HourlyStationPressure = tbl.HourlyStationPressure; +HourlyWindDirection = tbl.HourlyWindDirection; +HourlyWindGustSpeed = tbl.HourlyWindGustSpeed; +HourlyWindSpeed = tbl.HourlyWindSpeed; +WindEquipmentChangeDate = tbl.WindEquipmentChangeDate; + +WBANs = [93796 93765 93729 03737 03703 13786 13762 13763 00154 13754 03736 13766 93719 03701 13769 00370 03719 93743 03741]; +% wBanList = urlreadtable('file:///D:/DorianRP/wbanmasterlist.html'); +% wBanList = wBanList{1}; +filename = 'lcd-stations.txt'; +filename2 = 'awos-stations.txt'; +filename3 = 'asos-stations.txt'; + +wBanList{1} = readWBAN(filename); +wBanList{2} = readAWOS(filename2); +wBanList{3} = readASOS(filename3); +clear filename filename2 filename3 +for Stat=[1:length(WBANs)] + + localWinds = datetime(DATE(endsWith(STATION,num2str(WBANs(Stat)))),'InputFormat','yyyy-MM-dd''T''HH:mm:ss','TimeZone','America/New_York'); + localShift = tzoffset(localWinds); + measuredWinds{Stat+40}(:,1) = datenum(datetime(DATE(endsWith(STATION,num2str(WBANs(Stat)))),'InputFormat','yyyy-MM-dd''T''HH:mm:ss')-localShift); + measuredWinds{Stat+40}(:,2) = HourlyWindSpeed(endsWith(STATION,num2str(WBANs(Stat)))).*0.44704; + measuredWinds{Stat+40}(:,3) = HourlyWindDirection(endsWith(STATION,num2str(WBANs(Stat)))); + + measueredPres{Stat+40}(:,1) = datenum(datetime(DATE(endsWith(STATION,num2str(WBANs(Stat)))),'InputFormat','yyyy-MM-dd''T''HH:mm:ss')-localShift); + measueredPres{Stat+40}(:,2) = HourlyStationPressure(endsWith(STATION,num2str(WBANs(Stat)))).*3386.3900009071; + + precipUse = endsWith(STATION,num2str(WBANs(Stat)))... + & REPORT_TYPE==-15 &... + minute(datetime(DATE,'InputFormat','yyyy-MM-dd''T''HH:mm:ss'))>=40; + clear localWinds localShift + localWinds = datetime(DATE(precipUse),'InputFormat','yyyy-MM-dd''T''HH:mm:ss','TimeZone','America/New_York'); + localShift = tzoffset(localWinds); + measueredRain{Stat+40}(:,1) = datenum(datetime(DATE(precipUse),'InputFormat','yyyy-MM-dd''T''HH:mm:ss')-localShift); + measueredRain{Stat+40}(:,2) = HourlyPrecipitation(precipUse).*0.0254*1000; + measueredRain{Stat+40}(isnan(measueredRain{Stat})==1,2)=0; + clear localWinds localShift precipUse + + + wBanIDX = find(wBanList{1}.WBAN==WBANs(Stat)); + wBanSource = 1; + if isempty(wBanIDX)==1 + wBanIDX = find(wBanList{2}.WBAN==WBANs(Stat)); + wBanSource = 2; + end + if isempty(wBanIDX)==1 + wBanIDX = find(wBanList{3}.WBAN==WBANs(Stat)); + wBanSource = 3; + end + if isempty(wBanIDX)==1 + switch Stat + case 10 + [pointsCS{Stat+40,2},pointsCS{Stat+40,3}] = deg2utm(34.90000,-76.88300); + pointsCS{Stat+40,1} = 'CHERRY POINT'; + pointsCS{Stat+40,4} = 'CP'; + pointsCS{Stat+40,5} = WBANs(Stat); + case 15 + [pointsCS{Stat+40,2},pointsCS{Stat+40,3}] = deg2utm(36.8167,-76.0333 ); + pointsCS{Stat+40,1} = 'OCEANA NAS'; + pointsCS{Stat+40,4} = 'ONS'; + pointsCS{Stat+40,5} = WBANs(Stat); + end + else + wbanLat = wBanList{wBanSource}.LAT(wBanIDX); + wbanLon = wBanList{wBanSource}.LON(wBanIDX); + + [pointsCS{Stat+40,2},pointsCS{Stat+40,3}] = deg2utm(wbanLat,wbanLon); + + pointsCS{Stat+40,1} = wBanList{wBanSource}.LOCATION{wBanIDX}; + pointsCS{Stat+40,4} = wBanList{wBanSource}.CALL{wBanIDX}; + + pointsCS{Stat+40,5} = WBANs(Stat); + end +end +pointsCS(50,4) = {'CPT'}; + + +pointsCS{37,2} = 452000; +pointsCS{37,3} = 3959200; +pointsCS{37,1} = 'OI V2'; + +pointsCS{38,2} = 347000; +pointsCS{38,3} = 3840000; +pointsCS{38,1} = 'BF V2'; + +pointsCS{39,2} = 465400; +pointsCS{39,3} = 3883600; +pointsCS{39,1} = 'Hole'; + +pointsCS{40,2} = 390000; +pointsCS{40,3} = 3930000; +pointsCS{40,1} = 'Pond'; + +%% AHPS Stations + +locations = [36.060710, -75.699941;... + 35.595547,-75.470031;... + 35.325700,-75.511900;... + 35.018333,-76.314444;... + 35.024444,-76.691944; + 35.435180,-76.399800;... + 34.667700,-77.063400;... + 35.915000,-76.722778;... + 36.298611,-76.218611;... + 35.537222,-76.622778;... + 35.543333,-77.061944;... + 36.4073,-75.9949;... + 35.6841,-75.4838;... + 35.9081,-75.6683;... + 35.1153,-75.9873;... + 35.89639,-75.62222;... + 34.95630,-76.27830]; + +locNames = {'Albemarle Sound @ Kitty Hawk ',... + 'Pamlico Sound @ Rodanthe Ferry Terminal ',... + 'Pamlico Sound @ Avon ',... + 'Pamlico Sound @ Cedar Island ',... + 'Neuse River @ Oriental ',... + 'Pamlico Sound @ Bell Island Pier ',... + 'Bogue Sound @ Emerald Isle ',... + 'Roanoke River @ Westover ',... + 'Pasquotank River near Mariners Wharf Park @ Elizabeth City',... + 'Pungo River @ Belhaven',... + 'Pamlico River @ Washington',... + 'Maple @ Coinjock Creek',... + 'Rodanthe 6N @ New Inlet',... + 'Manteo - Roanoke Marshes',... + 'Coast Guard Station @ Ocracoke',... + 'Roanoke Sound',... + 'Lola'}; + +locNamesCODE = {... + 'KITN7',... %7 + 'ROFN7',... %15 + 'AVON7',... %1 + 'CTIN7',... %None + 'ORLN7',... %10 + 'BIPN7',... %2 + 'EMDN7',... %5 + 'WESN7',... %16 + 'EMWN7',... %6 + 'BLHN7',... %3 + 'PAMN7',... %11 + 'COJN7',... %4 + 'PEAN7',... %12 + 'RMLN7',... %14 + 'OCAN7',... %9 + 'RDFN7',... %13 + 'LOLN7'}; %8 + +locNamesID = {... + 'KH',... %7 + 'RF',... %15 + 'AV',... %1 + 'CI',... %None + 'NRO',... %10 + 'BI',... %2 + 'EI',... %5 + 'WO',... %16 + 'EC',... %6 + 'BH',... %3 + 'WH',... %11 + 'CJ',... %4 + 'NI',... %12 + 'RM',... %14 + 'OC',... %9 + 'RS',...%13 + 'LO'}; %8 + + %[1:7 9 11:16] +for i = 1:length(locations) + [pointsCS{i+59,2},pointsCS{i+59,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); + pointsCS{i+59,1} = locNames{i}; + pointsCS{i+59,5} = locNamesCODE{i}; + pointsCS{i+59,4} = locNamesID{i}; + +end +% M 65 +% Faves 74 62 61 60 67 69 70 +% Nope 72 66 71 73 68 +pointsCS{76,4} = 'LOA'; + + + %% AWOS Pts + asos = importASOS("asos.txt"); +opts = delimitedTextImportOptions("NumVariables", 7); +opts.DataLines = [2, Inf]; +opts.Delimiter = ","; +opts.VariableNames = ["stid", "station_name", "lat", "lon", "elev", "begints", "iem_network"]; +opts.VariableTypes = ["string", "string", "double", "double", "double", "string", "categorical"]; +opts.ExtraColumnsRule = "ignore"; +opts.EmptyLineRule = "read"; +opts = setvaropts(opts, ["stid", "station_name", "begints"], "WhitespaceRule", "preserve"); +opts = setvaropts(opts, ["stid", "station_name", "begints", "iem_network"], "EmptyFieldRule", "auto"); + +% Import the data +awosID = readtable("awosID.csv", opts); + clear opts + + stationsASOS = unique(asos.station); + +for Stat = 1:length(stationsASOS) +awosIDS = find(asos.station==stationsASOS(Stat),1); +awosIDX = find(awosID.stid==cellstr(stationsASOS(Stat)),1); + +pointsCS(Stat+76,5) = cellstr(stationsASOS(Stat)); +pointsCS(Stat+76,4) = cellstr(stationsASOS(Stat)); +[pointsCS{Stat+76,2},pointsCS{Stat+76,3}] = wgs2utm(asos.lat(awosIDS),asos.lon(awosIDS),18,'N'); +pointsCS(Stat+76,1) = {awosID.station_name{awosIDX}}; +% pointsCS{Stat+76,1} = pointsCS{Stat+76,1}(2:end-1); + +end + +pointsCS{77,4} = 'DCG'; +pointsCS{78,4} = 'ENG'; + +pointsCS{90,1} = 'Currituck Country Airport'; +pointsCS{90,4} = 'CCA'; + +pointsCS{88,1} = 'Cherry Point Marine Corps Air Station'; +pointsCS{88,4} = 'CPM'; + +pointsCS{87,4} = 'BOF'; +pointsCS{86,4} = 'PIN'; + +pointsCS{85,1} = 'Beaufort Airport'; +pointsCS{85,4} = 'BFA'; + +pointsCS{85,1} = 'Beaufort Airport'; +pointsCS{85,4} = 'BFA'; + +pointsCS{84,1} = 'Manteo Dare Airport'; +pointsCS{84,4} = 'MDA'; + +pointsCS{83,1} = 'Hatteras Airport'; +pointsCS{83,4} = 'HTA'; + +pointsCS{82,1} = 'First flight Airport'; +pointsCS{82,4} = 'FFA'; + +pointsCS{81,1} = 'New Berm Airport'; +pointsCS{81,4} = 'NBA'; + +pointsCS{80,1} = 'Edenton Airport'; +pointsCS{80,4} = 'EDA'; + +%% Add more details +CSs_F = [6 7 9 22 8 11 18 10 19 20 25 24 23 21]; +CSs_F = [6 7 9 22 8 11 18 10 19 20 25 24 23 21 74 60 61 67 69 70 65]; + +CSsH_F = [12 13 14:16 26 18 19 30 31]; + +CSU = [27 17 18 19]; +CSM = [6 9 12 16 35 42 45 46 50 53 59]; +CSM = [6 9 12 16 35 42 45 46 50 53 59 64 68 69 74 76 77:91]; +CSM = [6 9 12 16 35 45 46 50 53 59 64 74 76 77 78 82:87 90]; +for i = 1:length(pointsCS) + if ismember(i,CSs_F) + pointsCS{i,6} = 'Water Level'; + end + + if ismember(i,CSsH_F) + pointsCS{i,7} = 'Wave'; + end + + if ismember(i,CSU) + pointsCS{i,8} = 'Current'; + end + + if ismember(i,CSM) + pointsCS{i,9} = 'Wind'; + end + +end + + pointsCS([6 13 17 26 27],10) = {'USACE'}; + pointsCS([10 11 20:22 33],10) = {'USGS'}; + pointsCS([23:25],10) = {'USACE'}; %Conery, Ian + + pointsCS([41:59 32],10) = {'NWS'}; %Conery, Ian + + pointsCS([30:31],10) = {'CDIP/ USACE'}; + pointsCS([16],10) = {'NDBC'}; + pointsCS([12],10) = {'NDBC/ USACE'}; + pointsCS([14:15],10) = {'NDBC/ UNC'}; + pointsCS([18:19],10) = {'UNC'}; + + pointsCS([9],10) = {'NOAA/ Duke'}; + pointsCS([8],10) = {'NOAA/ USCG'}; + pointsCS([7],10) = {'NOAA'}; + + pointsCS([34],10) = {'NDBC/ NOAA'}; + pointsCS([35],10) = {'NDBC'}; + pointsCS([36],10) = {'NDBC/ NOAA'}; + + pointsCS([60:76],10) = {'ISU/ HADS'}; + pointsCS([77:91],10) = {'ISU/ ASOS'}; + + +% pointsCS([12],7) = {'Wave (3 m Buoy)'}; + pointsCS([12],11) = {'47 m'}; +% pointsCS([14],7) = {'Wave (Waverider Buoy)'}; + pointsCS([14],11) = {'21 m'}; +% pointsCS([15],7) = {'Wave (Waverider Buoy)'}; + pointsCS([15],11) = {'18 m'}; +% pointsCS([16],7) = {'Wave (3 m Buoy)'}; + pointsCS([16],11) = {'59 m'}; +% pointsCS([30],7) = {'Wave (Datawell Buoy)'}; + pointsCS([30],11) = {'30 m'}; +% pointsCS([31],7) = {'Wave (Datawell Buoy)'}; + pointsCS([31],11) = {'18 m'}; +% pointsCS([26],7) = {'Wave (Waverider Buoy)'}; + pointsCS([26],11) = {'17 m'}; + + + + pointsCS([7],1) = {'Oregon Inlet Marina'}; + pointsCS([11],1) = {'Albemarle Sound @ Leonards Point'}; + pointsCS([8],1) = {'Hatteras Coast Guard'}; + pointsCS([9],1) = {'Beaufort Duke Marine Lab'}; + pointsCS([7],1) = {'Oregon Inlet Marina'}; + + pointsCS([20],1) = {'Currituck Sound @ Point Harbour'}; + pointsCS([21],1) = {'Roanoke Sound @ Point Island'}; + pointsCS([22],1) = {'Bogue Sound @ Atlantic Beach'}; + + pointsCS([23],1) = {'Villa Dunes Dock'}; + pointsCS([24],1) = {'Kill Devil Hills @ Hayman Street'}; + pointsCS([25],1) = {'Jean Guite Creek Outlet'}; + + pointsCS([27],1) = {'FRF AWAC'}; + pointsCS([27],11) = {'6 m'}; + + pointsCS([17],1) = {'FRF AWAC'}; + pointsCS([17],11) = {'11 m'}; +% pointsCS([17],8) = {'Current (Nortek AWAC)'}; + + pointsCS([14],1) = {'Nags Head Buoy'}; + pointsCS([15],1) = {'Oregon Inlet Buoy'}; + pointsCS([16],1) = {'Diamond Shoals Buoy'}; + pointsCS([30],1) = {'Oslow Bay Buoy'}; + pointsCS([31],1) = {'Cape Henry Buoy'}; + + pointsCS([18],1) = {'Currituck Sound North'}; + pointsCS([18],11) = {'2.3 m'}; +% pointsCS([18],7) = {'Wave (Nortek AWAC)'}; +% pointsCS([18],8) = {'Current (Nortek Aquadopp)'}; + + pointsCS([19],1) = {'Currituck Sound South'}; + pointsCS([19],11) = {'2.6 m'}; +% pointsCS([19],7) = {'Wave (Nortek AWAC)'}; +% pointsCS([19],8) = {'Current (Nortek Aquadopp)'}; + +% pointsCS([6],8) = {'Current (Nortek AWAC)'}; + pointsCS([6],11) = {'6 m'}; + pointsCS([6],1) = {'FRF Pier'}; + + pointsCS([26],1) = {'FRF 17 m Buoy'}; + pointsCS([13],1) = {'FRF 26 m Buoy'}; + pointsCS([13],11) = {'26 m'}; + + + pointsCS([42],1) = {'Michael J Smith Field'}; + pointsCS([45],1) = {'Edenton Northeast Airport'}; + pointsCS([46],1) = {'Elizabth City Coast Guard'}; + pointsCS([50],1) = {'Cherry Point Marine Corps Air Station'}; + pointsCS([50],4) = {'CPM'}; + + pointsCS([53],1) = {'Coasltal Carolina Airport'}; + pointsCS([59],1) = {'Warren Field Airport'}; + + +%% Add Elevation +pointsCS(41,12) = {20.85} ; +pointsCS(45,12) = {6.10} ; +pointsCS(46,12) = {7.5} ; +pointsCS(50,12) = {8.80} ; +pointsCS(50,12) = {9.90}; +pointsCS(53,12) = {6.10} ; +pointsCS(59,12) = {11.80}; + +pointsCS(64,12) = {1.40}; +pointsCS(74,12) = {2}; + +pointsCS(76,12) = {3.74}; +pointsCS(77,12) = {0.51}; +pointsCS(78,12) = {0.6}; + +pointsCS(82,12) = {4}; +pointsCS(83,12) = {3}; +pointsCS(84,12) = {4}; +pointsCS(85,12) = {3}; +pointsCS(86,12) = {5}; +pointsCS(87,12) = {3.16}; +pointsCS(90,12) = {5.5}; + +pointsCS(35,12) = {4.6}; + +pointsCS(9,12) = {0}; +pointsCS(12,12) = {0}; +pointsCS(16,12) = {0}; + +pointsCS(6,12) = {11.4}; +%% Adjust out of dry zone +pointsCS{23,2} = pointsCS{23,2} - 100; +pointsCS{32,2} = pointsCS{32,2} - 1000; +pointsCS{51,2} = pointsCS{51,2} - 1000; +pointsCS{62,2} = pointsCS{62,2} - 1000; +pointsCS{43,2} = pointsCS{43,2} - 3000; +pointsCS{72,3} = pointsCS{72,3} - 10000; + +pointsCS{60,2} = pointsCS{60,2} - 500; + +pointsCS{61,2} = pointsCS{61,2} - 900; +pointsCS{61,3} = pointsCS{61,3} - 250; + +pointsCS{92,2} = pointsCS{60,2} + 350; +pointsCS{92,3} = pointsCS{60,3} - 900; +pointsCS{92,1} = [pointsCS{60,1} '_Vsouth']; +pointsCS(92,4:12) = pointsCS(60,4:12); + +pointsCS{35,3} = pointsCS{35,3} - 2000; +pointsCS{82,2} = pointsCS{82,2} - 1000; +pointsCS{83,3} = pointsCS{83,3} - 1000; + +pointsCS{93,2} = pointsCS{22,2} + 2750; +pointsCS{93,3} = pointsCS{22,3} + 100; +pointsCS{93,1} = [pointsCS{22,1} '_VEast']; +pointsCS(93,4:12) = pointsCS(22,4:12); + +pointsCS{94,2} = pointsCS{22,2} - 550; +pointsCS{94,3} = pointsCS{22,3} + 250; +pointsCS{94,1} = [pointsCS{22,1} '_VWest']; +pointsCS(94,4:12) = pointsCS(22,4:12); + +pointsCS{95,2} = 350000; +pointsCS{95,3} = 3977900; +pointsCS{95,1} = [pointsCS{67,1} '_VEast']; +pointsCS(95,4:12) = pointsCS(67,4:12); + +pointsCS{96,2} = 409700; +pointsCS{96,3} = 3883600; +pointsCS{96,1} = [pointsCS{74,1} '_VSouth']; +pointsCS(96,4:12) = pointsCS(74,4:12); + +pointsCS{97,2} = 438200; +pointsCS{97,3} = 3896000; +pointsCS{97,1} = [pointsCS{24,1} '_VSouth']; +pointsCS(97,4:12) = pointsCS(24,4:12); + +pointsCS(38,1:12) = pointsCS(9,1:12); + +%% DUNEX Points + +% Setup the Import Options and import the data +opts = delimitedTextImportOptions("NumVariables", 2); + +% Specify range and delimiter +opts.DataLines = [1, Inf]; +opts.Delimiter = ","; + +% Specify column names and types +opts.VariableNames = ["VarName1", "VarName2"]; +opts.VariableTypes = ["double", "double"]; + +% Specify file level properties +opts.ExtraColumnsRule = "ignore"; +opts.EmptyLineRule = "read"; + +% Import the data +CoordinatesBC = readtable("D:\Alexander\DUNEX\Coordinates_BC.txt", opts); + +% Convert to output type +CoordinatesBC = table2array(CoordinatesBC); + +% Clear temporary variables +clear opts + +for i = 1:length(CoordinatesBC) + pointsCS{i+97,1} = ['DUNEX_' num2str(i)]; + pointsCS{i+97,4} = ['D_' num2str(i)]; + [pointsCS{i+97,2},pointsCS{i+97,3}] = wgs2utm(CoordinatesBC(i,2),CoordinatesBC(i,1),18,'N'); +end + +%% Fix two bound pts + +[pointsCS{114,3}] = pointsCS{114,3}+400; + +[pointsCS{113,2}] = pointsCS{113,2}-500; +% [pointsCS{113,3}] = pointsCS{113,3}+500; + + + +%% DUNEX Points +clear locations locNames locNamesID + +locations = [36.400701, -75.823317;... + 36.392170, -75.824346;... + 35.779135, -75.532475;... + 35.746968, -75.496067;... + 35.743821, -75.500800;... + 35.621202, -75.456779;... + 35.620127, -75.464034;... +]; + +locNames = {'Currituck Banks Estuarine Reserve',... + 'Currituck Banks Estuarine Reserve Nearshore',... + 'Mid Oregon Inlet',... + 'South Oregon Inlet',... + 'South Oregon Inlet Nearshore',... + 'Round Hammock Bay',... + 'Round Hammock Bay Nearshore'}; + +locNamesID = {... + 'CB',... + 'CBN',... + 'MI',... + 'SI',... + 'SIN',... + 'HB',... + 'HBN'}; %8 + + +for i = 1:length(locations) + [pointsCS{i+129,2},pointsCS{i+129,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); + pointsCS{i+129,1} = locNames{i}; + pointsCS{i+129,4} = locNamesID{i}; + +end + +%% Add DUNEX_R +R_PTS = readmatrix("D:\Alexander\DUNEX_R\R. Housego DUNEX groundwater modeling locations_AJMR.xlsx",'Sheet','Combined'); + +for i = 1:size(R_PTS,1) + pointsCS{i+136,1} = ['DUNEX_R_' num2str(i)]; + pointsCS{i+136,4} = ['DR_' num2str(i)]; + [pointsCS{i+136,2},pointsCS{i+136,3}] = wgs2utm(R_PTS(i,2),R_PTS(i,1),18,'N'); +end + +%% Add Mulligan PTS +M_PTS = readcell("D:\Alexander\MulliganPTS_V2.xlsx"); + +for i = 1:size(M_PTS,1) + pointsCS{i+160,1} = M_PTS{i,1}; + pointsCS{i+160,4} = M_PTS{i,4}; + [pointsCS{i+160,2},pointsCS{i+160,3}] = wgs2utm(M_PTS{i,2},M_PTS{i,3},18,'N'); +end + + pointsCS(169,[2 3]) = pointsCS(61,[2 3]); + pointsCS(164,[2 3]) = pointsCS(115,[2 3]); + +for i = 1:size(M_PTS,1) + [webPoints(i,1),webPoints(i,2)] = utm2deg(pointsCS{i+160,2},pointsCS{i+160,3},'18 N'); +end +%% Add Chris PTS +C_PTS = readcell("D:\Alexander\ChrisPTS.xlsx"); + +for i = 1:size(C_PTS,1) + pointsCS{i+172,1} = ['Cpt_' C_PTS{i,1}]; + pointsCS{i+172,4} = C_PTS{i,1}; + [pointsCS{i+172,2},pointsCS{i+172,3}] = wgs2utm(C_PTS{i,2},C_PTS{i,3},18,'N'); +end + + +%% Add Hohonu Pts + + + + +%% Check in pol +pol = readPol('D:\Alexander\DUNEX\NCShoreALL.pol'); +clear inPol + +for PolCount = 1:length(pol) +for CS = 1:length(pointsCS) + inPol(PolCount,CS) = inpolygon(pointsCS{CS,2},pointsCS{CS,3},pol{PolCount}(:,1),pol{PolCount}(:,2)); + +end +end +find(max(inPol)) + +%% Save +save('D:\DUNEX_RT\Operation\DUNEX_Sept7.mat','pointsCS') +%% Make Obs Files +flowGrid = load('D:\Alexander\DUNEX_R\Cone7W_100.mat'); +% flowGrid = load('D:\Alexander\RT_25m\C7_25.mat'); + +% flowGrid = load('D:\NCBathy\Cone7\C9S_50.mat') +fileID=fopen('D:\Alexander\Dec28.obs','w'); +% fileID=fopen('C9_50MET_V5.obs','w'); + +for line=1:length(pointsCS) + + obsIDX = NearestValue([pointsCS{line,2:3}],flowGrid.data.X,flowGrid.data.Y); + if obsIDX(1) == 1 + obsIDX(1) = 2; + end + if obsIDX(2) == 1 + obsIDX(2) = 2; + end + if line ==71 + fprintf(fileID,[num2str(line) '_' pointsCS{line,1}(1:5) ' %d %d\n'],obsIDX(1),obsIDX(2)); + elseif length(pointsCS{line,1})>10 + fprintf(fileID,[num2str(line) '_' pointsCS{line,1}(1:10) ' %d %d\n'],obsIDX(1),obsIDX(2)); + else + fprintf(fileID,[num2str(line) '_' pointsCS{line,1}(1:end) ' %d %d\n'],obsIDX(1),obsIDX(2)); + end +end +fclose(fileID); + +fileID=fopen('D:\Alexander\Dec28.loc','w'); +clear waveObsPts +% for i = 1:40 +for i = 1:length(pointsCS) + obsIDX = NearestValue([pointsCS{i,2:3}],flowGrid.data.X,flowGrid.data.Y); + if obsIDX(1) == 1 + obsIDX(1) = 2; + end + if obsIDX(2) == 1 + obsIDX(2) = 2; + end + + waveObsPts(i,:) = [flowGrid.data.X(obsIDX(1),obsIDX(2)),flowGrid.data.Y(obsIDX(1),obsIDX(2))]; + fprintf(fileID,' %1.7f %1.7f\n',[waveObsPts(i,1),waveObsPts(i,2)])'; + +end + +fclose(fileID) +%end + + diff --git a/makeCSptsDUNEXR_Sept7.m b/makeCSptsDUNEXR_Sept7.m new file mode 100644 index 0000000..3a21415 --- /dev/null +++ b/makeCSptsDUNEXR_Sept7.m @@ -0,0 +1,821 @@ +%% Make CS Points +clear pointsCS + +load('CSpoints.mat'); +% Realtime Points +% Create Observation File +locations = [36.606,-74.840;... + 36.260,-75.594;... + 36.001,-75.421;... + 35.750,-75.330;... + 35.025,-75.363; + 36.189244, -75.739155;... + 36.3205,-75.872;... + 36.1656,-75.8155;... + 36.0866, -75.76833;... + 35.8964389,-75.6220889;... + 34.7113528,-76.7368333;... + 35.96176,-75.64163;... + 36.04318,-75.68936;... + 36.12932,-75.74501;... + 36.20002, -75.7151]; + +locNames = {'Virginia Beach Wave',... + 'Duck 26 Wave',... + 'Nages Head Wave',... + 'Oregon Inlet Wave',... + 'Diamond Shoals Wave',... + 'Duck 11 AWAC',... + 'CS North',... + 'CS South',... + 'USGS CURRITUCK SOUND NR POINT HARBOR',... + 'USGS ROANOKE SOUND AT POND ISLAND',... + 'USGS BOGUE SOUND AT ATLANTIC BEACH',... + 'Villa Dunes SW Dock Shoreline',... + 'Hayman St Dock SW Shoreline',... + 'Gunther Telephone Pole'... + 'Duck 17 Wave'}; + +for i = 1:length(locations) + pointsCS{i+11,1} = locNames{i}; + [pointsCS{i+11,2},pointsCS{i+11,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); +end + + +pointsCS{8,3} = pointsCS{8,3} + 2500; +pointsCS{7,2} = pointsCS{7,2} - 500; +[pointsCS{30,2},pointsCS{30,3}]= wgs2utm(34.213,-76.946,18,'N'); +[pointsCS{31,2},pointsCS{31,3}]= wgs2utm(36.914,-75.720,18,'N'); +pointsCS{30,1} = 'Onslow Bay Wave'; +pointsCS{31,1} = 'Cape Henry Wave'; +[pointsCS{32,2},pointsCS{32,3}]= wgs2utm(36.0175833,-75.6715833,18,'N'); +pointsCS{32,1} = 'Kitty Hawk Airport'; +[pointsCS{33,2},pointsCS{33,3}]= wgs2utm(36.20002,-75.7151,18,'N'); +pointsCS{33,1} = 'FRF 17m'; +pointsCS(33,4) = {'F17'}; +pointsCS{10,1} = 'Currituck Sound @ Corolla'; +pointsCS(1:21,4) = {'CS 1','CS 2','CS 3','CS 4','CS 5','FP','OI','HT','BF','CC','AS','VB','F26','NH','O18','DS','F11','CN','CS','PH','PI'}; +pointsCS(22,4) = {'AB'}; +pointsCS(23,4) = {'VD'}; +pointsCS(24,4) = {'HD'}; +pointsCS(25,4) = {'JC'}; +pointsCS(30,4) = {'OB'}; +pointsCS(31,4) = {'CH'}; +pointsCS(32,4) = {'KH'}; + + +pointsCS{27,1} = 'FRF 6m AWAC'; +[pointsCS{27,2},pointsCS{27,3}]= wgs2utm(36.187328,-75.7465267,18,'N'); +pointsCS{27,4} = 'F6'; +pointsCS(26,4) = {'F17'}; + + +for i = 1:length(locations) + pointsCS{i+11,1} = locNames{i}; + [pointsCS{i+11,2},pointsCS{i+11,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); +end + +pointsCS(28,:) = pointsCS(18,:); +pointsCS(29,:) = pointsCS(19,:); +pointsCS{28,1} = 'CS North 2'; +pointsCS{29,1} = 'CS South 2'; + +% NDBC + +[pointsCS{34,2},pointsCS{34,3}] = deg2utm(36.778,-76.302); +pointsCS{34,1} = 'Money Point'; + +[pointsCS{35,2},pointsCS{35,3}] = deg2utm(34.622,-76.525); +pointsCS{35,1} = 'Cape Lookout'; + +[pointsCS{36,2},pointsCS{36,3}] = deg2utm(36.962,-76.424); +pointsCS{36,1} = 'Dominion Terminal'; + +pointsCS(34,4) = {'MP'}; +pointsCS(35,4) = {'CPL'}; +pointsCS(36,4) = {'DV'}; + +% StatNum +pointsCS{6,5} = 8651370; %Dck +pointsCS{7,5} = 8652587; %OI +pointsCS{8,5} = 8654467; %Hat +pointsCS{9,5} = 8656483; %Beau + +pointsCS{12,5} = '44014'; %VB +pointsCS{16,5} = '41025'; %DS +pointsCS{30,5} = '41159'; %OB +pointsCS{31,5} = '44099'; %CH +pointsCS{34,5} = 'MNPV2'; %MP +pointsCS{35,5} = 'CLKN7'; %CL +pointsCS{36,5} = 'DOMV2'; %DV + +% Import Winds from NWS + +opts = delimitedTextImportOptions("NumVariables", 124); + +% Specify range and delimiter +opts.DataLines = [1, Inf]; +opts.Delimiter = ","; + +% Specify column names and types +opts.VariableNames = ["STATION", "DATE", "REPORT_TYPE", "SOURCE", "AWND", "BackupDirection", "BackupDistance", "BackupDistanceUnit", "BackupElements", "BackupElevation", "BackupElevationUnit", "BackupEquipment", "BackupLatitude", "BackupLongitude", "BackupName", "CDSD", "CLDD", "DSNW", "DailyAverageDewPointTemperature", "DailyAverageDryBulbTemperature", "DailyAverageRelativeHumidity", "DailyAverageSeaLevelPressure", "DailyAverageStationPressure", "DailyAverageWetBulbTemperature", "DailyAverageWindSpeed", "DailyCoolingDegreeDays", "DailyDepartureFromNormalAverageTemperature", "DailyHeatingDegreeDays", "DailyMaximumDryBulbTemperature", "DailyMinimumDryBulbTemperature", "DailyPeakWindDirection", "DailyPeakWindSpeed", "DailyPrecipitation", "DailySnowDepth", "DailySnowfall", "DailySustainedWindDirection", "DailySustainedWindSpeed", "DailyWeather", "HDSD", "HTDD", "HeavyFog", "HourlyAltimeterSetting", "HourlyDewPointTemperature", "HourlyDryBulbTemperature", "HourlyPrecipitation", "HourlyPresentWeatherType", "HourlyPressureChange", "HourlyPressureTendency", "HourlyRelativeHumidity", "HourlySeaLevelPressure", "HourlySkyConditions", "HourlyStationPressure", "HourlyVisibility", "HourlyWetBulbTemperature", "HourlyWindDirection", "HourlyWindGustSpeed", "HourlyWindSpeed", "MonthlyAverageRH", "MonthlyDaysWithGT001Precip", "MonthlyDaysWithGT010Precip", "MonthlyDaysWithGT32Temp", "MonthlyDaysWithGT90Temp", "MonthlyDaysWithLT0Temp", "MonthlyDaysWithLT32Temp", "MonthlyDepartureFromNormalAverageTemperature", "MonthlyDepartureFromNormalCoolingDegreeDays", "MonthlyDepartureFromNormalHeatingDegreeDays", "MonthlyDepartureFromNormalMaximumTemperature", "MonthlyDepartureFromNormalMinimumTemperature", "MonthlyDepartureFromNormalPrecipitation", "MonthlyDewpointTemperature", "MonthlyGreatestPrecip", "MonthlyGreatestPrecipDate", "MonthlyGreatestSnowDepth", "MonthlyGreatestSnowDepthDate", "MonthlyGreatestSnowfall", "MonthlyGreatestSnowfallDate", "MonthlyMaxSeaLevelPressureValue", "MonthlyMaxSeaLevelPressureValueDate", "MonthlyMaxSeaLevelPressureValueTime", "MonthlyMaximumTemperature", "MonthlyMeanTemperature", "MonthlyMinSeaLevelPressureValue", "MonthlyMinSeaLevelPressureValueDate", "MonthlyMinSeaLevelPressureValueTime", "MonthlyMinimumTemperature", "MonthlySeaLevelPressure", "MonthlyStationPressure", "MonthlyTotalLiquidPrecipitation", "MonthlyTotalSnowfall", "MonthlyWetBulb", "NormalsCoolingDegreeDay", "NormalsHeatingDegreeDay", "REM", "REPORT_TYPE1", "SOURCE1", "ShortDurationEndDate005", "ShortDurationEndDate010", "ShortDurationEndDate015", "ShortDurationEndDate020", "ShortDurationEndDate030", "ShortDurationEndDate045", "ShortDurationEndDate060", "ShortDurationEndDate080", "ShortDurationEndDate100", "ShortDurationEndDate120", "ShortDurationEndDate150", "ShortDurationEndDate180", "ShortDurationPrecipitationValue005", "ShortDurationPrecipitationValue010", "ShortDurationPrecipitationValue015", "ShortDurationPrecipitationValue020", "ShortDurationPrecipitationValue030", "ShortDurationPrecipitationValue045", "ShortDurationPrecipitationValue060", "ShortDurationPrecipitationValue080", "ShortDurationPrecipitationValue100", "ShortDurationPrecipitationValue120", "ShortDurationPrecipitationValue150", "ShortDurationPrecipitationValue180", "Sunrise", "Sunset", "TStorms", "WindEquipmentChangeDate"]; +opts.VariableTypes = ["string", "string", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "string", "double", "double", "string", "string", "string", "string", "double", "double", "double", "double", "string", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "double", "double", "double", "double", "double", "double", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "string", "datetime"]; +opts = setvaropts(opts, 124, "InputFormat", "yyyy-MM-dd"); +opts = setvaropts(opts, [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 34, 35, 38, 39, 40, 41, 46, 58, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 123], "WhitespaceRule", "preserve"); +opts = setvaropts(opts, [3, 51, 59, 60, 61, 62, 63, 64, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "TrimNonNumeric", true); +opts = setvaropts(opts, [3, 51, 59, 60, 61, 62, 63, 64, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120], "ThousandsSeparator", ","); +opts = setvaropts(opts, [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 34, 35, 38, 39, 40, 41, 46, 58, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 123], "EmptyFieldRule", "auto"); +opts.ExtraColumnsRule = "ignore"; +opts.EmptyLineRule = "read"; + +% Import the data +tbl = readtable("NWS.csv", opts); + +% Convert to output type +STATION = tbl.STATION; +DATE = tbl.DATE; +REPORT_TYPE = tbl.REPORT_TYPE; +HourlyAltimeterSetting = tbl.HourlyAltimeterSetting; +HourlyPrecipitation = tbl.HourlyPrecipitation; +HourlyStationPressure = tbl.HourlyStationPressure; +HourlyWindDirection = tbl.HourlyWindDirection; +HourlyWindGustSpeed = tbl.HourlyWindGustSpeed; +HourlyWindSpeed = tbl.HourlyWindSpeed; +WindEquipmentChangeDate = tbl.WindEquipmentChangeDate; + +WBANs = [93796 93765 93729 03737 03703 13786 13762 13763 00154 13754 03736 13766 93719 03701 13769 00370 03719 93743 03741]; +% wBanList = urlreadtable('file:///D:/DorianRP/wbanmasterlist.html'); +% wBanList = wBanList{1}; +filename = 'lcd-stations.txt'; +filename2 = 'awos-stations.txt'; +filename3 = 'asos-stations.txt'; + +wBanList{1} = readWBAN(filename); +wBanList{2} = readAWOS(filename2); +wBanList{3} = readASOS(filename3); +clear filename filename2 filename3 +for Stat=[1:length(WBANs)] + + localWinds = datetime(DATE(endsWith(STATION,num2str(WBANs(Stat)))),'InputFormat','yyyy-MM-dd''T''HH:mm:ss','TimeZone','America/New_York'); + localShift = tzoffset(localWinds); + measuredWinds{Stat+40}(:,1) = datenum(datetime(DATE(endsWith(STATION,num2str(WBANs(Stat)))),'InputFormat','yyyy-MM-dd''T''HH:mm:ss')-localShift); + measuredWinds{Stat+40}(:,2) = HourlyWindSpeed(endsWith(STATION,num2str(WBANs(Stat)))).*0.44704; + measuredWinds{Stat+40}(:,3) = HourlyWindDirection(endsWith(STATION,num2str(WBANs(Stat)))); + + measueredPres{Stat+40}(:,1) = datenum(datetime(DATE(endsWith(STATION,num2str(WBANs(Stat)))),'InputFormat','yyyy-MM-dd''T''HH:mm:ss')-localShift); + measueredPres{Stat+40}(:,2) = HourlyStationPressure(endsWith(STATION,num2str(WBANs(Stat)))).*3386.3900009071; + + precipUse = endsWith(STATION,num2str(WBANs(Stat)))... + & REPORT_TYPE==-15 &... + minute(datetime(DATE,'InputFormat','yyyy-MM-dd''T''HH:mm:ss'))>=40; + clear localWinds localShift + localWinds = datetime(DATE(precipUse),'InputFormat','yyyy-MM-dd''T''HH:mm:ss','TimeZone','America/New_York'); + localShift = tzoffset(localWinds); + measueredRain{Stat+40}(:,1) = datenum(datetime(DATE(precipUse),'InputFormat','yyyy-MM-dd''T''HH:mm:ss')-localShift); + measueredRain{Stat+40}(:,2) = HourlyPrecipitation(precipUse).*0.0254*1000; + measueredRain{Stat+40}(isnan(measueredRain{Stat})==1,2)=0; + clear localWinds localShift precipUse + + + wBanIDX = find(wBanList{1}.WBAN==WBANs(Stat)); + wBanSource = 1; + if isempty(wBanIDX)==1 + wBanIDX = find(wBanList{2}.WBAN==WBANs(Stat)); + wBanSource = 2; + end + if isempty(wBanIDX)==1 + wBanIDX = find(wBanList{3}.WBAN==WBANs(Stat)); + wBanSource = 3; + end + if isempty(wBanIDX)==1 + switch Stat + case 10 + [pointsCS{Stat+40,2},pointsCS{Stat+40,3}] = deg2utm(34.90000,-76.88300); + pointsCS{Stat+40,1} = 'CHERRY POINT'; + pointsCS{Stat+40,4} = 'CP'; + pointsCS{Stat+40,5} = WBANs(Stat); + case 15 + [pointsCS{Stat+40,2},pointsCS{Stat+40,3}] = deg2utm(36.8167,-76.0333 ); + pointsCS{Stat+40,1} = 'OCEANA NAS'; + pointsCS{Stat+40,4} = 'ONS'; + pointsCS{Stat+40,5} = WBANs(Stat); + end + else + wbanLat = wBanList{wBanSource}.LAT(wBanIDX); + wbanLon = wBanList{wBanSource}.LON(wBanIDX); + + [pointsCS{Stat+40,2},pointsCS{Stat+40,3}] = deg2utm(wbanLat,wbanLon); + + pointsCS{Stat+40,1} = wBanList{wBanSource}.LOCATION{wBanIDX}; + pointsCS{Stat+40,4} = wBanList{wBanSource}.CALL{wBanIDX}; + + pointsCS{Stat+40,5} = WBANs(Stat); + end +end +pointsCS(50,4) = {'CPT'}; + + +pointsCS{37,2} = 452000; +pointsCS{37,3} = 3959200; +pointsCS{37,1} = 'OI V2'; + +pointsCS{38,2} = 347000; +pointsCS{38,3} = 3840000; +pointsCS{38,1} = 'BF V2'; + +pointsCS{39,2} = 465400; +pointsCS{39,3} = 3883600; +pointsCS{39,1} = 'Hole'; + +pointsCS{40,2} = 390000; +pointsCS{40,3} = 3930000; +pointsCS{40,1} = 'Pond'; + +%% AHPS Stations + +locations = [36.060710, -75.699941;... + 35.595547,-75.470031;... + 35.325700,-75.511900;... + 35.018333,-76.314444;... + 35.024444,-76.691944; + 35.435180,-76.399800;... + 34.667700,-77.063400;... + 35.915000,-76.722778;... + 36.298611,-76.218611;... + 35.537222,-76.622778;... + 35.543333,-77.061944;... + 36.4073,-75.9949;... + 35.6841,-75.4838;... + 35.9081,-75.6683;... + 35.1153,-75.9873;... + 35.89639,-75.62222;... + 34.95630,-76.27830]; + +locNames = {'Albemarle Sound @ Kitty Hawk ',... + 'Pamlico Sound @ Rodanthe Ferry Terminal ',... + 'Pamlico Sound @ Avon ',... + 'Pamlico Sound @ Cedar Island ',... + 'Neuse River @ Oriental ',... + 'Pamlico Sound @ Bell Island Pier ',... + 'Bogue Sound @ Emerald Isle ',... + 'Roanoke River @ Westover ',... + 'Pasquotank River near Mariners Wharf Park @ Elizabeth City',... + 'Pungo River @ Belhaven',... + 'Pamlico River @ Washington',... + 'Maple @ Coinjock Creek',... + 'Rodanthe 6N @ New Inlet',... + 'Manteo - Roanoke Marshes',... + 'Coast Guard Station @ Ocracoke',... + 'Roanoke Sound',... + 'Lola'}; + +locNamesCODE = {... + 'KITN7',... %7 + 'ROFN7',... %15 + 'AVON7',... %1 + 'CTIN7',... %None + 'ORLN7',... %10 + 'BIPN7',... %2 + 'EMDN7',... %5 + 'WESN7',... %16 + 'EMWN7',... %6 + 'BLHN7',... %3 + 'PAMN7',... %11 + 'COJN7',... %4 + 'PEAN7',... %12 + 'RMLN7',... %14 + 'OCAN7',... %9 + 'RDFN7',... %13 + 'LOLN7'}; %8 + +locNamesID = {... + 'KH',... %7 + 'RF',... %15 + 'AV',... %1 + 'CI',... %None + 'NRO',... %10 + 'BI',... %2 + 'EI',... %5 + 'WO',... %16 + 'EC',... %6 + 'BH',... %3 + 'WH',... %11 + 'CJ',... %4 + 'NI',... %12 + 'RM',... %14 + 'OC',... %9 + 'RS',...%13 + 'LO'}; %8 + + %[1:7 9 11:16] +for i = 1:length(locations) + [pointsCS{i+59,2},pointsCS{i+59,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); + pointsCS{i+59,1} = locNames{i}; + pointsCS{i+59,5} = locNamesCODE{i}; + pointsCS{i+59,4} = locNamesID{i}; + +end +% M 65 +% Faves 74 62 61 60 67 69 70 +% Nope 72 66 71 73 68 +pointsCS{76,4} = 'LOA'; + + + %% AWOS Pts + asos = importASOS("asos.txt"); +opts = delimitedTextImportOptions("NumVariables", 7); +opts.DataLines = [2, Inf]; +opts.Delimiter = ","; +opts.VariableNames = ["stid", "station_name", "lat", "lon", "elev", "begints", "iem_network"]; +opts.VariableTypes = ["string", "string", "double", "double", "double", "string", "categorical"]; +opts.ExtraColumnsRule = "ignore"; +opts.EmptyLineRule = "read"; +opts = setvaropts(opts, ["stid", "station_name", "begints"], "WhitespaceRule", "preserve"); +opts = setvaropts(opts, ["stid", "station_name", "begints", "iem_network"], "EmptyFieldRule", "auto"); + +% Import the data +awosID = readtable("awosID.csv", opts); + clear opts + + stationsASOS = unique(asos.station); + +for Stat = 1:length(stationsASOS) +awosIDS = find(asos.station==stationsASOS(Stat),1); +awosIDX = find(awosID.stid==cellstr(stationsASOS(Stat)),1); + +pointsCS(Stat+76,5) = cellstr(stationsASOS(Stat)); +pointsCS(Stat+76,4) = cellstr(stationsASOS(Stat)); +[pointsCS{Stat+76,2},pointsCS{Stat+76,3}] = wgs2utm(asos.lat(awosIDS),asos.lon(awosIDS),18,'N'); +pointsCS(Stat+76,1) = {awosID.station_name{awosIDX}}; +% pointsCS{Stat+76,1} = pointsCS{Stat+76,1}(2:end-1); + +end + +pointsCS{77,4} = 'DCG'; +pointsCS{78,4} = 'ENG'; + +pointsCS{90,1} = 'Currituck Country Airport'; +pointsCS{90,4} = 'CCA'; + +pointsCS{88,1} = 'Cherry Point Marine Corps Air Station'; +pointsCS{88,4} = 'CPM'; + +pointsCS{87,4} = 'BOF'; +pointsCS{86,4} = 'PIN'; + +pointsCS{85,1} = 'Beaufort Airport'; +pointsCS{85,4} = 'BFA'; + +pointsCS{85,1} = 'Beaufort Airport'; +pointsCS{85,4} = 'BFA'; + +pointsCS{84,1} = 'Manteo Dare Airport'; +pointsCS{84,4} = 'MDA'; + +pointsCS{83,1} = 'Hatteras Airport'; +pointsCS{83,4} = 'HTA'; + +pointsCS{82,1} = 'First flight Airport'; +pointsCS{82,4} = 'FFA'; + +pointsCS{81,1} = 'New Berm Airport'; +pointsCS{81,4} = 'NBA'; + +pointsCS{80,1} = 'Edenton Airport'; +pointsCS{80,4} = 'EDA'; + +%% Add more details +CSs_F = [6 7 9 22 8 11 18 10 19 20 25 24 23 21]; +CSs_F = [6 7 9 22 8 11 18 10 19 20 25 24 23 21 74 60 61 67 69 70 65]; + +CSsH_F = [12 13 14:16 26 18 19 30 31]; + +CSU = [27 17 18 19]; +CSM = [6 9 12 16 35 42 45 46 50 53 59]; +CSM = [6 9 12 16 35 42 45 46 50 53 59 64 68 69 74 76 77:91]; +CSM = [6 9 12 16 35 45 46 50 53 59 64 74 76 77 78 82:87 90]; +for i = 1:length(pointsCS) + if ismember(i,CSs_F) + pointsCS{i,6} = 'Water Level'; + end + + if ismember(i,CSsH_F) + pointsCS{i,7} = 'Wave'; + end + + if ismember(i,CSU) + pointsCS{i,8} = 'Current'; + end + + if ismember(i,CSM) + pointsCS{i,9} = 'Wind'; + end + +end + + pointsCS([6 13 17 26 27],10) = {'USACE'}; + pointsCS([10 11 20:22 33],10) = {'USGS'}; + pointsCS([23:25],10) = {'USACE'}; %Conery, Ian + + pointsCS([41:59 32],10) = {'NWS'}; %Conery, Ian + + pointsCS([30:31],10) = {'CDIP/ USACE'}; + pointsCS([16],10) = {'NDBC'}; + pointsCS([12],10) = {'NDBC/ USACE'}; + pointsCS([14:15],10) = {'NDBC/ UNC'}; + pointsCS([18:19],10) = {'UNC'}; + + pointsCS([9],10) = {'NOAA/ Duke'}; + pointsCS([8],10) = {'NOAA/ USCG'}; + pointsCS([7],10) = {'NOAA'}; + + pointsCS([34],10) = {'NDBC/ NOAA'}; + pointsCS([35],10) = {'NDBC'}; + pointsCS([36],10) = {'NDBC/ NOAA'}; + + pointsCS([60:76],10) = {'ISU/ HADS'}; + pointsCS([77:91],10) = {'ISU/ ASOS'}; + + +% pointsCS([12],7) = {'Wave (3 m Buoy)'}; + pointsCS([12],11) = {'47 m'}; +% pointsCS([14],7) = {'Wave (Waverider Buoy)'}; + pointsCS([14],11) = {'21 m'}; +% pointsCS([15],7) = {'Wave (Waverider Buoy)'}; + pointsCS([15],11) = {'18 m'}; +% pointsCS([16],7) = {'Wave (3 m Buoy)'}; + pointsCS([16],11) = {'59 m'}; +% pointsCS([30],7) = {'Wave (Datawell Buoy)'}; + pointsCS([30],11) = {'30 m'}; +% pointsCS([31],7) = {'Wave (Datawell Buoy)'}; + pointsCS([31],11) = {'18 m'}; +% pointsCS([26],7) = {'Wave (Waverider Buoy)'}; + pointsCS([26],11) = {'17 m'}; + + + + pointsCS([7],1) = {'Oregon Inlet Marina'}; + pointsCS([11],1) = {'Albemarle Sound @ Leonards Point'}; + pointsCS([8],1) = {'Hatteras Coast Guard'}; + pointsCS([9],1) = {'Beaufort Duke Marine Lab'}; + pointsCS([7],1) = {'Oregon Inlet Marina'}; + + pointsCS([20],1) = {'Currituck Sound @ Point Harbour'}; + pointsCS([21],1) = {'Roanoke Sound @ Point Island'}; + pointsCS([22],1) = {'Bogue Sound @ Atlantic Beach'}; + + pointsCS([23],1) = {'Villa Dunes Dock'}; + pointsCS([24],1) = {'Kill Devil Hills @ Hayman Street'}; + pointsCS([25],1) = {'Jean Guite Creek Outlet'}; + + pointsCS([27],1) = {'FRF AWAC'}; + pointsCS([27],11) = {'6 m'}; + + pointsCS([17],1) = {'FRF AWAC'}; + pointsCS([17],11) = {'11 m'}; +% pointsCS([17],8) = {'Current (Nortek AWAC)'}; + + pointsCS([14],1) = {'Nags Head Buoy'}; + pointsCS([15],1) = {'Oregon Inlet Buoy'}; + pointsCS([16],1) = {'Diamond Shoals Buoy'}; + pointsCS([30],1) = {'Oslow Bay Buoy'}; + pointsCS([31],1) = {'Cape Henry Buoy'}; + + pointsCS([18],1) = {'Currituck Sound North'}; + pointsCS([18],11) = {'2.3 m'}; +% pointsCS([18],7) = {'Wave (Nortek AWAC)'}; +% pointsCS([18],8) = {'Current (Nortek Aquadopp)'}; + + pointsCS([19],1) = {'Currituck Sound South'}; + pointsCS([19],11) = {'2.6 m'}; +% pointsCS([19],7) = {'Wave (Nortek AWAC)'}; +% pointsCS([19],8) = {'Current (Nortek Aquadopp)'}; + +% pointsCS([6],8) = {'Current (Nortek AWAC)'}; + pointsCS([6],11) = {'6 m'}; + pointsCS([6],1) = {'FRF Pier'}; + + pointsCS([26],1) = {'FRF 17 m Buoy'}; + pointsCS([13],1) = {'FRF 26 m Buoy'}; + pointsCS([13],11) = {'26 m'}; + + + pointsCS([42],1) = {'Michael J Smith Field'}; + pointsCS([45],1) = {'Edenton Northeast Airport'}; + pointsCS([46],1) = {'Elizabth City Coast Guard'}; + pointsCS([50],1) = {'Cherry Point Marine Corps Air Station'}; + pointsCS([50],4) = {'CPM'}; + + pointsCS([53],1) = {'Coasltal Carolina Airport'}; + pointsCS([59],1) = {'Warren Field Airport'}; + + +%% Add Elevation +pointsCS(41,12) = {20.85} ; +pointsCS(45,12) = {6.10} ; +pointsCS(46,12) = {7.5} ; +pointsCS(50,12) = {8.80} ; +pointsCS(50,12) = {9.90}; +pointsCS(53,12) = {6.10} ; +pointsCS(59,12) = {11.80}; + +pointsCS(64,12) = {1.40}; +pointsCS(74,12) = {2}; + +pointsCS(76,12) = {3.74}; +pointsCS(77,12) = {0.51}; +pointsCS(78,12) = {0.6}; + +pointsCS(82,12) = {4}; +pointsCS(83,12) = {3}; +pointsCS(84,12) = {4}; +pointsCS(85,12) = {3}; +pointsCS(86,12) = {5}; +pointsCS(87,12) = {3.16}; +pointsCS(90,12) = {5.5}; + +pointsCS(35,12) = {4.6}; + +pointsCS(9,12) = {0}; +pointsCS(12,12) = {0}; +pointsCS(16,12) = {0}; + +pointsCS(6,12) = {11.4}; +%% Adjust out of dry zone +pointsCS{23,2} = pointsCS{23,2} - 100; +pointsCS{32,2} = pointsCS{32,2} - 1000; +pointsCS{51,2} = pointsCS{51,2} - 1000; +pointsCS{62,2} = pointsCS{62,2} - 1000; +pointsCS{43,2} = pointsCS{43,2} - 3000; +pointsCS{72,3} = pointsCS{72,3} - 10000; + +pointsCS{60,2} = pointsCS{60,2} - 500; + +pointsCS{61,2} = pointsCS{61,2} - 900; +pointsCS{61,3} = pointsCS{61,3} - 250; + +pointsCS{92,2} = pointsCS{60,2} + 350; +pointsCS{92,3} = pointsCS{60,3} - 900; +pointsCS{92,1} = [pointsCS{60,1} '_Vsouth']; +pointsCS(92,4:12) = pointsCS(60,4:12); + +pointsCS{35,3} = pointsCS{35,3} - 2000; +pointsCS{82,2} = pointsCS{82,2} - 1000; +pointsCS{83,3} = pointsCS{83,3} - 1000; + +pointsCS{93,2} = pointsCS{22,2} + 2750; +pointsCS{93,3} = pointsCS{22,3} + 100; +pointsCS{93,1} = [pointsCS{22,1} '_VEast']; +pointsCS(93,4:12) = pointsCS(22,4:12); + +pointsCS{94,2} = pointsCS{22,2} - 550; +pointsCS{94,3} = pointsCS{22,3} + 250; +pointsCS{94,1} = [pointsCS{22,1} '_VWest']; +pointsCS(94,4:12) = pointsCS(22,4:12); + +pointsCS{95,2} = 350000; +pointsCS{95,3} = 3977900; +pointsCS{95,1} = [pointsCS{67,1} '_VEast']; +pointsCS(95,4:12) = pointsCS(67,4:12); + +pointsCS{96,2} = 409700; +pointsCS{96,3} = 3883600; +pointsCS{96,1} = [pointsCS{74,1} '_VSouth']; +pointsCS(96,4:12) = pointsCS(74,4:12); + +pointsCS{97,2} = 438200; +pointsCS{97,3} = 3896000; +pointsCS{97,1} = [pointsCS{24,1} '_VSouth']; +pointsCS(97,4:12) = pointsCS(24,4:12); + +pointsCS(38,1:12) = pointsCS(9,1:12); + +%% DUNEX Points + +% Setup the Import Options and import the data +opts = delimitedTextImportOptions("NumVariables", 2); + +% Specify range and delimiter +opts.DataLines = [1, Inf]; +opts.Delimiter = ","; + +% Specify column names and types +opts.VariableNames = ["VarName1", "VarName2"]; +opts.VariableTypes = ["double", "double"]; + +% Specify file level properties +opts.ExtraColumnsRule = "ignore"; +opts.EmptyLineRule = "read"; + +% Import the data +CoordinatesBC = readtable("D:\Alexander\DUNEX\Coordinates_BC.txt", opts); + +% Convert to output type +CoordinatesBC = table2array(CoordinatesBC); + +% Clear temporary variables +clear opts + +for i = 1:length(CoordinatesBC) + pointsCS{i+97,1} = ['DUNEX_' num2str(i)]; + pointsCS{i+97,4} = ['D_' num2str(i)]; + [pointsCS{i+97,2},pointsCS{i+97,3}] = wgs2utm(CoordinatesBC(i,2),CoordinatesBC(i,1),18,'N'); +end + +%% Fix two bound pts + +[pointsCS{114,3}] = pointsCS{114,3}+400; + +[pointsCS{113,2}] = pointsCS{113,2}-500; +% [pointsCS{113,3}] = pointsCS{113,3}+500; + + + +%% DUNEX Points +clear locations locNames locNamesID + +locations = [36.400701, -75.823317;... + 36.392170, -75.824346;... + 35.779135, -75.532475;... + 35.746968, -75.496067;... + 35.743821, -75.500800;... + 35.621202, -75.456779;... + 35.620127, -75.464034;... +]; + +locNames = {'Currituck Banks Estuarine Reserve',... + 'Currituck Banks Estuarine Reserve Nearshore',... + 'Mid Oregon Inlet',... + 'South Oregon Inlet',... + 'South Oregon Inlet Nearshore',... + 'Round Hammock Bay',... + 'Round Hammock Bay Nearshore'}; + +locNamesID = {... + 'CB',... + 'CBN',... + 'MI',... + 'SI',... + 'SIN',... + 'HB',... + 'HBN'}; %8 + + +for i = 1:length(locations) + [pointsCS{i+129,2},pointsCS{i+129,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); + pointsCS{i+129,1} = locNames{i}; + pointsCS{i+129,4} = locNamesID{i}; + +end + +%% Add DUNEX_R +R_PTS = readmatrix("D:\Alexander\DUNEX_R\R. Housego DUNEX groundwater modeling locations_AJMR.xlsx",'Sheet','Combined'); + +for i = 1:size(R_PTS,1) + pointsCS{i+136,1} = ['DUNEX_R_' num2str(i)]; + pointsCS{i+136,4} = ['DR_' num2str(i)]; + [pointsCS{i+136,2},pointsCS{i+136,3}] = wgs2utm(R_PTS(i,2),R_PTS(i,1),18,'N'); +end + +%% Add Mulligan PTS +M_PTS = readcell("D:\Alexander\MulliganPTS_V2.xlsx"); + +for i = 1:size(M_PTS,1) + pointsCS{i+160,1} = M_PTS{i,1}; + pointsCS{i+160,4} = M_PTS{i,4}; + [pointsCS{i+160,2},pointsCS{i+160,3}] = wgs2utm(M_PTS{i,2},M_PTS{i,3},18,'N'); +end + + pointsCS(169,[2 3]) = pointsCS(61,[2 3]); + pointsCS(164,[2 3]) = pointsCS(115,[2 3]); + +for i = 1:size(M_PTS,1) + [webPoints(i,1),webPoints(i,2)] = utm2deg(pointsCS{i+160,2},pointsCS{i+160,3},'18 N'); +end +%% Add Chris PTS +C_PTS = readcell("D:\Alexander\ChrisPTS.xlsx"); + +for i = 1:size(C_PTS,1) + pointsCS{i+172,1} = ['Cpt_' C_PTS{i,1}]; + pointsCS{i+172,4} = C_PTS{i,1}; + [pointsCS{i+172,2},pointsCS{i+172,3}] = wgs2utm(C_PTS{i,2},C_PTS{i,3},18,'N'); +end + + +%% Add Hohonu Pts +locations = [ + 36.22332, -75.772544;... + 36.13097, -75.745303;... + 36.01498, -75.687458;... + 35.910474, -75.594299;... + 35.898637, -75.615641;... + 35.869354, -75.663404;... +]; + +locShiftUTM = [ + -1500, -1500;... + -200, 0;... + 0, -1500;... + 400, 100;... + 500, -100;... + -100, 0;... +]; + +locNames = {'Duck Dare County NC',... + 'Southern Shores NC',... + 'Collington Creek Inn Dock Kill Devil Hills',... + 'Jennettes Pier, Nags Head',... + 'Hwy 64 Little Bridge',... + 'Coastal Studies Institute Wanchese NC'}; + +locNamesID = {... + 'HHD',... + 'HHS',... + 'HHC',... + 'HHJ',... + 'HHH',... + 'HHW'}; + +locIDs = [ + 10015; %Duck, Dare County, NC + 10020; %Southern Shores, NC + 10011; %Collington Creek Inn Dock, Kill Devil Hills + 10012; %Jennette's Pier, Nags Head + 10009; %Hwy 64, Little Bridge + 10010]; %Coastal Studies Institute, Wanchese, NC + + +for i = 1:length(locations) + [pointsCS{i+180,2},pointsCS{i+180,3}] = wgs2utm(locations(i,1),locations(i,2),18,'N'); + pointsCS{i+180,2} = pointsCS{i+180,2} + locShiftUTM(i,1); + pointsCS{i+180,3} = pointsCS{i+180,3} + locShiftUTM(i,2); + pointsCS{i+180,1} = locNames{i}; + pointsCS{i+180,4} = locNamesID{i}; + pointsCS{i+180,5} = locIDs(1); +end + + + + +%% Check in pol +pol = readPol('D:\Alexander\DUNEX\NCShoreALL.pol'); +clear inPol + +for PolCount = 1:length(pol) +for CS = 1:length(pointsCS) + inPol(PolCount,CS) = inpolygon(pointsCS{CS,2},pointsCS{CS,3},pol{PolCount}(:,1),pol{PolCount}(:,2)); + +end +end +find(max(inPol)) + +%% Save +save('D:\DUNEX_RT\Operation\DUNEX_Sept7.mat','pointsCS','-v7.3') +%% Make Obs Files +flowGrid = load('D:\Alexander\DUNEX_R\Cone7W_100.mat'); +% flowGrid = load('D:\Alexander\RT_25m\C7_25.mat'); + +% flowGrid = load('D:\NCBathy\Cone7\C9S_50.mat') +fileID=fopen('D:\DUNEX_RT\Operation\Sept7.obs','w'); +% fileID=fopen('C9_50MET_V5.obs','w'); + +for line=1:length(pointsCS) + + obsIDX = NearestValue([pointsCS{line,2:3}],flowGrid.data.X,flowGrid.data.Y); + if obsIDX(1) == 1 + obsIDX(1) = 2; + end + if obsIDX(2) == 1 + obsIDX(2) = 2; + end + if line ==71 + fprintf(fileID,[num2str(line) '_' pointsCS{line,1}(1:5) ' %d %d\n'],obsIDX(1),obsIDX(2)); + elseif length(pointsCS{line,1})>10 + fprintf(fileID,[num2str(line) '_' pointsCS{line,1}(1:10) ' %d %d\n'],obsIDX(1),obsIDX(2)); + else + fprintf(fileID,[num2str(line) '_' pointsCS{line,1}(1:end) ' %d %d\n'],obsIDX(1),obsIDX(2)); + end +end +fclose(fileID); + +fileID=fopen('D:\DUNEX_RT\Operation\Sept7.loc','w'); +clear waveObsPts +% for i = 1:40 +for i = 1:length(pointsCS) + obsIDX = NearestValue([pointsCS{i,2:3}],flowGrid.data.X,flowGrid.data.Y); + if obsIDX(1) == 1 + obsIDX(1) = 2; + end + if obsIDX(2) == 1 + obsIDX(2) = 2; + end + + waveObsPts(i,:) = [flowGrid.data.X(obsIDX(1),obsIDX(2)),flowGrid.data.Y(obsIDX(1),obsIDX(2))]; + fprintf(fileID,' %1.7f %1.7f\n',[waveObsPts(i,1),waveObsPts(i,2)])'; + +end + +fclose(fileID) +%end + + diff --git a/naninterp.m b/naninterp.m new file mode 100644 index 0000000..1f6e65c --- /dev/null +++ b/naninterp.m @@ -0,0 +1,5 @@ +function X = naninterp(X) +% Interpolate over NaNs +% See INTERP1 for more info +X(isnan(X)) = interp1(find(~isnan(X)), X(~isnan(X)), find(isnan(X)),'pchip'); +return \ No newline at end of file diff --git a/readASOS.m b/readASOS.m new file mode 100644 index 0000000..bf78cb4 --- /dev/null +++ b/readASOS.m @@ -0,0 +1,125 @@ +function asosstations = readASOS(filename, startRow, endRow) +%IMPORTFILE Import numeric data from a text file as a matrix. +% ASOSSTATIONS = IMPORTFILE(FILENAME) Reads data from text file FILENAME +% for the default selection. +% +% ASOSSTATIONS = IMPORTFILE(FILENAME, STARTROW, ENDROW) Reads data from +% rows STARTROW through ENDROW of text file FILENAME. +% +% Example: +% asosstations = importfile('asos-stations.txt', 3, 920); +% +% See also TEXTSCAN. + +% Auto-generated by MATLAB on 2019/11/25 13:24:05 + +%% Initialize variables. +if nargin<=2 + startRow = 3; + endRow = inf; +end + +%% Read columns of data as text: +% For more information, see the TEXTSCAN documentation. +formatSpec = '%9s%5s%7s%6s%31s%31s%21s%2s%32s%10s%11s%7s%6s%59s%12s%s%[^\n\r]'; + +%% Open the text file. +fileID = fopen(filename,'r'); + +%% Read columns of data according to the format. +% This call is based on the structure of the file used to generate this +% code. If an error occurs for a different file, try regenerating the code +% from the Import Tool. +dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines', startRow(1)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); +for block=2:length(startRow) + frewind(fileID); + dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines', startRow(block)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + for col=1:length(dataArray) + dataArray{col} = [dataArray{col};dataArrayBlock{col}]; + end +end + +%% Remove white space around all cell columns. +dataArray{4} = strtrim(dataArray{4}); +dataArray{5} = strtrim(dataArray{5}); +dataArray{6} = strtrim(dataArray{6}); +dataArray{14} = strtrim(dataArray{14}); + +%% Close the text file. +fclose(fileID); + +%% Convert the contents of columns containing numeric text to numbers. +% Replace non-numeric text with NaN. +raw = repmat({''},length(dataArray{1}),length(dataArray)-1); +for col=1:length(dataArray)-1 + raw(1:length(dataArray{col}),col) = mat2cell(dataArray{col}, ones(length(dataArray{col}), 1)); +end +numericData = NaN(size(dataArray{1},1),size(dataArray,2)); + +for col=[1,2,3,10,11,13,15] + % Converts text in the input cell array to numbers. Replaced non-numeric + % text with NaN. + rawData = dataArray{col}; + for row=1:size(rawData, 1) + % Create a regular expression to detect and remove non-numeric prefixes and + % suffixes. + regexstr = '(?.*?)(?([-]*(\d+[\,]*)+[\.]{0,1}\d*[eEdD]{0,1}[-+]*\d*[i]{0,1})|([-]*(\d+[\,]*)*[\.]{1,1}\d+[eEdD]{0,1}[-+]*\d*[i]{0,1}))(?.*)'; + try + result = regexp(rawData(row), regexstr, 'names'); + numbers = result.numbers; + + % Detected commas in non-thousand locations. + invalidThousandsSeparator = false; + if numbers.contains(',') + thousandsRegExp = '^[-/+]*\d+?(\,\d{3})*\.{0,1}\d*$'; + if isempty(regexp(numbers, thousandsRegExp, 'once')) + numbers = NaN; + invalidThousandsSeparator = true; + end + end + % Convert numeric text to numbers. + if ~invalidThousandsSeparator + numbers = textscan(char(strrep(numbers, ',', '')), '%f'); + numericData(row, col) = numbers{1}; + raw{row, col} = numbers{1}; + end + catch + raw{row, col} = rawData{row}; + end + end +end + + +%% Split data into numeric and string columns. +rawNumericColumns = raw(:, [1,2,3,10,11,13,15]); +rawStringColumns = string(raw(:, [4,5,6,7,8,9,12,14,16])); + + +%% Replace non-numeric cells with NaN +R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),rawNumericColumns); % Find non-numeric cells +rawNumericColumns(R) = {NaN}; % Replace non-numeric cells + +%% Make sure any text containing is properly converted to an categorical +for catIdx = [4,5,6,7,9] + idx = (rawStringColumns(:, catIdx) == ""); + rawStringColumns(idx, catIdx) = ""; +end + +%% Create output variable +asosstations = table; +asosstations.NCDCID = cell2mat(rawNumericColumns(:, 1)); +asosstations.WBAN = cell2mat(rawNumericColumns(:, 2)); +asosstations.COOPID = cell2mat(rawNumericColumns(:, 3)); +asosstations.CALL = rawStringColumns(:, 1); +asosstations.LOCATION = rawStringColumns(:, 2); +asosstations.ALT_NAME = rawStringColumns(:, 3); +asosstations.COUNTRY = categorical(rawStringColumns(:, 4)); +asosstations.ST = categorical(rawStringColumns(:, 5)); +asosstations.COUNTY = categorical(rawStringColumns(:, 6)); +asosstations.LAT = cell2mat(rawNumericColumns(:, 4)); +asosstations.LON = cell2mat(rawNumericColumns(:, 5)); +asosstations.ELEV = categorical(rawStringColumns(:, 7)); +asosstations.UTC = cell2mat(rawNumericColumns(:, 6)); +asosstations.STNTYPEBEGDT = rawStringColumns(:, 8); +asosstations.GHCND = cell2mat(rawNumericColumns(:, 7)); +asosstations.VarName16 = categorical(rawStringColumns(:, 9)); diff --git a/readAWOS.m b/readAWOS.m new file mode 100644 index 0000000..615da20 --- /dev/null +++ b/readAWOS.m @@ -0,0 +1,121 @@ +function awosstations = readAWOS(filename, startRow, endRow) +%IMPORTFILE Import numeric data from a text file as a matrix. +% AWOSSTATIONS = IMPORTFILE(FILENAME) Reads data from text file FILENAME +% for the default selection. +% +% AWOSSTATIONS = IMPORTFILE(FILENAME, STARTROW, ENDROW) Reads data from +% rows STARTROW through ENDROW of text file FILENAME. +% +% Example: +% awosstations = importfile('awos-stations.txt', 3, 1132); +% +% See also TEXTSCAN. + +% Auto-generated by MATLAB on 2019/11/25 13:21:35 + +%% Initialize variables. +if nargin<=2 + startRow = 3; + endRow = inf; +end + +%% Read columns of data as text: +% For more information, see the TEXTSCAN documentation. +formatSpec = '%8s%6s%8s%3s%33s%21s%3s%31s%10s%11s%7s%6s%s%[^\n\r]'; + +%% Open the text file. +fileID = fopen(filename,'r'); + +%% Read columns of data according to the format. +% This call is based on the structure of the file used to generate this +% code. If an error occurs for a different file, try regenerating the code +% from the Import Tool. +dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines', startRow(1)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); +for block=2:length(startRow) + frewind(fileID); + dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines', startRow(block)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + for col=1:length(dataArray) + dataArray{col} = [dataArray{col};dataArrayBlock{col}]; + end +end + +%% Remove white space around all cell columns. +dataArray{4} = strtrim(dataArray{4}); +dataArray{5} = strtrim(dataArray{5}); + +%% Close the text file. +fclose(fileID); + +%% Convert the contents of columns containing numeric text to numbers. +% Replace non-numeric text with NaN. +raw = repmat({''},length(dataArray{1}),length(dataArray)-1); +for col=1:length(dataArray)-1 + raw(1:length(dataArray{col}),col) = mat2cell(dataArray{col}, ones(length(dataArray{col}), 1)); +end +numericData = NaN(size(dataArray{1},1),size(dataArray,2)); + +for col=[1,2,9,10,12] + % Converts text in the input cell array to numbers. Replaced non-numeric + % text with NaN. + rawData = dataArray{col}; + for row=1:size(rawData, 1) + % Create a regular expression to detect and remove non-numeric prefixes and + % suffixes. + regexstr = '(?.*?)(?([-]*(\d+[\,]*)+[\.]{0,1}\d*[eEdD]{0,1}[-+]*\d*[i]{0,1})|([-]*(\d+[\,]*)*[\.]{1,1}\d+[eEdD]{0,1}[-+]*\d*[i]{0,1}))(?.*)'; + try + result = regexp(rawData(row), regexstr, 'names'); + numbers = result.numbers; + + % Detected commas in non-thousand locations. + invalidThousandsSeparator = false; + if numbers.contains(',') + thousandsRegExp = '^[-/+]*\d+?(\,\d{3})*\.{0,1}\d*$'; + if isempty(regexp(numbers, thousandsRegExp, 'once')) + numbers = NaN; + invalidThousandsSeparator = true; + end + end + % Convert numeric text to numbers. + if ~invalidThousandsSeparator + numbers = textscan(char(strrep(numbers, ',', '')), '%f'); + numericData(row, col) = numbers{1}; + raw{row, col} = numbers{1}; + end + catch + raw{row, col} = rawData{row}; + end + end +end + + +%% Split data into numeric and string columns. +rawNumericColumns = raw(:, [1,2,9,10,12]); +rawStringColumns = string(raw(:, [3,4,5,6,7,8,11,13])); + + +%% Replace non-numeric cells with NaN +R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),rawNumericColumns); % Find non-numeric cells +rawNumericColumns(R) = {NaN}; % Replace non-numeric cells + +%% Make sure any text containing is properly converted to an categorical +for catIdx = [1,4,5,6,7,8] + idx = (rawStringColumns(:, catIdx) == ""); + rawStringColumns(idx, catIdx) = ""; +end + +%% Create output variable +awosstations = table; +awosstations.NCDCID = cell2mat(rawNumericColumns(:, 1)); +awosstations.WBAN = cell2mat(rawNumericColumns(:, 2)); +awosstations.COOPID = categorical(rawStringColumns(:, 1)); +awosstations.CALL = rawStringColumns(:, 2); +awosstations.LOCATION = rawStringColumns(:, 3); +awosstations.COUNTRY = categorical(rawStringColumns(:, 4)); +awosstations.ST = categorical(rawStringColumns(:, 5)); +awosstations.COUNTY = categorical(rawStringColumns(:, 6)); +awosstations.LAT = cell2mat(rawNumericColumns(:, 3)); +awosstations.LON = cell2mat(rawNumericColumns(:, 4)); +awosstations.ELEV = categorical(rawStringColumns(:, 7)); +awosstations.UTC = cell2mat(rawNumericColumns(:, 5)); +awosstations.STNTYPE = categorical(rawStringColumns(:, 8)); + diff --git a/readPol.m b/readPol.m new file mode 100644 index 0000000..5128251 --- /dev/null +++ b/readPol.m @@ -0,0 +1,52 @@ +function [points] = readPol(fname) +%% reads a Delft3D polygon into a cell array + +opts = delimitedTextImportOptions("NumVariables", 5); + +% Specify range and delimiter +opts.DataLines = [9, Inf]; +opts.Delimiter = " "; + +% Specify column names and types +opts.VariableNames = ["VarName1", "Coordinate", "Var3", "Var4", "Var5"]; +opts.SelectedVariableNames = ["VarName1", "Coordinate"]; +opts.VariableTypes = ["double", "double", "string", "string", "string"]; + +% Specify file level properties +opts.ExtraColumnsRule = "ignore"; +opts.EmptyLineRule = "read"; +opts.ConsecutiveDelimitersRule = "join"; +opts.LeadingDelimitersRule = "ignore"; + +% Specify variable properties +opts = setvaropts(opts, ["Var3", "Var4", "Var5"], "WhitespaceRule", "preserve"); +opts = setvaropts(opts, ["Var3", "Var4", "Var5"], "EmptyFieldRule", "auto"); + +% Import the data +NCShoreALL = readtable(fname, opts); + +%% Convert to output type +NCShoreALL = table2array(NCShoreALL); + +%% Clear temporary variables +clear opts + +SegCount = 1; +PtsCount = 1; +for Line = 2:length(NCShoreALL) +if isnan(NCShoreALL(Line,1))==1 +elseif Line>3 && isnan(NCShoreALL(Line-1,1))==1 + continue +elseif Line>3 && isnan(NCShoreALL(Line-2,1))==1 + PtsCount = 1; + SegCount = SegCount+1; + + continue +else + points{SegCount}(PtsCount,:) = NCShoreALL(Line,:); + PtsCount = PtsCount+1; +end +end + + +end diff --git a/readWBAN.m b/readWBAN.m new file mode 100644 index 0000000..f56f886 --- /dev/null +++ b/readWBAN.m @@ -0,0 +1,132 @@ +function lcdstations = importfile(filename, startRow, endRow) +%IMPORTFILE Import numeric data from a text file as a matrix. +% LCDSTATIONS = IMPORTFILE(FILENAME) Reads data from text file FILENAME +% for the default selection. +% +% LCDSTATIONS = IMPORTFILE(FILENAME, STARTROW, ENDROW) Reads data from +% rows STARTROW through ENDROW of text file FILENAME. +% +% Example: +% lcdstations = importfile('lcd-stations.txt', 1, 272); +% +% See also TEXTSCAN. + +% Auto-generated by MATLAB on 2019/11/25 12:59:26 + +%% Initialize variables. +if nargin<=2 + startRow = 1; + endRow = inf; +end + +%% Read columns of data as text: +% For more information, see the TEXTSCAN documentation. +formatSpec = '%5s%5s%11s%20s%11s%6s%4s%12s%12s%52s%61s%26s%2s%3s%9s%11s%11s%9s%4s%s%[^\n\r]'; + +%% Open the text file. +fileID = fopen(filename,'r'); + +%% Read columns of data according to the format. +% This call is based on the structure of the file used to generate this +% code. If an error occurs for a different file, try regenerating the code +% from the Import Tool. +dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines', startRow(1)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); +for block=2:length(startRow) + frewind(fileID); + dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', '', 'WhiteSpace', '', 'TextType', 'string', 'HeaderLines', startRow(block)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n'); + for col=1:length(dataArray) + dataArray{col} = [dataArray{col};dataArrayBlock{col}]; + end +end + +%% Remove white space around all cell columns. +dataArray{2} = strtrim(dataArray{2}); +dataArray{4} = strtrim(dataArray{4}); +dataArray{5} = strtrim(dataArray{5}); +dataArray{7} = strtrim(dataArray{7}); +dataArray{10} = strtrim(dataArray{10}); +dataArray{11} = strtrim(dataArray{11}); + +%% Close the text file. +fclose(fileID); + +%% Convert the contents of columns containing numeric text to numbers. +% Replace non-numeric text with NaN. +raw = repmat({''},length(dataArray{1}),length(dataArray)-1); +for col=1:length(dataArray)-1 + raw(1:length(dataArray{col}),col) = mat2cell(dataArray{col}, ones(length(dataArray{col}), 1)); +end +numericData = NaN(size(dataArray{1},1),size(dataArray,2)); + +for col=[1,6,8,9,16,17,18,20] + % Converts text in the input cell array to numbers. Replaced non-numeric + % text with NaN. + rawData = dataArray{col}; + for row=1:size(rawData, 1) + % Create a regular expression to detect and remove non-numeric prefixes and + % suffixes. + regexstr = '(?.*?)(?([-]*(\d+[\,]*)+[\.]{0,1}\d*[eEdD]{0,1}[-+]*\d*[i]{0,1})|([-]*(\d+[\,]*)*[\.]{1,1}\d+[eEdD]{0,1}[-+]*\d*[i]{0,1}))(?.*)'; + try + result = regexp(rawData(row), regexstr, 'names'); + numbers = result.numbers; + + % Detected commas in non-thousand locations. + invalidThousandsSeparator = false; + if numbers.contains(',') + thousandsRegExp = '^[-/+]*\d+?(\,\d{3})*\.{0,1}\d*$'; + if isempty(regexp(numbers, thousandsRegExp, 'once')) + numbers = NaN; + invalidThousandsSeparator = true; + end + end + % Convert numeric text to numbers. + if ~invalidThousandsSeparator + numbers = textscan(char(strrep(numbers, ',', '')), '%f'); + numericData(row, col) = numbers{1}; + raw{row, col} = numbers{1}; + end + catch + raw{row, col} = rawData{row}; + end + end +end + + +%% Split data into numeric and string columns. +rawNumericColumns = raw(:, [1,6,8,9,16,17,18,20]); +rawStringColumns = string(raw(:, [2,3,4,5,7,10,11,12,13,14,15,19])); + + +%% Replace non-numeric cells with NaN +R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),rawNumericColumns); % Find non-numeric cells +rawNumericColumns(R) = {NaN}; % Replace non-numeric cells + +%% Make sure any text containing is properly converted to an categorical +for catIdx = [2,8,9,10,11,12] + idx = (rawStringColumns(:, catIdx) == ""); + rawStringColumns(idx, catIdx) = ""; +end + +%% Create output variable +lcdstations = table; +lcdstations.WBAN = cell2mat(rawNumericColumns(:, 1)); +lcdstations.TRANSMITTAL_ID = rawStringColumns(:, 1); +lcdstations.TRANSMITTAL_ID_TYPE = categorical(rawStringColumns(:, 2)); +lcdstations.CALL = rawStringColumns(:, 3); +lcdstations.FAA_ID = rawStringColumns(:, 4); +lcdstations.WMO_ID = cell2mat(rawNumericColumns(:, 2)); +lcdstations.NWSLI_ID = rawStringColumns(:, 5); +lcdstations.COOP_ID = cell2mat(rawNumericColumns(:, 3)); +lcdstations.GHCND_ID = cell2mat(rawNumericColumns(:, 4)); +lcdstations.CITY = rawStringColumns(:, 6); +lcdstations.LOCATION = rawStringColumns(:, 7); +lcdstations.LOCATION_AREA = categorical(rawStringColumns(:, 8)); +lcdstations.STATE_PROV = categorical(rawStringColumns(:, 9)); +lcdstations.FIPS_COUNTRY_CODE = categorical(rawStringColumns(:, 10)); +lcdstations.NWS_REGION = categorical(rawStringColumns(:, 11)); +lcdstations.LAT = cell2mat(rawNumericColumns(:, 5)); +lcdstations.LON = cell2mat(rawNumericColumns(:, 6)); +lcdstations.ELEV = cell2mat(rawNumericColumns(:, 7)); +lcdstations.ELEV_GROUND_UNIT = categorical(rawStringColumns(:, 12)); +lcdstations.UTC = cell2mat(rawNumericColumns(:, 8)); + diff --git a/read_grads.m b/read_grads.m new file mode 100644 index 0000000..882f3d3 --- /dev/null +++ b/read_grads.m @@ -0,0 +1,1304 @@ +function [data,header]=read_grads(file_name,var_name,varargin) +% [var,header]=read_grads(file_name,var_name) is a function to read +% in binary files using their GrADS descriptor header. +% If var_name is 'all' or non-existent, all variables are read and +% sent to the base-workspace. +% Please check before-hand the data-type (big/little endian), as well +% as the data precision (single/double...), and adjust if necessary +% the header at the beginning of read_grads.m. +% Optionally, you can improve the indications from the header file in +% the sub-function grads_name (hereafter). +% +% Kristof Sturm, sturm@dkrz.de or sturm@lgge.obs.ujf-grenoble.fr, 29.10.02 + +global l_quiet + +n=strmatch('quiet',{varargin{1:2:end}}); +if isempty(n) + l_quiet=0; +else + switch lower(varargin{2*(n-1)+2}) + case {1,'yes'} + l_quiet=1; + case {0,'no'} + l_quiet=0; + end +end + +header=struct('FILENAME',file_name,... + 'VARSIZE',{[]},... + 'NVAR',0,... + 'DATANAME','-',... + 'FID',{[]},... + 'BINTYPE','-',... + 'BINPRECISION','float32',... + 'DSET','-',... + 'DTYPE',1,... + 'INDEX','-',... + 'TITLE','-',... + 'UNDEF',0,... + 'OPTIONS',{[]},... + 'XDEF',{[]},... + 'YDEF',{[]},... + 'ZDEF',{[]},... + 'TDEF',{[]},... + 'VARS',struct([]),... + 'FILEHEADER',0,... + 'THEADER',0,... + 'XYHEADER',0); + +header.XDEF.rev=0; +header.YDEF.rev=0; +header.ZDEF.rev=0; + +% [comp,max_size,endian]=computer; +endian='L'; +if endian=='L' + header.BINTYPE='ieee-le'; +elseif endian=='B' + header.BINTYPE='ieee-be'; +end + +data=[]; + +file_name=deblank(file_name); +if exist(file_name,'file') + fid_ctl = fopen(file_name,'r'); + % disp(['CTL opened: ',num2str(fid_ctl)]) + % [header.FID]=deal([fid_ctl 0]); + header(1).FID{1}=fid_ctl; + if isunix, sep='/'; + else + sep='\\'; + end + if ~isempty(strfind(file_name,sep)) + slash=max(strfind(file_name,sep)); + header(1).DIR=file_name(1:slash); + file_name=file_name((slash+1):end); + end + header(1).FILENAME=file_name; +else + error(['Inexistent header file ',file_name]) +end + +% Enabling read_grads to handle netcdf files. + +point=strfind(file_name,'.'); +suf=lower(file_name(point(end)+1:end)); + +if strcmp(suf,'ctl') +% reading the .ctl file : +while ~feof(fid_ctl) + line=fgets(fid_ctl); + if isempty(line(1:end-1)), break, end + % cutting the line into words. + line_gaps=isspace(line); + % removing consecutive blancks. + while line_gaps(1)==1, line_gaps(1)=[]; line(1)=[]; end + if line(1)=='*' + if ~l_quiet + disp(line) + end + else + no_gaps=0; + while ~no_gaps + line_gap2=find(line_gaps); + if any(diff(line_gap2)==1) + dup=1+find(diff(line_gap2)==1); + line_gaps(line_gap2(dup))=[]; + line(line_gap2(dup))=[]; + else + no_gaps=1; + end + end + entry=line(1:(min(find(line_gaps))-1)); + words={''}; + for n=1:(sum(line_gaps)-1) + words{n}=line((line_gap2(n)+1):(line_gap2(n+1)-1)); + end + header=read_header(entry,words); + % disp(words) + end +end + +% Opening the binary file for later reading: +fid_bin = fopen(header.DATANAME,'r', header.BINTYPE ); +% disp(['BIN opened: ',num2str(fid_bin)]) +[header(1).FID] = {fid_ctl, fid_bin}; + +fclose(fid_ctl); +nvar=size(header.VARS,1); +header.NVAR=nvar; + +if nargin>1 & isempty(var_name) + if ~l_quiet + disp(['Header for ',header.FILENAME,' read.']) + end + fclose(header.FID{2}); + return +end + +if nargout==0 + assignin('caller','header',header) + assignin('caller','vars',vars); +end + +if header.DTYPE % Gridded data set + + % Computing the size of each variable: + var_size=zeros(nvar,4); % array of the var. size [X,Y,Z,T] + var_size(:,1)=header.XDEF.num; + var_size(:,2)=header.YDEF.num; + var_size(:,3)=cat(1,header.VARS.levs); + var_size(:,4)=header.TDEF.num; + header.VARSIZE={var_size}; + if exist('grads_name','file') + [vars,header]=grads_name(header,vars); + end + + % reading the bin. file : + if nargin == 1 | strcmp(lower(var_name),'all') + read_data(header); + elseif nargin == 2 + t_limits=[1 header.TDEF.num]; + ivar=strmatch(var_name,{header.VARS.name},'exact'); + if isempty(ivar) + if ~l_quiet + disp(['The variable ',var_name,' cannot be found in ',header.DATANAME]) + end + data=[]; + return + end + z_limits=[1 header.VARS(ivar).levs]; + y_limits=[1 header.YDEF.num]; + x_limits=[1 header.XDEF.num]; + data=read_var(header,var_name,t_limits,z_limits,y_limits,x_limits); + header.XDEF.vec=header.XDEF.vec(x_limits(1):x_limits(2)); + header.XDEF.num=length(header.XDEF.vec); + header.YDEF.vec=header.YDEF.vec(y_limits(1):y_limits(2)); + header.YDEF.num=length(header.YDEF.vec); + else + for n=1:2:nargin-2 + switch lower(varargin{n}) + case {'x'} + x_limits=varargin{n+1}; + case {'lon'} + lon_limits=sort(varargin{n+1}); + x_limits=interp1(header.XDEF.vec,1:header.XDEF.num,... + lon_limits,'nearest',NaN); + if any(isnan(x_limits)) + if ~l_quiet + disp(['The X-limits ',num2str(lon_limits),... + ' exceed the data coverage ',... + num2str(header.XDEF.vec([1 end]))]) + end + data=[]; + return + end + case {'y'} + y_limits=varargin{n+1}; + case {'lat'} + lat_limits=sort(varargin{n+1}); + y_limits=interp1(header.YDEF.vec,1:header.YDEF.num,... + lat_limits,'nearest',NaN); + if any(isnan(y_limits)) + if ~l_quiet + disp(['The Y-limits ',num2str(lat_limits),... + ' exceed the data coverage ',... + num2str(header.YDEF.vec([1 end]))]) + end + data=[]; + return + end + if header.YDEF.rev, + y_limits=header.YDEF.num*ones(size(y_limits))-fliplr(y_limits)+1; + end + case {'t','time'} + t_limits=varargin{n+1}; + case {'z','lev'} + z_limits=varargin{n+1}; + ivar=strmatch(var_name,{header.VARS.name},'exact'); + if isempty(ivar) + if ~l_quiet + disp(['The variable ',var_name,' cannot be found in ',header.DATANAME]) + end + data=[]; + return + end + if any(z_limits>header.VARS(ivar).levs) + if ~l_quiet + disp(['The variable ',var_name,' has only ',... + header.VARS(ivar).levs,' levels.']) + end + data=[]; + return + end + end + end + if ~exist('t_limits','var'), t_limits=[1 header.TDEF.num]; end + if ~exist('z_limits','var') + ivar=strmatch(var_name,{header.VARS.name},'exact'); + if isempty(ivar) + if ~l_quiet + disp(['The variable ',var_name,' cannot be found in ',header.DATANAME]) + end + data=[]; + return + end + z_limits=[1 header.VARS(ivar).levs]; + end + if ~exist('y_limits','var') + y_limits=[1 header.YDEF.num]; + end + if ~exist('x_limits','var') + x_limits=[1 header.XDEF.num]; + end + data=read_var(header,var_name,t_limits,z_limits,y_limits,x_limits); + header.XDEF.vec=header.XDEF.vec(x_limits(1):x_limits(2)); + header.XDEF.num=length(header.XDEF.vec); + if header.YDEF.rev, + y_limits=header.YDEF.num*ones(size(y_limits))-fliplr(y_limits)+1; + end + header.YDEF.vec=header.YDEF.vec(y_limits(1):y_limits(2)); + header.YDEF.num=length(header.YDEF.vec); + end + + % if header.XDEF.rev, header.XDEF.vec=header.XDEF.vec([end:-1:1]); end + % if header.YDEF.rev, header.YDEF.vec=header.YDEF.vec([end:-1:1]); end + % if header.ZDEF.rev, header.ZDEF.vec=header.ZDEF.vec([end:-1:1]); end + +else % Station data set + + data=read_station(header); + +end + +fclose(header.FID{2}); + +elseif strcmp(suf,'nc') % Enabling NetCDF in read_grads, based on snctools + old_dir=pwd; + if isfield(header,'DIR') + cd(header.DIR) + end % if + + % Reading the header, conforming to GrADS conventions: + ncheader=nc_info(file_name); + + header.FILENAME=ncheader.Filename; + header.DATANAME=ncheader.Filename; + header.NVAR=length(ncheader.DataSet); + + fields={{'lon','longitude','x','i'},'XDEF'; + {'lat','latitude','y','j'},'YDEF'; + {'lev','plev','nv','bnds'},'ZDEF'; + {'time','tps','t','l'},'TDEF'}; + for idim=1:size(fields,1) + for dim=fields{idim,1} + dim_id=strmatch(dim{1},{ncheader.DataSet.Name},'exact'); + if ~isempty(dim_id), break, end + end % for + if isempty(dim_id) + disp(['Dim ',fields{idim,2},' is missing.']) + vec=1; + num=1; + type='LINEAR'; + else + num=ncheader.DataSet(dim_id).Size; + vec=nc_varget(file_name,dim{1}); + if length(unique(diff(vec)))==1 + type='LINEAR'; + else + type='LEVELS'; + end + if all(diff(vec)<0) + rev=1; + vec=flipud(reshape(vec,[],1)); + elseif all(diff(vec)>0) + rev=0; + else + error(['Unsuitable vector ',dim{1}]) + end + end % if + + DEF=struct('num',num,'vec',vec,'type',type,'rev',rev); + + header=setfield(header,fields{idim,2},DEF); + end % for idim + + for ivar=1:header.NVAR + header.VARS(ivar).id=ivar; + header.VARS(ivar).name=ncheader.DataSet(ivar).Name; + header.VARS(ivar).size=ones(1,4); + for idim=1:length(ncheader.DataSet(ivar).Dimension) + [dim_id,j]=ind2sub(size(cat(1,fields{:,1})),... + strmatch(ncheader.DataSet(ivar).Dimension(idim),... + cat(1,fields{:,1}),'exact')); + header.VARS(ivar).size(dim_id)=... + getfield(eval(['header.',fields{dim_id,2}]),'num'); + end % for + header.VARS(ivar).levs=header.VARS(ivar).size(3); + end % for + + header.VARSIZE={cat(1,header.VARS.size)}; + + if nargin==1 | isempty(var_name) | strcmp(var_name,'all') + data=[]; + if exist('old_dir','var') + cd(old_dir) + end + return + end + + var_id=strmatch(var_name,{ncheader.DataSet.Name}); + if isempty(var_id) + error(['Variable ',var_name,' is not available in ',file_name,... + ': ',{ncheader.DataSet.Name}]) + end % if + + for n=1:2:nargin-2 + switch lower(varargin{n}) + case {'x'} + x_limits=varargin{n+1}; + case {'lon'} + lon_limits=sort(varargin{n+1}); + x_limits=interp1(header.XDEF.vec,1:header.XDEF.num,... + lon_limits,'nearest',NaN); + if any(isnan(x_limits)) + if ~l_quiet + disp(['The X-limits ',num2str(lon_limits),... + ' exceed the data coverage ',... + num2str(header.XDEF.vec([1 end])')]) + end + data=[]; + return + end + case {'y'} + y_limits=varargin{n+1}; + case {'lat'} + lat_limits=sort(varargin{n+1}); + y_limits=interp1(header.YDEF.vec,1:header.YDEF.num,... + lat_limits,'nearest',NaN); + if any(isnan(y_limits)) + if ~l_quiet + disp(['The Y-limits ',num2str(lat_limits),... + ' exceed the data coverage ',... + num2str(header.YDEF.vec([1 end])')]) + end + data=[]; + return + end + if header.YDEF.rev, + y_limits=header.YDEF.num*ones(size(y_limits))-fliplr(y_limits)+1; + end + case {'t','l','time'} + t_limits=varargin{n+1}; + case {'z','k','lev'} + z_limits=varargin{n+1}; + ivar=strmatch(var_name,{header.VARS.name},'exact'); + if isempty(ivar) + if ~l_quiet + disp(['The variable ',var_name,' cannot be found in ',header.DATANAME]) + end + data=[]; + return + end + if any(z_limits>header.VARS(ivar).levs) + if ~l_quiet + disp(['The variable ',var_name,' has only ',... + header.VARS(ivar).levs,' levels.']) + end + data=[]; + return + end + end % switch + end % for + + if ~exist('t_limits','var'), t_limits=[1 header.TDEF.num]; end + if ~exist('z_limits','var') + ivar=strmatch(var_name,{header.VARS.name},'exact'); + if isempty(ivar) + if ~l_quiet + disp(['The variable ',var_name,' cannot be found in ',header.DATANAME]) + end + data=[]; + return + end + z_limits=[1 header.VARS(ivar).levs]; + end % if + if ~exist('y_limits','var') + y_limits=[1 header.YDEF.num]; + end + if ~exist('x_limits','var') + x_limits=[1 header.XDEF.num]; + end + % data=read_var(header,var_name,t_limits,z_limits,y_limits,x_limits); + % Retrieve the corresponding variable: + + if all(header.VARS(var_id).size([3 4])==[1 1]) + data=nc_varget(file_name,var_name,... + [y_limits(1),x_limits(1)]-1,... + diff(cat(1,y_limits,x_limits),1,2)'+1); + elseif header.VARS(var_id).size(3)==1 + data=nc_varget(file_name,var_name,... + [t_limits(1),y_limits(1),x_limits(1)]-1,... + diff(cat(1,t_limits,y_limits,x_limits),1,2)'+1); + elseif header.VARS(var_id).size(4)==1 + data=nc_varget(file_name,var_name,... + [z_limits(1),y_limits(1),x_limits(1)]-1,... + diff(cat(1,z_limits,y_limits,x_limits),1,2)'+1); + else + data=nc_varget(file_name,var_name,... + [t_limits(1),z_limits(1),y_limits(1),x_limits(1)]-1,... + diff(cat(1,t_limits,z_limits,y_limits,x_limits),1,2)'+1); + end + + header.XDEF.vec=header.XDEF.vec(x_limits(1):x_limits(2)); + header.XDEF.num=length(header.XDEF.vec); + if header.YDEF.rev, + y_limits=header.YDEF.num*ones(size(y_limits))-fliplr(y_limits)+1; + end + if diff(y_limits)<0, error('Unsuitable Y limits'), end + header.YDEF.vec=header.YDEF.vec(y_limits(1):y_limits(2)); + header.YDEF.num=length(header.YDEF.vec); + + header.ZDEF.vec=z_limits(1):z_limits(2); + header.ZDEF.num=diff(z_limits)+1; + + header.TDEF.vec=t_limits(1):t_limits(2); + header.TDEF.num=diff(t_limits)+1; + + if length(size(data))==2 + data=permute(data,[2 1]); + elseif length(size(data))==3 & header.ZDEF.num==1 + data=permute(data,[3 2 4 1]); + elseif length(size(data))==3 & header.TDEF.num==1 + data=permute(data,[3 2 1]); + elseif length(size(data))==4 + data=permute(data,[4 3 2 1]); + end % if + + if header.YDEF.rev + data=flipdim(data,2); + end + + if exist('old_dir','var') + cd(old_dir) + end +else + disp(['Suffix .',suf,' is not yet enabled.']) +end % if +return + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +function header=read_header(entry,words) +% sets the header values according to what was read in the .ctl-file. +% cf. GrADS documentation : http://grads.iges.org/grads/gadoc/descriptorfile.html + +global l_quiet + +header=evalin('caller','header'); +fid_ctl=header.FID{1}; + +grid_fields={'num','type','vec','rev'}; + +switch upper(entry) + case 'DSET' % Name of the bin. data file. + param=deal(words{1}); + if param(1)=='^' & isfield(header,'DIR') + param(1)=[]; + param=[header.DIR,param]; + elseif param(1)=='^' + param(1)=[]; + end + if exist(param,'file') + header.DATANAME=param; + else + error(['Non-existent file ',param]) + end + % + case 'DTYPE' % Gridded or station data-file (not used later) + param=lower(words{1}); + switch param + case 'grib' + header.DTYPE=1; + case 'station' + header.DTYPE=0; + end + % + case 'STNMAP' % Name of the map file for station data (set in INDEX) + if header.DTYPE + warning([header.FILENAME,' cannot specify STNMAP=',param,' for a gridded data set.']) + end + param=deal(words{1}); + if param(1)=='^' + param(1)=[]; + end + if exist(param,'file') + header.INDEX=param; + else + error(['Non-existent file ',param]) + end + % + case 'INDEX' % Name of the GRIB map file (not used later) + [header.INDEX]=strcat(words{:}); + % + case 'TITLE' % Data title (not used later) + line={words{:}}; + space=cell(size(line)); + [space{:}]=deal(char(32)); + line=cat(1,line,space); + line=reshape(line,1,prod(size(line))); % Rearranging the title to keep spaces between words. + header.TITLE=deblank(cat(2,line{:})); + % + case 'UNDEF' % Missing or undefined data value + param=words{1}; + if isreal(str2num(param)) + header(1).UNDEF=str2num(param); + else + error(['Wrong missing value format : ',param]) + end + % + case 'OPTIONS' % Possible options (not all implemented...) + for param=words + param=param{1}; + if ~ischar(param), error(['Wrong option format : ',param]), end + switch lower(param) + case 'big_endian' + header.BINTYPE='ieee-be'; + case 'cray_32bit_ieee' + header.BINTYPE='cray'; + case 'little_endian' + header.BINTYPE='ieee-le'; + case 'binprecision' + % Strange syntax to eliminate digits in BINPRECISION + param=words{2}(find(isnan(str2double(cellstr(upper(words{2})'))))); + if any(strmatch(param,... + {'uchar','schar','int','uint','float','single','double',... + 'real*','integer*','bit','ubit','char','short','ushort', ... + 'long','ulong'})) + header.BINPRECISION=words{2}; + end + case 'xrev' + header.XDEF.rev=1; + case 'yrev' + header.YDEF.rev=1; + case 'zrev' + header.ZDEF.rev=1; + case 'sequential' + % Structure of the binary file: ([4 bit][XYHEADER bit][XDEF.num + % x YDEF.num x BINPRECISION bit][4 bit]) x NVAR + header.SEQ=1; + otherwise + fprintf('Option %s not yet supported.\n',param); + end + end % for param=words + % +% $$$ Matlab C/Fortran Description +% $$$ 'uchar' 'unsigned char' unsigned character, 8 bits. +% $$$ 'schar' 'signed char' signed character, 8 bits. +% $$$ 'int8' 'integer*1' integer, 8 bits. +% $$$ 'int16' 'integer*2' integer, 16 bits. +% $$$ 'int32' 'integer*4' integer, 32 bits. +% $$$ 'int64' 'integer*8' integer, 64 bits. +% $$$ 'uint8' 'integer*1' unsigned integer, 8 bits. +% $$$ 'uint16' 'integer*2' unsigned integer, 16 bits. +% $$$ 'uint32' 'integer*4' unsigned integer, 32 bits. +% $$$ 'uint64' 'integer*8' unsigned integer, 64 bits. +% $$$ 'single' 'real*4' floating point, 32 bits. +% $$$ 'float32' 'real*4' floating point, 32 bits. +% $$$ 'double' 'real*8' floating point, 64 bits. +% $$$ 'float64' 'real*8' floating point, 64 bits. + + case 'XDEF' % Description of the X-axis (longitude usually) + % Checking the number of x-grid coordinates: + if isreal(str2num(words{1})) + words{1}=str2num(words{1}); + elseif str2num(words{1})>1 + else + error(['Wrong number of x-grid arguments : ', ... + num2str(words{1})]) + end + + switch upper(words{2}) + case 'LINEAR' + vec(1)=str2num(words{3}); + vec(2)=str2num(words{4}); + vec2=vec(1) + vec(2) * [0:(words{1}-1)]; + words{3}=vec2; % KS, 24.11.2003: coord vector in all cases. + case 'LEVELS' +% $$$ try % all on the same line +% $$$ for i=1:words{1} +% $$$ vec(i)=str2num(words{i+2}); +% $$$ end +% $$$ words{3}=vec; +% $$$ catch % all levels written column-wise +% $$$ for i=1:words{1} +% $$$ % vec(i)=fscanf(fid_ctl,'%i',1); +% $$$ vec(i)=str2num(fgetl(fid_ctl)); +% $$$ end +% $$$ words{3}=vec; +% $$$ end +% vec=str2num([words{3:end}]'); +% vec=str2num(cell2mat({words{3:end}}'))'; + vec=str2num(strvcat(words{3:end})); + + while length(vec) < words{1} + point=ftell(fid_ctl); + read_line=str2num(fgetl(fid_ctl)); + if isempty(read_line) + fseek(fid_ctl,point,'bof'); + break + else + vec=cat(2,vec,read_line); + end + end + if length(vec)==words{1} + words{3}=vec; + else + error(['Unsuitable number of X-levels : ',num2str(length(vec))]) + end + otherwise + error(['Unsuitable x-mapping method : ',words{2}]) + end + + % if header(1).XDEF.rev, words{3}=fliplr(words{3}); end + [header(1).XDEF]=cell2struct({words{1},words{2},words{3},header(1).XDEF.rev},grid_fields,2); + + % + case 'YDEF' % Description of the Y-axis (latitude usually) + % Checking the number of y-grid coordinates: + if isreal(str2num(words{1})) + words{1}=str2num(words{1}); + elseif str2num(words{1})>1 + else + error(['Wrong number of y-grid arguments : ', ... + num2str(words{1})]) + end + + switch upper(words{2}) + case 'LINEAR' + vec(1)=str2num(words{3}); + vec(2)=str2num(words{4}); + vec2=vec(1) + vec(2) * [0:(words{1}-1)]; + words{3}=vec2; + case 'LEVELS' +% $$$ try % all on the same line +% $$$ for i=1:words{1} +% $$$ vec(i)=str2num(words{i+2}); +% $$$ end +% $$$ words{3}=vec; +% $$$ catch % all levels written column-wise +% $$$ for i=1:words{1} +% $$$ % vec(i)=fscanf(fid_ctl,'%i',1); +% $$$ vec(i)=str2num(fgetl(fid_ctl)); +% $$$ end +% $$$ words{3}=vec; +% $$$ end +% vec=str2num([words{3:end}]'); +% vec=str2num(cell2mat({words{3:end}}'))'; + vec=str2num(strvcat(words{3:end})); + while length(vec) < words{1} + point=ftell(fid_ctl); + read_line=str2num(fgetl(fid_ctl)); + if isempty(read_line) + fseek(fid_ctl,point,'bof'); + break + else + vec=cat(2,vec,read_line); + end + end + if length(vec)==words{1} + words{3}=vec; + else + error(['Unsuitable number of Y-levels : ',num2str(length(vec))]) + end + otherwise + error(['Unsuitable y-mapping method : ',words{2}]) + end + +% if header.YDEF.rev, words{3}=fliplr(words{3}); end + [header(1).YDEF]=cell2struct({words{1},words{2},words{3},header(1).YDEF.rev},grid_fields,2); + % + case 'ZDEF' % Description of the Z-axis + % Checking the number of z-grid coordinates: + if isreal(str2num(words{1})) + words{1}=str2num(words{1}); + elseif str2num(words{1})>1 + else + error(['Wrong number of z-grid arguments : ', ... + num2str(words{1})]) + end + + switch upper(words{2}) + case 'LINEAR' + vec(1)=str2num(words{3}); + vec(2)=str2num(words{4}); + vec2=vec(1) + vec(2) * [0:(words{1}-1)]; + words{3}=vec2; + case 'LEVELS' +% $$$ try % all on the same line +% $$$ for i=1:str2num(words{1}) +% $$$ vec(i)=str2num(words{i+2}); +% $$$ end +% $$$ words{3}=vec; +% $$$ catch % all levels written column-wise +% $$$ for i=1:words{1} +% $$$ % vec(i)=fscanf(fid_ctl,'%i',1); +% $$$ vec(i)=str2num(fgetl(fid_ctl)); +% $$$ end +% $$$ words{3}=vec; +% $$$ end +% vec=str2num([words{3:end}]'); +% vec=str2num(cell2mat({words{3:end}}'))'; + vec=str2num(strvcat(words{3:end})); + while length(vec) < words{1} + point=ftell(fid_ctl); + read_line=str2num(fgetl(fid_ctl)); + if isempty(read_line) + fseek(fid_ctl,point,'bof'); + break + else + vec=cat(2,vec,read_line); + end + end + if length(vec)==words{1} + words{3}=vec; + else + error(['Unsuitable number of Z-levels : ',num2str(length(vec))]) + end + otherwise + error(['Unsuitable z-mapping method : ',words{2}]) + end + + % if header.ZDEF.rev, words{3}=fliplr(words{3}); end + [header(1).ZDEF]=cell2struct({words{1},words{2},words{3},header(1).ZDEF.rev},grid_fields,2); + % + case 'TDEF' % Description of the T-axis + % Checking the number of t-grid coordinates: + if isreal(str2num(words{1})) + words{1}=str2num(words{1}); + elseif str2num(words{1})>1 + else + error(['Wrong number of t-scale argument : ', ... + num2str(words{1})]) + end + + if any(upper(words{2})~='LINEAR') + error(['Unsuitable t-mapping method : ',words{2}]) + end + + param=words{3}; + if (param(3)~=':' | param(6)~='Z' | ... + ~isreal(str2num(param([1:2 4:5 7:8 12:length(param)])))) + error(['Unsuitable date format : ',param]) + else + vec(1)=str2num(param(1:2)); % hour + vec(2)=str2num(param(4:5)); % min + vec(3)=str2num(param(7:8)); % day + switch lower(param(9:11)) % month + case 'jan' + vec(4)=1; + case 'feb' + vec(4)=2; + case 'mar' + vec(4)=3; + case 'apr' + vec(4)=4; + case 'may' + vec(4)=5; + case 'jun' + vec(4)=6; + case 'jul' + vec(4)=7; + case 'aug' + vec(4)=8; + case 'sep' + vec(4)=9; + case 'oct' + vec(4)=10; + case 'nov' + vec(4)=11; + case 'dec' + vec(4)=12; + otherwise + error(['Wrong month format : ',param(9:11)]) + end + + vec(5)=str2num(param(12:length(param))); % year + if vec(5)<10 + vec(5)=vec(5)+2000; + elseif vec(5)<100 + vec(5)=vec(5)+1900; + end + + % The time-axis is written in the matlab-time format + % (cf. datestr, datevec...): + init_time=datenum(vec(5),vec(4),vec(3),vec(1),vec(2),0); + + param=words{4}; + if isreal(str2num(param(1:end-2))) + time_increment=str2num(param(1:end-2)); + param(1:end-2)=[]; + else + error(['Wrong time increment argument : ',param]) + end + + switch lower(param) + case 'mn' + time_increment=time_increment*datenum(0,0,0,0,1,0); + case 'hr' + time_increment=time_increment*datenum(0,0,0,1,0,0); + case 'dy' % NB: datenum(0,0,1,0,0,0) = 1. + time_increment=time_increment; + case 'mo' % standardised month + time_increment=time_increment*365.25/12; + case 'yr' % standardised year + time_increment=time_increment*365.25; + otherwise + error(['Wrong time increment argument : ',param]) + end + + % Writing the final time axis: + clear vec + vec(1)=init_time; + vec(2)=time_increment; + + [header(1).TDEF]=cell2struct({words{1},words{2},vec,0},grid_fields,2); + end + % + case 'VARS' % Number and size of variables + if isreal(str2num(words{1})) + n_var = str2num(words{1}); + else + error(['Wrong variable number argument : ',words{1}]) + end + + % Reading the variables : + + var_format={'id','name','levs','units','descr'}; + varl={}; + + for i=1:n_var + line_var=fgetl(fid_ctl); + n_blank=length(line_var); + line_var=strrep(line_var,' ',' '); + while length(line_var) < n_blank + n_blank=length(line_var); + line_var=strrep(line_var,' ',' '); + end + while isspace(line_var(1)), line_var(1)=[]; end + var_loc={i,'',NaN,'',''}; + var_hole=min(find(isspace(line_var))); + var_loc{2}=line_var(1:(var_hole-1)); + line_var(1:var_hole)=[]; + + var_hole=min(find(isspace(line_var))); + var_loc{3}=str2num(line_var(1:(var_hole-1))); + % cf GrADS doc: If levs is 0, the variable does not correspond + % to any vertical level + var_loc{3}=max([var_loc{3},1]); + line_var(1:var_hole)=[]; + + var_hole=min(find(isspace(line_var))); + var_loc{4}=line_var(1:(var_hole-1)); + line_var(1:var_hole)=[]; + + var_loc{5}=line_var; + + varl=cat(1,varl,var_loc); + end + + vars=cell2struct(varl,var_format,2); + + if ~l_quiet + disp(['Is it the end ? ',fgets(fid_ctl)]); + else + endvars=deblank(fgets(fid_ctl)); + if ~strcmpi((endvars),'ENDVARS') + error(['Wrong end of file : ',endvars]) + end + end + + header(1).VARS=vars; + assignin('caller','vars',vars); + % + case 'FILEHEADER' % n-byte header of binary data, not to be read + [header.FILEHEADER]=str2num(words{1}); + % + case 'THEADER' % n-byte header for each T-block, not to be read + [header.THEADER]=str2num(words{1}); + % + case 'XYHEADER' % n-byte header for each XY-block, not to be read + [header.XYHEADER]=str2num(words{1}); + % + otherwise + error(['Unknown entry : ',entry]) +end + +return + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +function data=read_data(header,var_name) +% data=read_data(header,var_name) is a function, usually called by +% read_grads.m to use the information contained in the header file +% (.ctl) for reading a binary GrADS file. +% If var_name is 'all', all variables are read and sent to the base- +% workspace. +% Kristof Sturm, 29.10.02 + +global l_quiet + +vars=header.VARS; +nvar=header.NVAR; +var_size=header.VARSIZE{:}; + +if nargin == 1 | strcmp(lower(var_name),'all') % All variables loaded into workspace + data_list={}; + % initialising the data matrices : + var_count=zeros(nvar,1); + for ivar=1:nvar + eval([vars(ivar).name,'=NaN*ones(',int2str(header.XDEF.num),',',... + int2str(header.YDEF.num),',',... + int2str(vars(ivar).levs),',',... + int2str(header.TDEF.num),');']); + fprintf('Size of %s : [%s].\n %s[X Y Z T]\n',... + vars(ivar).name,int2str(size(eval(vars(ivar).name))),... + char(32*ones(1,length(vars(ivar).name)))); + end + + method = 'loop'; % mainly for debugging... + + switch method + case 'loop' + frewind(header.FID{2}); + % Implementing the sequential option: + if isfield(header,'SEQ') && header.SEQ + fseek(header.FID{2},4,'bof'); + end + + if header.FILEHEADER + fseek(header.FID{2},header.FILEHEADER,'bof'); +% $$$ if isfield(header,'SEQ') && header.SEQ +% $$$ fseek(header.FID{2},8,'cof'); +% $$$ end + end + + for l=1:header.TDEF.num + if header.THEADER + fseek(header.FID{2},header.THEADER,'cof'); +% $$$ if isfield(header,'SEQ') && header.SEQ +% $$$ fseek(header.FID{2},8,'cof'); +% $$$ end + end + for ivar=1:nvar + data=eval(vars(ivar).name); + count0=var_count(ivar); + for k=1:vars(ivar).levs + if header.XYHEADER + fseek(header.FID{2},header.XYHEADER,'cof'); + end + [data(:,:,k,l) count1]=fread(header.FID{2},[header.XDEF.num header.YDEF.num],header.BINPRECISION); + count0=count0+count1; + if isfield(header,'SEQ') && header.SEQ + fseek(header.FID{2},8,'cof'); + end + end % end k-loop + data(data==header.UNDEF)=NaN; % replacing the + % missing/undefined values + % by NaN (not-a-number) + +% data(data==header.UNDEF)=0; % replacing the + % missing/undefined values by + % NaN (not-a-number) +% data=sparse(data); + eval([vars(ivar).name,'=data;']); + var_count(ivar)=var_count(ivar)+count0; + % bytes(ivar)=ftell(header.FID{2}); + clear data + end % end ivar-loop + end % end l-loop + + % Send the relevent variables into the base workspace: + % assignin('base','var_count',var_count); + % assignin('base','bytes',bytes); + for ivar=1:nvar + data=eval(vars(ivar).name); + if header.XDEF.rev, data=flipdim(data,1); end + if header.YDEF.rev, data=flipdim(data,2); end + if header.ZDEF.rev, data=flipdim(data,3); end + assignin('base',vars(ivar).name,data); + end + % % end 'loop' + otherwise + for ivar=1:nvar + data=read_var(header,vars(ivar).name); + assignin('base',vars(ivar).name,data); + data_list=cat(1,data_list,{data}); + end + data=[]; + assignin('caller','data_list',data_list); + end +else % Individual var. reading + switch var_name + case {vars.name} + fprintf('Variable %s extracted from %s. \n',var_name, ... + header.DATANAME); + data=read_var(header,var_name); + otherwise + error(['Variable ',var_name,' not available in ', ... + header.DATANAME]); + end +end + +return + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +function data=read_var(header,ivar,t_limits,z_limits,y_limits,x_limits) +% data=read_varseq(header,ivar) reads in 'ivar' from +% 'header.DATANAME' and return it as a 4-D matlab matrix. +% 'ivar' can be the variable''s short name or its number id. + +global l_quiet + +vars=header.VARS; +nvar=header.NVAR; +var_size=header.VARSIZE{:}; + +% different behaviour of the f* functions according to the chosen data precision : +switch lower(header.BINPRECISION) + case {'uchar','schar','int8','uint8'} + byte_length=1; + case {'int16','uint16'} + byte_length=2; + case {'float32','single','int32','uint32'} + byte_length=4; + case {'float64','double','int64','uint64'} + byte_length=8; + otherwise + byte_length=1; +end + +if isempty(ivar) + if ~l_quiet + disp(['Header for ',header.FILENAME,' read.']) + end + data=[]; + return +end + +if ischar(ivar) + var_name=ivar; + ivar=strmatch(ivar,{vars.name},'exact'); + if isempty(ivar) + if ~l_quiet + disp(['The variable ',var_name,' cannot be found in ',header.DATANAME]) + end + data=[]; + return + end + clear var_name +end + +if ivar==1 + byte_ini=0; +else + byte_ini = sum(prod(var_size(1:(ivar-1),1:3),2),1) ; +end + +if isfield(header,'SEQ') && header.SEQ + byte_ini=byte_ini+(sum(var_size(1:ivar-1,3))*8+4)/byte_length; +end + +if header.FILEHEADER + byte_ini = byte_ini + header.FILEHEADER/byte_length; +% $$$ if isfield(header,'SEQ') && header.SEQ +% $$$ byte_ini=byte_ini+8/byte_length; +% $$$ end +end + +if header.THEADER + byte_ini = byte_ini + header.THEADER/byte_length; +% $$$ if isfield(header,'SEQ') && header.SEQ +% $$$ byte_ini=byte_ini+8/byte_length; +% $$$ end +end + +if header.XYHEADER + byte_ini=byte_ini+(sum(var_size(1:ivar-1,3))+1)*header.XYHEADER/byte_length; +% $$$ if isfield(header,'SEQ') && header.SEQ +% $$$ byte_ini=byte_ini+(sum(var_size(1:ivar-1,3))+1)*8/byte_length; +% $$$ end +end + +block_length = sum(prod(var_size(:,1:3),2),1); + +if isfield(header,'SEQ') && header.SEQ + block_length=block_length+sum(var_size(:,3))*8/byte_length; +end + +if header.XYHEADER + block_length=block_length+sum(var_size(:,3))*header.XYHEADER/byte_length; +end + +if header.THEADER + block_length=block_length+header.THEADER/byte_length; +end + +slice_length = header.XDEF.num*header.YDEF.num+header.XYHEADER/byte_length; + +if isfield(header,'SEQ') && header.SEQ + slice_length = slice_length + 8/byte_length ; +end + +var_length = prod([header.XDEF.num header.YDEF.num diff(z_limits)+1]); + +if header.XYHEADER + var_length = var_length + (diff(z_limits)+1)*header.XYHEADER/byte_length; +end + +if isfield(header,'SEQ') && header.SEQ + var_length=var_length+(diff(z_limits)+1)*8/byte_length; +end + +% disp(byte_ini) +% Selecting the starting time slice : +byte_ini=byte_ini + (t_limits(1)-1)*block_length + (z_limits(1)-1)*slice_length ; + +err_stat = fseek(header.FID{2},byte_ini*byte_length,'bof'); +if err_stat == -1, ferror(header.FID{2}), end + +% data=NaN(diff(x_limits)+1,diff(y_limits)+1,diff(z_limits)+1,diff(t_limits)+1); +data=NaN*ones(diff(x_limits)+1,diff(y_limits)+1,diff(z_limits)+1,diff(t_limits)+1); + +% size(data) +count_byte = 0; +count_byte2 = 0; +for l=1:(t_limits(2)-t_limits(1)+1) + file_ind = ftell(header.FID{2}); + for k=1:(z_limits(2)-z_limits(1)+1) + if all([x_limits y_limits]==[1 header.XDEF.num 1 header.YDEF.num]) + try + [data(:,:,k,l),n]=fread(header.FID{2},[header.XDEF.num header.YDEF.num],header.BINPRECISION); + count_byte=count_byte+n; + catch + warning(['Data read-in interrupted at l=',int2str(l),' and k=',int2str(k)]) + break + end + else + % Advance to the j-th row: + fseek(header.FID{2},(y_limits(1)-1)*header.XDEF.num*byte_length,'cof'); + for j=1:(diff(y_limits)+1) + fseek(header.FID{2},(x_limits(1)-1)*byte_length,'cof'); + [data(:,j,k,l),n]=fread(header.FID{2},diff(x_limits)+1,header.BINPRECISION); + fseek(header.FID{2},(header.XDEF.num-x_limits(2))*byte_length,'cof'); + end + fseek(header.FID{2},(header.YDEF.num-y_limits(2))*header.XDEF.num*byte_length,'cof'); + end + if isfield(header,'SEQ') && header.SEQ + fseek(header.FID{2},8,'cof'); + end + if header.XYHEADER + fseek(header.FID{2},header.XYHEADER,'cof'); + end + end + count_byte2=count_byte2+ftell(header.FID{2})-file_ind; + if l < header.TDEF.num + err_stat=fseek(header.FID{2},(block_length-var_length)*byte_length,'cof'); + if err_stat == -1, ferror(header.FID{2}), end + end +end + +% disp([byte_ini block_length slice_length var_length file_ind/byte_length ftell(header.FID{2})/byte_length]) + +data(find(data==header.UNDEF))=NaN; % replacing the missing/undefined values by NaN (not-a-number) + +if header.XDEF.rev, data=flipdim(data,1); end +if header.YDEF.rev, data=flipdim(data,2); end +if header.ZDEF.rev, data=flipdim(data,3); end + +%if count_byte ~= count_byte2/byte_length +% warning(['Number of elements read : ',num2str(count_byte),... +% ' .NEQ. number of bytes advanced in ',header.DATANAME,': ',num2str(count_byte2/byte_length)]) +%end + +%fprintf('%i bytes were read in %s .\n size(%s) = [%s], i.e. %i elements.\n',... +% count_byte2,header.DATANAME,vars(ivar).name,int2str(size(data)),count_byte); +% count_byte2,header.DATANAME,vars(ivar).name,int2str(size(data)),prod(size(data))); + +return + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +function data=read_station(header) +% This function uses the information read from the GrADS .ctl file +% to read STATION data into the matlab workspace. +% No reference to the .map file is currently made. +% cf. http://grads.iges.org/grads/gradoc/aboutstationdata.html +% Kristof Sturm, 30.X.02 + +global l_quiet + +fid_bin = header.FID{2}; +fseek(fid_bin,0,'eof'); +eof=ftell(fid_bin); +frewind(fid_bin); +file_end=0; +istat=1; + +data_format={'id','name','lat','lon','var'}; +data_tot={}; +% Reading the header : + +while 1 + + data_loc={0,'',0,0,[]}; + + boh=ftell(fid_bin); + + stid=fscanf(fid_bin,'%8c',1); + lat=fread(fid_bin,1,'float32'); + lon=fread(fid_bin,1,'float32'); + tim=fread(fid_bin,1,'float32'); + nlev=fread(fid_bin,1,'int32'); + nflag=fread(fid_bin,1,'int32'); + + eoh=ftell(fid_bin); + length_h=eoh-boh; + + var=NaN(header.NVAR,header.TDEF.num); + + % Reading all variables, skipping the headers : + for t=1:header.TDEF.num + + var(:,t)=fread(fid_bin,header.NVAR,'float32'); + + if ftell(fid_bin) < (eof-2*length_h) + file_err=fseek(fid_bin,2*length_h,'cof'); + if file_err==-1, ferror(fid_bin), end + else + fprintf('EOF reached for %s.\n\n',header.DATANAME); + file_end=1; + break + end + var(find(var==header.UNDEF))=NaN; + end + + if file_end, break, end + + % Rewinding for reading the first of the next headers : + file_err=fseek(fid_bin,-length_h,'cof'); + if file_err==-1, ferror(fid_bin), end + + % saving all relevant informations into the local cell : + [data_loc]={istat,deblank(lower(stid)),lat,lon,var}; + data_tot=cat(1,data_tot,data_loc); + istat=istat+1; +end + +data=cell2struct(data_tot,data_format,2); + +return + diff --git a/rt_run.mdf b/rt_run.mdf index 6cac2ab..9ef6553 100644 --- a/rt_run.mdf +++ b/rt_run.mdf @@ -13,10 +13,10 @@ Commnt = no. dry points: 1068 Fildry = #NCShoreALLSquare2_100.dry# Commnt = no. thin dams: 0 Commnt = -Itdate = #2021-09-08# +Itdate = #2021-09-29# Tunit = #M# -Tstart = 7.2000000e+02 -Tstop = 3.6000000e+03 +Tstart = 3.6000000e+02 +Tstop = 3.2400000e+03 Dt = 0.25 Tzone = 0 Commnt = @@ -93,9 +93,9 @@ PHhydr = #YYYYYY# PHderv = #YYY# PHproc = #YYYYYYYYYY# PHflux = #YYYY# -Flmap = 7.2000000e+02 60 3.6000000e+03 -Flhis = 7.2000000e+02 10 3.6000000e+03 -Flpp = 7.2000000e+02 60 3.6000000e+03 +Flmap = 3.6000000e+02 60 3.2400000e+03 +Flhis = 3.6000000e+02 10 3.2400000e+03 +Flpp = 3.6000000e+02 60 3.2400000e+03 Flrst = 60 Commnt = Online = #N# diff --git a/sdfopen.m b/sdfopen.m new file mode 100644 index 0000000..558efbf --- /dev/null +++ b/sdfopen.m @@ -0,0 +1,1281 @@ +% sdfopen() - Opens EDF/GDF/SDF files for reading and writing. The EDF format is specified +% in [1], GDF in [2]. SDF is the SIESTA convention (see [3], pp.8-9); SDF uses +% the EDF format. +% Usage: +% >> EDF = sdfopen(Filename,'r' [,CHAN]); % prepare to read CHAN channels +% >> EDF = sdfopen(Filename,'r' [,CHAN [,MODE [,TSR]]]); % all arguments +% % then +% >> [S,EDF] = sdfread(EDF, SecRead, SecStart); % reads the opened EDF data file. +% >> [S,EDF] = sdfread(EDF, Inf); % reads the whole opened EDF data file. +% +% Inputs: +% CHAN - [int vector] Specifies the channel(s) to read. Else, a re-referencing +% matrix. [Default|0 -> read all channels]. +% MODE - +% +% 'UCAL' [Default mode] Indicates that no calibration (re-scaling) to physical dim. +% is performed. Outputs are 16-bit integers. +% +% 'SIESTA' - Indicates that channels #1-#6 are re-referenced to (M1+M2)/2 +% (Note: 'UCAL' overrides 'SIESTA') +% 'AFIR' - Indicates that Adaptive FIR filtering is used for ECG removal. +% Implements Adaptive FIR filtering for ECG removal in EDF/GDF-tb. +% based on the algorithm of Mikko Koivuluoma +% A delay of EDF.AFIR.delay number of samples has to be considered. +% 'SIESTA+AFIR' - Does both. +% 'RAW' - One column represents one EDF-block +% 'Notch50Hz' - Implements a simple FIR-notch filter at 50 Hz +% 'RECG' - Implements ECG minimization with regression analysis +% 'TECG' - Implements ECG minimization with template removal (test status) +% 'HPF0.0Hz' - Implements a high-pass filter (with zero at z=+1, i.e. a differentiator). +% In this case, a notch-filter and/or sub-sampling is recommended. +% 'TAUx.yS' - Compensates time-constant of x.y seconds +% 'EOG[hvr]' - Produces HEOG, VEOG and/or REOG output (CHAN not considered) +% 'OVERFLOW' - Performs overflow detection +% 'Units_Blocks' - Requests the EDF-field arguments to SDFREAD in blocks +% [default is seconds] +% TSR - [optional] The target (re)sampling rate. Currently, only downsampling +% from 256 Hz or 200 Hz to 100 Hz is supported. The details are described +% in the appendix of [4]. +% +% Outputs: +% EDF - data structure read from the input file header. +% EDF.ErrNo ~= 0 Indicates that an error occurred +% 1: First 8 bytes are not '0 ', violating the EDF spec. +% 2: Invalid date (unable to guess correct date) +% 4: Incorrect date information (later than current date) +% 16: Incorrect filesize: Header information does not match actual size +% EDF.FILE.FID = -1 indicates that file has not been opened +% (for compatibility with former versions). +% EDF.WarnNo ~=0 Indicates EDF structure problems +% 1: ascii(0) in 1st header +% 2: ascii(0) in 2nd header +% 4: invalid SPR +% 4: invalid samples_per_record-values +% 8: date not in EDF-format (tries to guess correct date, see also E2) +% 16: invalid number_of-channels-value +% 32: invalid value of the EDF header length +% 64: invalid value of block_duration +% 128: Polarity of #7 probably inverted +% +% Example: +% To open an EDF/SDF file for writing: +% >> [EDF] = sdfopen(EDF,'w') % or equivalently +% >> [EDF] = sdfopen(EDF.FileName,'w',EDF.Dur,EDF.SampleRate); +% +% Note: Fields EDF.FileName, EDF.NS, EDF.Dur and EDF.EDF.SampleRate must be defined. +% +% Author: (C) 1997-2002 by Alois Schloegl, 15 Jun 2002 #0.85, (Header reworked for +% EEGLAB format, Arnaud Delorme and Scott Makeig, 27 Dec 2002) +% +% See also: fopen, SDFREAD, SDFWRITE, SDFCLOSE, SDFSEEK, SDFREWIND, SDFTELL, SDFEOF + +% References: +% [1] Bob Kemp, Alpo Värri, Agostinho C. Rosa, Kim D. Nielsen and John Gade. +% A simple format for exchange of digitized polygraphic recordings. +% Electroencephalography and Clinical Neurophysiology, 82 (1992) 391-393. +% See also: http://www.medfac.leidenuniv.nl/neurology/knf/kemp/edf/edf_spec.htm +% +% [2] Alois Schlögl, Oliver Filz, Herbert Ramoser, Gert Pfurtscheller. +% GDF - A GENERAL DATAFORMAT FOR BIOSIGNALS +% Technical Report, Department for Medical Informatics, +% Universtity of Technology, Graz (1999) +% See also: http://www-dpmi.tu-graz.ac.at/~schloegl/matlab/eeg/gdf4/tr_gdf.ps +% +% [3] The SIESTA recording protocol. +% See http://www.ai.univie.ac.at/siesta/protocol.html +% and http://www.ai.univie.ac.at/siesta/protocol.rtf +% +% [4] Alois Schlögl +% The electroencephalogram and the adaptive autoregressive model: theory and applications. +% (ISBN 3-8265-7640-3) Shaker Verlag, Aachen, Germany. +% See also: "http://www.shaker.de/Online-Gesamtkatalog/Details.idc?ISBN=3-8265-7640-3" + +% Testing state +% +% (1) reads header information and writes the header; can be used to check SDFOPEN or for correcting headerinformation +% EDF=sdfopen(EDF,'r+'); EDF=sdfclose(EDF); +% +% (2a) Minimal requirements for opening an EDF-File +% EDF.FileName='file.edf'; % define filename +% EDF.NS = 5; % fix number of channels +% EDF=sdfopen(EDF,'w'); +% write file +% define header somewhen before +% EDF=sdfclose(EDF); % writes the corrected header information +% +% (2b) Minimal requirements for opening an EDF-File +% EDF=sdfopen('file.edf','w',N); % N number of channels +% .. do anything, e.g define header +% EDF=sdfopen(EDF,'w+'); % writes Header information + +% This program is free software; you can redistribute it and/or +% modify it under the terms of the GNU General Public License +% as published by the Free Software Foundation; either version 2 +% of the License, or (at your option) any later version. +% +% This program 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 General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program; if not, write to the Free Software +% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +function [EDF,H1,h2]=sdfopen(arg1,arg2,arg3,arg4,arg5,arg6) + + INFO='(C) 1997-2002 by Alois Schloegl, 15 Jun 2002 #0.85'; +% a.schloegl@ieee.org +% Version 0.85 + +if nargin<2, arg2='r';end; + +if 1,exist('OCTAVE_VERSION'); + EDF.AS.Method='sdfopen'; + mfilename=EDF.AS.Method; +else + EDF.AS.Method=mfilename; +end; + +EDF.AS.Method=[EDF.AS.Method '-' arg2]; +EDF.AS.Date=fix(clock); +EDF.AS.Info=INFO; +EDF.AS.Ver = 0.82; + +if isstruct(arg1) + EDF=arg1; + FILENAME=EDF.FileName; +else + FILENAME=arg1; +end; + +H1idx=[8 80 80 8 8 8 44 8 8 4]; +H2idx=[16 80 8 8 8 8 8 80 8 32]; + +%%%%% Define Valid Data types %%%%%% +%GDFTYPES=[0 1 2 3 4 5 6 7 16 17 255+(1:64) 511+(1:64)]; +GDFTYPES=[0 1 2 3 4 5 6 7 16 17 255+[1 12 22 24] 511+[1 12 22 24]]; + +%%%%% Define Size for each data type %%%%% +GDFTYP_BYTE=zeros(1,512+64); +GDFTYP_BYTE(256+(1:64))=(1:64)/8; +GDFTYP_BYTE(512+(1:64))=(1:64)/8; +GDFTYP_BYTE(1:18)=[1 1 1 2 2 4 4 8 8 4 8 0 0 0 0 0 4 8]'; + +%EDF.GDFTYP.TEXT={'char','int8','uint8','int16','uint16','int32','uint32','int64','uint64','float32','float64'}; +%GDFTYP_BYTE=[1 1 1 2 2 4 4 8 8 4 8 0 0 0 0 0 4 8]'; +%GDFTYPES=[0 1 2 3 4 5 6 7 16 17]; + +EDF.ErrNo = 0; + +%%%%%%% ============= READ ===========%%%%%%%%%%%% +if (strcmp(arg2,'r') | strcmp(arg2,'r+')) + +[EDF.FILE.FID,MESSAGE]=fopen(FILENAME,arg2,'ieee-le'); +%EDF.FILE.FID=fid; + +EDF.FILE.stderr=2; +if EDF.FILE.FID<0 + %fprintf(EDF.FILE.stderr,'Error GDFOPEN: %s %s\n',MESSAGE,FILENAME); + H1=MESSAGE; H2=FILENAME; + EDF.ErrNo = [32,EDF.ErrNo]; + return; +end; +if (arg2=='r') + EDF.FILE.OPEN = 1; +elseif (arg2=='r+') + EDF.FILE.OPEN = 2; +end; +EDF.FileName = FILENAME; + +PPos=min([max(find(FILENAME=='.')) length(FILENAME)+1]); +SPos=max([0 find(FILENAME==filesep)]); +EDF.FILE.Ext = FILENAME(PPos+1:length(FILENAME)); +EDF.FILE.Name = FILENAME(SPos+1:PPos-1); +if SPos==0 + EDF.FILE.Path = pwd; +else + EDF.FILE.Path = FILENAME(1:SPos-1); +end; +EDF.FileName = [EDF.FILE.Path filesep EDF.FILE.Name '.' EDF.FILE.Ext]; + +%%% Read Fixed Header %%% +[tmp,count]=fread(EDF.FILE.FID,184,'uchar'); % +if count<184 + EDF.ErrNo = [64,EDF.ErrNo]; + return; +end; +H1=setstr(tmp'); % + +EDF.VERSION=H1(1:8); % 8 Byte Versionsnummer +if ~(strcmp(EDF.VERSION,'0 ') | strcmp(EDF.VERSION(1:3),'GDF')) + EDF.ErrNo = [1,EDF.ErrNo]; + if ~strcmp(EDF.VERSION(1:3),' '); % if not a scoring file, +% return; + end; +end; +EDF.PID = deblank(H1(9:88)); % 80 Byte local patient identification +EDF.RID = deblank(H1(89:168)); % 80 Byte local recording identification + +IsGDF=strcmp(EDF.VERSION(1:3),'GDF'); + +if IsGDF + %EDF.T0=[str2num(H1(168+[1:4])) str2num(H1(168+[5 6])) str2num(H1(168+[7 8])) str2num(H1(168+[9 10])) str2num(H1(168+[11 12])) str2num(H1(168+[13:16]))/100 ]; + if 1, % if strcmp(EDF.VERSION(4:8),' 0.12'); + % Note: in future versions the date format might change. + EDF.T0(1) = str2num( H1(168 + [ 1:4])); + EDF.T0(2) = str2num( H1(168 + [ 5 6])); + EDF.T0(3) = str2num( H1(168 + [ 7 8])); + EDF.T0(4) = str2num( H1(168 + [ 9 10])); + EDF.T0(5) = str2num( H1(168 + [11 12])); + EDF.T0(6) = str2num( H1(168 + [13:16]))/100; + end; + + if str2num(EDF.VERSION(4:8))<0.12 + tmp = setstr(fread(EDF.FILE.FID,8,'uchar')'); % 8 Byte Length of Header + EDF.HeadLen = str2num(tmp); % 8 Byte Length of Header + else + EDF.HeadLen = fread(EDF.FILE.FID,1,'int64'); % 8 Byte Length of Header + end; + EDF.reserved1 = fread(EDF.FILE.FID,8+8+8+20,'uchar'); % 44 Byte reserved + + EDF.NRec = fread(EDF.FILE.FID,1,'int64'); % 8 Byte # of data records + if strcmp(EDF.VERSION(4:8),' 0.10') + EDF.Dur = fread(EDF.FILE.FID,1,'float64'); % 8 Byte # duration of data record in sec + else + tmp = fread(EDF.FILE.FID,2,'uint32'); % 8 Byte # duration of data record in sec + EDF.Dur = tmp(1)./tmp(2); + end; + EDF.NS = fread(EDF.FILE.FID,1,'uint32'); % 4 Byte # of signals +else + if exist('OCTAVE_VERSION')>=5 + tmp=(find((toascii(H1)<32) | (toascii(H1)>126))); %%% snytax for OCTAVE + else + tmp=(find((H1<32) | (H1>126))); %%% syntax for Matlab + end; + if ~isempty(tmp) %%%%% not EDF because filled out with ASCII(0) - should be spaces + %H1(tmp)=32; + EDF.ErrNo=[1025,EDF.ErrNo]; + end; + %EDF.T0=[str2num(H1(168+[7 8])) str2num(H1(168+[4 5])) str2num(H1(168+[1 2])) str2num(H1(168+[9 10])) str2num(H1(168+[12 13])) str2num(H1(168+[15 16])) ]; + + EDF.T0 = zeros(1,6); + ErrT0=0; + tmp = str2num( H1(168 + [ 7 8])); + if ~isempty(tmp), EDF.T0(1) = tmp; else ErrT0 = 1; end; + tmp = str2num( H1(168 + [ 4 5])); + if ~isempty(tmp), EDF.T0(2) = tmp; else ErrT0 = 1; end; + tmp = str2num( H1(168 + [ 1 2])); + if ~isempty(tmp), EDF.T0(3) = tmp; else ErrT0 = 1; end; + tmp = str2num( H1(168 + [ 9 10])); + if ~isempty(tmp), EDF.T0(4) = tmp; else ErrT0 = 1; end; + tmp = str2num( H1(168 + [12 13])); + if ~isempty(tmp), EDF.T0(5) = tmp; else ErrT0 = 1; end; + tmp = str2num( H1(168 + [15 16])); + if ~isempty(tmp), EDF.T0(6) = tmp; else ErrT0 = 1; end; + + if any(EDF.T0~=fix(EDF.T0)); ErrT0=1; end; + + if ErrT0, + ErrT0=0; + EDF.ErrNo = [1032,EDF.ErrNo]; + + tmp = H1(168 + [1:8]); + for k = [3 2 1], + %fprintf(1,'\n zz%szz \n',tmp); + [tmp1,tmp] = strtok(tmp,' :./-'); + tmp1 = str2num([tmp1,' ']); + + if isempty(tmp1) + ErrT0 = ErrT0 | 1; + else + EDF.T0(k) = tmp1; + end; + end; + tmp = H1(168 + [9:16]); + for k = [4 5 6], + [tmp1,tmp] = strtok(tmp,' :./-'); + tmp1=str2num([tmp1,' ']); + if isempty(tmp1) + ErrT0 = ErrT0 | 1; + else + EDF.T0(k) = tmp1; + end; + end; + if ErrT0 + EDF.ErrNo = [2,EDF.ErrNo]; + end; + else + % Y2K compatibility until year 2084 + if EDF.T0(1) < 85 % for biomedical data recorded in the 1950's and converted to EDF + EDF.T0(1) = 2000+EDF.T0(1); + elseif EDF.T0(1) < 100 + EDF.T0(1) = 1900+EDF.T0(1); + %else % already corrected, do not change + end; + end; + H1(185:256)=setstr(fread(EDF.FILE.FID,256-184,'uchar')'); % + EDF.HeadLen = str2num(H1(185:192)); % 8 Bytes Length of Header + EDF.reserved1=H1(193:136); % 44 Bytes reserved + EDF.NRec = str2num(H1(237:244)); % 8 Bytes # of data records + EDF.Dur = str2num(H1(245:252)); % 8 Bytes # duration of data record in sec + EDF.NS = str2num(H1(253:256)); % 4 Bytes # of signals + EDF.AS.H1 = H1; % for debugging the EDF Header +end; + +if isempty(EDF.NS) %%%%% not EDF because filled out with ASCII(0) - should be spaces + fprintf(EDF.FILE.stderr, 'Warning SDFOPEN: invalid NS-value in header of %s\n',EDF.FileName); + EDF.ErrNo=[1040,EDF.ErrNo]; + EDF.NS=1; +end; + +if isempty(EDF.HeadLen) %%%%% not EDF because filled out with ASCII(0) - should be spaces + EDF.ErrNo=[1056,EDF.ErrNo]; + EDF.HeadLen=256*(1+EDF.NS); +end; + + +if any(~isempty(EDF.reserved1)) %%%%% not EDF because filled out with ASCII(0) - should be spaces + fprintf(2, 'Warning SDFOPEN: 44bytes-reserved-field of fixed header is not empty in %s\n',EDF.FILE.Name); + %EDF.ErrNo=[1057,EDF.ErrNo]; +end; + + +if isempty(EDF.NRec) %%%%% not EDF because filled out with ASCII(0) - should be spaces + EDF.ErrNo=[1027,EDF.ErrNo]; + EDF.NRec = -1; +end; + +if isempty(EDF.Dur) %%%%% not EDF because filled out with ASCII(0) - should be spaces + EDF.ErrNo=[1088,EDF.ErrNo]; + EDF.Dur=30; +else + if ~IsGDF, + if (EDF.Dur>1) & (EDF.Dur~=fix(EDF.Dur)), % Blockduration must be in seconds or subsecond range + EDF.ErrNo=[1088,EDF.ErrNo]; + end; + end; +end; + +if any(EDF.T0>[2084 12 31 24 59 59]) | any(EDF.T0<[1985 1 1 0 0 0]) + EDF.ErrNo = [4, EDF.ErrNo]; +end; + +%%% Read variable Header %%% +if ~IsGDF + idx1=cumsum([0 H2idx]); + idx2=EDF.NS*idx1; + + h2=zeros(EDF.NS,256); + [H2,count]=fread(EDF.FILE.FID,EDF.NS*256,'uchar'); + if count < EDF.NS*256 + EDF.ErrNo=[8,EDF.ErrNo]; + return; + end; + + %tmp=find((H2<32) | (H2>126)); % would confirm + tmp = find((H2<32) | ((H2>126) & (H2~=255) & (H2~=181)& (H2~=230))); + if ~isempty(tmp) %%%%% not EDF because filled out with ASCII(0) - should be spaces + H2(tmp) = 32; + EDF.ErrNo = [1026,EDF.ErrNo]; + end; + + for k=1:length(H2idx); + %disp([k size(H2) idx2(k) idx2(k+1) H2idx(k)]); + h2(:,idx1(k)+1:idx1(k+1))=reshape(H2(idx2(k)+1:idx2(k+1)),H2idx(k),EDF.NS)'; + end; + %size(h2), + h2=setstr(h2); + %(h2(:,idx1(9)+1:idx1(10))), + %abs(h2(:,idx1(9)+1:idx1(10))), + + EDF.Label = h2(:,idx1(1)+1:idx1(2)); + EDF.Transducer = h2(:,idx1(2)+1:idx1(3)); + EDF.PhysDim = h2(:,idx1(3)+1:idx1(4)); + EDF.PhysMin = str2num(h2(:,idx1(4)+1:idx1(5))); + EDF.PhysMax = str2num(h2(:,idx1(5)+1:idx1(6))); + EDF.DigMin = str2num(h2(:,idx1(6)+1:idx1(7))); + EDF.DigMax = str2num(h2(:,idx1(7)+1:idx1(8))); + EDF.PreFilt = h2(:,idx1(8)+1:idx1(9)); + EDF.SPR = str2num(h2(:,idx1(9)+1:idx1(10))); + %EDF.reserved = h2(:,idx1(10)+1:idx1(11)); + EDF.GDFTYP = 3*ones(1,EDF.NS); % datatype + + if isempty(EDF.SPR), + fprintf(EDF.FILE.stderr, 'Warning SDFOPEN: invalid SPR-value in header of %s\n',EDF.FileName); + EDF.SPR=ones(EDF.NS,1); + EDF.ErrNo=[1028,EDF.ErrNo]; + end; +else + fseek(EDF.FILE.FID,256,'bof'); + EDF.Label = setstr(fread(EDF.FILE.FID,[16,EDF.NS],'uchar')'); + EDF.Transducer = setstr(fread(EDF.FILE.FID,[80,EDF.NS],'uchar')'); + EDF.PhysDim = setstr(fread(EDF.FILE.FID,[ 8,EDF.NS],'uchar')'); +% EDF.AS.GDF.TEXT = EDF.GDFTYP.TEXT; + EDF.PhysMin = fread(EDF.FILE.FID,[EDF.NS,1],'float64'); + EDF.PhysMax = fread(EDF.FILE.FID,[EDF.NS,1],'float64'); + EDF.DigMin = fread(EDF.FILE.FID,[EDF.NS,1],'int64'); + EDF.DigMax = fread(EDF.FILE.FID,[EDF.NS,1],'int64'); + + EDF.PreFilt = setstr(fread(EDF.FILE.FID,[80,EDF.NS],'uchar')'); % + EDF.SPR = fread(EDF.FILE.FID,[ 1,EDF.NS],'uint32')'; % samples per data record + EDF.GDFTYP = fread(EDF.FILE.FID,[ 1,EDF.NS],'uint32'); % datatype + % fread(EDF.FILE.FID,[32,EDF.NS],'uchar')'; % datatype +end; + +% EDF=gdfcheck(EDF,1); +if any(EDF.PhysMax==EDF.PhysMin), EDF.ErrNo=[1029,EDF.ErrNo]; end; +if any(EDF.DigMax ==EDF.DigMin ), EDF.ErrNo=[1030,EDF.ErrNo]; end; +EDF.Cal = (EDF.PhysMax-EDF.PhysMin)./(EDF.DigMax-EDF.DigMin); +EDF.Off = EDF.PhysMin - EDF.Cal .* EDF.DigMin; +EDF.Calib=[EDF.Off';(diag(EDF.Cal))]; +EDF.SampleRate = EDF.SPR / EDF.Dur; + +EDF.AS.spb = sum(EDF.SPR); % Samples per Block +EDF.AS.bi = [0;cumsum(EDF.SPR)]; +EDF.AS.BPR = ceil(EDF.SPR.*GDFTYP_BYTE(EDF.GDFTYP+1)'); +EDF.AS.SAMECHANTYP = all(EDF.AS.BPR == (EDF.SPR.*GDFTYP_BYTE(EDF.GDFTYP+1)')) & all(EDF.GDFTYP(:)==EDF.GDFTYP(1)); +EDF.AS.GDFbi = [0;cumsum(ceil(EDF.SPR.*GDFTYP_BYTE(EDF.GDFTYP+1)'))]; +EDF.AS.bpb = sum(ceil(EDF.SPR.*GDFTYP_BYTE(EDF.GDFTYP+1)')); % Bytes per Block +EDF.AS.startrec = 0; +EDF.AS.numrec = 0; +EDF.FILE.POS = 0; + +status = fseek(EDF.FILE.FID, 0, 'eof'); +EDF.AS.endpos = ftell(EDF.FILE.FID); +fseek(EDF.FILE.FID, EDF.HeadLen, 'bof'); + +%[status EDF.AS.endpos EDF.HeadLen EDF.AS.bpb EDF.NRec] +if EDF.NRec == -1 % unknown record size, determine correct NRec + EDF.NRec = floor((EDF.AS.endpos - EDF.HeadLen) / EDF.AS.bpb); +elseif EDF.NRec ~= ((EDF.AS.endpos - EDF.HeadLen) / EDF.AS.bpb); + EDF.ErrNo=[16,EDF.ErrNo]; +% EDF.NRec = floor((EDF.AS.endpos - EDF.HeadLen) / EDF.AS.bpb); +end; + +% if Channelselect, ReReferenzing and Resampling +% Overflowcheck, Adaptive FIR +% Layer 4 + +%if nargin<3 %%%%% Channel Selection +if nargin <3 %else + arg3=0; +end; + +EDF.SIE.ChanSelect = 1:EDF.NS; +EDF.SIE.InChanSelect = 1:EDF.NS; + +EDF.SIE.RR=1; +EDF.SIE.RS=0; %exist('arg5')==1; if EDF.SIE.RS, EDF.SIE.RS==(arg5>0); end; +EDF.SIE.TH=0; %(exist('arg6')==1); +EDF.SIE.RAW=0; +EDF.SIE.REGC=0; +EDF.SIE.TECG=0; +EDF.SIE.AFIR=0; +EDF.SIE.FILT=0; +EDF.SIE.TimeUnits_Seconds=1; +EDF.AS.MAXSPR=max(EDF.SPR(EDF.SIE.ChanSelect)); % Layer 3 defines EDF.AS.MAXSPR in GDFREAD + +EDF.SIE.ReRefMx=eye(EDF.NS); +EDF.SIE.REG=eye(EDF.NS); +EDF.SIE.ReRefMx = EDF.SIE.ReRefMx(:,EDF.SIE.ChanSelect); +EDF.Calib=EDF.Calib*EDF.SIE.REG*EDF.SIE.ReRefMx; + +%if nargin>2 %%%%% Channel Selection + EDF.SIE.REG=eye(EDF.NS); + if arg3==0 + EDF.SIE.ChanSelect = 1:EDF.NS; + EDF.SIE.InChanSelect = 1:EDF.NS; + EDF.SIE.ReRefMx = eye(EDF.NS); + else + [nr,nc]=size(arg3); + if all([nr,nc]>1), % Re-referencing + EDF.SIE.ReRefMx = [[arg3 zeros(size(arg3,1),EDF.NS-size(arg3,2))]; zeros(EDF.NS-size(arg3,1),EDF.NS)]; + EDF.SIE.InChanSelect = find(any(EDF.SIE.ReRefMx')); + EDF.SIE.ChanSelect = find(any(EDF.SIE.ReRefMx)); + if nargin>3 + % fprintf(EDF.FILE.stderr,'Error SDFOPEN: Rereferenzing does not work correctly with %s (more than 3 input arguments)\n',arg4); + end; + else + EDF.SIE.ChanSelect = arg3; %full(sparse(1,arg3(:),1,1,EDF.NS)); + EDF.SIE.InChanSelect = arg3; + EDF.SIE.ReRefMx = eye(EDF.NS); + end; + end; + + if (exist('sedfchk')==2), + EDF=sedfchk(EDF); % corrects incorrect Header information. + end; + + %EDF.SIE.CS=1; + EDF.SIE.RR=1; + EDF.SIE.RS=exist('arg5')==1; if EDF.SIE.RS, EDF.SIE.RS==(arg5>0); end; + EDF.SIE.TH=0; %(exist('arg6')==1); + EDF.SIE.RAW=0; + EDF.SIE.REGC=0; + EDF.SIE.TECG=0; + EDF.SIE.AFIR=0; + EDF.SIE.FILT=0; + EDF.AS.MAXSPR=max(EDF.SPR(EDF.SIE.ChanSelect)); % Layer 3 defines EDF.AS.MAXSPR in GDFREAD + + EDF.SIE.REG=eye(EDF.NS); + + %elseif nargin>3 %%%%% RE-REFERENCING + if nargin>3 + if ~isempty(findstr(upper(arg4),'SIESTA')) + EDF.SIE.ReRefMx = eye(EDF.NS);% speye(EDF.NS); + EDF.SIE.ReRefMx(7,1:6)=[1 1 1 -1 -1 -1]/2; + EDF.SIE.TH=1; + % calculate (In)ChanSelect based on ReRefMatrix + EDF.SIE.InChanSelect = find(any(EDF.SIE.ReRefMx')); + EDF.SIE.ChanSelect = find(any(EDF.SIE.ReRefMx)); + end; + if ~isempty(findstr(upper(arg4),'EOG')) + tmp=findstr(upper(arg4),'EOG'); + tmp=lower(strtok(arg4(tmp:length(arg4)),' +')); + EDF.SIE.ReRefMx = sparse(EDF.NS,EDF.NS);% speye(EDF.NS); + if any(tmp=='h'); EDF.SIE.ReRefMx(8:9,1)=[ 1 -1 ]'; end; + if any(tmp=='v'); EDF.SIE.ReRefMx(1:9,2)=[ 1 0 0 1 0 0 1 -1 -1]';end; + if any(tmp=='r'); EDF.SIE.ReRefMx(3:9,3)=[ 1 0 0 1 2 -2 -2]'/2; end; + %EDF.SIE.TH=1; + % calculate (In)ChanSelect based on ReRefMatrix + EDF.SIE.InChanSelect = find(any(EDF.SIE.ReRefMx')); + EDF.SIE.ChanSelect = find(any(EDF.SIE.ReRefMx)); + end; + + if ~isempty(findstr(upper(arg4),'UCAL')) + %EDF.SIE.ReRefMx = speye(EDF.NS); % OVERRIDES 'SIESTA' and 'REGRESS_ECG' + EDF.SIE.RR = 0; + end; + if ~isempty(findstr(upper(arg4),'RAW')) + EDF.SIE.RAW = 1; + end; + if ~isempty(findstr(upper(arg4),'OVERFLOW')) + EDF.SIE.TH = 1; + end; + if ~isempty(findstr(upper(arg4),'FailingElectrodeDetector')) + EDF.SIE.FED = 1; + EDF.SIE.TH = 2; + end; + + if ~isempty(findstr(upper(arg4),'ECG')), % identify ECG channel for some ECG artifact processing method + if ~isempty(findstr(upper(arg4),'SIESTA')) + channel1=12; + %channel2=1:9; + M=zeros(EDF.NS,1);M(channel1)=1; + end + if isfield(EDF,'ChanTyp') + M=upper(char(EDF.ChanTyp(channel1)))=='C'; + channel1=find(M); + M=(upper(char(EDF.ChanTyp))=='E' | upper(char(EDF.ChanTyp))=='O' ); + %channel2=find(M); + else + channel1=12; + %channel2=1:9; + M=zeros(EDF.NS,1);M(channel1)=1; + end; + + end; + if ~isempty(findstr(upper(arg4),'RECG')) + EDF.SIE.REGC = 1; + if all(EDF.SIE.InChanSelect~=channel1) + EDF.SIE.InChanSelect=[EDF.SIE.InChanSelect channel1]; + end; + end; + + if ~isempty(findstr(upper(arg4),'TECG')) + fprintf(EDF.FILE.stderr,'SDFOPEN: status of TECG Mode: alpha test passed\n'); + %%%% TECG - ToDo + % - optimize window + if exist([lower(EDF.FILE.Name) 'ECG.mat']); + if exist('OCTAVE_VERSION')==5 + load(file_in_loadpath([lower(EDF.FILE.Name) 'ECG.mat'])); + else + load([lower(EDF.FILE.Name) 'ECG.mat']); + end; + if isstruct(QRS) + EDF.SIE.TECG = 1; + %%% EDF.AS.MAXSPR=size(QRS.Templates,1)/3; + EDF.AS.MAXSPR=max(EDF.AS.MAXSPR,EDF.SPR(channel1)); + else + fprintf(EDF.FILE.stderr,'WARNING SDFOPEN: %s invalid for TECG\n',[ lower(EDF.FILE.Name) 'ECG.mat']); + end; + else + fprintf(EDF.FILE.stderr,'WARNING SDFOPEN: %s not found\t (needed for Mode=TECG)\n',[lower(EDF.FILE.Name) 'ECG.mat']); + end; + end; + + if ~isempty(findstr(upper(arg4),'AFIR')) + % Implements Adaptive FIR filtering for ECG removal in EDF/GDF-tb. + % based on the Algorithm of Mikko Koivuluoma + + % channel2 determines which channels should be corrected with AFIR + + %EDF = sdf_afir(EDF,12,channel2); + channel2=EDF.SIE.ChanSelect; + fprintf(EDF.FILE.stderr,'Warning SDFOPEN: option AFIR still buggy\n'); + if isempty(find(channel2)) + EDF.SIE.AFIR=0; + else + EDF.SIE.AFIR=1; + EDF.AFIR.channel2=channel2; + + EDF.AFIR.alfa=0.01; + EDF.AFIR.gamma=1e-32; + + EDF.AFIR.delay = ceil(0.05*EDF.AS.MAXSPR/EDF.Dur); + EDF.AFIR.nord = EDF.AFIR.delay+EDF.AS.MAXSPR/EDF.Dur; + + EDF.AFIR.nC = length(EDF.AFIR.channel2); + EDF.AFIR.w = zeros(EDF.AFIR.nC, max(EDF.AFIR.nord)); + EDF.AFIR.x = zeros(1, EDF.AFIR.nord); + EDF.AFIR.d = zeros(EDF.AFIR.delay, EDF.AFIR.nC); + + channel1=12; + + if isfield(EDF,'ChanTyp') + if upper(char(EDF.ChanTyp(channel1)))=='C'; + EDF.AFIR.channel1 = channel1; + else + EDF.AFIR.channel1 = find(EDF.ChanTyp=='C'); + fprintf(EDF.FILE.stderr,'Warning %s: #%i is not an ECG channel, %i used instead\n' ,filename,channel1,EDF.AFIR.channel1); + end; + else + EDF.AFIR.channel1 = channel1; + end; + + if all(EDF.SIE.InChanSelect~=channel1) + EDF.SIE.InChanSelect=[EDF.SIE.InChanSelect channel1]; + end; + end; + end; + + + if isempty(findstr(upper(arg4),'NOTCH50')) + EDF.Filter.A=1; + EDF.Filter.B=1; + else + EDF.SIE.FILT=1; + EDF.Filter.A=1; + EDF.Filter.B=1; + %if all(EDF.SampleRate(EDF.SIE.ChanSelect)==100) + if EDF.AS.MAXSPR/EDF.Dur==100 + EDF.Filter.B=[1 1]/2; + %elseif all(EDF.SampleRate(EDF.SIE.ChanSelect)==200) + elseif EDF.AS.MAXSPR/EDF.Dur==200 + EDF.Filter.B=[1 1 1 1]/4; + %elseif all(EDF.SampleRate(EDF.SIE.ChanSelect)==256) + elseif EDF.AS.MAXSPR/EDF.Dur==400 + EDF.Filter.B=ones(1,8)/8; + %elseif all(EDF.SampleRate(EDF.SIE.ChanSelect)==256) + elseif EDF.AS.MAXSPR/EDF.Dur==256 + EDF.Filter.B=poly([exp([-1 1 -2 2]*2*pi*i*50/256)]); %max(EDF.SampleRate(EDF.SIE.ChanSelect)))]); + EDF.Filter.B=EDF.Filter.B/sum(EDF.Filter.B); + else + fprintf(EDF.FILE.stderr,'Warning SDFOPEN: 50Hz Notch does not fit\n'); + end; + end; + + + + if ~isempty(findstr(upper(arg4),'NOTCH60')) + fprintf(EDF.FILE.stderr,'Warning SDFOPEN: option NOTCH60 not implemented yet.\n'); + end; + + + if ~isempty(findstr(upper(arg4),'HPF')), % high pass filtering + if EDF.SIE.FILT==0; EDF.Filter.B=1; end; + EDF.SIE.FILT=1; + EDF.Filter.A=1; + end; + if ~isempty(findstr(upper(arg4),'HPF0.0Hz')), % high pass filtering + EDF.Filter.B=conv([1 -1], EDF.Filter.B); + elseif ~isempty(findstr(upper(arg4),'TAU')), % high pass filtering / compensate time constant + tmp=findstr(upper(arg4),'TAU'); + TAU=strtok(upper(arg4(tmp:length(arg4))),'S'); + tau=str2num(TAU); + if isempty(tau) + fprintf(EDF.FILE.stderr,'Warning SDFOPEN: invalid tau-value.\n'); + else + EDF.Filter.B=conv([1 (EDF.Dur/EDF.AS.MAXSPR/tau-1)], EDF.Filter.B); + end; + + %%%% example 'HPF_1.0Hz_Hamming', % high pass filtering + elseif ~isempty(findstr(upper(arg4),'HPF')), % high pass filtering + tmp=findstr(upper(arg4),'HPF'); + FilterArg0=arg4(tmp+4:length(arg4)); + %[tmp,FilterArg0]=strtok(arg4,'_'); + [FilterArg1,FilterArg2]=strtok(FilterArg0,'_'); + [FilterArg2,FilterArg3]=strtok(FilterArg2,'_'); + tmp=findstr(FilterArg1,'Hz'); + F0=str2num(FilterArg1(1:tmp-1)); + B=feval(FilterArg2,F0*EDF.AS.MAXSPR/EDF.Dur); + B=B/sum(B); + B(ceil(length(B)/2))=(B(ceil(length(B)/2)))-1; + + EDF.Filter.B=conv(-B, EDF.Filter.B); + end; + + + if ~isempty(findstr(upper(arg4),'UNITS_BLOCK')) + EDF.SIE.TimeUnits_Seconds=0; + end; + + end; % end nargin >3 + + if EDF.SIE.FILT==1; + EDF.Filter.Z=[]; + for k=1:length(EDF.SIE.ChanSelect), + [tmp,EDF.Filter.Z(:,k)]=filter(EDF.Filter.B,EDF.Filter.A,zeros(length(EDF.Filter.B+1),1)); + end; + EDF.FilterOVG.Z=EDF.Filter.Z; + end; + + if EDF.SIE.REGC + FN=[lower(EDF.FILE.Name) 'cov.mat']; + if exist(FN)~=2 + fprintf(EDF.FILE.stderr,'Warning %s: Covariance-file %s not found.\n',EDF.AS.Method,FN); + EDF.SIE.REGC=0; + else + if exist('OCTAVE_VERSION')==5 + load(file_in_loadpath(FN)); + else + load(FN); + end; + if exist('XC') == 1 + %EDF.SIE.COV = tmp.XC; + %[N,MU,COV,Corr]=decovm(XC); + N=size(XC,2); + COV=(XC(2:N,2:N)/XC(1,1)-XC(2:N,1)*XC(1,2:N)/XC(1,1)^2); + + %clear tmp; + %cov = diag(EDF.Cal)*COV*diag(EDF.Cal); + mcov = M'*diag(EDF.Cal)*COV*diag(EDF.Cal); + %mcov(~())=0; + EDF.SIE.REG = eye(EDF.NS) - M*((mcov*M)\(mcov)); + EDF.SIE.REG(channel1,channel1) = 1; % do not remove the regressed channels + %mcov, EDF.SIE.REG, + else + fprintf(EDF.FILE.stderr,'Error %s: Regression Coefficients for ECG minimization not available.\n',EDF.AS.Method); + end; + end; + + end; + + if EDF.SIE.TECG == 1; + % define channels that should be corrected + if isfield(QRS,'Version') + OutChanSelect=[1:11 13:EDF.NS]; + if EDF.SIE.REGC % correct templates + QRS.Templates=QRS.Templates*EDF.SIE.REG; + fprintf(EDF.FILE.stderr,'Warning SDFOPEN: Mode TECG+RECG not tested\n'); + end; + if QRS.Version~=2 + fprintf(EDF.FILE.stderr,'Warning SDFOPEN Mode TECG: undefined QRS-version\n'); + end; + else + %OutChanSelect=find(EDF.ChanTyp=='E' | EDF.ChanTyp=='O'); + OutChanSelect=[1:9 ]; + if any(EDF.SIE.ChanSelect>10) + fprintf(EDF.FILE.stderr,'Warning SDFOPEN: Mode TECG: Only #1-#9 are corrected\n'); + end; + if EDF.SIE.REGC, % correct the templates + QRS.Templates=QRS.Templates*EDF.SIE.REG([1:9 12],[1:9 12]); + fprintf(EDF.FILE.stderr,'Warning SDFOPEN: Mode TECG+RECG not tested\n'); + end; + + end; + fs = EDF.SPR(12)/EDF.Dur; + QRS.Templates=detrend(QRS.Templates,0); %remove mean + EDF.TECG.idx = [(QRS.Index-fs/2-1) (EDF.NRec+1)*EDF.SPR(12)]; %include terminating element + EDF.TECG.idxidx = 1; %pointer to next index + + % initialize if any spike is detected before first window + pulse = zeros(length(QRS.Templates),1); + Index=[]; + while EDF.TECG.idx(EDF.TECG.idxidx) < 1, + Index=[Index EDF.TECG.idx(EDF.TECG.idxidx)-EDF.AS.startrec*EDF.SPR(12)]; + EDF.TECG.idxidx=EDF.TECG.idxidx+1; + end; + if ~isempty(Index) + pulse(Index+length(QRS.Templates)) = 1; + end; + + for i=1:length(EDF.SIE.InChanSelect), + k=find(OutChanSelect==EDF.SIE.InChanSelect(i)); + if isempty(k) + EDF.TECG.QRStemp(:,i) = zeros(fs,1); + else + EDF.TECG.QRStemp(:,i) = QRS.Templates(0.5*fs:1.5*fs-1,k).*hanning(fs); + end; + [tmp,EDF.TECG.Z(:,i)] = filter(EDF.TECG.QRStemp(:,i),1,pulse); + end; + end; % if EDF.SIE.TECG==1 + + %syms Fp1 Fp2 M1 M2 O2 O1 A1 A2 C3 C4 + for k=EDF.SIE.ChanSelect, + %fprintf(1,'#%i: ',k); + tmp=find(EDF.SIE.ReRefMx(:,k))'; + + if EDF.SIE.ReRefMx(tmp(1),k)==1, + x=EDF.Label(tmp(1),:); + else + x=sprintf('%3.1f*%s',EDF.SIE.ReRefMx(tmp(1),k),deblank(EDF.Label(tmp(1),:))); + end; + for l=2:length(tmp), L=tmp(l); + if (EDF.SPR(tmp(l-1),:)~=EDF.SPR(tmp(l),:)) + fprintf(EDF.FILE.stderr,'Warning %s: SampleRate Mismatch in "%s", channel #%i and #%i\n',upper(EDF.AS.Method),EDF.FILE.Name,tmp(l-1),tmp(l)); + end; + if ~strcmp(EDF.PhysDim(tmp(l-1),:),EDF.PhysDim(tmp(l),:)) + fprintf(EDF.FILE.stderr,'Warning %s: Dimension Mismatch in "%s", channel #%i and #%i\n',upper(EDF.AS.Method),EDF.FILE.Name,tmp(l-1),tmp(l)); + end; + if ~strcmp(EDF.Transducer(tmp(l-1),:),EDF.Transducer(tmp(l),:)) + fprintf(EDF.FILE.stderr,'Warning %s: Transducer Mismatch in "%s", channel #%i and #%i\n',upper(EDF.AS.Method),EDF.FILE.Name,tmp(l-1),tmp(l)); + end; + if ~strcmp(EDF.PreFilt(tmp(l-1),:),EDF.PreFilt(tmp(l),:)) + fprintf(EDF.FILE.stderr,'Warning %s: PreFiltering Mismatch in "%s", channel #%i and #%i\n',upper(EDF.AS.Method),EDF.FILE.Name,tmp(l-1),tmp(l)); + end; + x=[x sprintf('+(%3.1f)*(%s)',EDF.SIE.ReRefMx(tmp(l),k),deblank(EDF.Label(tmp(l),:)))]; + end; + EDF.Label(k,1:length(x))=x; %char(sym(x)) + end; + %Label, + EDF.SIE.ReRefMx = EDF.SIE.ReRefMx(:,EDF.SIE.ChanSelect); + if exist('OCTAVE_VERSION')>=5, + EDF.Calib = (EDF.Calib*EDF.SIE.REG*EDF.SIE.ReRefMx); % important to be sparse, otherwise overflow-check does not work correctly. + fprintf(EDF.FILE.stderr,'Warning SDFOPEN: Overflow Check does not work without SPARSE\n'); + else + EDF.Calib = sparse(EDF.Calib*EDF.SIE.REG*EDF.SIE.ReRefMx); % important to be sparse, otherwise overflow-check does not work correctly. + end; + + if 1, % ??? not sure, whether it has any advantage + EDF.PhysDim = EDF.PhysDim(EDF.SIE.ChanSelect,:); + EDF.PreFilt = EDF.PreFilt(EDF.SIE.ChanSelect,:); + EDF.Transducer = EDF.Transducer(EDF.SIE.ChanSelect,:); + end; + + if EDF.SIE.RS, + tmp = EDF.AS.MAXSPR/EDF.Dur; + if arg5==0 + %arg5 = max(EDF.SPR(EDF.SIE.ChanSelect))/EDF.Dur; + + elseif ~rem(tmp,arg5); % The target sampling rate must divide the source sampling rate + EDF.SIE.RS = 1; + tmp=tmp/arg5; + EDF.SIE.T = ones(tmp,1)/tmp; + elseif arg5==100; % Currently, only the target sampling rate of 100Hz are supported. + EDF.SIE.RS=1; + tmp=EDF.AS.MAXSPR/EDF.Dur; + if exist('OCTAVE_VERSION') + load resample_matrix4octave.mat T256100 T200100; + else + load('resample_matrix'); + end; + if 1, + if tmp==400, + EDF.SIE.T=ones(4,1)/4; + elseif tmp==256, + EDF.SIE.T=T256100; + elseif tmp==200, + EDF.SIE.T=T200100; + elseif tmp==100, + EDF.SIE.T=1; + else + fprintf('Warning %s-READ: sampling rates should be equal\n',upper(EDF.AS.Method)); + end; + else + tmp=EDF.SPR(EDF.SIE.ChanSelect)/EDF.Dur; + if all((tmp==256) | (tmp<100)) + EDF.SIE.RS = 1; + %tmp=load(RSMN,'T256100'); + EDF.SIE.T = T256100; + elseif all((tmp==400) | (tmp<100)) + EDF.SIE.RS = 1; + EDF.SIE.T = ones(4,1)/4; + elseif all((tmp==200) | (tmp<100)) + EDF.SIE.RS = 1; + %tmp=load(RSMN,'T200100'); + EDF.SIE.T = T200100; + elseif all(tmp==100) + %EDF.SIE.T=load('resample_matrix','T100100'); + EDF.SIE.RS=0; + else + EDF.SIE.RS=0; + fprintf('Warning %s-READ: sampling rates should be equal\n',upper(EDF.AS.Method)); + end; + end; + else + fprintf(EDF.FILE.stderr,'Error %s-READ: invalid target sampling rate of %i Hz\n',upper(EDF.AS.Method),arg5); + EDF.SIE.RS=0; + EDF.ErrNo=[EDF.ErrNo,]; + %EDF=sdfclose(EDF); + %return; + end; + end; + + FN=[lower(EDF.FILE.Name), 'th.mat']; + if exist(FN)~=2, + if EDF.SIE.TH, % && ~exist('OCTAVE_VERSION'), + fprintf(EDF.FILE.stderr,'Warning %s: THRESHOLD-file %s not found.\n',EDF.AS.Method,FN); + EDF.SIE.TH=0; + end; + else + if exist('OCTAVE_VERSION')==5 + tmp=load(file_in_loadpath(FN)); + else + tmp=load(FN); + end; + if isfield(tmp,'TRESHOLD') + EDF.SIE.THRESHOLD = tmp.TRESHOLD; + %else + %fprintf(EDF.FILE.stderr,'Error %s: TRESHOLD''s not found.\n',EDF.AS.Method); + end; + end; + if EDF.SIE.TH>1, % Failing electrode detector + fprintf(2,'Warning SDFOPEN: FED not implemented yet\n'); + for k=1:length(InChanSelect),K=InChanSelect(k); + %for k=1:EDF.NS, + % [y1,EDF.Block.z1{k}] = filter([1 -1], 1, zeros(EDF.SPR(K)/EDF.Dur,1)); + % [y2,EDF.Block.z2{k}] = filter(ones(1,EDF.SPR(K)/EDF.Dur)/(EDF.SPR(K)/EDF.Dur),1,zeros(EDF.SPR(K)/EDF.Dur,1)); + + % [y3,EDF.Block.z3{k}] = filter(ones(1,EDF.SPR(K)/EDF.Dur)/(EDF.SPR(K)/EDF.Dur),1,zeros(EDF.SPR(K)/EDF.Dur,1)); + end; + end; + +% Initialization of Bufferblock for random access (without EDF-blocklimits) of data + if ~EDF.SIE.RAW & EDF.SIE.TimeUnits_Seconds + EDF.Block.number=[0 0 0 0]; %Actual Blocknumber, start and end time of loaded block, diff(EDF.Block.number(1:2))==0 denotes no block is loaded; + % EDF.Blcok.number(3:4) indicate start and end of the returned data, [units]=samples. + EDF.Block.data=[]; + EDF.Block.dataOFCHK=[]; + end; + +%end; % end of SDFOPEN-READ + + + +%%%%%%% ============= WRITE ===========%%%%%%%%%%%% + +elseif (arg2=='w') | (arg2=='w+') +% fprintf(EDF.FILE.stderr,'error EDFOPEN: write mode not possible.\n'); + H1=[]; H2=[]; +% return; + +EDF.SIE.RAW = 0; +if ~isstruct(arg1) % if arg1 is the filename + EDF.FileName=arg1; + if nargin<3 + tmp=input('SDFOPEN: list of samplerates for each channel? '); + EDF.SampleRate = tmp(:); + else + EDF.SampleRate=arg3; + end; + EDF.NS=length(EDF.SampleRate); + if nargin<4 + tmp=input('SDFOPEN: Duration of one block in seconds: '); + EDF.Dur = tmp; + EDF.SPR=EDF.Dur*EDF.SampleRate; + else + if ~isempty(findstr(upper(arg4),'RAW')) + EDF.SIE.RAW = 1; + else + EDF.Dur = arg4; + EDF.SPR=EDF.Dur*EDF.SampleRate; + end; + end; +end; + +FILENAME=EDF.FileName; +if (arg2=='w') + [fid,MESSAGE]=fopen(FILENAME,'w','ieee-le'); +elseif (arg2=='w+') % may be called only by SDFCLOSE + if EDF.FILE.OPEN==2 + [fid,MESSAGE]=fopen(FILENAME,'r+','ieee-le'); + else + fprintf(EDF.FILE.stderr,'Error SDFOPEN-W+: Cannot open %s for write access\n',FILENAME); + return; + end; +end; +if fid<0 + %fprintf(EDF.FILE.stderr,'Error EDFOPEN: %s\n',MESSAGE); + H1=MESSAGE;H2=[]; + EDF.ErrNo = EDF.ErrNo + 32; + fprintf(EDF.FILE.stderr,'Error SDFOPEN-W: Could not open %s \n',FILENAME); + return; +end; +EDF.FILE.FID = fid; +EDF.FILE.OPEN = 2; + +%%%% generate optional parameters + +PPos=min([max(find(FILENAME=='.')) length(FILENAME)+1]); +SPos=max([0 find(FILENAME==filesep)]); +EDF.FILE.Ext = FILENAME(PPos+1:length(FILENAME)); +EDF.FILE.Name = FILENAME(SPos+1:PPos-1); +if SPos==0 + EDF.FILE.Path = pwd; +else + EDF.FILE.Path = FILENAME(1:SPos-1); +end; +EDF.FileName = [EDF.FILE.Path filesep EDF.FILE.Name '.' EDF.FILE.Ext]; + +% Check all fields of Header1 +if ~isfield(EDF,'VERSION') + fprintf('Warning SDFOPEN-W: EDF.VERSION not defined; default=EDF assumed\n'); + EDF.VERSION='0 '; % default EDF-format + %EDF.ErrNo = EDF.ErrNo + 128; + %fclose(EDF.FILE.FID); return; +end; + +IsGDF=strcmp(upper(EDF.VERSION(1:3)),'GDF'); +if ~IsGDF + EDF.VERSION = '0 '; + fprintf(EDF.FILE.stderr,'\nData are stored with integer16.\nMeasures for minimizing round-off errors have been taken.\nDespite, overflow and round off errors may occur.\n'); + + if sum(EDF.SPR)>61440/2; + fprintf(EDF.FILE.stderr,'\nWarning SDFOPEN: One block exceeds 61440 bytes.\n') + end; +else + EDF.VERSION = 'GDF 0.12'; +end; + +if ~isfield(EDF,'PID') + fprintf(EDF.FILE.stderr,'Warning SDFOPEN-W: EDF.PID not defined\n'); + EDF.PID=setstr(32+zeros(1,80)); +end; +if ~isfield(EDF,'RID') + fprintf(EDF.FILE.stderr,'Warning SDFOPEN-W: EDF.RID not defined\n'); + EDF.RID=setstr(32+zeros(1,80)); +end; +if ~isfield(EDF,'T0') + EDF.T0=zeros(1,6); + fprintf(EDF.FILE.stderr,'Warning SDFOPEN-W: EDF.T0 not defined\n'); +end; +if ~isfield(EDF,'reserved1') + EDF.reserved1=char(ones(1,44)*32); +else + tmp=min(8,size(EDF.reserved1,2)); + EDF.reserved1=[EDF.reserved1(1,1:tmp) 32+zeros(1,44-tmp)]; +end; +if ~isfield(EDF,'NRec') + EDF.NRec=-1; +end; +if ~isfield(EDF,'Dur') + fprintf('Warning SDFOPEN-W: EDF.Dur not defined\n'); + EDF.Dur=NaN; + EDF.ErrNo = EDF.ErrNo + 128; + fclose(EDF.FILE.FID); return; +end; +if ~isfield(EDF,'NS') + EDF.ERROR = sprintf('Error SDFOPEN-W: EDF.NS not defined\n'); + EDF.ErrNo = EDF.ErrNo + 128; + fclose(EDF.FILE.FID); return; +end; + +% Check all fields of Header2 +if ~isfield(EDF,'Label') + EDF.Label=setstr(32+zeros(EDF.NS,16)); + fprintf(EDF.FILE.stderr,'Warning SDFOPEN-W: EDF.Label not defined\n'); +else + tmp=min(16,size(EDF.Label,2)); + EDF.Label=[EDF.Label(1:EDF.NS,1:tmp) 32+zeros(EDF.NS,16-tmp)]; +end; +if ~isfield(EDF,'Transducer') + EDF.Transducer=setstr(32+zeros(EDF.NS,80)); +else + tmp=min(80,size(EDF.Transducer,2)); + EDF.Transducer=[EDF.Transducer(1:EDF.NS,1:tmp) 32+zeros(EDF.NS,80-tmp)]; +end; +if ~isfield(EDF,'PreFilt') + EDF.PreFilt=setstr(32+zeros(EDF.NS,80)); +else + tmp=min(80,size(EDF.PreFilt,2)); + EDF.PreFilt=[EDF.PreFilt(1:EDF.NS,1:tmp) 32+zeros(EDF.NS,80-tmp)]; +end; +if ~isfield(EDF,'PhysDim') + EDF.PhysDim=setstr(32+zeros(EDF.NS,8)); + fprintf(EDF.FILE.stderr,'Warning SDFOPEN-W: EDF.PhysDim not defined\n'); +else + tmp=min(8,size(EDF.PhysDim,2)); + EDF.PhysDim=[EDF.PhysDim(1:EDF.NS,1:tmp) 32+zeros(EDF.NS,8-tmp)]; +end; + +if ~isfield(EDF,'PhysMin') + fprintf(EDF.FILE.stderr,'Warning SDFOPEN-W: EDF.PhysMin not defined\n'); + EDF.PhysMin=repmat(nan,EDF.NS,1); + %EDF.ERROR = sprintf('Error SDFOPEN-W: EDF.PhysMax not defined\n'); + %EDF.ErrNo = EDF.ErrNo + 128; + %fclose(EDF.FILE.FID); return; +else + EDF.PhysMin=EDF.PhysMin(1:EDF.NS); +end; +if ~isfield(EDF,'PhysMax') + fprintf('Warning SDFOPEN-W: EDF.PhysMax not defined\n'); + EDF.PhysMax=repmat(nan,EDF.NS,1); + %EDF.ERROR = sprintf('Error SDFOPEN-W: EDF.PhysMax not defined\n'); + %EDF.ErrNo = EDF.ErrNo + 128; + %fclose(EDF.FILE.FID); return; +else + EDF.PhysMax=EDF.PhysMax(1:EDF.NS); +end; +if ~isfield(EDF,'DigMin') + fprintf(EDF.FILE.stderr,'Warning SDFOPEN-W: EDF.DigMin not defined\n'); + EDF.DigMin=repmat(nan,EDF.NS,1); + %EDF.ERROR = sprintf('Error SDFOPEN-W: EDF.DigMax not defined\n'); + %EDF.ErrNo = EDF.ErrNo + 128; + %fclose(EDF.FILE.FID); return; +else + EDF.DigMin=EDF.DigMin(1:EDF.NS); +end; +if ~isfield(EDF,'DigMax') + fprintf('Warning SDFOPEN-W: EDF.DigMax not defined\n'); + EDF.DigMax=repmat(nan,EDF.NS,1); + %EDF.ERROR = sprintf('Error SDFOPEN-W: EDF.DigMax not defined\n'); + %EDF.ErrNo = EDF.ErrNo + 128; + %fclose(EDF.FILE.FID); return; +else + EDF.DigMax=EDF.DigMax(1:EDF.NS); +end; +if ~isfield(EDF,'SPR') + fprintf('Warning SDFOPEN-W: EDF.SPR not defined\n'); + EDF.SPR=repmat(nan,EDF.NS,1); + EDF.ERROR = sprintf('Error SDFOPEN-W: EDF.SPR not defined\n'); + EDF.ErrNo = EDF.ErrNo + 128; + fclose(EDF.FILE.FID); return; +else + EDF.SPR=reshape(EDF.SPR(1:EDF.NS),EDF.NS,1); +end; + +if IsGDF + if ~isfield(EDF,'GDFTPY') + EDF.ERROR = sprintf('Error SDFOPEN-W: EDF.GDFTYP not defined\n'); + EDF.ErrNo = EDF.ErrNo + 128; + fclose(EDF.FILE.FID); return; + else + EDF.GDFTYP=EDF.GDFTYP(1:EDF.NS); + end; +else + EDF.GDFTYP=3+zeros(1,EDF.NS); +end; + +%%%%%% generate Header 1, first 256 bytes +EDF.HeadLen=(EDF.NS+1)*256; +H1=setstr(32*ones(1,256)); +H1(1:8)=EDF.VERSION; %sprintf('%08i',EDF.VERSION); % 8 Byte Versionsnummer +H1( 8+(1:length(EDF.PID)))=EDF.PID; +H1(88+(1:length(EDF.RID)))=EDF.RID; +%H1(185:192)=sprintf('%-8i',EDF.HeadLen); + +if IsGDF + H1(168+(1:16))=sprintf('%04i%02i%02i%02i%02i%02i%02i',floor(EDF.T0),rem(EDF.T0(6),1)); + fwrite(fid,H1(1:184),'uchar'); + fwrite(fid,EDF.HeadLen,'int64'); + fwrite(fid,ones(8,1)*32,'byte'); % EP_ID=ones(8,1)*32; + fwrite(fid,ones(8,1)*32,'byte'); % Lab_ID=ones(8,1)*32; + fwrite(fid,ones(8,1)*32,'byte'); % T_ID=ones(8,1)*32; + fwrite(fid,ones(20,1)*32,'byte'); % + fwrite(fid,EDF.NRec,'int64'); + %fwrite(fid,EDF.Dur,'float64'); + [n,d]=rat(EDF.Dur); fwrite(fid,[n d], 'uint32'); + fwrite(fid,EDF.NS,'uint32'); +else + H1(168+(1:16))=sprintf('%02i.%02i.%02i%02i:%02i:%02i',rem(EDF.T0([3 2 1 4 5 6]),100)); + H1(185:192)=sprintf('%-8i',EDF.HeadLen); + H1(193:236)=EDF.reserved1; + H1(237:244)=sprintf('%-8i',EDF.NRec); + H1(245:252)=sprintf('%-8i',EDF.Dur); + H1(253:256)=sprintf('%-4i',EDF.NS); + H1(find(H1==0))=32; + fwrite(fid,H1,'uchar'); +end; + +%%%%%% generate Header 2, NS*256 bytes +if ~IsGDF; + sPhysMin=32+zeros(EDF.NS,8); + sPhysMax=32+zeros(EDF.NS,8); + for k=1:EDF.NS, + tmp=sprintf('%-8g',EDF.PhysMin(k)); + lt=length(tmp); + if lt<9 + sPhysMin(k,1:lt)=tmp; + else + if any(upper(tmp)=='E') | find(tmp=='.')>8, + fprintf(EDF.FILE.stderr,'Error SDFOPEN-W: PhysMin(%i) does not fit into header\n', k); + else + sPhysMin(k,:)=tmp(1:8); + end; + end; + tmp=sprintf('%-8g',EDF.PhysMax(k)); + lt=length(tmp); + if lt<9 + sPhysMax(k,1:lt)=tmp; + else + if any(upper(tmp)=='E') | find(tmp=='.')>8, + fprintf(EDF.FILE.stderr,'Error SDFOPEN-W: PhysMin(%i) does not fit into header\n', k); + else + sPhysMax(k,:)=tmp(1:8); + end; + end; + end; + sPhysMin=reshape(sprintf('%-8.1f',EDF.PhysMin)',8,EDF.NS)'; + sPhysMax=reshape(sprintf('%-8.1f',EDF.PhysMax)',8,EDF.NS)'; + + idx1=cumsum([0 H2idx]); + idx2=EDF.NS*idx1; + h2=setstr(32*ones(EDF.NS,256)); + size(h2); + h2(:,idx1(1)+1:idx1(2))=EDF.Label; + h2(:,idx1(2)+1:idx1(3))=EDF.Transducer; + h2(:,idx1(3)+1:idx1(4))=EDF.PhysDim; + %h2(:,idx1(4)+1:idx1(5))=sPhysMin; + %h2(:,idx1(5)+1:idx1(6))=sPhysMax; + h2(:,idx1(4)+1:idx1(5))=sPhysMin; + h2(:,idx1(5)+1:idx1(6))=sPhysMax; + h2(:,idx1(6)+1:idx1(7))=reshape(sprintf('%-8i',EDF.DigMin)',8,EDF.NS)'; + h2(:,idx1(7)+1:idx1(8))=reshape(sprintf('%-8i',EDF.DigMax)',8,EDF.NS)'; + h2(:,idx1(8)+1:idx1(9))=EDF.PreFilt; + h2(:,idx1(9)+1:idx1(10))=reshape(sprintf('%-8i',EDF.SPR)',8,EDF.NS)'; + h2(h2==0)=32; + for k=1:length(H2idx); + fwrite(fid,h2(:,idx1(k)+1:idx1(k+1))','uchar'); + end; +else + fwrite(fid, EDF.Label','16*uchar'); + fwrite(fid, EDF.Transducer','80*uchar'); + fwrite(fid, EDF.PhysDim','8*uchar'); + fwrite(fid, EDF.PhysMin,'float64'); + fwrite(fid, EDF.PhysMax,'float64'); + fwrite(fid, EDF.DigMin,'int64'); + fwrite(fid, EDF.DigMax,'int64'); + fwrite(fid, EDF.PreFilt','80*uchar'); + fwrite(fid, EDF.SPR,'uint32'); + fwrite(fid, EDF.GDFTYP,'uint32'); + fprintf(fid,'%c',32*ones(32,EDF.NS)); +end; + +tmp = ftell(EDF.FILE.FID); +if tmp ~= (256 * (EDF.NS+1)) + fprintf(1,'Warning %s-WRITE: incorrect header length %i bytes\n',upper(EDF.AS.Method),tmp); +%else fprintf(1,'sdfopen in write mode: header info stored correctly\n'); +end; + +EDF.AS.spb = sum(EDF.SPR); % Samples per Block +11, +EDF.AS.bi = [0;cumsum(EDF.SPR)]; +EDF.AS.BPR = ceil(EDF.SPR.*GDFTYP_BYTE(EDF.GDFTYP+1)'); +EDF.AS.SAMECHANTYP = all(EDF.AS.BPR == (EDF.SPR.*GDFTYP_BYTE(EDF.GDFTYP+1)')) & all(EDF.GDFTYP(:)~=EDF.GDFTYP(1)); +%EDF.AS.GDFbi= [0;cumsum(EDF.AS.BPR)]; +EDF.AS.GDFbi = [0;cumsum(ceil(EDF.SPR.*GDFTYP_BYTE(EDF.GDFTYP+1)'))]; +EDF.AS.bpb = sum(ceil(EDF.SPR.*GDFTYP_BYTE(EDF.GDFTYP+1)')); % Bytes per Block +EDF.AS.startrec = 0; +EDF.AS.numrec = 0; +EDF.FILE.POS = 0; + +else % if arg2 is not 'r' or 'w' + fprintf(EDF.FILE.stderr,'Warning %s: Incorrect 2nd argument. Argument2 must be ''r'' or ''w''\n',upper(EDF.AS.Method)); +end; + +if EDF.ErrNo>0 + fprintf(EDF.FILE.stderr,'ERROR %i SDFOPEN\n',EDF.ErrNo); +end; diff --git a/setup_nctoolbox.m b/setup_nctoolbox.m new file mode 100644 index 0000000..0b1f957 --- /dev/null +++ b/setup_nctoolbox.m @@ -0,0 +1,19 @@ +function setup_nctoolbox + +home = fileparts(which(mfilename)); +addpath(fullfile(home, 'java')); +addpath(fullfile(home, 'cdm')); + +% Added so that we can swap out utitlies modules for different user groups, +% like sura shelf_hypoxia +addpath(genpath(fullfile(home, 'cdm', 'utilities'))); + +warning off +try + setup_nctoolbox_java; +catch me + ex = MException('MBARI:NCTOOLBOX', 'Failed to setup the Java classpath'); + ex.throw +end +warning on +disp('NCTOOLBOX added to Matlab path') diff --git a/utm2deg.m b/utm2deg.m new file mode 100644 index 0000000..4e20f01 --- /dev/null +++ b/utm2deg.m @@ -0,0 +1,134 @@ +function [Lat,Lon] = utm2deg(xx,yy,utmzone) +% ------------------------------------------------------------------------- +% [Lat,Lon] = utm2deg(x,y,utmzone) +% +% Description: Function to convert vectors of UTM coordinates into Lat/Lon vectors (WGS84). +% Some code has been extracted from UTMIP.m function by Gabriel Ruiz Martinez. +% +% Inputs: +% x, y , utmzone. +% +% Outputs: +% Lat: Latitude vector. Degrees. +ddd.ddddd WGS84 +% Lon: Longitude vector. Degrees. +ddd.ddddd WGS84 +% +% Example 1: +% x=[ 458731; 407653; 239027; 230253; 343898; 362850]; +% y=[4462881; 5126290; 4163083; 3171843; 4302285; 2772478]; +% utmzone=['30 T'; '32 T'; '11 S'; '28 R'; '15 S'; '51 R']; +% [Lat, Lon]=utm2deg(x,y,utmzone); +% fprintf('%11.6f ',lat) +% 40.315430 46.283902 37.577834 28.645647 38.855552 25.061780 +% fprintf('%11.6f ',lon) +% -3.485713 7.801235 -119.955246 -17.759537 -94.799019 121.640266 +% +% Example 2: If you need Lat/Lon coordinates in Degrees, Minutes and Seconds +% [Lat, Lon]=utm2deg(x,y,utmzone); +% LatDMS=dms2mat(deg2dms(Lat)) +%LatDMS = +% 40.00 18.00 55.55 +% 46.00 17.00 2.01 +% 37.00 34.00 40.17 +% 28.00 38.00 44.33 +% 38.00 51.00 19.96 +% 25.00 3.00 42.41 +% LonDMS=dms2mat(deg2dms(Lon)) +%LonDMS = +% -3.00 29.00 8.61 +% 7.00 48.00 4.40 +% -119.00 57.00 18.93 +% -17.00 45.00 34.33 +% -94.00 47.00 56.47 +% 121.00 38.00 24.96 +% +% Author: +% Rafael Palacios +% Universidad Pontificia Comillas +% Madrid, Spain +% Version: Apr/06, Jun/06, Aug/06 +% Aug/06: corrected m-Lint warnings +%------------------------------------------------------------------------- + +% Argument checking +% +error(nargchk(3, 3, nargin)); %3 arguments required +n1=length(xx); +n2=length(yy); +n3=size(utmzone,1); +if (n1~=n2 || n1~=n3) + error('x,y and utmzone vectors should have the same number or rows'); +end +c=size(utmzone,2); +if (c~=4) + error('utmzone should be a vector of strings like "30 T"'); +end + + + +% Memory pre-allocation +% +Lat=zeros(n1,1); +Lon=zeros(n1,1); + + +% Main Loop +% +for i=1:n1 + if (utmzone(i,4)>'X' || utmzone(i,4)<'C') + fprintf('utm2deg: Warning utmzone should be a vector of strings like "30 T", not "30 t"\n'); + end + if (utmzone(i,4)>'M') + hemis='N'; % Northern hemisphere + else + hemis='S'; + end + + x=xx(i); + y=yy(i); + zone=str2double(utmzone(i,1:2)); + + sa = 6378137.000000 ; sb = 6356752.314245; + +% e = ( ( ( sa ^ 2 ) - ( sb ^ 2 ) ) ^ 0.5 ) / sa; + e2 = ( ( ( sa ^ 2 ) - ( sb ^ 2 ) ) ^ 0.5 ) / sb; + e2cuadrada = e2 ^ 2; + c = ( sa ^ 2 ) / sb; +% alpha = ( sa - sb ) / sa; %f +% ablandamiento = 1 / alpha; % 1/f + + X = x - 500000; + + if hemis == 'S' || hemis == 's' + Y = y - 10000000; + else + Y = y; + end + + S = ( ( zone * 6 ) - 183 ); + lat = Y / ( 6366197.724 * 0.9996 ); + v = ( c / ( ( 1 + ( e2cuadrada * ( cos(lat) ) ^ 2 ) ) ) ^ 0.5 ) * 0.9996; + a = X / v; + a1 = sin( 2 * lat ); + a2 = a1 * ( cos(lat) ) ^ 2; + j2 = lat + ( a1 / 2 ); + j4 = ( ( 3 * j2 ) + a2 ) / 4; + j6 = ( ( 5 * j4 ) + ( a2 * ( cos(lat) ) ^ 2) ) / 3; + alfa = ( 3 / 4 ) * e2cuadrada; + beta = ( 5 / 3 ) * alfa ^ 2; + gama = ( 35 / 27 ) * alfa ^ 3; + Bm = 0.9996 * c * ( lat - alfa * j2 + beta * j4 - gama * j6 ); + b = ( Y - Bm ) / v; + Epsi = ( ( e2cuadrada * a^ 2 ) / 2 ) * ( cos(lat) )^ 2; + Eps = a * ( 1 - ( Epsi / 3 ) ); + nab = ( b * ( 1 - Epsi ) ) + lat; + senoheps = ( exp(Eps) - exp(-Eps) ) / 2; + Delt = atan(senoheps / (cos(nab) ) ); + TaO = atan(cos(Delt) * tan(nab)); + longitude = (Delt *(180 / pi ) ) + S; + latitude = ( lat + ( 1 + e2cuadrada* (cos(lat)^ 2) - ( 3 / 2 ) * e2cuadrada * sin(lat) * cos(lat) * ( TaO - lat ) ) * ( TaO - lat ) ) * ... + (180 / pi); + + Lat(i)=latitude; + Lon(i)=longitude; + +end \ No newline at end of file diff --git a/vecmag.m b/vecmag.m new file mode 100644 index 0000000..43e5774 --- /dev/null +++ b/vecmag.m @@ -0,0 +1,15 @@ +function [mag] = vecmag(x,y,z) +%% Tiny function to find the mag of 2 or 3 vectors +% Because I'm tired of writing sqrt +% Alexander Rey, Queen's University, Oct 30 2019 + + +if nargin == 1 +mag = x; +elseif nargin == 2 +mag = sqrt(x.^2+y.^2); +elseif nargin == 3 +mag = sqrt(x.^2+y.^2+z.^2); +end +end + diff --git a/water_properties.m b/water_properties.m new file mode 100644 index 0000000..2329f37 --- /dev/null +++ b/water_properties.m @@ -0,0 +1,62 @@ +function water = water_properties + +% WATER_PROPERTIES Returns function handles to compute physical properties +% of water dependent on temperature, from 0.1 to 100 celsius. +% +% Water properties: +% Density [kg/m^3] +% Kinematic Viscosity [m^2/s] +% Bulk Modulus [Pa] +% +% Independent variable: +% Temperature [C] +% +% Examples: +% water = water_properties; +% % Compute water properties for a single temperature value +% water.nu(27) +% water.rho(27) +% water.K(27) +% % Create a short alias +% nu = water.nu; +% % Plot viscosity for multiple temperature values +% t = 10:80; +% plot(t,nu(t),'*') +% +% Requires: +% water_data.mat +% +% Author: +% Ildeberto de los Santos Ruiz +% idelossantos@ittg.edu.mx + +data_file = 'water_data.mat'; +if exist(data_file) + disp('Loading data...') + x = load(data_file); +else + errorStruct.message = 'Data file not found.'; + errorStruct.identifier = 'water_properties:fileNotFound'; + error(errorStruct) +end + +% Temperature (C) +temperature = x.temperature; + +% Density, rho (kg/m^3) +density = x.density; + +% Kinematic Viscosity, nu (m^2/s) +viscosity = x.viscosity; + +% Bulk Modulus, K (Pa) +bulk_modulus = x.bulk_modulus; + +% Function handle for density +water.rho = @(t) interp1(temperature,density,t,'spline'); + +% Function handle for viscosity +water.nu = @(t) interp1(temperature,viscosity,t,'spline'); + +% Function handle for bulk modulus +water.K = @(t) interp1(temperature,bulk_modulus,t,'spline'); diff --git a/wgs2utm.m b/wgs2utm.m new file mode 100644 index 0000000..52fe1cd --- /dev/null +++ b/wgs2utm.m @@ -0,0 +1,155 @@ +function [x,y,utmzone,utmhemi] = wgs2utm(Lat,Lon,utmzone,utmhemi) +% ------------------------------------------------------------------------- +% [x,y,utmzone] = wgs2utm(Lat,Lon,Zone) +% +% Description: +% Convert WGS84 coordinates (Latitude, Longitude) into UTM coordinates +% (northing, easting) according to (optional) input UTM zone and +% hemisphere. +% +% Input: +% Lat: WGS84 Latitude scalar, vector or array in decimal degrees. +% Lon: WGS84 Longitude scalar, vector or array in decimal degrees. +% utmzone (optional): UTM longitudinal zone. Scalar or same size as Lat +% and Lon. +% utmhemi (optional): UTM hemisphere as a single character, 'N' or 'S', +% or array of 'N' or 'S' characters of same size as Lat and Lon. +% +% Output: +% x: UTM easting in meters. +% y: UTM northing in meters. +% utmzone: UTM longitudinal zone. +% utmhemi: UTM hemisphere as array of 'N' or 'S' characters. +% +% Author notes: +% I downloaded and tried deg2utm.m from Rafael Palacios but found +% differences of up to 1m with my reference converters in southern +% hemisphere so I wrote my own code based on "Map Projections - A +% Working Manual" by J.P. Snyder (1987). Quick quality control performed +% only by comparing with LINZ converter +% (www.linz.govt.nz/apps/coordinateconversions/) and Chuck Taylor's +% (http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html) on a +% few test points, so use results with caution. Equations not suitable +% for a latitude of +/- 90deg. +% +% UPDATE: Following requests, this new version allows forcing UTM zone +% in input. +% +% Examples: +% +% % set random latitude and longitude arrays +% Lat= 90.*(2.*rand(3)-1) +% Lon= 180.*(2.*rand(3)-1) +% +% % let the function find appropriate UTM zone and hemisphere from data +% [x1,y1,utmzone1,utmhemi1] = wgs2utm(Lat,Lon) +% +% % forcing unique UTM zone and hemisphere for all data entries +% % note: resulting easting and northing are way off the usual values +% [x2,y2,utmzone2,utmhemi2] = wgs2utm(Lat,Lon,60,'S') +% +% % forcing different UTM zone and hemisphere for each data entry +% % note: resulting easting and northing are way off the usual values +% utmzone = floor(59.*rand(3))+1 +% utmhemi = char(78 + 5.*round(rand(3))) +% [x3,y3,utmzone3,utmhemi3] = wgs2utm(Lat,Lon,utmzone,utmhemi) +% +% Author: +% Alexandre Schimel +% MetOcean Solutions Ltd +% New Plymouth, New Zealand +% +% Version 2: +% February 2011 +%------------------------------------------------------------------------- + +%% Argument checking +if ~sum(double(nargin==[2,4])) + error('Wrong number of input arguments');return +end +n1=size(Lat); +n2=size(Lon); +if (n1~=n2) + error('Lat and Lon should have same size');return +end +if exist('utmzone','var') && exist('utmhemi','var') + n3=size(utmzone); + n4=size(utmhemi); + if (sort(n3)~=sort(n4)) + error('utmzone and utmhemi should have same size');return + end + if max(n3)~=1 && max(n3)~=max(n1) + error('utmzone should have either same size as Lat and Long, or size=1');return + end +end + +% expand utmzone and utmhemi if needed +if exist('utmzone','var') && exist('utmhemi','var') + n3=size(utmzone); + n4=size(utmhemi); + if n3==[1 1] + utmzone = utmzone.*ones(size(Lat)); + utmhemi = char(utmhemi.*ones(size(Lat))); + end +end + +%% coordinates in radians +lat = Lat.*pi./180; +lon = Lon.*pi./180; + +%% WGS84 parameters +a = 6378137; %semi-major axis +b = 6356752.314245; %semi-minor axis +% b = 6356752.314140; %GRS80 value, originally used for WGS84 before refinements +e = sqrt(1-(b./a).^2); % eccentricity + +%% UTM parameters +% lat0 = 0; % reference latitude, not used here +if exist('utmzone','var') + Lon0 = 6.*utmzone-183; % reference longitude in degrees +else + Lon0 = floor(Lon./6).*6+3; % reference longitude in degrees +end +lon0 = Lon0.*pi./180; % in radians +k0 = 0.9996; % scale on central meridian + +FE = 500000; % false easting +if exist('utmhemi','var') + FN = double(utmhemi=='S').*10000000; +else + FN = (Lat < 0).*10000000; % false northing +end + +%% Equations parameters +eps = e.^2./(1-e.^2); % e prime square +% N: radius of curvature of the earth perpendicular to meridian plane +% Also, distance from point to polar axis +N = a./sqrt(1-e.^2.*sin(lat).^2); +T = tan(lat).^2; +C = ((e.^2)./(1-e.^2)).*(cos(lat)).^2; +A = (lon-lon0).*cos(lat); +% M: true distance along the central meridian from the equator to lat +M = a.*( ( 1 - e.^2./4 - 3.*e.^4./64 - 5.*e.^6./256 ) .* lat ... + -( 3.*e.^2./8 + 3.*e.^4./32 + 45.*e.^6./1024 ) .* sin(2.*lat) ... + +( 15.*e.^4./256 + 45.*e.^6./1024 ) .* sin(4.*lat) ... + -(35.*e.^6./3072 ) .* sin(6.*lat) ); + +%% easting +x = FE + k0.*N.*( A ... + + (1-T+C) .* A.^3./6 ... + + (5-18.*T+T.^2+72.*C-58.*eps) .* A.^5./120 ); + +%% northing +% M(lat0) = 0 so not used in following formula +y = FN + k0.*M + k0.*N.*tan(lat).*( A.^2./2 ... + + (5-T+9.*C+4.*C.^2) .* A.^4./24 ... + + (61-58.*T+T.^2+600.*C-330.*eps) .* A.^6./720 ); + +%% UTM zone +if exist('utmzone','var') && exist('utmhemi','var') + utmzone = utmzone; + utmhemi = utmhemi; +else + utmzone = floor(Lon0./6)+31; + utmhemi = char( 83.* (Lat < 0) + 78.* (Lat >= 0) ); +end