clear all
close all

opts = delimitedTextImportOptions("NumVariables", 30);

% Specify range and delimiter
opts.DataLines = [25, Inf];
opts.Delimiter = ",";

% Specify column names and types
%opts.VariableNames = ["LabviewDateTime", "ThermistorTemp", "BathTemp", "BathSetPoint", "PressuredBar", "MaxFlow", "FlowRate", "PumpVolume", "CRC", "ID", "DATETIME", "UTCSECS", "CTDDEPTH", "CTDTEMP", "CTDSALINITY", "SAMPLECOUNTER", "RESETCOUNTER", "ERRORCOUNTER", "HOUSINGTEMPERATURE", "HOUSINGHUMIDITY", "INPUTVOLTAGE", "INPUTCURRENT", "FOOBARPHVALUE", "BACKUPBATTERY", "VRSVOLTS", "VRSSTDDEV", "VKVOLTS", "VKSTDDEV", "IKAMPS", "IBAMPS"];
%opts.VariableNames = ["dtLV",   "thermTemp", "bathTemp", "bathSP", "pressureDBar", "maxFlow", "flowRate", "cycleNum", "pumpVolume", "CRC", "ID", "dateTime", "utcSecs", "ctdDepth", "ctdTemp", "ctdSalinity", "sampleCounter", "resetCounter", "errorCounter", "housingTemp", "housingHumidity", "inputVoltage", "inputCurrent", "foobarPHValue", "backupBattery", "vrsVolts", "vrsStdDev", "vkVolts", "vkStdDev", "ikAmps", "ibAmps"];
%opts.VariableTypes = ["datetime", "double", "double",   "double", "double",         "double", "double",     "double",   "double", "string", "categorical", "datetime", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double"];
%For the new VI with SetTemp, SetPressure and StepNum
opts.VariableNames = ["dtLV",   "thermTemp", "bathTemp", "bathSP", "pressureDBar", "maxFlow", "flowRate", "pumpVolume", "CRC", "ID", "dateTime", "utcSecs", "ctdDepth", "ctdTemp", "ctdSalinity", "sampleCounter", "resetCounter", "errorCounter", "housingTemp", "housingHumidity", "inputVoltage", "inputCurrent", "foobarPHValue", "backupBattery", "vrsVolts", "vrsStdDev", "vkVolts", "vkStdDev", "ikAmps", "ibAmps", "SetTemp", "SetPressure", "StepNum"];
opts.VariableTypes = ["datetime", "double", "double",   "double", "double",         "double", "double",    "double", "string", "categorical", "datetime", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double"];

% Specify file level properties
opts.ExtraColumnsRule = "ignore";
opts.EmptyLineRule = "read";

% Specify variable properties
opts = setvaropts(opts, "CRC", "WhitespaceRule", "preserve");
opts = setvaropts(opts, ["CRC", "ID"], "EmptyFieldRule", "auto");
%opts = setvaropts(opts, "dtLV", "InputFormat", "MM/dd/uuuu hh:mm:ss aa");
%opts = setvaropts(opts, "dateTime", "InputFormat", "MM/dd/uuuu hh:mm:ss aa");

%% Process files
path = '\\atlas\ProjectLibrary\ChemSensors\GeneM\GDF pH Sensor\Data\Cal Data\Calcs\DataFiles\'
fullPath = strcat(path, '*.csv');

dataFiles = dir(strcat(path, '*.csv'));
fileDatenums = dataFiles.date;
[sortedTime, i] = sort([dataFiles.datenum]);
sortedDataFileList = dataFiles(i);

for i=1:length(dataFiles)
    % Import the data
    disp("Processing: " + dataFiles(1).name);
    dataTable{i} = readtable(strcat(path, sortedDataFileList(i).name), opts);
end

% Create overview plot
createOverviewPlot2(dataTable, sortedDataFileList, 1);

% Separate out cycles
%[cycle, numCycles] = getCycles(dataTable, "pressure");

% Waterfall plot
%plotPressureWaterfall(cycle, numCycles)

figure('name', "Vrs vs Time", 'NumberTitle', 'off');
plot(dataTable{1}.dtLV, dataTable{1}.vrsVolts)
title('time vs Vrs')

%Plot individual cycles
numBins = 100;
xIncr = 0.2;
yIncr = 0.3;
left = 0.05;
bottom = 0.65;
width = 0.25;
height = 0.25;

polyOrder = 3;

for i=2:2:50
    cycleIndex = i/2;
    windowText = sprintf("Cycle Num: %i", i/2);
    figure('name', windowText, 'NumberTitle', 'off', 'Unit', 'normalized','Position', [left, bottom, width, height]);
    hold on

    indexes = find(dataTable{1}.StepNum == i);
    cycle{cycleIndex}.xIncr = dataTable{1}.pressureDBar(indexes);
    cycle{cycleIndex}.yIncr = dataTable{1}.vrsVolts(indexes);

    lastwarn('')
    cycle{cycleIndex}.polyFitValsIncr = polyfit(cycle{cycleIndex}.xIncr, cycle{cycleIndex}.yIncr, polyOrder);
    [warnMsg, warnId] = lastwarn;
    if isempty(warnMsg)
    
    cycle{cycleIndex}.yFitIncr = polyval(cycle{cycleIndex}.polyFitValsIncr, cycle{cycleIndex}.xIncr);
    cycle{cycleIndex}.maxResidualIncr = max(abs(cycle{cycleIndex}.yFitIncr - cycle{cycleIndex}.yIncr));
    cycle{cycleIndex}.meanResidualIncr = mean(abs(cycle{cycleIndex}.yFitIncr - cycle{cycleIndex}.yIncr));
    plot(cycle{cycleIndex}.xIncr, cycle{cycleIndex}.yIncr, cycle{cycleIndex}.xIncr, cycle{cycleIndex}.yFitIncr);
    titleString1 = sprintf('Incr P fit mean(abs(residual)): %.3e max(abs(residual)): %.3e\n', cycle{cycleIndex}.meanResidualIncr, cycle{cycleIndex}.maxResidualIncr);

    indexes = find(dataTable{1}.StepNum == i+1);
    cycle{cycleIndex}.xDecr = dataTable{1}.pressureDBar(indexes);
    cycle{cycleIndex}.yDecr = dataTable{1}.vrsVolts(indexes);
    cycle{cycleIndex}.polyFitValsDecr = polyfit(cycle{cycleIndex}.xDecr, cycle{cycleIndex}.yDecr, polyOrder);
    cycle{cycleIndex}.yFitDecr = polyval(cycle{cycleIndex}.polyFitValsDecr, cycle{cycleIndex}.xDecr);
    cycle{cycleIndex}.maxResidualDecr = max(abs(cycle{cycleIndex}.yFitDecr - cycle{cycleIndex}.yDecr));
    cycle{cycleIndex}.meanResidualDecr = mean(abs(cycle{cycleIndex}.yFitDecr - cycle{cycleIndex}.yDecr));
    plot(cycle{cycleIndex}.xDecr, cycle{cycleIndex}.yDecr, cycle{cycleIndex}.xDecr, cycle{cycleIndex}.yFitDecr);
    titleString2 = sprintf('Decr P fit mean(abs(residual)): %.3e max(abs(residual)): %.3e\n', cycle{cycleIndex}.meanResidualDecr, cycle{cycleIndex}.maxResidualDecr);

    cycle{cycleIndex}.xBoth = [cycle{cycleIndex}.xIncr; cycle{cycleIndex}.xDecr];
    cycle{cycleIndex}.yBoth = [cycle{cycleIndex}.yIncr; cycle{cycleIndex}.yDecr];
    cycle{cycleIndex}.polyFitValsBoth = polyfit(cycle{cycleIndex}.xBoth, cycle{cycleIndex}.yBoth, polyOrder);
    cycle{cycleIndex}.yFitBoth = polyval(cycle{cycleIndex}.polyFitValsBoth, cycle{cycleIndex}.xBoth);
    cycle{cycleIndex}.maxResidualBoth = max(abs(cycle{cycleIndex}.yFitBoth - cycle{cycleIndex}.yBoth));
    cycle{cycleIndex}.meanResidualBoth = mean(abs(cycle{cycleIndex}.yFitBoth - cycle{cycleIndex}.yBoth));
    plot(cycle{cycleIndex}.xBoth, cycle{cycleIndex}.yFitBoth);
    titleString3 = sprintf('All data fit mean(abs(residual)): %.3e max(abs(residual)): %.3e\n', cycle{cycleIndex}.meanResidualBoth, cycle{cycleIndex}.maxResidualBoth);

    legend(titleString1, 'incr fit', titleString2, 'decr fit', titleString3, 'FontSize', 16, 'location', 'northeast');
    xlabel('Pressure (dBar)');
    ylabel('Vrs (volts)');

    left = left + xIncr;
    if(mod(i, 10) == 0)
        bottom = bottom - yIncr;
        left = 0.05;
    end
    else
        disp 'skipping this cycle'
        cycle{cycleIndex}.yFitIncr = NaN;
        cycle{cycleIndex}.maxResidualIncr = NaN;
        cycle{cycleIndex}.meanResidualIncr = NaN;
       
        cycle{cycleIndex}.xDecr = NaN;
        cycle{cycleIndex}.yDecr = NaN;
        cycle{cycleIndex}.polyFitValsDecr = NaN;
        cycle{cycleIndex}.yFitDecr = NaN;
        cycle{cycleIndex}.maxResidualDecr = NaN;
        cycle{cycleIndex}.meanResidualDecr = NaN;

        cycle{cycleIndex}.xBoth = NaN;
        cycle{cycleIndex}.yBoth = NaN;
        cycle{cycleIndex}.polyFitValsBoth = NaN;
        cycle{cycleIndex}.yFitBoth = NaN;
        cycle{cycleIndex}.maxResidualBoth = NaN;
        cycle{cycleIndex}.meanResidualBoth = NaN
    end
end
