function tsgqc_GUI % % % 5 novembre 2007 % Initialization tasks % ******************** clc % Determine the directory where the program is store. % functions (icons) should be store at a lower level % MAKE the path working on UNIX machine % --------------------------------------------------- tsgqcname = mfilename; fulltsgqcname = mfilename('fullpath'); DEFAULT_PATH_FILE = strrep(fulltsgqcname, tsgqcname, '') ; % Screen limits for the GUI % ------------------------- set(0,'Units','normalized'); guiLimits = get(0,'ScreenSize'); guiLimits(1) = guiLimits(1) + 0.05; guiLimits(2) = guiLimits(2) + 0.1; guiLimits(3) = guiLimits(3) - 0.1; guiLimits(4) = guiLimits(4) - 0.2; % Create and then hide the GUI as it is being constructed. % -------------------------------------------------------- hMainFig = figure(... 'Name', 'TSG Validation', ... 'NumberTitle', 'off', ... 'Resize', 'on', ... 'Menubar','none', ... 'Toolbar', 'none', ... 'Tag', 'ButtonMotionOff', ... 'WindowButtonMotionFcn', @MouseMotion, ... 'HandleVisibility','callback',... 'Visible','on',... 'Units', 'normalized',... 'Position',guiLimits); % Construct the Menu % ----------------- hFileMenu = uimenu(... 'Parent', hMainFig,... 'HandleVisibility','callback',... 'Label', 'File'); hOpenMenu = uimenu(... 'Parent', hFileMenu,... 'Tag', 'off', ... 'Label','Open',... 'Accelerator','O',... 'HandleVisibility','callback',... 'Callback', @OpenMenuCallback); hSaveMenu = uimenu(... 'Parent', hFileMenu,... 'Label','Save',... 'Accelerator','S',... 'Tag', 'off', ... 'HandleVisibility','callback',... 'Callback',@SaveMenuCallback); hQuitMenu = uimenu(... 'Parent',hFileMenu,... 'Label','Quit',... 'Separator','on',... 'Accelerator','Q',... 'HandleVisibility','callback',... 'Callback',@QuitMenuCallback); % Construct the Toolbar % ----------------- hToolbar = uitoolbar(... % Toolbar for Open and Print buttons 'Parent',hMainFig, ... 'HandleVisibility','callback'); hSavePushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','Save file',... 'CData',iconRead( ... [DEFAULT_PATH_FILE 'tsg_icon\savedoc.mat']),... 'HandleVisibility','callback', ... 'ClickedCallback', @SaveMenuCallback); hZoomPushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'Separator', 'on', ... 'TooltipString','Zoom',... 'CData', iconRead(fullfile(matlabroot, ... '/toolbox/matlab/icons/zoom.mat')),... 'HandleVisibility','callback', ... 'ClickedCallback', @ZoomMenuCallback); hPanPushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','Pan',... 'CData',iconRead(fullfile(matlabroot, ... '/toolbox/matlab/icons/pan.mat')),... 'HandleVisibility','callback', ... 'ClickedCallback', @PanMenuCallback); hQCPushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','Validation codes',... 'Separator', 'on', ... 'Tag', 'off', ... 'CData',iconRead(... [DEFAULT_PATH_FILE 'tsg_icon\qcicon.mat']),... 'HandleVisibility','callback', ... 'ClickedCallback', @QCMenuCallback); hMapPushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','Map and ship track',... 'Separator', 'on', ... 'Tag', 'off', ... 'CData',iconRead(... [DEFAULT_PATH_FILE 'tsg_icon\mapicon.mat']),... 'HandleVisibility','callback', ... 'ClickedCallback', @MapMenuCallback); hClimPushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','Climatology',... 'Separator', 'on', ... 'Tag', 'off', ... 'CData',iconRead(... [DEFAULT_PATH_FILE 'tsg_icon\climicon.mat']),... 'HandleVisibility','callback', ... 'ClickedCallback', @ClimMenuCallback); hBottlePushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','Plot the Buckets',... 'Separator', 'on', ... 'Tag', 'off', ... 'CData',iconRead(... [DEFAULT_PATH_FILE 'tsg_icon\bottleicon.mat']),... 'HandleVisibility','callback', ... 'ClickedCallback', @BottleMenuCallback); % Static text that displays the position, salinity and temperature % ---------------------------------------------------------------- hInfoText = uicontrol(... 'Parent', hMainFig, ... 'Style', 'text', ... 'Fontsize', 12, ... 'Visible','on',... 'Units', 'normalized',... 'String', 'Information sur la position du curseur', ... 'Position', [.05, .95, .9, .03]); % Construct the plot axes % ----------------------- hPlotAxes(1) = axes(... % the axes for plotting Salinity 'Parent', hMainFig, ... 'Units', 'normalized', ... 'Visible', 'off', ... 'HandleVisibility','callback', ... 'Position',[.05, .6, .9, .32]); hPlotAxes(2) = axes(... % the axes for plotting temperature 'Parent', hMainFig, ... 'Units', 'normalized', ... 'Visible', 'off', ... 'HandleVisibility','callback', ... 'Position',[.05, .3, .9, .25]); hPlotAxes(3) = axes(... % the axes for plotting ship velocity 'Parent', hMainFig, ... 'Units', 'normalized', ... 'Visible', 'off', ... 'HandleVisibility','callback', ... 'Position',[.05, .05, .9, .2]); % The map will be plot in a uipanel hMapPanel = uipanel( ... 'Parent', hMainFig, ... 'Units', 'normalized', ... 'Visible', 'off', ... 'Position',[0, 0, 1, .57]); hPlotAxes(4) = axes(... % the axes for plotting ship track map 'Parent', hMapPanel, ... 'Units', 'normalized', ... 'Visible', 'off', ... 'Color', 'none', ... 'Tag', 'off', ... 'UserData', [], ... 'HandleVisibility','callback', ... 'Position',[.05, .05, .9, .9]); % Construct the context menu for the Quality control codes % ------------------------------------------------------- hQcCmenu = uicontextmenu(... 'Parent', hMainFig, ... 'HandleVisibility','callback' ); hQcCmenuNocontrol = uimenu(... 'Parent', hQcCmenu,... 'HandleVisibility','off', ... 'Label', 'No control',... 'ForegroundColor', 'k',... 'Callback', @QcNoControl); hQcCmenuGood = uimenu(... 'Parent', hQcCmenu,... 'HandleVisibility','off', ... 'Label', 'Good',... 'ForegroundColor', 'b',... 'Callback', @QcGood); hQcCmenuProbGood = uimenu(... 'Parent', hQcCmenu,... 'HandleVisibility','off', ... 'Label', 'Probably Good',... 'Callback', @QcProbGood,... 'ForegroundColor', 'g'); hQcCmenuProbBad = uimenu(... 'Parent', hQcCmenu,... 'HandleVisibility','off', ... 'Label', 'Probably bad',... 'ForegroundColor', 'm',... 'Callback', @QcProbBad); hQcCmenuBad = uimenu(... 'Parent', hQcCmenu,... 'HandleVisibility','off', ... 'Label', 'Bad',... 'ForegroundColor', 'r',... 'Callback', @QcBad); % Initialisation % -------------- tsg_initialisation(hMainFig, hQcCmenu) % Callbacks for tsgcqc_GUI % ************************ %---------------------------------------------------------------------- function OpenMenuCallback(hObject, eventdata) % Callback function run when the Open menu item is selected % Pointer set to watch during reading and plotting % ------------------------------------------------ set( hMainFig, 'Pointer', 'watch' ); % Make the filename % ATTENTION : function OpenMenuCallback(hObject, eventdata) % This has to be made general for UNIX and WINDOWS system % --------------------------------------------------------- [filename, pathname] = uigetfile( ... [DEFAULT_PATH_FILE '*.*'], 'Pick an NetCdf file'); if ~isequal(filename, 0) % Read the data % ------------- error = tsg_readTsgData( hMainFig, filename ); if error % The file has been open and read % ------------------------------- set( hOpenMenu, 'Tag', 'on' ); % The callback to detect the mouse motion can be set to on % -------------------------------------------------------- set( hMainFig, 'Tag', 'ButtonMotionOn'); % Make the Salinity, temperature and velocity plot % ------------------------------------------------ tsg_plot_SalTempVel( hMainFig, hPlotAxes ); % Plot the Map with the ship trackline % ------------------------------------ tsg_plotmap( hMainFig, hPlotAxes) end end % Pointer reset to arrow % ---------------------- set( hMainFig, 'Pointer', 'arrow' ); end %---------------------------------------------------------------------- function ZoomMenuCallback(hObject, eventdata) % Callback function run when the Open menu item is selected % Returns a zoom mode object for the figure handle hZoom = zoom(hMainFig); % Specifies whether this mode is currently enabled on the figure zoomOnOff = get(hZoom, 'Enable' ); switch zoomOnOff case 'on' zoom off zoomAdaptiveDateTicks('off'); case 'off' pan off set(hQCPushtool, 'Tag', 'off' ); zoom on zoomAdaptiveDateTicks('on'); end % zoomColor = get(hZoomPushtool,'CData'); % set(hZoomplusPushtool,'CData', zoomColor); end %---------------------------------------------------------------------- function PanMenuCallback(hObject, eventdata) % Callback function run when the Open menu item is selected % Returns a pan mode object for the figure handle hPan = pan(hMainFig); % Specifies whether this mode is currently enabled on the figure panOnOff = get(hPan, 'Enable' ); switch panOnOff case 'on' pan off panAdaptiveDateTicks('off'); case 'off' zoom off set(hQCPushtool, 'Tag', 'off' ); pan on panAdaptiveDateTicks('on'); end end %---------------------------------------------------------------------- function QCMenuCallback(gcbo, eventdata,handles) % Callback function run when the QC pushbutton is selected % Desactivate the Zoom and Pan functions. % --------------------------------------- zoom off; pan off panAdaptiveDateTicks('off');zoomAdaptiveDateTicks('off'); % Retrieve named application data % ------------------------------- tsg = getappdata( hMainFig, 'tsg_data'); % Toggle the tag of the Qc pushbutton to 'on' or 'off' % ---------------------------------------------------- switch get(hQCPushtool, 'Tag'); case 'off' set(hQCPushtool, 'Tag', 'on' ); set(hPlotAxes(1),'UIContextMenu', hQcCmenu); set( hMainFig, 'Pointer', 'crosshair'); case 'on' set(hQCPushtool, 'Tag', 'off' ); set(hPlotAxes(1),'UIContextMenu', []); set(hMainFig,'Pointer','arrow'); end qualityCode = -1; ind = []; while strcmp( get(hQCPushtool, 'Tag'),'on') k = waitforbuttonpress; % If the QC pushbutton is pressed we quit the callback % ---------------------------------------------------- if strcmp( get(hQCPushtool, 'Tag'),'off') % Desactivate the context menu use to choose the % Quality Codes % ---------------------------------------------- set(hQcCmenu, 'Visible', 'off'); break end % Test if the right mouse button is clicked % ----------------------------------------- if strcmp(get(hMainFig, 'SelectionType'), 'alt') && ~isempty(ind) % Wait for a QC Context Menu choice : The user choose the % quality code % ------------------------------------------------------- uiwait qualityCode = 1; else % Mouse motion callback desactivated when a selection is % made. Otherwise there is a conflict with the map if it % is activated % ------------------------------------------------------- set( hMainFig, 'Tag', 'ButtonMotionOff'); % Selection of the data within the figure % --------------------------------------- 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); p2 = max(point1,point2); % calculate locations ind = find(tsg.TIME > p1(1,1) & tsg.TIME < p2(1,1) & ... tsg.PSAL > p1(1,2) & tsg.PSAL < p2(1,2)); % As soon as a modification took place the data should be % saved % ------------------------------------------------------- set( hSaveMenu, 'Tag', 'on' ); % Selection made : Mouse motion callback re-activated % -------------------------------------------------- set( hMainFig, 'Tag', 'ButtonMotionOn'); end % Plot the data with the color of the chosen quality Code. % Is it the right place for this source code ???? % -------------------------------------------------------- if qualityCode ~= -1 quality = get( hQcCmenu, 'UserData'); tsg.PSAL_QC(ind) = quality.Code; % Save the modifications % ---------------------- setappdata( hMainFig, 'tsg_data', tsg); axes(hPlotAxes(1)); hold on color = ['.' quality.Color]; plot(tsg.TIME(ind), tsg.PSAL(ind), color ); hold off end end end %--------------------------------------------------------------------- function QcNoControl(hObject, eventdata) % Callback function run when the QC context menu is selected % Retrieve Default Quality Code and Color % --------------------------------------- qc = getappdata( hMainFig, 'qcColor'); quality.Code = qc.Code.NO_CONTROL; quality.Color = qc.Color.NO_CONTROL; set( hQcCmenu, 'UserData', quality ); % uiwait in the QCMenuCallback function % ------------------------------------- uiresume end %--------------------------------------------------------------------- function QcGood(hObject, eventdata) % Callback function run when the QC context menu is selected % Retrieve named application data % ------------------------------- qc = getappdata( hMainFig, 'qcColor'); quality.Code = qc.Code.GOOD; quality.Color = qc.Color.GOOD; set( hQcCmenu, 'UserData', quality ); % uiwait in the QCMenuCallback function % ------------------------------------- uiresume end %--------------------------------------------------------------------- function QcProbGood(hObject, eventdata) % Callback function run when the QC context menu is selected % Retrieve named application data % ------------------------------- qc = getappdata( hMainFig, 'qcColor'); quality.Code = qc.Code.PROBABLY_GOOD; quality.Color = qc.Color.PROBABLY_GOOD; set( hQcCmenu, 'UserData', quality ); % uiwait in the QCMenuCallback function % ------------------------------------- uiresume end %--------------------------------------------------------------------- function QcProbBad(hObject, eventdata) % Callback function run when the QC context menu is selected % Retrieve named application data % ------------------------------- qc = getappdata( hMainFig, 'qcColor'); quality.Code = qc.Code.PROBABLY_BAD; quality.Color = qc.Color.PROBABLY_BAD; set( hQcCmenu, 'UserData', quality ); % uiwait in the QCMenuCallback function % ------------------------------------- uiresume end %--------------------------------------------------------------------- function QcBad(hObject, eventdata) % Callback function run when the QC context menu is selected % Retrieve named application data % ------------------------------- qc = getappdata( hMainFig, 'qcColor'); quality.Code = qc.Code.BAD; quality.Color = qc.Color.BAD; set( hQcCmenu, 'UserData', quality ); % uiwait in the QCMenuCallback function % ------------------------------------- uiresume end %--------------------------------------------------------------------- function MouseMotion(hObject, eventdata) % Test if the callback can be activated % ------------------------------------- if strcmp( get( hMainFig, 'Tag'), 'ButtonMotionOn') % Retrieve named application data % ------------------------------- tsg = getappdata( hMainFig, 'tsg_data'); % Get the mouse position % ---------------------- point = get(gcf,'CurrentPoint'); if point(1) > .05 && point(2) > .6 && point(1) < .95 && point(2) < .92 % Get current position of cusor and return its coordinates in % axes with handle h_axes % ----------------------------------------------------------- [x, y] = gpos(hPlotAxes(1)); if x > tsg.TIME(1) && x < tsg.TIME(end) indCursor = find( tsg.TIME > x); set( hInfoText, 'String',... strcat(... datestr(tsg.TIME(indCursor(1)),'dd mmmm yyyy'),... ' - Latitute = ', num2str(tsg.LATITUDE(indCursor(1))), ... ' - Longitude = ', num2str(tsg.LONGITUDE(indCursor(1))), ... ' - Salinity = ', num2str(tsg.PSAL(indCursor(1))), ... ' - Temperature = ', num2str(tsg.TEMP_TSG(indCursor(1)))... )); % Plot the position on the map if this one is active % -------------------------------------------------- if strcmp( get(hMapPanel, 'Visible'), 'on') % Select the map axes % ------------------- axes( hPlotAxes(4)); if isempty( get(hMapPanel, 'UserData')) hMarker = m_line( ... tsg.LONGITUDE(indCursor(1)), tsg.LATITUDE(indCursor(1)),... 'Marker','o','MarkerSize',5, ... 'Color','r', 'MarkerFaceColor','r'); set(hMapPanel, 'UserData', hMarker) else delete(get(hMapPanel, 'UserData')); hMarker = m_line( ... tsg.LONGITUDE(indCursor(1)), tsg.LATITUDE(indCursor(1)),... 'Marker','o','MarkerSize',5, ... 'Color','r', 'MarkerFaceColor','r'); set(hMapPanel, 'UserData', hMarker); end end end end end end %--------------------------------------------------------------------- function MapMenuCallback(hObject, eventdata) % Callback function run when the Map tool bar item is selected % Make the earth map visible or not if strcmp( get(hMapPanel, 'Visible'), 'off' ) set(hMapPanel, 'Visible', 'on' ); else set(hMapPanel, 'Visible', 'off' ); end end %--------------------------------------------------------------------- function BottleMenuCallback(hObject, eventdata) % Callback function run when the Bottle tool bar item is selected % % Plot or Delete the buckets measurements on the Salinity graph % % Need to read them right now - but they will be soon in the NetCdf % file % Test if the bucket Push button has been pressed % ----------------------------------------------- if strcmp( get(hBottlePushtool, 'Tag'), 'off') % Bucket Push button - Tag set to 'on' % ------------------------------------ set( hBottlePushtool, 'Tag', 'on' ); % Test if the TSG and bucket files have been read % ----------------------------------------------- if strcmp( get(hOpenMenu, 'Tag'), 'on' ) && ... isempty(getappdata( hMainFig, 'bucket_data')) % Build the filename % ------------------ [filename, pathname] = uigetfile( ... [DEFAULT_PATH_FILE '*.btl'], 'Pick a bottle file'); if ~isequal(filename, 0) % Read the data % ------------- error = tsg_readBucketData(hMainFig, filename ); end end % Retrieve named application data % ------------------------------- bucket = getappdata( hMainFig, 'bucket_data'); hLine = get( hPlotAxes(1), 'UserData'); % Plot the bucket if the file has been read % ----------------------------------------- if ~isempty(bucket) axes( hPlotAxes(1) ); hLine.Bucket = line( ... bucket.TIME_WS, bucket.PSAL_WS,... 'Linestyle', 'none', 'Marker','o','MarkerSize',5, ... 'Color','r', 'MarkerFaceColor','r'); % Store the handle of the bucketline % ---------------------------------- set( hPlotAxes(1), 'UserData', hLine ); end else set( hBottlePushtool, 'Tag', 'off' ); % The bucket pushbutton has been pressed again : % Delete the bucket on figure % ---------------------------------------------- hLine = get( hPlotAxes(1), 'UserData'); delete(hLine.Bucket); end end %--------------------------------------------------------------------- function ClimMenuCallback(hObject, eventdata) % Callback function run when the ClimMenu menu item is selected % % Plot or delete salinity climatology over Salinity plot % % Function to be written % Test if the climatology Push button has been pressed % ---------------------------------------------------- if strcmp( get(hClimPushtool, 'Tag'), 'off') % Climatology push button - Tag set to 'on' % ----------------------------------------- set( hClimPushtool, 'Tag', 'on' ); % Test if the TSG and bucket files have been read % ----------------------------------------------- if strcmp( get(hOpenMenu, 'Tag'), 'on' ) % Plot a Fake Climatology % ----------------------- tsg = getappdata( hMainFig, 'tsg_data' ); hLine = get( hPlotAxes(1), 'UserData'); axes( hPlotAxes(1) ); hLine.stdClimMinus = line( ... tsg.TIME, tsg.PSAL - .5,'Linestyle', '-', 'Color','r'); hLine.stdClimPlus = line( ... tsg.TIME, tsg.PSAL + .5,'Linestyle', '-', 'Color','r'); % Store the handle of the bucketline % ---------------------------------- set( hPlotAxes(1), 'UserData', hLine ); end else set( hClimPushtool, 'Tag', 'off' ); % The bucket pushbutton has been pressed again : % Delete the bucket on figure % ---------------------------------------------- hLine = get( hPlotAxes(1), 'UserData'); delete(hLine.stdClimMinus); delete(hLine.stdClimPlus); end end % ----------------------------------------------------------------- function SaveMenuCallback(hObject, eventdata) % Callback function run when the Save menu item is selected [fileName, pathName, filterIndex] = uiputfile('*.txt', ... 'Save file name'); fileName = [pathName fileName]; error = tsg_writeTsgData( hMainFig, fileName ); if ~error % end end % ----------------------------------------------------------------- function QuitMenuCallback(hObject, eventdata) % Callback function run when the Quit menu item is selected % If the data have been modified and not save, the program % propose to save the data % -------------------------------------------------------- if strcmp( get( hSaveMenu, 'Tag' ), 'on') selection = ... questdlg('The file has been modified. Do you want to save it ?',... 'Save before Quit?',... 'Yes', 'No', 'Yes'); if strcmp(selection, 'Yes') return; else delete(hMainFig); end else selection = ... questdlg(['Quit ' get(hMainFig, 'Name') '?'],... ['Quit ' get(hMainFig, 'Name') '?'],... 'Yes', 'No', 'Yes'); if strcmp(selection, 'No') return; else delete(hMainFig); end end end end