
%
% Creates a NetCDF file from a .mat file
%
% The code is adapted to save a unique file for each group of transects,
% that is, Cross, zigzag Before, and zigzag After. The tests are not meant
% to be written into a NetCDF file, so they are skipped
% 
% 
% v0
%   Lucio Bellomo, 22 June 2015


function mat2nc(matFileName)


%% Generate some comments based on the group of transects considered
[filePath, matFileName, ~] = fileparts(matFileName);

% Cruise name
comment{1} = 'OUTPACE cruise - R/V L''Atalante';

% Which Long Duration Station
iCom = 2;
if strcmp(matFileName(1:3),'LDA')
    comment{iCom} = 'Long Duration Station A';
elseif strcmp(matFileName(1:3),'LDB')
    comment{iCom} = 'Long Duration Station B';
elseif strcmp(matFileName(1:3),'LDC')
    comment{iCom} = 'Long Duration Station C';
elseif strcmp(matFileName(1:4),'Test')
    comment{iCom} = 'Post-calibration test';
else
    error('Unrecognized group of transects!');
end

% Which part of the station
if length(matFileName) <= 3
    % all the station (LDA, LDB, or LDC)
elseif length(matFileName) == 4 || length(matFileName) == 6
    % post-cal test
else
    % cross, before, or after of one of the stations
    iCom = iCom+1;
    if strcmp(matFileName(5:9),'Cross')
        comment{iCom} = 'Cross';
    elseif strcmp(matFileName(5:9),'Befor')
        comment{iCom} = 'MVP Before (zigzag)';
    else
        comment{iCom} = 'MVP After (zigzag)';
    end
end

% Which transect
if length(matFileName) > 10
    iCom = iCom+1;
    comment{iCom} = ['Transect #' matFileName(end)];
end

% Which Fish configuration
iCom = iCom+1;
if strcmp(matFileName(1:3),'LDA')
    if length(matFileName) > 3
        if strcmp(matFileName(5:9),'Cross') || strcmp(matFileName(5:10),'Before')
            comment{iCom} = 'MVP fish equipped with: AML uCTD, WetLabs Fluorometer, LOPC';
        else
            comment{iCom} = 'MVP fish equipped with: Valeport SVPT, WetLabs Fluorometer, LOPC';
        end
    end
else
    comment{iCom} = 'MVP fish equipped with: Valeport SVPT, WetLabs Fluorometer, LOPC';
end


%% Load the .mat file
load([filePath filesep matFileName '.mat']);    % this gives the structures: info, metadata, and data


%% Extract metadata
for iProf = 1 : length(metadata)
    rawFileName(iProf,:) = metadata(iProf).fileName;
    transectName{iProf}  = metadata(iProf).transectName;
end
profileIndex = [metadata.profileIndex]';
shipLog      = [metadata.shipLog]; shipLog = [shipLog.value]';
lon          = [metadata.lon];     lon     = [lon.value]';
lat          = [metadata.lat];     lat     = [lat.value]';
date         = [metadata.date];    date    = [date.value]';

% Adjust the date
RefDateTime = '1950-01-01 00:00:00';
date = date - datenum(RefDateTime,'yyyy-mm-dd HH:MM:SS');


%% Put data into matrices
pres = data(1).pres.value;  % one single vector for pressure only
for iProf = 1 : length(data)
    temp(:,iProf)       = data(iProf).temp.value;
    ptemp(:,iProf)      = data(iProf).ptemp.value;
    cond(:,iProf)       = data(iProf).cond.value;
    soundVel(:,iProf)   = data(iProf).soundVel.value;
    psal(:,iProf)       = data(iProf).psal.value;
    dens(:,iProf)       = data(iProf).dens.value;
    pdens(:,iProf)      = data(iProf).pdens.value;
    chla(:,iProf)       = data(iProf).chla.value;
    vertSpeed(:,iProf)  = data(iProf).vertSpeed.value;
