function varargout = maskADCP(varargin) % MASKADCP allows the user to view a raw ADCP file and interactively mark % areas of data to be marked as bad in the mask (.msk) file and % subsequently be replaced with fill values % % if maskADCP invoked without arguements, it will ask for a file. % maskADCP('file','datafilename.cdf','mask','maskfilename.msk') % % the mask file is open if the button in the upper right hand corner is red % and shows the mask file name. Click on it in this state to close the % mask file. When the mask file is closed (or not known) no masking is % displayed on the plots. When the mask file is open, any clicking of the % mouse in an axis window will mark data! For one-D data, you ahve to % click on the actual line. % % written by Marinna Martini % U.S. Geological Survey Woods Hole Science Center % Version 0.0 beta beta 28-feb-2008 %%% START USGS BOILERPLATE -------------% % Use of this program is described in: % % Acoustic Doppler Current Profiler Data Processing System Manual % Jessica M. Côté, Frances A. Hotchkiss, Marinna Martini, Charles R. Denham % Revisions by: Andrée L. Ramsey, Stephen Ruane % U.S. Geological Survey Open File Report 00-458 % Check for later versions of this Open-File, it is a living document. % % Program written in Matlab v7.1.0 SP3 % Program updated in Matlab 7.2.0.232 (R2006a) % Program ran on PC with Windows XP Professional OS. % % "Although this program has been used by the USGS, no warranty, % expressed or implied, is made by the USGS or the United States % Government as to the accuracy and functioning of the program % and related program material nor shall the fact of distribution % constitute any such warranty, and no responsibility is assumed % by the USGS in connection therewith." % %%% END USGS BOILERPLATE -------------- % MASKADCP M-file for maskADCP.fig % MASKADCP, by itself, creates a new MASKADCP or raises the existing % singleton*. % % H = MASKADCP returns the handle to a new MASKADCP or the handle to % the existing singleton*. % % MASKADCP('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in MASKADCP.M with the given input arguments. % % MASKADCP('Property','Value',...) creates a new MASKADCP or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before maskADCP_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to maskADCP_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help maskADCP % Last Modified by GUIDE v2.5 12-Mar-2008 14:49:09 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @maskADCP_OpeningFcn, ... 'gui_OutputFcn', @maskADCP_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before maskADCP is made visible. function maskADCP_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to maskADCP (see VARARGIN) % Choose default command line output for maskADCP handles.output = hObject; % figure1: 1.000034179687500e+002 % sliderTimeShift: 1.060206298828125e+002 % axes1: 1.010040283203125e+002 % axes2: 1.010040283203125e+002 % axes3: 1.010040283203125e+002 % axes4: 1.010040283203125e+002 % output: 1.000034179687500e+002 % slider 1 controls time shift % look for a filename in the varargin handles.mydata = []; handles.mydata.masktoggle = []; handles.mydata.fill = 1E35; for i = 1:length(varargin), if strcmp(varargin{i},'file'), handles.mydata.datafile = varargin{i+1}; end if strcmp(varargin{i},'mask'), handles.mydata.maskfile = varargin{i+1}; end end if ~isfield(handles.mydata,'datafile') || isempty(handles.mydata.datafile), [filename, pathname] = uigetfile('*.cdf','Open a netCDF time series file'); if ~filename, return; end handles.mydata.datafile = fullfile(pathname, filename); end % open the netCDF file and do the basic checks cdf = netcdf(handles.mydata.datafile); if isempty(cdf), disp('problem opening %s',handles.mydata.datafile); return; end filehandles{1} = cdf; handles.mydata.cdf = cdf; % for passing to other methods if isfield(handles.mydata,'maskfile') && ~isempty(handles.mydata.maskfile), handles = getmaskfile(handles); filehandles{2} = handles.mydata.msk; else set(handles.maskfilebutton,'String','Push for mask file'); set(handles.masktogglebutton,'String','Not Masking'); end set(handles.figure1,'UserData',filehandles); % store the netCDF file pointer here so I can close it later set(handles.figure1,'DeleteFcn','cdf = get(gcf,''UserData''); for n=1:length(cdf), disp(sprintf(''closing %s\nApply mask using postmask.m'', char(ncnames(cdf{n})))); close(cdf{n}); end; clear cdf n'); % and this is the code that will close it clear filehandles if isempty(cdf), disp(['Unable to open netCDF file ',handles.mydata.datafile]); return; end dimnames = ncnames(dim(cdf)); handles.mydata.israwADCP = 0; % flag for the TIM variable handles.mydata.isEPIC = 0; for i=1:length(dimnames), % is this a burst data file if strcmp(dimnames{i},'ensemble'), handles.mydata.israwADCP = 1; end if strcmp(dimnames{i},'time'), handles.mydata.isEPIC = 1; end end set(handles.textTitle,'string',handles.mydata.datafile) % these set up the data views handles.mydata.Curplotset = 1; if handles.mydata.israwADCP, handles.mydata.plotset = {'vel','cor','AGC','PGd','orientation',... 'STDorientation','Press-Temp','xmit','VD','EWD'}; handles.mydata.shapes = {'2d','2d','2d','2d','1d','1d','1d','1d','1d','1d'}; handles.mydata.clims = {[-500 500],[0 256],[0 256],[0 100],[],[],[],[],[],[]}; handles.mydata.varset = {{'vel1','vel2','vel3','vel4'},... {'cor1','cor2','cor3','cor4'},... {'AGC1','AGC2','AGC3','AGC4'},... {'PGd1','PGd2','PGd3','PGd4'},... {'Hdg','Ptch','Roll',''},... {'HdgSTD','PtchSTD','RollSTD',''},... {'Pressure','PressVar','Tx','sv'}, ... {'xmitc','xmitv','dac',''},... {'VDD3','VDD1','VDC',''},... {'EWD1','EWD2','EWD3','EWD4'} ... }; else handles.mydata.plotset = {'vel','Werr, cor, AGC, PGd',... 'orientation', 'Press, Temp, range'}; end % variables never to be masked handles.mydata.mask.nomaskvars = {'ensemble','Rec','D','bin','TIM'}; handles.mydata.icell = 1; disp('Loading time, one moment...') if handles.mydata.israwADCP, handles.mydata.tm = datenum(gregorian(cdf{'TIM'}(:))); handles.mydata.ens = cdf{'Rec'}(:); handles.mydata.cells = cdf{'D'}(:); elseif handles.mydata.isEPIC, handles.mydata.tm = datenum(gregorian(cdf{'time'}(:)+cdf{'time2'}(:)./(1000*24*3600))); handles.mydata.cells = cdf{'depth'}(:); else disp('Unable to load record dimension'); return; end disp(sprintf('Data found from %s to %s',datestr(handles.mydata.tm(1)),datestr(handles.mydata.tm(end)))) disp(sprintf('Data found from ensemble %d to %d',handles.mydata.ens(1),handles.mydata.ens(end))) set(handles.textStartTime,'string',sprintf('%s, #%d',... datestr(handles.mydata.tm(1),0),handles.mydata.ens(1))) set(handles.textEndTime,'string',sprintf('%s, #%d',... datestr(handles.mydata.tm(end),0),handles.mydata.ens(end))) handles.mydata.days2view = 3; % a random starter % look for N days of data dayN = find(handles.mydata.tm > handles.mydata.tm(1)+handles.mydata.days2view, 1,'first'); handles.mydata.idx2view = [1 dayN]; recspan = handles.mydata.idx2view(2) - handles.mydata.idx2view(1); handles.mydata.timespan = handles.mydata.tm(end) - handles.mydata.tm(1); handles.mydata.dT = gmean(diff(handles.mydata.tm)); % estimate time between ensembles handles.mydata.nens = length(handles.mydata.tm); % slider 1 - move along in time % slider 1 limits -- maybe change the view zoom for the number of samples % [min_step max_step]Slider step size. This property controls the amount % the slider Value changes when you click the mouse on the % arrow button (min_step) or on the slider trough (max_step). % Specify SliderStep as a two-element vector; each value % must be in the range [0, 1]. The actual % step size is a function of the specified SliderStep and % the total slider range (Max - Min). % The default, [0.01 0.10], provides a 1 percent change for % clicks on the arrow button and a 10 percent change for clicks in the trough. % start with 7 days set(handles.sliderTimeShift,'Value',handles.mydata.tm(1),'Min',handles.mydata.tm(1),... 'Max',handles.mydata.tm(end),'SliderStep',[handles.mydata.days2view/handles.mydata.timespan, 0.1]); set(handles.sliderTimeShift,'Tooltipstring','Move along in time') handles.mydata.CurPlot = 1; % put varnames into listbox here set(handles.listboxWhichPlot,'string',handles.mydata.plotset,'Value',1); set(handles.listboxWhichPlot,'Tooltipstring','Select data to display'); % minimum zoom in time to maximum zoom, limit by the number of ensembles % figure out a best smallest window based on the minimum number of % ensembles that will render well handles.mydata.minensdisplayed = 100; ens2view = floor(handles.mydata.days2view./handles.mydata.dT); % max we can display is handles.mydata.nens set(handles.sliderTimeView,'Value',ens2view,'Min',handles.mydata.minensdisplayed,... 'Max',handles.mydata.nens,'SliderStep',[0.1 0.6]); set(handles.sliderTimeView,'Tooltipstring','Zoom in and out in time') set(handles.textTimeView,'string',sprintf('%5.2f days = %5.2f hours, #%d ensembles',... handles.mydata.days2view, handles.mydata.days2view*24, recspan)) handles.mydata.Curmask = []; handles.mydata.TaggedAxis = []; % because we don't know what to do with this yet handles.output = []; % so I can find this window later set(gcf,'Name','maskADCP') % because some things fail when gone through first handles.mydata.initialize = 1; set(gcf,'Tag','maskADCPwindow') %disp(sprintf('slider from %s to %s', datestr(handles.mydata.tm(1), datestr(handles.mydata.tm(1))))) % Update handles structure guidata(gcf, handles); %guidata(hObject, handles); guidata(hObject, handles); % This sets up the initial plot - only do when we are invisible % so window can get raised using example. if strcmp(get(hObject,'Visible'),'off') updateplot(gcf, handles); %updateplot(hObject, handles) end % UIWAIT makes maskADCP wait for user response (see UIRESUME) % uiwait(handles.figure1); % ------------------ updates the plot - this is a user function function updateplot(hObject, handles) cdf = handles.mydata.cdf; idx = handles.mydata.idx2view; varset = handles.mydata.varset{handles.mydata.Curplotset}; % cell array of varnames clims = handles.mydata.clims{handles.mydata.Curplotset}; setshape = handles.mydata.shapes{handles.mydata.Curplotset}; % is there a mask file open? showmask = 0; if isfield(handles.mydata,'msk') && ~isempty(handles.mydata.msk), showmask = 1; msk = handles.mydata.msk; end phand = [0 0 0 0]; set(handles.textPlotStart,'string',sprintf('%s, #%d',... datestr(handles.mydata.tm(idx(1)),0),handles.mydata.ens(idx(1)))) set(handles.textPlotEnd,'string',sprintf('%s, #%d',... datestr(handles.mydata.tm(idx(2)),0),handles.mydata.ens(idx(2)))) switch setshape, case '2d', for iax = 1:4, eval(sprintf('axes(handles.axes%d);',iax)) cla; set(gca,'DrawMode','fast') data = cdf{varset{iax}}(idx(1):idx(2),:)'; phand(iax) = pcolor(handles.mydata.tm(idx(1):idx(2)),handles.mydata.cells,data); % image does not render well with changing color limits %phand(iax) = image(handles.mydata.tm(idx(1):idx(2)),handles.mydata.cells,data); shading flat; set(phand(iax),'ButtonDownFcn','maskADCP(''axes_ButtonDownFcn'',gcbo,[],guidata(gcbo))'); if ~isempty(clims), caxis(clims); else caxis('auto'); end % TODO - colorbar has trouble with NaNs if ~isnan(cdf{varset{iax}}(idx(1):idx(2),:)'); handles.mydata.caxes{iax} = colorbar('location','EastOutside'); end ylabel(sprintf('%s, %s',varset{iax},cdf{'D'}.units(:))); if iax == 4, datetick('x','keepticks','keeplimits'); else set(gca,'XTickLabel',[]); end set(gca,'Tag',sprintf('axis%d',iax)) if showmask, hold on mask = msk{varset{iax}}(idx(1):idx(2),:)'; goods = find(mask == 0); bads = find(mask == 1); mask(bads) = handles.mydata.fill; mask(goods) = NaN; %mhand(iax) = image(handles.mydata.tm(idx(1):idx(2)),handles.mydata.cells,mask); mhand(iax) = pcolor(handles.mydata.tm(idx(1):idx(2)),handles.mydata.cells,mask); set(mhand(iax),'ButtonDownFcn','maskADCP(''axes_ButtonDownFcn'',gcbo,[],guidata(gcbo))'); shading flat hold off end set(gca,'DrawMode','normal') end case '1d', for iax = 1:4, eval(sprintf('axes(handles.axes%d);',iax)) cla; if ~isempty(cdf{varset{iax}}), % some are odd sets data = cdf{varset{iax}}(idx(1):idx(2),:)'; phand(iax) = plot(handles.mydata.tm(idx(1):idx(2)),data); ylabel(sprintf('%s, %s',varset{iax},cdf{varset{iax}}.units(:))); if iax == 4, datetick('x','keepticks','keeplimits'); else set(gca,'XTickLabel',[]); end ylims = get(gca,'Ylim'); set(phand(iax),'ButtonDownFcn','maskADCP(''axes_ButtonDownFcn'',gcbo,[],guidata(gcbo))'); if showmask, hold on mask = msk{varset{iax}}(idx(1):idx(2),:)'; goods = find(mask == 0); bads = find(mask == 1); mask(bads) = data(bads); mask(goods) = NaN; mhand(iax) = plot(handles.mydata.tm(idx(1):idx(2)),mask,'r'); set(mhand(iax),'ButtonDownFcn','maskADCP(''axes_ButtonDownFcn'',gcbo,[],guidata(gcbo))'); set(gca,'Ylim',ylims) hold off end else % make a dummy plot phand(iax) = plot(handles.mydata.tm(idx(1):idx(2)),... zeros(length(handles.mydata.tm(idx(1):idx(2))),1),'w'); ylabel('none'); if iax == 4, datetick('x','keepticks','keeplimits'); else set(gca,'XTickLabel',[]); end ylims = get(gca,'Ylim'); text(0.5,0.5,'Empty plot','units','normalized') end set(gca,'Tag',sprintf('axis%d',iax)) end end if handles.mydata.initialize, handles.mydata.initialize = 0; end % Update handles structure % gcbo = handle of objcte whos call back is executing % note that hObject will be [] if something other than a direct callback % calls this function hObject = gcf; guidata(gcf, handles); %guidata(hObject, handles); % --- Outputs from this function are returned to the command line. function varargout = maskADCP_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure %varargout{1} = handles.output; % --- Executes on slider movement. function sliderTimeShift_Callback(hObject, eventdata, handles) % hObject handle to sliderTimeShift (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) newtmstart = round(get(hObject,'Value')); % this is the *middle* value %disp(datestr(newtmstart)) if newtmstart > (handles.mydata.tm(end)-handles.mydata.days2view), newtmstart = handles.mydata.tm(end)-handles.mydata.days2view; elseif newtmstart < handles.mydata.tm(1), newtmstart = handles.mydata.tm(1); end handles.mydata.idx2view(1) = find(handles.mydata.tm >= newtmstart, 1,'first'); newtmend = newtmstart+handles.mydata.days2view; if newtmend > handles.mydata.tm(end), newtmend = handles.mydata.tm(end); elseif newtmend < handles.mydata.tm(1), newtmend = handles.mydata.tm(1)+handles.mydata.days2view; end handles.mydata.idx2view(2) = ... find(handles.mydata.tm >= newtmend, 1,'first'); disp(sprintf('viewing from %s to %s', datestr(handles.mydata.tm(handles.mydata.idx2view(1))),... datestr(handles.mydata.tm(handles.mydata.idx2view(2))))); % Update handles structure guidata(gcf, handles); %guidata(hObject, handles); updateplot(gcf, handles); %updateplot(hObject, handles); % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider % --- Executes during object creation, after setting all properties. function sliderTimeShift_CreateFcn(hObject, eventdata, handles) % hObject handle to sliderTimeShift (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end % --- Executes on selection change in listboxWhichPlot. function listboxWhichPlot_Callback(hObject, eventdata, handles) % hObject handle to listboxWhichPlot (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: contents = get(hObject,'String') returns listboxWhichPlot contents as cell array % contents{get(hObject,'Value')} returns selected item from listboxWhichPlot handles.mydata.Curplotset = get(hObject,'Value'); % Update handles structure guidata(gcf, handles); %guidata(hObject, handles); updateplot(gcf, handles); %updateplot(hObject, handles); % --- Executes during object creation, after setting all properties. function listboxWhichPlot_CreateFcn(hObject, eventdata, handles) % hObject handle to listboxWhichPlot (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: listbox controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes on mouse press over figure background, over a disabled or % --- inactive control, or over an axes background. function figure1_WindowButtonDownFcn(hObject, eventdata, handles) % hObject handle to figure1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % disp(sprintf('figure1_WindowButtonDownFcn: working in %s', get(gco,'Tag'))) % this always gets executed. % --- Executes on mouse press over axes background. % had to be made the call back function of the plot object function axes_ButtonDownFcn(hObject, eventdata, handles) % hObject handle to axes1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) %disp(sprintf('axes_ButtonDownFcn: working in %s', get(gca,'Tag'))) %don't do anything if there's no mask file open if ~isfield(handles.mydata,'msk') || isempty(handles.mydata.msk), disp('No mask file open') return end % location and size of the rubberband box as [x y width height], where x and y define % the lower left corner, and width and height define the size. initialRect is in % the units specified by the current figure's Units property, and measured from the % lower left corner of the figure window. point1 = get(gca,'CurrentPoint'); % button down detected finalRect = rbbox; % return figure units point2 = get(gca,'CurrentPoint'); % button up detected point1 = point1(1,1:2); % extract x and y point2 = point2(1,1:2); p1 = min(point1,point2); % calculate locations offset = abs(point1-point2); % and dimensions x = [p1(1) p1(1)+offset(1) p1(1)+offset(1) p1(1) p1(1)]; y = [p1(2) p1(2) p1(2)+offset(2) p1(2)+offset(2) p1(2)]; % hold on % axis manual % plot(x,y) if strcmp(handles.mydata.shapes(handles.mydata.Curplotset),'2d'), for iax = 1:4, eval(sprintf('axes(handles.axes%d);',iax)) hold on plot(x,y) end else hold on plot(x,y) handles.mydata.TaggedAxis = sscanf(get(gca,'Tag'),'axis%d'); end % now organize the results into iformation that can be added to the mask file handles.mydata.mask.bbox = [min(x) max(x) min(y) max(y)]; % ask user if they want to apply mask all variables handles.mydata.mask.doall = 0; button = questdlg('Apply mask to all variables?','Masking','No'); if ~isempty(button) && strcmpi(button,'Yes'), handles.mydata.mask.doall = 1; update_maskfile(handles) elseif strcmpi(button,'No'), handles.mydata.mask.doall = 0; update_maskfile(handles) else disp('user cancelled, no update applied to the mask file') end guidata(gcf, handles); %guidata(hObject, handles); updateplot(gcf, handles); %updateplot(hObject, handles); function update_maskfile(handles) % set the mask in the file % first, locate the bounding box in terms of file indeces % the bounding box is in whatever the x and y units were in the plot, % mainly depth and time bbox = handles.mydata.mask.bbox; % translate x/tm into index junk = find(handles.mydata.tm >= bbox(1),1,'first'); if ~isempty(junk), tmidx(1) = junk; elseif bbox(1) < 1, tmidx(1) = 1; elseif bbox(1) > length(handles.mydata.tm), tmidx(1) = length(handles.mydata.tm); end junk = find(handles.mydata.tm >= bbox(2),1,'first'); if ~isempty(junk), tmidx(2) = junk; elseif bbox(2) < 1, tmidx(2) = 1; elseif bbox(2) > length(handles.mydata.tm), tmidx(2) = length(handles.mydata.tm); end if strcmp(handles.mydata.shapes(handles.mydata.Curplotset),'2d'), junk = find(handles.mydata.cells >= bbox(3),1,'first'); if ~isempty(junk), binidx(1) = junk; elseif bbox(3) < 1, binidx(1) = 1; elseif bbox(3) > handles.mydata.cells, binidx(1) = handles.mydata.cells; end junk = find(handles.mydata.cells >= bbox(4),1,'first'); if ~isempty(junk), binidx(2) = junk; elseif bbox(4) < 1, binidx(2) = 1; elseif bbox(4) > handles.mydata.cells, binidx(2) = length(handles.mydata.cells); end else binidx(1) = 1; binidx(2) = 1; end % check one more time! if (tmidx(1)<1) || (tmidx(1)>length(handles.mydata.tm)) || ... (tmidx(2)<1) || (tmidx(2)>length(handles.mydata.tm)) || ... (binidx(1)<1) || (binidx(1)>length(handles.mydata.cells)) || ... (binidx(2)<1) || (binidx(2)>length(handles.mydata.cells)) , disp('mask was out of bounds of the range of the data in the file') return end % give it a go in the mask file msk = handles.mydata.msk; % what variables get the mask? if ~handles.mydata.mask.doall, % just do the variables in the window varset = handles.mydata.varset{handles.mydata.Curplotset}; % cell array of varnames if strcmp(handles.mydata.shapes(handles.mydata.Curplotset),'1d'), varset = varset(handles.mydata.TaggedAxis); end else allvars = ncnames(var(msk)); n = 1; nomask = 0; for vidx = 1:length(allvars), % is this one of the never to be masked variables? for nmidx = 1:length(handles.mydata.mask.nomaskvars), if strcmp(allvars{vidx},handles.mydata.mask.nomaskvars{nmidx}), nomask = 1; end end if nomask, nomask = 0; else varset{n} = allvars{vidx}; n = n+1; end end end disp(sprintf('RDI Ensemble number range to be masked are %d to %d',... msk{'Rec'}(tmidx(1)), msk{'Rec'}(tmidx(2)))); disp(sprintf('That''s from %s to %s',... datestr(handles.mydata.tm(tmidx(1))), datestr(handles.mydata.tm(tmidx(2))))); % now update the mask file if isempty(handles.mydata.masktoggle), disp('mask toggle variable was empty, applying mask') end for ivar = 1:length(varset), if length(dim(msk{varset{ivar}})) == 1, % one dimensional theMask = ones(tmidx(2)-tmidx(1)+1,1).*handles.mydata.masktoggle; msk{varset{ivar}}(tmidx(1):tmidx(2)) = theMask; disp(sprintf('Masked %s from file index %d to %d',varset{ivar},tmidx(1),tmidx(2))) elseif length(dim(msk{varset{ivar}})) == 2, % two dimensional theMask = ones(tmidx(2)-tmidx(1)+1,binidx(2)-binidx(1)+1).*handles.mydata.masktoggle; msk{varset{ivar}}(tmidx(1):tmidx(2),binidx(1):binidx(2)) = theMask; disp(sprintf('Masked %s from file index %d to %d and bins %d to %d',... varset{ivar},tmidx(1),tmidx(2),binidx(1),binidx(2))) else % this shouldn't be in an ADCP file disp('This variable has more dimensions than expected in an ADCP file') end end return % --- Executes on button press in maskfilebutton. function maskfilebutton_Callback(hObject, eventdata, handles) % hObject handle to maskfilebutton (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % first see if a mask file is open: if isfield(handles.mydata,'msk') && ~isempty(handles.mydata.msk), close(handles.mydata.msk); set(handles.maskfilebutton,'BackgroundColor',[0.92549 0.913725 0.847059]) set(handles.maskfilebutton,'String','Push for mask file') set(handles.masktogglebutton,'BackgroundColor',[0.92549 0.913725 0.847059]) set(handles.masktogglebutton,'String','Not Masking') %msgbox(sprintf('%s is closed',handles.mydata.maskfile)) handles.mydata.msk = []; handles.mydata.maskfile = []; handles.mydata.masktoggle = []; set(handles.figure1,'UserData',{handles.mydata.cdf}); else handles = getmaskfile(handles); end guidata(gcf, handles); %guidata(hObject, handles); updateplot(gcf, handles); %updateplot(hObject, handles); function handles = getmaskfile(handles) if ~isfield(handles.mydata,'maskfile'), handles.mydata.maskfile = []; end if isempty(handles.mydata.maskfile), Curdir = pwd; pathname = fileparts(handles.mydata.datafile); if isempty(pathname), pathname = '.'; end cd(pathname); [filename, pathname] = uigetfile('*.msk','Open a netCDF mask file'); cd(Curdir); if ~filename, disp('User cancelled, no mask file opened') return; end handles.mydata.maskfile = fullfile(pathname, filename); end % open the netCDF file and do the basic checks handles.mydata.msk = netcdf(handles.mydata.maskfile,'write'); if isempty(handles.mydata.msk), disp('problem opening mask file %s',handles.mydata.maskfile); return; end if isempty(handles.mydata.msk.CreatedBy(:)) || ... ~strcmp(handles.mydata.msk.CreatedBy(:),'mkadcpmask'), disp('file %s is not an ADCP mask file',handles.mydata.maskfile); return; end set(handles.figure1,'UserData',{handles.mydata.cdf, handles.mydata.msk}); [pathname, filename, fileext] = fileparts(handles.mydata.maskfile); set(handles.maskfilebutton,'String',[filename, fileext]); set(handles.maskfilebutton,'BackgroundColor',[1 0 0]); set(handles.masktogglebutton,'String','Masking'); set(handles.masktogglebutton,'BackgroundColor',[1 0 0]); set(handles.masktogglebutton,'Tooltipstring','Push to switch to unmask mode') handles.mydata.masktoggle = 1; guidata(gcf, handles); %guidata(hObject, handles); % --- Executes during object deletion, before destroying properties. function figure1_DeleteFcn(hObject, eventdata, handles) % hObject handle to figure1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) disp('in figure1_DeleteFcn') % -------------------------------------------------------------------- function maskADCPmenu_Callback(hObject, eventdata, handles) % hObject handle to maskADCPmenu (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % -------------------------------------------------------------------- function SetClims_Callback(hObject, eventdata, handles) % hObject handle to SetClims (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) disp('in SetClims') clims = handles.mydata.clims{handles.mydata.Curplotset}; dlg_title = sprintf('Limits for %s',... handles.mydata.plotset{handles.mydata.Curplotset}); def = {num2str(clims(1)),num2str(clims(2))}; result = inputdlg({'min:','max:'},dlg_title,1,def); if ~isempty(result), handles.mydata.clims{handles.mydata.Curplotset} = ... [str2double(result{1}), str2double(result{2})]; guidata(gcf, handles); %guidata(hObject, handles); updateplot(gcf, handles); %updateplot(hObject, handles); end % --- Executes on slider movement. function sliderTimeView_Callback(hObject, eventdata, handles) % hObject handle to sliderTimeView (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to de*middle* value newensspan = round(get(hObject,'Value')); if newensspan > handles.mydata.nens, newensspan = handles.mydata.nens; elseif newensspan < handles.mydata.minensdisplayed, newensspan = handles.mydata.minensdisplayed; end handles.mydata.days2view = newensspan.*handles.mydata.dT; % handles.mydata.idx2view is the start and end netCDF file indeces we're viewing % now move the end index in view tmstart = handles.mydata.tm(handles.mydata.idx2view(1)); newtmend = tmstart + handles.mydata.days2view; if newtmend > handles.mydata.tm(end), newtmend = handles.mydata.tm(end); elseif newtmend < handles.mydata.tm(1), newtmend = handles.mydata.tm(1)+handles.mydata.days2view; end handles.mydata.idx2view(2) = ... find(handles.mydata.tm >= newtmend, 1,'first'); disp(sprintf('viewing from %s to %s', datestr(handles.mydata.tm(handles.mydata.idx2view(1))),... datestr(handles.mydata.tm(handles.mydata.idx2view(2))))); set(handles.textTimeView,'string',sprintf('%5.2f days = %5.2f hours, #%d ensembles',... handles.mydata.days2view, handles.mydata.days2view*24, ... handles.mydata.idx2view(2) - handles.mydata.idx2view(1))) % update the time slider accordingly newstep = [handles.mydata.days2view/handles.mydata.timespan, 0.1]; if newstep(1) > 1, newstep(1) = 1; end if newstep(1) < 0, newstep(1) = 0; end set(handles.sliderTimeShift,'SliderStep',newstep); % Update handles structure guidata(gcf, handles); %guidata(hObject, handles); updateplot(gcf, handles); %updateplot(hObject, handles);termine range of slider % --- Executes during object creation, after setting all properties. function sliderTimeView_CreateFcn(hObject, eventdata, handles) % hObject handle to sliderTimeView (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end % --- Executes on button press in masktogglebutton. function masktogglebutton_Callback(hObject, eventdata, handles) % hObject handle to masktogglebutton (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) if isempty(handles.mydata.masktoggle), warndlg('Mask file is not open'); elseif handles.mydata.masktoggle, % now applying mask, switch set(handles.masktogglebutton,'String','Removing Mask'); set(handles.masktogglebutton,'BackgroundColor',[0 1 0]); set(handles.masktogglebutton,'Tooltipstring','Push to switch to mask mode') handles.mydata.masktoggle = 0; else % change to apply mask set(handles.masktogglebutton,'String','Masking'); set(handles.masktogglebutton,'BackgroundColor',[1 0 0]); set(handles.masktogglebutton,'Tooltipstring','Push to switch to unmask mode') handles.mydata.masktoggle = 1; end guidata(gcf, handles); %guidata(hObject, handles);