diff --git a/TODOS b/TODOS index d04e3fa03c4cb212fbe6d2058148b5d93e29ed73..8407f842b1d39439a0dafd5b30d097e09a61b06c 100644 --- a/TODOS +++ b/TODOS @@ -72,6 +72,17 @@ III - Bottle_OffMenuCallback set(hdl_Toggletool, 'Enable', 'off'); set(hdl_Toggletool, 'State', 'off'); +27/01/2008 +---------- +Mettre en place des tests automatiques pour la validation des donnees : +0 < SSS < 45 +-3 < SST < 40 +etc. +Attention aux affichages des bouteilles dans le module de correction : +la fonction 'diffTsgSample' calcule les differences quand les codes de +qualité des TSG et des WS sont inferieurs a 2 (PROBABLY_GOOD). Les autres +bouteilles ne seront pas affichees dans l'axe 2 (differences de salinite). +Le QC des bouteilles devra etre fait dans l'axe 1. diff --git a/tsg_util/corTsgMethod1.m b/tsg_util/corTsgMethod1.m index 25811cb51929b94ed8eff9b9a5fae30dd9149174..d6c6b7e81f2fc1d0ef16bb94d236d25420e9c050 100644 --- a/tsg_util/corTsgMethod1.m +++ b/tsg_util/corTsgMethod1.m @@ -1,4 +1,4 @@ -function corTsgMethod1(hMainFig, dateMin, dateMax) +function [error] = corTsgMethod1(hMainFig, dateMin, dateMax) % % Correct the TSG salinity time series with the Water sample. % Use the median value of TIME_WINDOWS water sample to compute the @@ -10,6 +10,8 @@ function corTsgMethod1(hMainFig, dateMin, dateMax) % dateMax ...... the correction is applied between dateMin and date Max % % Output +% Error ........ 1 everything OK +% ........ -1 dateMax <= date Min % % TO DO % corTsgMethod1.m @@ -20,6 +22,7 @@ function corTsgMethod1(hMainFig, dateMin, dateMax) % 4) Test on the validation code. do we apply the correction whatever the % is the code ? % 5) Return an Error code ? +% 6) Test Date_Min < Date_Max % Get application data % -------------------- @@ -34,61 +37,75 @@ TIME_WINDOWS = tsg.cst.COR_TIME_WINDOWS; % ------------------------------------------------------ dt = find(sample.DAYD >= dateMin & sample.DAYD <= dateMax); -% TO DO : Initialisation de la structure 'cor' -% -------------------------------------------- +if dateMax > dateMin -% -------------------------------------------- -for i = 1 : length(dt) + % TO DO : Initialisation de la structure 'cor' + % -------------------------------------------- - % Find the sample within TIME_WINDOWS - % ------------------------------------ - ind = find( sample.DAYD(dt) >= sample.DAYD(dt(i)) - TIME_WINDOWS/2 &... - sample.DAYD(dt) <= sample.DAYD(dt(i)) + TIME_WINDOWS/2); + % -------------------------------------------- + for i = 1 : length(dt) - % Compute the median difference and error within TIME_WINDOWS - % ----------------------------------------------------------- - if ~isempty(ind) - cor.DAYD(i) = sample.DAYD(i); - cor.DIFF(i) = median(sample.SSPS_DIF(ind)); - cor.ERROR(i) = std(sample.SSPS_DIF(ind))/sqrt(length(ind)); - cor.NVALUE(i) = length(ind); + % Find the sample within TIME_WINDOWS + % ------------------------------------ + ind = find( sample.DAYD(dt) >= sample.DAYD(dt(i)) - TIME_WINDOWS/2 &... + sample.DAYD(dt) <= sample.DAYD(dt(i)) + TIME_WINDOWS/2); + + % Compute the median difference and error within TIME_WINDOWS + % ----------------------------------------------------------- + if ~isempty(ind) + cor.DAYD(i) = sample.DAYD(i); + cor.DIFF(i) = median(sample.SSPS_DIF(ind)); + cor.ERROR(i) = std(sample.SSPS_DIF(ind))/sqrt(length(ind)); + cor.NVALUE(i) = length(ind); + end end -end -% The error is maximum if the median is computed with less than 4 samples -% ----------------------------------------------------------------------- -cor.ERROR( find(cor.NVALUE < 4) ) = 1; + % The error is maximum if the median is computed with less than 4 samples + % ----------------------------------------------------------------------- + cor.ERROR( cor.NVALUE < 4 ) = 1; -% The correction is applied between dateMin and dateMax -% We attribute to dateMin the first correction computed -% and to dateMax the last one -% -% Find the tsg date in the interval dateMin-dateMax -% ------------------------------------------------- -dtTsg = find(tsg.DAYD >= dateMin & tsg.DAYD <= dateMax); - -if cor.DAYD(1) ~= dateMin - cor.DAYD = [tsg.DAYD(dtTsg(1)) cor.DAYD]; - cor.DIFF = [cor.DIFF(1) cor.DIFF]; - cor.ERROR = [cor.ERROR(1) cor.ERROR]; - cor.NVALUE = [cor.NVALUE(1) cor.NVALUE]; -end -if cor.DAYD(end) ~= dateMax - cor.DAYD = [cor.DAYD tsg.DAYD(dtTsg(end))]; - cor.DIFF = [cor.DIFF cor.DIFF(end)]; - cor.ERROR = [cor.ERROR cor.ERROR(end)]; - cor.NVALUE = [cor.NVALUE cor.NVALUE(end)]; -end + % The correction is applied between dateMin and dateMax + % We attribute to dateMin the first correction computed + % and to dateMax the last one + % + % Find the tsg date in the interval dateMin-dateMax + % ------------------------------------------------- + dtTsg = find(tsg.DAYD >= dateMin & tsg.DAYD <= dateMax); + + if cor.DAYD(1) ~= dateMin + cor.DAYD = [tsg.DAYD(dtTsg(1)) cor.DAYD]; + cor.DIFF = [cor.DIFF(1) cor.DIFF]; + cor.ERROR = [cor.ERROR(1) cor.ERROR]; + cor.NVALUE = [cor.NVALUE(1) cor.NVALUE]; + end + if cor.DAYD(end) ~= dateMax + cor.DAYD = [cor.DAYD tsg.DAYD(dtTsg(end))]; + cor.DIFF = [cor.DIFF cor.DIFF(end)]; + cor.ERROR = [cor.ERROR cor.ERROR(end)]; + cor.NVALUE = [cor.NVALUE cor.NVALUE(end)]; + end -% The correction is applied to the TSG between dateMin and dateMax using -% a linear interpolation -% ---------------------------------------------------------------------- -tsg.SSPS_ADJUSTED(dtTsg) = tsg.SSPS(dtTsg) + ... - interp1(cor.DAYD, cor.DIFF, tsg.DAYD(dtTsg)); -tsg.SSPS_ADJUSTED_ERROR(dtTsg) = ... + % The correction is applied to the TSG between dateMin and dateMax using + % a linear interpolation + % ---------------------------------------------------------------------- + tsg.SSPS_ADJUSTED(dtTsg) = tsg.SSPS(dtTsg) + ... + interp1(cor.DAYD, cor.DIFF, tsg.DAYD(dtTsg)); + tsg.SSPS_ADJUSTED_ERROR(dtTsg) = ... interp1(cor.DAYD, cor.ERROR, tsg.DAYD(dtTsg)); - -% Update tsg application data -% --------------------------- -setappdata( hMainFig, 'tsg_data', tsg); + + % Update tsg application data + % --------------------------- + setappdata( hMainFig, 'tsg_data', tsg); + + % everything OK + % ------------- + error = 1; + +else + + % DateMax <= DateMin + % ------------------ + error = -1; + +end diff --git a/tsg_util/diffTsgSample.m b/tsg_util/diffTsgSample.m index 895b416e083055030f9d12a8c08c0fe5ffa15acb..7059d6f7f993c2d5685888651ee939bdb7aeb89c 100644 --- a/tsg_util/diffTsgSample.m +++ b/tsg_util/diffTsgSample.m @@ -9,37 +9,52 @@ function diffTsgSample(hTsgGUI) tsg = getappdata( hTsgGUI, 'tsg_data'); sample = getappdata( hTsgGUI, 'sample' ); +% Get PROBABLY_GOOD code +% ---------------------- +probablyGoodCode = get(tsg.qc.hash, 'PROBABLY_GOOD', 'code'); + +% Consider only tsg data with NO_CONTROL, GOOD and PROBABLY_GOOD code +% ------------------------------------------------------------------- +indTsg = find( tsg.SSPS_QC <= probablyGoodCode ); + [m, n] = size(sample.SSPS); -% time difference between 2 succesive TSG measurements -% ---------------------------------------------------- -dt = tsg.DAYD(2) - tsg.DAYD(1); +% time difference between 2 successive TSG measurements +% Not use anymore. Now use a constant tsg.cst.TSG_WS_TIMEDIFF in the test +% ----------------------------------------------------------------------- +% dt = min(diff(tsg.DAYD)); -% Loop on the samples -% ------------------- +% Loop on the samples with NO_CONTROL, GOOD and PROBABLY_GOOD code +% ---------------------------------------------------------------- for i= 1 : m - - % Indice of the TSG measurement the closest to the sample - % -------------------------------------------------------- + + if sample.SSPS_QC(i) <= probablyGoodCode + + % Compute the differences between the sample and the time serie + % ------------------------------------------------------------- timeDiff = abs(tsg.DAYD - sample.DAYD(i)); - - [timeMin, indMin] = min(timeDiff); - - if timeDiff(indMin) < dt && ~isnan(tsg.ssps.smooth.val(indMin)) - - sample.SSPS_SMOOTH(i) = tsg.ssps.smooth.val(indMin); - sample.SSPS_QC(i) = 1; - else - sample.SSPS_QC(i) = 0; + + % Compute the indice of the TSG measurement the closest to the sample + % taking into account the TSG quality code + % ------------------------------------------------------------------- + [timeMin, indMin] = min(timeDiff(indTsg)); + indMin = indTsg( indMin ); + + % Keep the smooth TSG value + % ------------------------- + if timeDiff(indMin) < tsg.cst.TSG_WS_TIMEDIFF && ... + ~isnan(tsg.ssps.smooth.val(indMin)) + + sample.SSPS_SMOOTH(i) = tsg.ssps.smooth.val(indMin); + end + end end % Salinity difference : Sample minus smoothed TSG % ----------------------------------------------- -indSample = find( sample.SSPS_QC == 1 ); -sample.SSPS_DIF(indSample) = ... - sample.SSPS(indSample) - sample.SSPS_SMOOTH(indSample); +sample.SSPS_DIF = sample.SSPS - sample.SSPS_SMOOTH; % update the sample structures in the application % ------------------------------------------------ -setappdata( hTsgGUI, 'sample', sample ); +setappdata( hTsgGUI, 'sample', sample ); \ No newline at end of file diff --git a/tsg_util/tsg_initialisation.m b/tsg_util/tsg_initialisation.m index ba734a95daa958a99b55bdd9e5eb7e1e8a84d77b..ea2062cba44a43984f739b95d0d16a7a4ddc8ca9 100644 --- a/tsg_util/tsg_initialisation.m +++ b/tsg_util/tsg_initialisation.m @@ -91,17 +91,22 @@ tsg.queue = queue; tsg.cst.TSG_DT_SMOOTH = datenum(0, 0, 0, 1, 0 , 0); % Smoothing of tsg time series : -% Salinity, in one 1 hour interval, should not depart the average for more +% Salinity, in 1 hour interval, should not depart the average for more % than SAL_STD_MAX standard deviation -% ----------------------------------------------------------------------- +% -------------------------------------------------------------------- tsg.cst.TSG_STDMAX = 0.1; % Correction is estimated by computing the median value of X tsg-sample % differences -% Amount of days used to compute the correction +% Time window in days used to compute the correction % --------------------------------------------------------------------- tsg.cst.COR_TIME_WINDOWS = 10; +% Maximum time difference between tsg data and water sample used to +% compute the difference : 5 minutes. +% ----------------------------------------------------------------- +tsg.cst.TSG_WS_TIMEDIFF = datenum(0, 0, 0, 0, 5, 0); + % Get variables list codes from class tsg_nc with file 'tsg_ncvar.csv' % -------------------------------------------------------------------- ncv = tsg_nc('tsg_ncvar.csv'); diff --git a/tsg_util/tsg_mergesample.m b/tsg_util/tsg_mergesample.m index 941caa5d0a4f998041cde049b42bb02de7093128..439df07e69d13955f14b47c93157c3802438bbd8 100644 --- a/tsg_util/tsg_mergesample.m +++ b/tsg_util/tsg_mergesample.m @@ -34,8 +34,12 @@ if ~isempty(tsg.SSPS_WS) sample.LONX = [sample.LONX; tsg.LONX_WS]; sample.SSPS = [sample.SSPS; tsg.SSPS_WS]; sample.SSPS_QC = [sample.SSPS_QC; tsg.SSPS_WS_QC]; - sample.SSPS_DIF = [sample.SSPS_DIF; zeros(size(sample.DAYD))]; - sample.SSPS_SMOOTH = [sample.SSPS_SMOOTH; zeros(size(sample.DAYD))]; + + % Fill the structure with NaN. NaN is test in diffTsgSample + % --------------------------------------------------------- + sample.SSPS_DIF = [sample.SSPS_DIF; NaN*ones(size(sample.DAYD))]; + sample.SSPS_SMOOTH = [sample.SSPS_SMOOTH; NaN*ones(size(sample.DAYD))]; + sample.SSPS_TYPE = [sample.SSPS_TYPE; ones(size(sample.DAYD))]; end @@ -50,8 +54,12 @@ if ~isempty(tsg.SSPS_EXT) sample.LONX = [sample.LONX; tsg.LONX_EXT]; sample.SSPS = [sample.SSPS; tsg.SSPS_EXT]; sample.SSPS_QC = [sample.SSPS_QC; tsg.SSPS_EXT_QC]; - sample.SSPS_DIF = [sample.SSPS_DIF; zeros(size(tsg.DAYD_EXT))]; - sample.SSPS_SMOOTH = [sample.SSPS_SMOOTH; zeros(size(tsg.DAYD_EXT))]; + + % Fill the structure with NaN. NaN is test in diffTsgSample + % --------------------------------------------------------- + sample.SSPS_DIF = [sample.SSPS_DIF; NaN*ones(size(tsg.DAYD_EXT))]; + sample.SSPS_SMOOTH = [sample.SSPS_SMOOTH; NaN*ones(size(tsg.DAYD_EXT))]; + sample.SSPS_TYPE = [sample.SSPS_TYPE; tsg.SSPS_EXT_TYPE]; end diff --git a/tsg_util/tsg_moveaverage.m b/tsg_util/tsg_moveaverage.m index a9a76f823b4235046af3663a3276e2bec01e2939..9ea494e046e2dc2c32bdea7e65af3801cce3d060 100644 --- a/tsg_util/tsg_moveaverage.m +++ b/tsg_util/tsg_moveaverage.m @@ -16,8 +16,6 @@ tsg = getappdata( hTsgGUI, 'tsg_data'); % Memory allocation % ----------------- -%tsg.ssps.smooth = zeros( size(tsg.SSPS) ); -%tsg.ssps.smooth.nval = zeros( size(tsg.SSPS) ); smooth = zeros( size(tsg.SSPS) ); nval = zeros( size(tsg.SSPS) ); @@ -36,11 +34,11 @@ for i = 1:length(tsg.SSPS) if ~isempty(ind2) - currentStd = Inf; + currentStd = Inf; previousStd = 0; % Compare Standard Deviation to the MAX acceptable STD - % ------------------------------------------------ + % ---------------------------------------------------- while currentStd > tsg.cst.TSG_STDMAX && currentStd ~= previousStd previousStd = currentStd; @@ -52,9 +50,8 @@ for i = 1:length(tsg.SSPS) % Indices of 'good' values of Param % --------------------------------- - ind2 = find( tsg.SSPS(ind1) >= meanParam - currentStd & ... - tsg.SSPS(ind1) <= meanParam + currentStd); - ind2 = ind1( ind2 ); + ind2 = ind1( tsg.SSPS(ind1) >= meanParam - currentStd & ... + tsg.SSPS(ind1) <= meanParam + currentStd ); end smooth(i) = nanmean( tsg.SSPS(ind2) ); @@ -71,5 +68,4 @@ tsg.ssps.smooth.nval = nval; % Update the tsg structure in the application % -------------------------------------------- -setappdata( hTsgGUI, 'tsg_data', tsg); - +setappdata( hTsgGUI, 'tsg_data', tsg); \ No newline at end of file diff --git a/tsgqc_GUI.m b/tsgqc_GUI.m index 9ed75e194966cbce1053c1984a123875a5d7e176..9dec098b24936b9c494abf4e04917f9043e7be74 100644 --- a/tsgqc_GUI.m +++ b/tsgqc_GUI.m @@ -1326,10 +1326,6 @@ end % Merge bucket and external samples % --------------------------------- tsg_mergesample( hMainFig ); - - % Compute the sample-TSG differences - % ---------------------------------- - diffTsgSample( hMainFig ); % plot Salinity Difference % ------------------------ @@ -1447,6 +1443,19 @@ end set( hetDateMin, 'String', datestr(x, 31)); end + % Color of date limit in red if dateMax <=datMin + % ------------------------------------------------------------------- + dateMin = datenum(get( hetDateMin, 'String'), 'yyyy-mm-dd HH:MM:SS'); + dateMax = datenum(get( hetDateMax, 'String'), 'yyyy-mm-dd HH:MM:SS'); + + if dateMax <= dateMin + set( hetDateMin, 'ForegroundColor','r'); + set( hetDateMax, 'ForegroundColor','r'); + else + set( hetDateMin, 'ForegroundColor','k'); + set( hetDateMax, 'ForegroundColor','k'); + end + % Enable ButtonMotion on main fig % ------------------------------- %set( hMainFig, 'WindowButtonMotionFcn', @MouseMotion); @@ -1502,13 +1511,23 @@ end % -------------------------------------- dateMin = datenum(get( hetDateMin, 'String'), 'yyyy-mm-dd HH:MM:SS'); dateMax = datenum(get( hetDateMax, 'String'), 'yyyy-mm-dd HH:MM:SS'); + + % Compute the sample-TSG differences + % ---------------------------------- + diffTsgSample( hMainFig ); % Correction % ---------- - corTsgMethod1(hMainFig, dateMin, dateMax); + error = corTsgMethod1(hMainFig, dateMin, dateMax); - plot_TsgAdjusted(hMainFig, hPlotAxes) + switch error + case 1 + plot_TsgAdjusted(hMainFig, hPlotAxes); + case -1 + msgbox('Date limits are not correct', 'Correction module', 'warn', 'modal'); + end + end %% Clim_OffMenuCallback