end


%% Replace NaN's with fillval (there shouldn't be any NaN, though!)
fillVal = -9.9999e+32;
pres(isnan(pres))           = fillVal;
temp(isnan(temp))           = fillVal;
ptemp(isnan(ptemp))         = fillVal;
cond(isnan(cond))           = fillVal;
soundVel(isnan(soundVel))   = fillVal;
psal(isnan(psal))           = fillVal;
dens(isnan(dens))           = fillVal;
pdens(isnan(pdens))         = fillVal;
chla(isnan(chla))           = fillVal;
vertSpeed(isnan(vertSpeed)) = fillVal;


%% Create the NetCDF
% Filename
ncFileName = [filePath filesep matFileName '.nc'];

% If it already exists, delete it in order to avoid problems
if exist(ncFileName,'file')
    delete(ncFileName);
end

% Size variables
[nDepth, nProf] = size(temp);
nRawFileName    = size(rawFileName,2);
nRefDate        = length(RefDateTime);
% - pad with spaces transectName if the length is not always the same
nTransectName = 0;
for iProf = 1 : length(metadata)
    if length(transectName{iProf}) > nTransectName
        nTransectName = length(transectName{iProf});
    end
end
transectNameTMP = transectName;
clear transectName;
for iProf = 1 : length(metadata)
    transectName(iProf,:) = [transectNameTMP{iProf} char(32)*ones(1,nTransectName-length(transectNameTMP{iProf}))];
end

% Dimension variables
nccreate(ncFileName,'TIME',               'Dimensions',{'TIME',nProf}, 'Datatype','double','Format','classic'); % t
nccreate(ncFileName,'PRES',               'Dimensions',{'PRES',nDepth},'Datatype','double','Format','classic'); % z

