diff --git a/tsg_io/private/GPStodegdec.m b/tsg_io/private/GPStodegdec.m new file mode 100644 index 0000000000000000000000000000000000000000..6ba440361e03b4fc0ebf035679a84b4619f9309f --- /dev/null +++ b/tsg_io/private/GPStodegdec.m @@ -0,0 +1,63 @@ +function OutData = GPStodegdec( InData ) +% +% Cette fonction permet de convertir des mesures GPS +% au format 25°13.34N en degre decimal. +% InData = {'25°13.34N', '15', '45°34.56S'}; + +% Dans cette premiere partie j'extraie du format GPS +% les degre, les minutes et l'hemisphere. + +% Look ahead from current position and test if ° is found. +% L'option ONCE ne conserve qu'une occurence. Au lieu de +% creer des cellules de cellules. On ne cree qu'une cellule +% de string. Plus facile a gerer. +% -------------------------------------------------------- +[v1 v2 v3 deg v5 v6] = regexp(InData, '\w*(?=°)', 'once'); + +% Look ahead from current position and test if . is found. +% -------------------------------------------------------- +[v1 v2 v3 min v5 v6] = regexp(InData, '(?<=°)\d*', 'once'); + +% Look ahead from current position and test if numbers are found +% -------------------------------------------------------- +[v1 v2 v3 sec v5 v6] = regexp(InData, '(?<=\.)\d*', 'once'); + +% Find any alphabetic character +% ----------------------------- +[v1 v2 v3 NSEW v5 v6] = regexp(InData, '[A-Z]', 'once'); + + +% Remplir les cellules vides par des NaN +% -------------------------------------- +IsEmpty = find( strcmp( deg, '') == 1 ); +deg(IsEmpty, 1) = {'NaN'}; +min(IsEmpty, 1) = {'NaN'}; +sec(IsEmpty, 1) = {'NaN'}; +NSEW(IsEmpty, 1) = {'NaN'}; + +% noNaN = find( strcmp( deg, 'NaN') == 0 ); + +[m n] = size(deg); +degre = NaN*ones(m,n); +minute = NaN*ones(m,n); +seconde = NaN*ones(m,n); + +% Conversion en numerique et en degre decimal +% ------------------------------------------- +degre = str2num( char( deg )); +minute = str2num( char( min )) / 60; +seconde = str2num( char( sec ))* .6 / 3600; + +OutData = degre + minute + seconde; + +% Determination du signe +% ---------------------- +IsNegative = find(strcmp(NSEW, 'S') == 1); +if ~isempty( IsNegative ) + OutData( IsNegative ) = -OutData( IsNegative ); +end +IsNegative = find(strcmp(NSEW, 'W') == 1); +if ~isempty( IsNegative ) + OutData( IsNegative ) = -OutData( IsNegative ); +end + diff --git a/tsg_io/private/choixparametres.m b/tsg_io/private/choixparametres.m new file mode 100644 index 0000000000000000000000000000000000000000..ae81a634e89f07cae25af8a04d348709764637fa --- /dev/null +++ b/tsg_io/private/choixparametres.m @@ -0,0 +1,204 @@ +function [choix, ColNo, paraName, nPara] = choixparametres( fid, DELIMITER ) +% +% Cette fonction permet a l'utilisateur de choisir les parametres presents +% dans le fichier et qui seront utilises par le programme. +% Le choix se fait sur les parametres suivants : +% date, heure, lat, lon +% La fonction retournera systematiquement les parametres suivants +% cond, hcond, sog, cog +% +% [ColNo, nPara] = choixparametres( fid, DELIMITER ); +% +% Input +% fid ........... Numero logique du fichier a decoder +% DELIMITER ..... caractere separant chaque parametre a decoder sur +% une ligne +% +% output +% choix ......... String 'yes' ou 'cancel' qui indique si le programme +% doit s'arreter +% ColNo ......... Structure donnant pour chaque parametre le numero de +% la colonne a lire +% paraName ...... Intitule des parametres de la ligne d'entete +% nPara ......... Nombre de parametre total present dans le fichier +% +% ------------------------------------------------------------------------ + +% Initialisation des indices de colonne que l'on conserve systematiquement +% ------------------------------------------------------------------------- +dateNo = 0; timeNo = 0; tempNo = 0; salNo = 0; condNo = 0; rawNo = 0; +latNo = 0; lonNo = 0; sogNo = 0; cogNo = 0; + +% Lecture de la 1ere ligne +% +% ATTENTION : Je considere que cette ligne est la ligne d'entete +% IL FAUDRAIT FAIRE UN TEST POUR VERIFIER QUE C'EST BIEN UNE LIGNE +% D'ENTETE +% -------------------------------------------------------------- +firstLine = fgets( fid ); + +% Decode la ligne d'entete et place l'intitule de chaque colonne +% dans une variable de type 'cell' : paraName avec nPara elements +% ------------------------------------------------------------------- +[paraName, nPara] = decodestr( firstLine, DELIMITER ); + +% Convertit les intitules de chaque colonne en caracteres minuscules +% ------------------------------------------------------------------ +paraName = lower(paraName); + +% Vector of indices of the list box items that are initially selected. +% -------------------------------------------------------------------- +ind = 0; +for ipar = 1 : nPara + header = char( paraName(1, ipar) ); + if ~isempty(strfind( header, 'date')) && dateNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + dateNo = ipar; + elseif ~isempty(strfind( header, 'time')) && timeNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + timeNo = ipar; + elseif ~isempty(strfind( header, 'temp')) && tempNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + tempNo = ipar; + elseif ~isempty(strfind( header, 'sal')) && salNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + salNo = ipar; + elseif ~isempty(strfind( header, 'cond')) && condNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + condNo = ipar; + elseif ~isempty(strfind( header, 'raw')) && rawNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + rawNo = ipar; + elseif ~isempty(strfind( header, 'lat')) && latNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + latNo = ipar; + elseif ~isempty(strfind( header, 'lon')) && lonNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + lonNo = ipar; + elseif ~isempty(strfind( header, 'sog')) && sogNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + sogNo = ipar; + elseif ~isempty(strfind( header, 'cog')) && cogNo == 0 + ind = ind + 1; + defAnsB(ind) = ipar; + cogNo = ipar; + end +end + +% Tant que 'choix' est egal à 'yes' on propose a l'utilisateur +% de faire le choix des entetes. Si le choix est fait, 'choix' est +% positionne a 'ok' +% ------------------------------------------------------------ +choix = 'yes'; +while strcmp( choix, 'yes' ) + + % Affichage d'une 'boite a liste' pour le choix des parametres + % ------------------------------------------------------------ + [colParaNo, okCol] = listdlg('PromptString', 'Choix des paramètres',... + 'ListString', paraName, 'InitialValue', defAnsB); + + if okCol == 1 + + % Le choix s'est bien passe + % ------------------------- + choix = 'ok'; + + % Initialisation de la structure indiquant le numero de colonnes des parametres + % presents dans le fichier intial et qui seront utilises dans TSG-QC + % -------------------------------------------------------------- + ColNo = struct( 'Date', 0, 'Time', 0, 'Lat', 0, 'Lon', 0, 'Temp', 0,... + 'Sal', 0, 'Cond', 0, 'Raw', 0, 'Sog', 0, 'Cog', 0); + + % Boucle sur les numeros de colonnes des parametres qui seront conserves + % ---------------------------------------------------------------------- + if ~isempty(okCol) + for icol = 1 : length(colParaNo) + + % Le programme conserve systematiquement la conductivite et les valeurs brutes + % ----------------------------------------------------------------------------- + if rawNo ~= 0 + i = find( colParaNo == rawNo ); + if isempty(i) + colParaNo = [colParaNo rawNo]; + end + end + if condNo ~= 0 + i = find( colParaNo == condNo ); + if isempty(i) + colParaNo = [colParaNo condNo]; + end + end + + % Convertion en caracteres + % ------------------------ + header = char( paraName(1, colParaNo(icol)) ); + + % Place les numeros des colonnes dans la structure + % ------------------------------------------------ + if strfind( header, 'date') ~= 0 + ColNo.Date = colParaNo(icol); + elseif strfind( header, 'time') ~= 0 + ColNo.Time = colParaNo(icol); + elseif strfind( header, 'lat') ~= 0 + ColNo.Lat = colParaNo(icol); + elseif strfind( header, 'lon') ~= 0 + ColNo.Lon = colParaNo(icol); + elseif strfind( header, 'temp') ~= 0 + ColNo.Temp = colParaNo(icol); + elseif strfind( header, 'sal') ~= 0 + ColNo.Sal = colParaNo(icol); + elseif strfind( header, 'cond') ~= 0 + ColNo.Cond = colParaNo(icol); + elseif strfind( header, 'raw') ~= 0 + ColNo.Raw = colParaNo(icol); + elseif strfind( header, 'sog') ~= 0 + ColNo.Sog = colParaNo(icol); + elseif strfind( header, 'cog') ~= 0 + ColNo.Cog = colParaNo(icol); + end + end + % ****************** + clear defAnsB + defAnsB = colParaNo; + clear colParaNo + % ****************** + end + + % Gestion d'erreur + % ---------------- + if ColNo.Date == 0 + choix = questdlg('Vous devez choisir une Date !!!',... + 'Aucune date choisie', 'yes', 'cancel', 'yes'); + elseif ColNo.Time == 0 + choix = questdlg('Vous devez choisir une Heure !!!',... + 'Aucune heure choisie', 'yes', 'cancel', 'yes'); + elseif ColNo.Lat == 0 + choix = questdlg('Vous devez choisir une Latitude !!!',... + 'Aucune latitude choisie', 'yes', 'cancel', 'yes'); + elseif ColNo.Lon == 0 + choix = questdlg('Vous devez choisir une Longitude !!!',... + 'Aucune longitude choisie', 'yes', 'cancel', 'yes'); + end + + else + + % On annulle le choix des parametres. Le programme se termine + % ----------------------------------------------------------- + choix = 'cancel'; + + end % fin de test if okCol == 1 + +end % Fin de boucle While + +% Revient en debut de fichier +% --------------------------- +frewind(fid); \ No newline at end of file diff --git a/tsg_io/private/decodeficlabview.m b/tsg_io/private/decodeficlabview.m new file mode 100644 index 0000000000000000000000000000000000000000..b4b16129576e8cf7f85f66e0a122ce8462a32289 --- /dev/null +++ b/tsg_io/private/decodeficlabview.m @@ -0,0 +1,144 @@ +function [date, time, lat, lon, sst, sss, cond, condRaw, sog, cog] =... + decodeficlabview( fid, DELIMITER, ColNo, paraName, nPara ) +% +% Fonction qui permet de lire les fichiers au format LabView +% La fonction : +% - lit les lignes incompletes +% - elimine les lignes d'entetes qui peuvent se trouver a differents +% endroits du fichier +% +% ATTENTION : Je fais l'hypothese que la premiere ligne du fichier +% est une ligne d'entete +% +% input +% fid ........... Numero logique du fichier a decoder +% DELIMITER ..... caractere separant chaque parametre a decoder sur +% une ligne +% nPara ......... Nombre de parametre total present dans le fichier +% +% output +% date .......... Dates - Cellule +% time .......... Heure - Cellule +% lat .......... Latitude - Tableau de double +% lon .......... Longitude - Tableau de double +% sst .......... Temperature - Tableau de double +% sss .......... Salinite - Tableau de double +% cond .......... Conductivite - Tableau de double +% condRaw ....... Conductivite brute - tableau de chaine de caracteres +% sog .......... Vitesse du navire - Tableau de double +% cog .......... Cap du navire - Tableau de double +% +% Mofication +% 23/01/2006 Initialisation de condRaw modifié +% Avant condRaw = NaN*ones(nblig, 1); +% Maintenant condRaw = char(blanks(1)*ones(nblig,1)); +% +% ------------------------------------------------------------------- + + % Le nombre d'elements de l'entete determine le nombre de chaine a lire. + % Je cree ici la chaine de caractere decrivant le format utilise par + % textscan + % -------------------------------------------------------------- + format = []; + for i = 1:nPara + format = [format ' %s']; + end + + % textscan permet de lire a peu pres tout, memes les lignes + % incompletes, plus courtes. + % Par contre les données lues sont enregistrees dans une + % Cellule de cellule + % ATTENTION : + % dans le cas de lignes incompletes textscan n'utilise pas + % enptyValue mais une chaine de caracteres vide + % ----------------------------------------------------------- + data = textscan(fid, format, 'delimiter', DELIMITER, 'emptyValue', NaN); + + % Remplace les chaines de caracteres vides par des NaN + % ---------------------------------------------------- + for icell = 1:length( data ) + vide = find( strcmp( data{icell}, '' ) == 1); + for j = 1 : length(vide) + data{icell}{vide(j)} = 'NaN'; + end + end + + % Selectionne les numeros des lignes qui ne sont pas des entetes + % ATTENTION + % Je fais l'hypothese que la premiere ligne du fichier est une ligne + % d'entete + % ------------------------------------------------------------------ + date = char( data{ColNo.Date} ); + ient = strcmp( data{1}, data{1}{1} ); + ient = find(ient == 0); + + % Initialisation + % -------------- + nblig = length(ient); + date = cell(nblig, 1); + time = cell(nblig, 1); + lat = NaN*ones(nblig, 1); + lon = NaN*ones(nblig, 1); + sst = NaN*ones(nblig, 1); + sss = NaN*ones(nblig, 1); + cond = NaN*ones(nblig, 1); + condRaw = char(blanks(1)*ones(nblig,1)); + sog = NaN*ones(nblig, 1); + cog = NaN*ones(nblig, 1); + + % Selection des parametres utiles au programme et conversion + % La date et l'heure sont stockes dans des cellules + % ---------------------------------------------------------- + if ColNo.Date ~= 0 + A = data(ColNo.Date); + B = char( A{1}(ient) ); + date = cellstr( B ); + end + if ColNo.Time ~= 0 + A = data(ColNo.Time); + B = char( A{1}(ient) ); + time = cellstr( B ); + end + if ColNo.Lat ~=0 + % Test si latitude en degre decimal ou degre minute + % -------------------------------------------------- + lat = str2num( char(data{ColNo.Lat}{ient}) ); + + % lat est vide si les latitudes sont en degres minutes. + % Conversion en degre decimal + % ----------------------------------------------------- + if isempty(lat) + lat = GPStodegdec( cellstr(char(data{ColNo.Lat}{ient})) ); + end + + end + + if ColNo.Lon ~= 0 + lon = str2num( char(data{ColNo.Lon}{ient}) ); + + % lon est vide si les latitudes sont en degres minutes. + % Conversion en degre decimal + % ----------------------------------------------------- + if isempty(lon) + lon = GPStodegdec( cellstr(char(data{ColNo.Lon}{ient})) ); + end + end + + if ColNo.Temp ~= 0 + sst = str2num( char(data{ColNo.Temp}{ient}) ); + end + if ColNo.Sal ~= 0 + sss = str2num( char(data{ColNo.Sal}{ient}) ); + end + if ColNo.Cond ~= 0 + cond = str2num( char(data{ColNo.Cond}{ient}) ); + end + if ColNo.Raw ~= 0 + condRaw = char( data{ColNo.Raw}{ient} ); + end + if ColNo.Sog ~= 0 + sog = str2num( char(data{ColNo.Sog}{ient}) ); + end + if ColNo.Cog ~= 0 + cog = str2num( char(data{ColNo.Cog}{ient}) ); + end \ No newline at end of file diff --git a/tsg_io/private/decodestr.m b/tsg_io/private/decodestr.m new file mode 100644 index 0000000000000000000000000000000000000000..caec50c8a9f96e92e57f3fe3f737f9d4f8e8292f --- /dev/null +++ b/tsg_io/private/decodestr.m @@ -0,0 +1,55 @@ +function [token, nToken] = DecodeStr( string, DELIMITER ) +% +% Retourne les éléments d'une chaine de caractères séparés par +% un delimiteur (virgule, point-virgule, etc.) +% +% [Token, nToken] = LecSadcpQuart( String, Delimiter ) +% +% Input: +% string ...... Chaine de caractères à décimer +% DELIMITEUR ... Caractère séparant les différents élèments +% de la chaine de caractères +% +% Output: +% nToken ...... Nombre d'élèments distincts, séparés par 'Delimiter' +% dans la chaine de caractères 'String' +% token ....... Cellule de dimension (nToken, 1) contenant les +% différents éllèments de la chaine de caractère +% +% 5 janvier 2007 +% +% Modifications +% ---------------------------------------------------------------------- + +% Initialisation de la Cellule +% ---------------------------- +token = cell(1,1); + +% Decode le 1er élèment de la chaine de caractère +% Celui-ci est renvoye dans la chaine de caracteres 'Str' +% tandis que le reste de la chaine est renvoye dans 'Remain' +% ---------------------------------------------------------- +[str, remain] = strtok( string, DELIMITER); + +% Boucle sur l'ensemble de la chaine jusqu'a ce que Str soit vide +% --------------------------------------------------------------- +nToken = 0; +while strcmp( str, '' ) ~= 1 + + % Incremente le compteur d'elements lus + % ------------------------------------- + nToken = nToken + 1; + + % Stocke les elements lus dans une Cellule + % ---------------------------------------- + token(1, nToken) = cellstr(str); + + % Decode chaque element de la chaine de caractere + % ----------------------------------------------- + [str, remain] = strtok( remain, DELIMITER); + +end + +% Enleve les caracteres blanc de debut et de fin de chaque element +% ---------------------------------------------------------------- +token = strtrim(token); \ No newline at end of file diff --git a/tsg_io/readTsgDataLabview.m b/tsg_io/readTsgDataLabview.m new file mode 100644 index 0000000000000000000000000000000000000000..4b95a6e0e2c19bc7c3402c49404743f65fa02807 --- /dev/null +++ b/tsg_io/readTsgDataLabview.m @@ -0,0 +1,146 @@ +function [error] = readTsgDataLabview( hTsgGUI, filename ) +% +% Fonction de lecture des fichiers TSG issus du programme +% d'acquisition LabView XXX +% +% [error] = rdtsglabview( Fichier ) +% +% Input +% hTsgGUI ............ Handel to the main user interface +% filename ........... Data filename +% +% Output +% error .............. 1: OK - -1 : an error occured +% +% Liste des intitules des colonnes dans les entetes des fichiers Labview : +% Date +% Pc Date - RMC_Date - ZDA_Date +% Heure +% Pc Time - RMC_Time - ZDA_Time - GLL_Time +% Position +% RMC_Latmn - RMC_Lonmn - RMC_Latdec - RMC_Londec - +% GGA_Latdec - GGA_Londec - GLL_Latdec - GLL_Londec +% Mesures +% SBE21_Temp1 - SBE21_Sal - SBE21_Cond - SBE21_Raw +% Vitesse et cap +% RMC_Sog - RMC_Cog - 3026L_Cog - 3026L_Sog +% Autre +% RMC_Status - GGA_Hog - VTG True Track - T - Magn Track - M - +% Ground spd- N - Ground Spd - K - dd - tete - ttt + + +% Get the data from the application GUI +% ------------------------------------- +tsg = getappdata( hTsgGUI, 'tsg_data'); + +% Display read file info on console +% --------------------------------- +fprintf('\nREAD_LABVIEW_FILE\n'); tic; + +% Chaque colonne du fichier est separee par DELIMITER +% --------------------------------------------------- +DELIMITER = ','; + +% Ouverture du fichier '.CSV' +% --------------------------- +fid = fopen( filename, 'r'); + +% Teste si le fichier existe +% -------------------------- +if fid ~= -1 + + % Choix des parametres qui seront utilises par TSG-QC + % ColNo : structure des numeros de colonnes a conserver + % --------------------------------------------------- + [choix, ColNo, paraName, nPara] = choixparametres( fid, DELIMITER ); + + if strcmp( choix, 'ok' ) == 1 + + % Lecture et decodage du fichier TSG LabView. En sortie + % ------------------------------------------ + [date, time, lat, lon, sst, sss, cond, condRaw, sog, cog] =... + decodeficlabview( fid, DELIMITER, ColNo, paraName, nPara ); + + % Nombre de lignes du fichier et allocation de memoire + % ---------------------------------------------------- + nblig = length(sst); + + % Indice des lignes pour lesquelles les dates + % ou les heures ne sont pas a NaN + % ------------------------------------------- + noNaN = find( strcmp( date, 'NaN') == 0 & strcmp( time, 'NaN') == 0 ); + + % Every variable are put in a structure + % ------------------------------------- + blanc = char(blanks(1)*ones(nblig,1)); + tsg.DAYD = NaN*ones(nblig,1); + tsg.DAYD(noNaN) = datenum(... + [char(date(noNaN)) blanc(noNaN) char(time(noNaN))],... + 'dd/mm/yyyy HH:MM:SS'); + + % save original date + % ------------------ + tsg.DATE = datestr( tsg.DAYD, 'yyyymmddHHMMSS' ); + tsg.LATX = lat; + tsg.LONX = lon; + tsg.SSJT = sst; + tsg.SSPS = sss; + + % Remplacer la valeur par tsg.qc.code.NOCONTROL + tsg.SSPS_QC = ones(nblig,1); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %tsg.SSPS_ADJ = tsgData(:,12); + %tsg.SSPS_ERR = tsgData(:,13); + + tsg.SPDC = sog; + + % Compute ship velocity from positions if sog not available + % --------------------------------------------------------- + if isempty(tsg.SPDC) + range = m_lldist(tsg.LONX,tsg.LATX); + ind = size(tsg.DAYD); + tsg.SPDC = zeros(size(ind)); + for i=1:length(tsg.DAYD)-1 + tsg.SPDC(i) = range(i) / ((tsg.DAYD(i+1)-tsg.DAYD(i)) * 24 * 1.854); + end + tsg.SPDC = [tsg.SPDC';0]; + end + + % populate tsg.file structure + % --------------------------- + tsg.file.name = filename; + tsg.file.type = 'ASCII'; + + % Save the data in the application GUI + % ------------------------------------ + setappdata( hTsgGUI, 'tsg_data', tsg ); + + % Clear the Workspace + % ------------------- + clear date time lat lon sst sss cond condRaw sog cog + + end % fin de boucle if strcmp(choix,'yes') + + % Fermeture du fichier + % -------------------- + fclose( fid ); + + % Display time to read file on console + % ------------------------------------ + t = toc; fprintf('...done (%6.2f sec).\n\n',t); + + error = 1; + +else + + % Gestion d'erreur ouverture de fichier + % ------------------------------------- + msg_error = ['TSG_LABVIEW file_lecture : Open file error : ' filename]; + warndlg( msg_error, 'LabView error dialog'); + sprintf('...cannot locate %s\n', filename); + error = -1; + return; + +end diff --git a/tsgqc_GUI.m b/tsgqc_GUI.m index 4d2c6f5ffb8a92dac96cea2a610f46fb3b69b69a..a8b63c42f1da99f1c37e47ddfefba3e21fbd32ca 100644 --- a/tsgqc_GUI.m +++ b/tsgqc_GUI.m @@ -448,7 +448,7 @@ tsg_initialisation(hMainFig, hQcCmenu) % This has to be made general for UNIX and WINDOWS system % --------------------------------------------------------- [fileName, pathname, filterIndex] = uigetfile( ... - {'*.txt';'*.xml';'*.nc';'*.btl'}, 'Pick a file'); + {'*.txt';'*.xml';'*.nc';'*.lbv';'*.btl'}, 'Pick a file'); error1 = -1; error2 = -1; @@ -470,6 +470,8 @@ tsg_initialisation(hMainFig, hQcCmenu) error2 = error1; end case 4 + error1 = readTsgDataLabview( hMainFig, fileName ); + case 5 error2 = readBucketData(hMainFig, fileName ); otherwise return;