Skip to content
Snippets Groups Projects
csv2btl.m 10.5 KiB
Newer Older
function csv2btl
% Programme de lecture des fichiers bouteilles au format CSV
% et conversion au format des fichiers BTL du programme TSG-QC
%
% ------------------------------------------------------------

% Repertoire courant par default
% ------------------------------
repIn = '.';
repOut = repIn;

% Constantes
% ----------
DELIMITER = ';';  % Chaque colonne du fichier est separee par DELIMITER
NBELEMENT = 6;    % Nombre d'élément de chaque ligne du fichier en entree

% define configuration file name as csv2btl.ini
% ---------------------------------------------
file_ini = strcat(mfilename,'.ini');
fid_ini = fopen(file_ini, 'r');

% if file exist, read it
% ----------------------
if (fid_ini ~= -1)
  
  % display information on command window
  % --------------------------------------
  fprintf('\nreading %s ...\n', file_ini);
  
  % test the end-of-file
  % --------------------
  while true
    
    % read next line
    % --------------
    inputText = textscan(fid_ini, '%s', 1, 'delimiter', '\n');
    
    % end of file, quit loop
    % ----------------------
    if feof(fid_ini)
      break
    end
    
    for ii = {'repIn', 'repOut'}
      
      % get key, use char because i is cell
      % -----------------------------------
      clef = char(ii);
      
      % use string instead cell
      % -----------------------
      str = inputText{1}{1};
      regex = strcat('^\s*', clef, '\s*=\s*["]*(.+?)["]*$');
      match = regexp( str, regex, 'tokens');
      
      
      % build tsg struct
      % ----------------
      if ~isempty(match)
        cfg.(clef) = match{1}{1};
        
        % for debbuging only
        % ------------------
        fprintf('%s -> %s\n', clef, cfg.(clef));
        continue
      end
    end
    
  end  % end of while loop
  
end

% close .ini file
% ---------------
fclose(fid_ini);

% Ouverture du fichier CSV
% ------------------------
[file, pathname, filterIndex] = uigetfile( {'*.csv'}, 'Pick a file');

