From 1746e7f21949eb222063edf7ce446911c39ddba8 Mon Sep 17 00:00:00 2001
From: Yves Gouriou <yves.gouriou@ird.fr>
Date: Thu, 31 Jan 2008 15:55:30 +0000
Subject: [PATCH] =?UTF-8?q?Am=C3=A9lioration=20de=20la=20m=C3=A9thode=20de?=
 =?UTF-8?q?=20correction=20par=20comparaison=20aux=20bouteilles?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 TODOS                         |  11 ++++
 tsg_util/corTsgMethod1.m      | 117 +++++++++++++++++++---------------
 tsg_util/diffTsgSample.m      |  57 +++++++++++------
 tsg_util/tsg_initialisation.m |  11 +++-
 tsg_util/tsg_mergesample.m    |  16 +++--
 tsg_util/tsg_moveaverage.m    |  14 ++--
 tsgqc_GUI.m                   |  31 +++++++--
 7 files changed, 164 insertions(+), 93 deletions(-)

diff --git a/TODOS b/TODOS
index d04e3fa..8407f84 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 25811cb..d6c6b7e 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 895b416..7059d6f 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 ba734a9..ea2062c 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 941caa5..439df07 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 a9a76f8..9ea494e 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 9ed75e1..9dec098 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
-- 
GitLab