function tsgcor_GUI( hTsgGUI ) % tsgcor_GUI % % GUI for correction of TSG data by comparison to samples % this GUI is a children of tsgqc_GUI % % %% COPYRIGHT & LICENSE % Copyright 2007 - IRD US191, all rights reserved. % % This file is part of tsgqc_GUI. % % Datagui 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. % % tsgqc_GUI 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 Datagui; if not, write to the Free Software % Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA %% Initialization tasks % ******************** clc % Screen limits for the GUI % ------------------------- set(0,'Units','normalized'); guiLimits = get(0,'ScreenSize'); guiLimits(1) = guiLimits(1) + 0.05; guiLimits(2) = guiLimits(2) + 0.05; guiLimits(3) = guiLimits(3) - 0.1; guiLimits(4) = guiLimits(4) - 0.2; % Create and then hide the GUI as it is being constructed. % -------------------------------------------------------- hTsgCorGUI = figure(... 'Name', 'TSG Correction', ... 'NumberTitle', 'off', ... 'Resize', 'on', ... 'Menubar','none', ... 'Toolbar', 'none', ... 'Tag', 'ButtonMotionOff', ... 'WindowButtonMotionFcn', @MouseMotion, ... 'CloseRequestFcn', @QuitProgram,... 'HandleVisibility','callback',... 'Visible','on',... 'Units', 'normalized',... 'Position',guiLimits); % Get the CONSTANTS % ----------------- cst = getappdata( hTsgGUI, 'constante'); % Construct the Menu % ----------------- hFileMenu = uimenu(... 'Parent', hTsgCorGUI,... 'HandleVisibility','callback',... 'Label', 'File'); 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',hTsgCorGUI, ... 'HandleVisibility','callback'); hZoomToggletool = uitoggletool(... % Open Zoom toolbar button 'Parent',hToolbar,... 'Separator', 'on', ... 'TooltipString','Zoom',... 'CData', iconRead(fullfile(matlabroot, ... '/toolbox/matlab/icons/zoom.mat')),... 'HandleVisibility','callback', ... 'Tag','PUSHTOOL_ZOOM',... 'Enable', 'off',... 'OffCallback', @Zoom_OffMenuCallback,... 'ONCallback', @Zoom_OnMenuCallback); hPanToggletool = uitoggletool(... % Open Pan toolbar button 'Parent',hToolbar,... 'TooltipString','Pan',... 'CData',iconRead(fullfile(matlabroot, ... '/toolbox/matlab/icons/pan.mat')),... 'HandleVisibility','callback', ... 'Tag','PUSHTOOL_PAN',... 'Enable', 'off',... 'OffCallback', @Pan_OffMenuCallback,... 'ONCallback', @Pan_OnMenuCallback); %'ClickedCallback', @PanMenuCallback); hBottlePushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','Plot the Samples',... 'Separator', 'on', ... 'Tag', 'off', ... 'CData',iconRead(... [DEFAULT_PATH_FILE 'tsg_icon' filesep 'bottleicon.mat']),... 'HandleVisibility','callback', ... 'ClickedCallback', @BottleMenuCallback); hStartlimitPushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','Start time',... 'Separator', 'on', ... 'Tag', 'off', ... 'CData',iconRead(... [DEFAULT_PATH_FILE 'tsg_icon' filesep 'startlimit.mat']),... 'HandleVisibility','callback', ... 'ClickedCallback', @TimeLimitCallback); hEndlimitPushtool = uipushtool(... % Open toolbar button 'Parent',hToolbar,... 'TooltipString','End time',... 'Tag', 'off', ... 'CData',iconRead(... [DEFAULT_PATH_FILE 'tsg_icon' filesep 'endlimit.mat']),... 'HandleVisibility','callback', ... 'ClickedCallback', @TimeLimitCallback); % Static text that displays the position, salinity and temperature % ---------------------------------------------------------------- hInfoText = uicontrol(... 'Parent', hTsgCorGUI, ... 'Style', 'text', ... 'Fontsize', 12, ... 'Fontweight', 'bold', ... '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', hTsgCorGUI, ... 'Units', 'normalized', ... 'Visible', 'off', ... 'HandleVisibility','callback', ... 'Position',[.25, .6, .7, .32]); hPlotAxes(2) = axes(... % the axes for plotting sample 'Parent', hTsgCorGUI, ... 'Units', 'normalized', ... 'Visible', 'off', ... 'HandleVisibility','callback', ... 'Position',[.25, .3, .7, .25]); hPlotAxes(3) = axes(... % the axes for plotting ship velocity 'Parent', hTsgCorGUI, ... 'Units', 'normalized', ... 'Visible', 'off', ... 'HandleVisibility','callback', ... 'Position',[.25, .05, .7, .2]); % Choose the date limits for the correction % -------------------------------------------------- % Create the uipanel hpDateLimit = uipanel( ... 'Parent', hTsgCorGUI, ... 'Title', 'Date Limits', ... 'Units', 'normalized', ... 'FontSize', 11, ... 'Fontweight', 'bold', ... 'BackgroundColor', 'white',... 'Position',[.01 .75 .2 .19]); htDateMin = uicontrol( ... 'Parent', hpDateLimit, ... 'Style', 'Text', ... 'String', 'Minimum (yyyy-mm-dd hh:mm:ss)', ... 'HorizontalAlignment', 'left', ... 'Units', 'normalized', ... 'backgroundcolor', 'white', ... 'FontSize', 10, ... 'Position',[.05 .8 .9 .15]); hetDateMin = uicontrol( ... 'Parent', hpDateLimit, ... 'Style', 'edit', ... 'Units', 'normalized', ... 'FontSize', 10, ... 'Position',[.05 .6 .9 .18]); htDateMax = uicontrol( ... 'Parent', hpDateLimit, ... 'Style', 'Text', ... 'String', 'Maximum (yyyy-mm-dd hh:mm:ss)', ... 'HorizontalAlignment', 'left', ... 'Units', 'normalized', ... 'backgroundcolor', 'white', ... 'FontSize', 10, ... 'Position',[.05 .3 .9 .15]); hetDateMax = uicontrol( ... 'Parent', hpDateLimit, ... 'Style', 'edit', ... 'Units', 'normalized', ... 'FontSize', 10, ... 'Position',[.05 .1 .9 .18]); % Choose the correction method % -------------------------------------------------- % Create the button group hbgMethod = uibuttongroup( ... 'Parent',hTsgCorGUI, ... 'Title','Correction Method', ... 'Units', 'normalized', ... 'FontSize',11, ... 'Fontweight', 'bold', ... 'BackgroundColor','white',... 'Position',[.01 .6 .2 .14]); % Create 2 radio buttons in the button group hrbLinear = uicontrol( ... 'Style','pushbutton', ... 'Parent',hbgMethod, ... 'Units', 'normalized', ... 'String','Linear adjustment',... 'pos',[.05 .55 .9 .4], ... 'HandleVisibility','callback', ... 'Callback', @CorLinearCallback); hrbMedian = uicontrol( ... 'Style','pushbutton', ... 'Parent',hbgMethod, ... 'Units', 'normalized', ... 'String','Running median filter',... 'pos',[.05 .05 .9 .4],... 'HandleVisibility','callback', ... 'Callback', @CorMedianCallback); % Initialize some button group properties set(hbgMethod,'SelectionChangeFcn',@selcbk); set(hbgMethod,'SelectedObject',[]); % No selection set(hbgMethod,'Visible','on'); % Construct the context menu to delete samples % -------------------------------------------- hSampleCmenu = uicontextmenu(... 'Parent', hTsgCorGUI, ... 'HandleVisibility','callback' ); hQcSampleNocontrol = uimenu(... 'Parent', hSampleCmenu,... 'HandleVisibility','off', ... 'Label', 'No control',... 'ForegroundColor', 'k',... 'Callback', @Qc); hQcSampleGood = uimenu(... 'Parent', hSampleCmenu,... 'HandleVisibility','off', ... 'Label', 'Good',... 'ForegroundColor', 'b',... 'Callback', @Qc); hQcSampleBad = uimenu(... 'Parent', hSampleCmenu,... 'HandleVisibility','off', ... 'Label', 'Bad',... 'ForegroundColor', 'r',... 'Callback', @Qc); % Pointer set to watch during reading and plotting % ------------------------------------------------ set( hTsgCorGUI, 'Pointer', 'watch' ); % Get the data useful to the correction GUI % ----------------------------------------- tsg = getappdata( hTsgGUI, 'tsg_data' ); % Merge bucket and external samples % --------------------------------- tsg_mergesample( hTsgGUI ); dateMin = datestr(tsg.TIME(1), 31); dateMax = datestr(tsg.TIME(end), 31); set( hetDateMin, 'String', dateMin); set( hetDateMax, 'String', dateMax); % dt between 2 tsg measurements TSG_SAMPLING_TIME = tsg.TIME(2) - tsg.TIME(1); % Running average of TSG time series over TSG_DT_SMOOTH hour. [psal_smooth, nval] = ... dev_moveaverage(tsg.TIME, tsg.PSAL, cst.TSG_DT_SMOOTH, cst.TSG_STDMAX); % Compute the sample-TSG differences sample = dev_diffTsgSample(tsg, psal_smooth, sample, TSG_SAMPLING_TIME); % Trac� % ----- tsg_plot_SalTsgSample( hTsgGUI, hPlotAxes ); % Pointer reset to arrow % ---------------------- set( hTsgCorGUI, 'Pointer', 'arrow' ); % The callback to detect the mouse motion can be set to on % -------------------------------------------------------- set( hTsgCorGUI, 'Tag', 'ButtonMotionOn'); % Callbacks for tsgcqc_GUI % ************************ %---------------------------------------------------------------------- function ZoomMenuCallback(hObject, eventdata) % Callback function run when the ... % Returns a zoom mode object for the figure handle % ------------------------------------------------ hZoom = zoom(hTsgCorGUI); % 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(hTsgCorGUI,'Pointer','arrow'); set(hEndlimitPushtool, 'Tag', 'off' ); set(hStartlimitPushtool, 'Tag', 'off' ); zoom on zoomAdaptiveDateTicks('on'); end end %---------------------------------------------------------------------- function PanMenuCallback(hObject, eventdata) % Callback function run when the .... % Returns a pan mode object for the figure handle % ----------------------------------------------- hPan = pan(hTsgCorGUI); % 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(hTsgCorGUI,'Pointer','arrow'); set(hEndlimitPushtool, 'Tag', 'off' ); set(hStartlimitPushtool, 'Tag', 'off' ); pan on panAdaptiveDateTicks('on'); end end %---------------------------------------------------------------------- function TimeLimitCallback(hObject, eventdata) % Callback function run when the .... % Desactivate the Zoom and Pan functions. % --------------------------------------- zoom off; pan off panAdaptiveDateTicks('off');zoomAdaptiveDateTicks('off'); % Retrieve named application data % ------------------------------- tsg = getappdata( hTsgGUI, 'tsg_data'); % Toggle the tag of the Qc pushbutton to 'on' or 'off' % ---------------------------------------------------- switch get(hObject, 'Tag'); case 'off' set(hObject, 'Tag', 'on' ); set( hTsgCorGUI, 'Pointer', 'crosshair'); case 'on' set(hObject, 'Tag', 'off' ); set(hTsgCorGUI,'Pointer','arrow'); end % Wait for key press % ------------------ [x, y] = ginput(1); % Write the date in the Editable uicontrol % ---------------------------------------- if hObject == hEndlimitPushtool set( hetDateMax, 'String', datestr(x, 31)); else set( hetDateMin, 'String', datestr(x, 31)); end set(hTsgCorGUI,'Pointer','arrow'); end %---------------------------------------------------------------------- function BottleMenuCallback(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'); % Toggle the tag of the Qc pushbutton to 'on' or 'off' % ---------------------------------------------------- switch get(hBottlePushtool, 'Tag'); case 'off' set(hBottlePushtool, 'Tag', 'on' ); set(hPlotAxes(2),'UIContextMenu', hSampleCmenu); set(hTsgCorGUI, 'Pointer', 'crosshair'); case 'on' set(hBottlePushtool, 'Tag', 'off' ); set(hPlotAxes(2),'UIContextMenu', []); set(hTsgCorGUI,'Pointer','arrow'); end qualityCode = -1; ind = []; while strcmp( get(hBottlePushtool, 'Tag'),'on') k = waitforbuttonpress; % If the QC pushbutton is pressed we quit the callback % ---------------------------------------------------- if strcmp( get(hBottlePushtool, 'Tag'),'off') % Desactivate the context menu use to choose the Quality Codes % ---------------------------------------------- set(hSampleCmenu, 'Visible', 'off'); break end % Test if the right mouse button is clicked % ----------------------------------------- if strcmp(get(hTsgCorGUI, '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( hTsgCorGUI, '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 % Retrieve named application data % ------------------------------- sample = getappdata( hTsgGUI, 'sample'); ind = find(sample.DAYD > p1(1,1) & sample.DAYD < p2(1,1) & ... sample.SSPS_DIF > p1(1,2) & sample.SSPS_DIF < p2(1,2)); % Selection made : Mouse motion callback re-activated % --------------------------------------------------- set( hTsgCorGUI, '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 tsg = getappdata( hTsgGUI, 'tsg_data'); sample.SSPS_QC(ind) = tsg.qc.Code.ACTIVE; % Save the modifications % ---------------------- setappdata( hTsgGUI, 'sample', sample); axes(hPlotAxes(2)); hold on color = ['o' tsg.qc.Color.ACTIVE]; plot(sample.DAYD(ind), sample.SSPS_DIF(ind), color ); hold off end end end %--------------------------------------------------------------------- function Qc(hObject, eventdata) % Callback function run when the QC context menu is selected % Retrieve Default Quality Code and Color % --------------------------------------- tsg = getappdata( hTsgGUI, 'qcColor'); switch hObject case hQcSampleNocontrol tsg.qc.Code.ACTIVE = tsg.qc.Code.NO_CONTROL; tsg.qc.Color.ACTIVE = tsg.qc.Color.NO_CONTROL; case hQcSampleGood tsg.qc.Code.ACTIVE = tsg.qc.Code.GOOD; tsg.qc.Color.ACTIVE = tsg.qc.Color.GOOD; case hQcSampleBad tsg.qc.Code.ACTIVE = tsg.qc.Code.PROBABLY_BAD; tsg.qc.Color.ACTIVE = tsg.qc.Color.PROBABLY_BAD; end setappdata( hMainFig, 'tsg_data', tsg ); % uiwait in the QCMenuCallback function % ------------------------------------- uiresume end %--------------------------------------------------------------------- function MouseMotion(hObject, eventdata) % Test if the callback can be activated % ------------------------------------- if strcmp( get( hTsgCorGUI, 'Tag'), 'ButtonMotionOn') % Retrieve named application data % ------------------------------- tsg = getappdata( hTsgGUI, '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); % use sprintf with format instead strcat & num2str but flag % - don't work with 0, eg %+07.4f set( hInfoText, 'String',... sprintf(['%s - Latitude = %s - Longitude = %s '... ' - Salinity = %07.4f - Temperature = %07.4f'],... datestr(tsg.TIME(indCursor(1)),'dd/mm/yyyy HH:MM'),... dd2dm(tsg.LATITUDE(indCursor(1)),0), ... dd2dm(tsg.LONGITUDE(indCursor(1)),1), ... tsg.PSAL(indCursor(1)), ... tsg.TEMP_TSG(indCursor(1))... )); end end 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( hTsgGUI, fileName ); % if ~error % % end end % ----------------------------------------------------------------- function CorLinearCallback(hObject, eventdata) % Callback function run when msgbox('Method not yet implemented', 'modal' ); end % ----------------------------------------------------------------- function CorMedianCallback(hObject, eventdata) % Callback function run when msgbox('Method not yet implemented', 'modal' ); % Get the time limits for the correction A TESTER % -------------------------------------- %dateMin = get( hetDateMin, 'String'); %dateMax = get( hetDateMax, 'String'); % Correction % ---------- % tsg = dev_corMethod1(tsg, sample, dateMin, dateMax, cst.COR_TIME_WINDOWS); % Update application data 'tsg' % ---------------------------- %tsg = getappdata( hTsgGUI, 'tsg_data' ); 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 QuitProgram; end else selection = ... questdlg(['Quit ' get(hTsgCorGUI, 'Name') '?'],... ['Quit ' get(hTsgCorGUI, 'Name') '?'],... 'Yes', 'No', 'Yes'); if strcmp(selection, 'No') return; else QuitProgram; end end end % ---------------------------------------------------------------- function QuitProgram(hObject, eventdata) delete(hTsgCorGUI); end end