if ~isequal(file, 0)
  % Lecture des fichiers Labviews
  % -----------------------------
  fileIn  = fullfile(pathname, file);
  file    = strrep(file, '.csv', '.btl');
  fileOut = fullfile(cfg.repOut, file);
  
  fprintf('\ninput file: %s\n', fileIn);
  fprintf('ouput file: %s\n', fileOut);
  
  
  % Parametres en sortie vides
  % --------------------------
  nblig = 0;
  DataIn = [];
  % 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
  % ----------------------------------------------------------------------
  theFormat = repmat(' %s', 1, NBELEMENT);
  
  % Ouverture du fichier en lecture '.CSV'
  % --------------------------------------
  fid = fopen( fileIn, 'r');
  % Teste si le fichier existe
  % --------------------------
  if fid ~= -1
    % Read the first 8 (3) lines
    % ----------------------
    for i = 1:8
      line = fgetl( fid );
    end
    % Lecture de la date d'analyse des bouteilles
    % -------------------------------------------
    C = textscan(line, '%*s %s %*s %*s %d/%d/%d', 4,'delimiter', DELIMITER);
    cruiseID = char(C{1});
    year  = double( C{4} );
    day = double( C{3} );
    month   = double( C{2} );
    % conversion au format du logiciel TSGQC
    % -------------------------------------
    dateAnalysis = datestr( datenum(year,month,day,0,0,0), 'yyyymmddHHMMSS'  );
    % Lecture du type de bouteilles
    % -----------------------------
    line = fgetl( fid );
    C = textscan(line,'%*s%s', 1,'delimiter', DELIMITER)';
    bottleType = char(C{1});
    % Skip 4 lines
    % ------------
    for i = 1:4
      line = fgetl( fid );
    end
    % Lecture des données
    %
    % 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, theFormat, 'delimiter', DELIMITER,...
      'headerLines', 0 ,...
      'treatAsEmpty', ' ',...
      'emptyValue', NaN);
    % Allocation de mémoire
    % ---------------------
    [m,n]   = size(data{1});
    latitude  = NaN*ones(m,1);
    longitude = NaN*ones(m,1);
    year      = NaN*ones(m,1);
    month     = NaN*ones(m,1);
    day       = NaN*ones(m,1);
    hour      = NaN*ones(m,1);
    min       = NaN*ones(m,1);
    sss_buck  = NaN*ones(m,1);
    % Decode la date
    % Attention a la position des mois et du jour. Il y a inversion
    % dans les fichiers de Denis entre 2006 2007
    % --------------
    for i = 1 : m
      tab = sscanf( char( data{2}(i)), '%d/%d/%d' );
      if ~isempty( tab )
        year(i)  = tab(3);
        month(i) = tab(1);
        day(i)   = tab(2);
      end
    end
    % Decode l'heure
    % --------------
    for i = 1 : m
      tab = sscanf( char( data{3}(i)), '%d:%d' );
      if ~isempty( tab )
        hour(i) = tab(1);
        min(i)  = tab(2);
      end
    end
    % Decode les latitudes
    % --------------------
    for i = 1 : m
      [tab, count, errmsg, nextindex] = sscanf( char( data{4}(i)), '%d°%d''%s' ); % Avec minutes
      if ~isempty( errmsg )
        tab = sscanf( char( data{4}(i)), '%d°%d %s' ); % sans minutes
      end
      if ~isempty( tab )
        latitude(i) = tab(1) + tab(2)/60;
        if strcmp( char(tab(3)), 'S' )
          latitude(i) = -latitude(i);
        end
      else
        latitude(i) = NaN;
      end
    end
    % Decode les longitudes
    % --------------------
    for i = 1 : m
      [tab, count, errmsg, nextindex] = sscanf( char( data{5}(i)), '%d°%d''%s' ); % Avec minutes
      if ~isempty( errmsg )
        tab = sscanf( char( data{5}(i)), '%d°%d %s' ); % sans minutes
      end
      if ~isempty( tab )
        longitude(i) = tab(1) + tab(2)/60;
        if strcmp( char(tab(3)), 'W' )
          longitude(i) = -longitude(i);
        end
      else
        longitude(i) = NaN;
      end
    end
    % Decode la salinite
    % ------------------
    for i = 1 : m
      tab = sscanf( char( data{6}(i)), '%f' );
      if ~isempty( tab )
        sss_buck(i) = tab(1);
      end
    end
    % Fermeture du fichier en lecture
    % -------------------------------
    fclose( fid );
    % Ecriture resultat
    % ----------------
    % Test si l'un des éléments de la date est à NaN
    % ----------------------------------------------
    ind = find(isnan(year) | isnan(month) | isnan(day) | isnan(hour) | isnan(min) );
    if ~isempty( ind )
      hmb = msgbox( [{'Date incomplète pour certains enregistrements.'} {' '} ...
        {'Ces enregistrements sont éliminés.'} {' '} ...
        {'Liste des enregistrements dans le fenêtre Matlab.'}],...
        'Décodage Date', 'warn', 'modal');
      disp( 'Warning Date' );
      disp( 'Date incomplète pour les enregistrements suivants' );
      disp(ind);
      uiwait( hmb );
      
      year(ind)      = [];
      month(ind)     = [];
      day(ind)       = [];
      hour(ind)      = [];
      min(ind)       = [];
      latitude(ind)  = [];
      longitude(ind) = [];
      sss_buck(ind)  = [];
    end
    % Test si l'un des éléments de la position est à NaN
    % --------------------------------------------------
    ind = find( isnan(latitude) | isnan(longitude) );
    if ~isempty( ind )
      msgbox( [{'Position incomplète pour certains enregistrements.'} {' '} ...
        {'Liste des enregistrements dans le fenêtre Matlab.'}],...
        'Décodage Position', 'warn', 'modal');
      disp( 'Warning Position' );
      disp( 'Position incomplète pour les enregistrements suivants' );
      disp(ind);
    end
    % Classement par date croissante
    % ------------------------------
    date = datenum(year, month, day, hour, min, 0 );
    [date, iOrder] = sort(date);
    year      = year(iOrder);
    month     = month(iOrder);
    day       = day(iOrder);
    hour      = hour(iOrder);
    min       = min(iOrder);
    latitude  = latitude(iOrder);
    longitude = longitude(iOrder);
    sss_buck  = sss_buck(iOrder);
    % Nombre d'enregistrements
    % ------------------------
    [nbRecords, n] = size(sss_buck);
    % Type de donnees : format NetCdf de tsgqc
    % Blank before and after WS, more readable after concatenation
    % ------------------------------------------------------------
    label     = ' WS ';
    sss_type  = label( ones(nbRecords,1), :);
    % Cree le tableau donnant la date d'analyse.
    % il faut une date par echantillon
    % ------------------------------------------
    dateAnalysis  = dateAnalysis( ones(nbRecords,1), :);
    % tableau des secondes - N'existe pas pour l'instant dans les feuilles
    % Excel
    % --------------------------------------------------------------------
    sec       = zeros(nbRecords,1);
    % Code d equlaite des mesures - tout a 0
    % --------------------------------------
    code      = zeros(size(sss_buck));
    % Cree un tableau de caracteres avec toutes les informations
    % ----------------------------------------------------------
    bucket = [year month day hour min sec latitude longitude sss_buck code];
    theFormat = '%04d %02d %02d %02d %02d %02d %12.7f %12.7f %6.3f %d';
      bucketStr(i, :) = sprintf( theFormat, bucket(i,:) );
    % Concatene le type et la date d'analyse
    % --------------------------------------
    bucketStr = [ bucketStr sss_type ];
    bucketStr = [ bucketStr dateAnalysis ];
    % Ouverture du fichier en sortie
    % ------------------------------
    fout = fopen( fileOut, 'w');
    
    if fout ~= -1
      fprintf( fout, '%%CruiseID %s\n', cruiseID );
      fprintf( fout, '%%WS_TYPE %s\n', bottleType );
      fprintf( fout, '%%HEADER YEAR MNTH DAYX hh mi ss LATX_EXT LONX_EXT SSPS_EXT SSPS_EXT_QC SSPS_EXT_TYPE SSPS_EXT_ANALDATE\n');
      if ~isempty(bucketStr)
        for i = 1:nbRecords
          fprintf(fout, '%s\n', bucketStr(i,:)');
      fclose( fout );
      display( 'End of program ...' );
    else
      fprintf('Opening error : %s\n', fileOut);