% Metadata
nccreate(ncFileName,'LONGITUDE',          'Dimensions',{'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'LATITUDE',           'Dimensions',{'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'SHIP_LOG',           'Dimensions',{'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'PROFILE_INDEX',      'Dimensions',{'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'RAW_FILE_NAME' ,     'Dimensions',{'TIME',nProf,['STRING' num2str(nRawFileName)],nRawFileName},  'Datatype','char','Format','classic');
nccreate(ncFileName,'TRANSECT_NAME' ,     'Dimensions',{'TIME',nProf,['STRING' num2str(nTransectName)],nTransectName},'Datatype','char','Format','classic');
nccreate(ncFileName,'REFERENCE_DATE_TIME','Dimensions',{['STRING' num2str(nRefDate)],nRefDate},                       'Datatype','char','Format','classic');

% Data
nccreate(ncFileName,'TEMP',               'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'PTEMP',              'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'COND',               'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'SV',                 'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'PSAL',               'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'DENS',               'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'PDENS',              'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'CHLA',               'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');
nccreate(ncFileName,'VERTICAL_VELOCITY',  'Dimensions',{'PRES',nDepth,'TIME',nProf},'Datatype','double','Format','classic');


%% Variable-specific attributes
ncwriteatt(ncFileName,'TIME','long_name',  'Julian day (UTC) of the profile relative to REFERENCE_DATE_TIME');
ncwriteatt(ncFileName,'TIME','time_origin',RefDateTime);
ncwriteatt(ncFileName,'TIME','units',      ['Days since ' RefDateTime ' (UTC)']);
ncwriteatt(ncFileName,'TIME','axis',      'T');

ncwriteatt(ncFileName,'PRES','long_name','Pressure');
ncwriteatt(ncFileName,'PRES','units',    'dbar');
ncwriteatt(ncFileName,'PRES','positive', 'down');
ncwriteatt(ncFileName,'PRES','_FillValue',fillVal);
ncwriteatt(ncFileName,'PRES','axis',      'Z');

ncwriteatt(ncFileName,'LONGITUDE','long_name', 'Longitude');
ncwriteatt(ncFileName,'LONGITUDE','units',     'degrees_east');
ncwriteatt(ncFileName,'LONGITUDE','valid_min', 0);
ncwriteatt(ncFileName,'LONGITUDE','valid_max', 360);

ncwriteatt(ncFileName,'LATITUDE','long_name', 'Latitude');
ncwriteatt(ncFileName,'LATITUDE','units',     'degrees_north');
ncwriteatt(ncFileName,'LATITUDE','valid_min', -90);
ncwriteatt(ncFileName,'LATITUDE','valid_max', 90);

ncwriteatt(ncFileName,'SHIP_LOG','long_name', 'Ship''s velocity');
ncwriteatt(ncFileName,'SHIP_LOG','units',     'knots');
ncwriteatt(ncFileName,'SHIP_LOG','valid_min', 0);
ncwriteatt(ncFileName,'SHIP_LOG','valid_max', 30);

ncwriteatt(ncFileName,'PROFILE_INDEX','long_name', 'MVP profile index');

ncwriteatt(ncFileName,'RAW_FILE_NAME','long_name','File name of the MVP .raw files processed');

ncwriteatt(ncFileName,'TRANSECT_NAME','long_name','Transect''s name (from 1 to 3 for the cross, form 1 to 8 for the zigzag)');

ncwriteatt(ncFileName,'REFERENCE_DATE_TIME','comment',    'Date of reference for Julian Days');
ncwriteatt(ncFileName,'REFERENCE_DATE_TIME','conventions','YYYY-MM-DD hh:mm:ss');

ncwriteatt(ncFileName,'TEMP','long_name', 'Temperature in-situ');
ncwriteatt(ncFileName,'TEMP','units',     'deg C');
ncwriteatt(ncFileName,'TEMP','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'TEMP','valid_min', -2);
ncwriteatt(ncFileName,'TEMP','valid_max', 40);

ncwriteatt(ncFileName,'PTEMP','long_name', 'Potential Temperature');
ncwriteatt(ncFileName,'PTEMP','units',     'deg C');
ncwriteatt(ncFileName,'PTEMP','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'PTEMP','valid_min', -2);
ncwriteatt(ncFileName,'PTEMP','valid_max', 40);

ncwriteatt(ncFileName,'COND','long_name', 'Conductivity');
ncwriteatt(ncFileName,'COND','units',     'mS/cm');
ncwriteatt(ncFileName,'COND','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'COND','valid_min', 0);
ncwriteatt(ncFileName,'COND','valid_max', 100);

ncwriteatt(ncFileName,'SV','long_name', 'Sound Velocity');
ncwriteatt(ncFileName,'SV','units',     'm/s');
ncwriteatt(ncFileName,'SV','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'SV','valid_min', 1000);
ncwriteatt(ncFileName,'SV','valid_max', 2000);

ncwriteatt(ncFileName,'PSAL','long_name', 'Practical Salinity');
ncwriteatt(ncFileName,'PSAL','units',     'psu');
ncwriteatt(ncFileName,'PSAL','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'PSAL','valid_min', 0);
ncwriteatt(ncFileName,'PSAL','valid_max', 50);

ncwriteatt(ncFileName,'DENS','long_name', 'Density in-situ');
ncwriteatt(ncFileName,'DENS','units',     'psu');
ncwriteatt(ncFileName,'DENS','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'DENS','valid_min', 1000);
ncwriteatt(ncFileName,'DENS','valid_max', 1050);

ncwriteatt(ncFileName,'PDENS','long_name', 'Potential Density');
ncwriteatt(ncFileName,'PDENS','units',     'psu');
ncwriteatt(ncFileName,'PDENS','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'PDENS','valid_min', 0);
ncwriteatt(ncFileName,'PDENS','valid_max', 50);

ncwriteatt(ncFileName,'CHLA','long_name', 'Chlorophyll-a concentration');
ncwriteatt(ncFileName,'CHLA','units',     'mg/l');
ncwriteatt(ncFileName,'CHLA','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'CHLA','valid_min', 0);
ncwriteatt(ncFileName,'CHLA','valid_max', 100);

ncwriteatt(ncFileName,'VERTICAL_VELOCITY','long_name', 'MVP Fish Vertical Velocity');
ncwriteatt(ncFileName,'VERTICAL_VELOCITY','units',     'm/s');
ncwriteatt(ncFileName,'VERTICAL_VELOCITY','_Fillvalue',fillVal);
ncwriteatt(ncFileName,'VERTICAL_VELOCITY','valid_min', -10);
ncwriteatt(ncFileName,'VERTICAL_VELOCITY','valid_max', 10);


%% Global attributes
% Title and group of transects
ncwriteatt(ncFileName,'/','title',        char('MVP processed profiles'));
for iCom = 1 : length(comment)
    ncwriteatt(ncFileName,'/',['comment_' num2str(iCom)],    char(comment{iCom}));
end

% Processing parameters
ncwriteatt(ncFileName,'/','MVP_payload',                                                         char(params.instrType));
ncwriteatt(ncFileName,'/','Sampling_frequency',                                                  char([num2str(params.fSampl.value) ' ' params.fSampl.unit]));
ncwriteatt(ncFileName,'/','Minimum_acceptable_pressure_value',                                   char([num2str(params.minValidPres.value) ' ' params.minValidPres.unit]));
if ~all(isnan(params.convertChla.value))
    ncwriteatt(ncFileName,'/','Chlorophyll-a_conversion__dark_counts',                           char([num2str(params.convertChla.value(1)) ' ' params.convertChla.unit{1}]));
    ncwriteatt(ncFileName,'/','Chlorophyll-a_conversion__scale_factor',                          char([num2str(params.convertChla.value(2)) ' ' params.convertChla.unit{2}]));
else
    ncwriteatt(ncFileName,'/','Chlorophyll-a_conversion',                                        char('Not applied'));
end
if ~isnan(params.tauPres.value)
    ncwriteatt(ncFileName,'/','Profile_filtering_pressure__time_constant',                       char([num2str(params.tauPres.value) ' ' params.tauPres.unit]));
else
    ncwriteatt(ncFileName,'/','Profile_filtering_pressure',                                      char('Noth Applied'));
end
if ~isnan(params.tauOthers.value)
    ncwriteatt(ncFileName,'/','Profile_filtering_other_variables__time_constant',                char([num2str(params.tauOthers.value) ' ' params.tauOthers.unit]));
else
    ncwriteatt(ncFileName,'/','Profile_filtering_other_variables',                               char('Noth Applied'));
end
if ~all(isnan(params.calibT.value))
    ncwriteatt(ncFileName,'/','Post-calibration_temperature_(c0+c1*temp+c2*pres)__c0',           char([num2str(params.calibT.value(1)) ' ' params.calibT.unit{1}]));
    ncwriteatt(ncFileName,'/','Post-calibration_temperature_(c0+c1*temp+c2*pres)__c1',           char([num2str(params.calibT.value(2)) ' ' params.calibT.unit{2}]));
    ncwriteatt(ncFileName,'/','Post-calibration_temperature_(c0+c1*temp+c2*pres)__c2',           char([num2str(params.calibT.value(3)) ' ' params.calibT.unit{3}]));
else
    ncwriteatt(ncFileName,'/','Post-calibration_temperature',                                    char('Not Applied'));
end
if strcmp(params.instrType,'uCTD+fluo')
    if ~all(isnan(params.calibC.value))
        ncwriteatt(ncFileName,'/','Post-calibration_conductivity_(c0+c1*cond+c2*pres)__c0',      char([num2str(params.calibC.value(1)) ' ' params.calibC.unit{1}]));
        ncwriteatt(ncFileName,'/','Post-calibration_conductivity_(c0+c1*cond+c2*pres)__c1',      char([num2str(params.calibC.value(2)) ' ' params.calibC.unit{2}]));
        ncwriteatt(ncFileName,'/','Post-calibration_conductivity_(c0+c1*cond+c2*pres)__c2',      char([num2str(params.calibC.value(3)) ' ' params.calibC.unit{3}]));
    else
        ncwriteatt(ncFileName,'/','Post-calibration_conductivity',                               char('Not Applied'));
    end
else
    if ~all(isnan(params.calibSV.value))
        ncwriteatt(ncFileName,'/','Post-calibration_sound_velocity_(c0+c1*soundVel+c2*pres)__c0',char([num2str(params.calibSV.value(1)) ' ' params.calibSV.unit{1}]));
        ncwriteatt(ncFileName,'/','Post-calibration_sound_velocity_(c0+c1*soundVel+c2*pres)__c1',char([num2str(params.calibSV.value(2)) ' ' params.calibSV.unit{2}]));
        ncwriteatt(ncFileName,'/','Post-calibration_sound_velocity_(c0+c1*soundVel+c2*pres)__c2',char([num2str(params.calibSV.value(3)) ' ' params.calibSV.unit{3}]));
    else
        ncwriteatt(ncFileName,'/','Post-calibration_sound_velocity',                             char('Not Applied'));
    end
end
if ~all(isnan(params.delayT.value))
    ncwriteatt(ncFileName,'/','Temperature_alignment_wrt_cond_or_soundvel_(c0+c1*vertVel^-1)__c0',  char([num2str(params.delayT.value(2)) ' ' params.delayT.unit{2}]));    % on purpose (2) then (1)
    ncwriteatt(ncFileName,'/','Temperature_alignment_wrt_cond_or_soundvel_(c0+c1*vertVel^-1)__c1',  char([num2str(params.delayT.value(1)) ' ' params.delayT.unit{1}]));
else
    ncwriteatt(ncFileName,'/','Temperature_alignment_wrt_cond_or_soundvel',                         char('Not Applied'));
end
if ~isnan(params.deltaPresFluo.value)
    ncwriteatt(ncFileName,'/','Distance_between_fluorometer_and_CTD_or_SVPT',                       char([num2str(params.deltaPresFluo.value) ' ' params.deltaPresFluo.unit]));
else
    ncwriteatt(ncFileName,'/','Distance_between_fluorometer_and_CTD_or_SVPT',                       char('Not Applied'));
end

% Generic
ncwriteatt(ncFileName,'/','conventions',  char('COARDS'));
ncwriteatt(ncFileName,'/','creation_date',char(datestr(now)));


%% Write variables
% Dimension variables
ncwrite(ncFileName,'TIME',               date);
ncwrite(ncFileName,'PRES',               pres);

% Real variables
ncwrite(ncFileName,'LONGITUDE',          lon);
ncwrite(ncFileName,'LATITUDE',           lat);
ncwrite(ncFileName,'SHIP_LOG',           shipLog);
ncwrite(ncFileName,'PROFILE_INDEX',      profileIndex);
ncwrite(ncFileName,'RAW_FILE_NAME',      rawFileName);
ncwrite(ncFileName,'TRANSECT_NAME',      transectName);
ncwrite(ncFileName,'REFERENCE_DATE_TIME',RefDateTime');
ncwrite(ncFileName,'TEMP',               temp);
ncwrite(ncFileName,'PTEMP',              ptemp);
ncwrite(ncFileName,'COND',               cond);
ncwrite(ncFileName,'SV',                 soundVel);
ncwrite(ncFileName,'PSAL',               psal);
ncwrite(ncFileName,'DENS',               dens);
ncwrite(ncFileName,'PDENS',              pdens);
ncwrite(ncFileName,'CHLA',               chla);
ncwrite(ncFileName,'VERTICAL_VELOCITY',  vertSpeed);
