diff --git a/AutomaticQC/imosHistoricalManualSetQC.m b/AutomaticQC/imosHistoricalManualSetQC.m index c4404dd3b..d46359d88 100644 --- a/AutomaticQC/imosHistoricalManualSetQC.m +++ b/AutomaticQC/imosHistoricalManualSetQC.m @@ -57,8 +57,15 @@ paramsLog = []; % read manual QC file for this dataset -[mqcPath, mqcFile, ~] = fileparts(sample_data.toolbox_input_file); -mqcFile = fullfile(mqcPath, [mqcFile, '.mqc']); +mqcFile = [sample_data.toolbox_input_file, '.mqc']; + +% we need to migrate any remnants of the old file naming convention +% for .mqc files. +[mqcPath, oldMqcFile, ~] = fileparts(sample_data.toolbox_input_file); +oldMqcFile = fullfile(mqcPath, [oldMqcFile, '.mqc']); +if exist(oldMqcFile, 'file') + movefile(oldMqcFile, mqcFile); +end if exist(mqcFile, 'file') load(mqcFile, '-mat', 'mqc'); diff --git a/AutomaticQC/readQCparameter.m b/AutomaticQC/readQCparameter.m index 4aa73e510..a1c119bce 100644 --- a/AutomaticQC/readQCparameter.m +++ b/AutomaticQC/readQCparameter.m @@ -64,8 +64,16 @@ if ~ischar(QCtest), error('QCtest must be a string'); end if ~ischar(param), error('param must be a string'); end -[pqcPath, pqcFile, ~] = fileparts(rawDataFile); -pqcFile = fullfile(pqcPath, [pqcFile, '.pqc']); +pqcFile = [rawDataFile, '.pqc']; + +% we need to migrate any remnants of the old file naming convention +% for .pqc files. +[pqcPath, oldPqcFile, ~] = fileparts(rawDataFile); +oldPqcFile = fullfile(pqcPath, [oldPqcFile, '.pqc']); +if exist(oldPqcFile, 'file') + movefile(oldPqcFile, pqcFile); +end + pqc = struct([]); if exist(pqcFile, 'file') diff --git a/AutomaticQC/writeQCparameter.m b/AutomaticQC/writeQCparameter.m index 134a7a559..26922d5c4 100644 --- a/AutomaticQC/writeQCparameter.m +++ b/AutomaticQC/writeQCparameter.m @@ -61,8 +61,16 @@ function writeQCparameter(rawDataFile, QCtest, param, value) if ~ischar(QCtest), error('QCtest must be a string'); end if ~ischar(param), error('param must be a string'); end -[pqcPath, pqcFile, ~] = fileparts(rawDataFile); -pqcFile = fullfile(pqcPath, [pqcFile, '.pqc']); +pqcFile = [rawDataFile, '.pqc']; + +% we need to migrate any remnants of the old file naming convention +% for .pqc files. +[pqcPath, oldPqcFile, ~] = fileparts(rawDataFile); +oldPqcFile = fullfile(pqcPath, [oldPqcFile, '.pqc']); +if exist(oldPqcFile, 'file') + movefile(oldPqcFile, pqcFile); +end + pqc = struct([]); if exist(pqcFile, 'file'), load(pqcFile, '-mat', 'pqc'); end diff --git a/FlowManager/displayManager.m b/FlowManager/displayManager.m index 8c9d22637..eb57022eb 100644 --- a/FlowManager/displayManager.m +++ b/FlowManager/displayManager.m @@ -478,8 +478,16 @@ function dataSelectCallback(ax, type, range) flags = flagFunc(panel, graphs, sample_data{setIdx}, vars); % write/update manual QC file for this dataset - [mqcPath, mqcFile, ~] = fileparts(sample_data{setIdx}.toolbox_input_file); - mqcFile = fullfile(mqcPath, [mqcFile, '.mqc']); + mqcFile = [sample_data{setIdx}.toolbox_input_file, '.mqc']; + + % we need to check first that there is not any remnants from + % the old .mqc file naming convention + [mqcPath, oldMqcFile, ~] = fileparts(sample_data{setIdx}.toolbox_input_file); + oldMqcFile = fullfile(mqcPath, [oldMqcFile, '.mqc']); + if exist(oldMqcFile, 'file') + movefile(oldMqcFile, mqcFile); + end + mqc = struct([]); if exist(mqcFile, 'file'), load(mqcFile, '-mat', 'mqc'); end @@ -552,8 +560,15 @@ function resetManQCCallback() end end - [mqcPath, mqcFile, ~] = fileparts(sample_data{resetIdx(j)}.toolbox_input_file); - mqcFile = fullfile(mqcPath, [mqcFile, '.mqc']); + mqcFile = [sample_data{resetIdx(j)}.toolbox_input_file, '.mqc']; + + % we need to migrate any remnants of the old file naming convention + % for .mqc files. + [mqcPath, oldMqcFile, ~] = fileparts(sample_data{resetIdx(j)}.toolbox_input_file); + oldMqcFile = fullfile(mqcPath, [oldMqcFile, '.mqc']); + if exist(oldMqcFile, 'file') + movefile(oldMqcFile, mqcFile); + end if exist(mqcFile, 'file') delete(mqcFile); @@ -594,8 +609,15 @@ function resetPropQCCallback() end end - [pqcPath, pqcFile, ~] = fileparts(sample_data{resetIdx(j)}.toolbox_input_file); - pqcFile = fullfile(pqcPath, [pqcFile, '.pqc']); + pqcFile = [sample_data{resetIdx(j)}.toolbox_input_file, '.pqc']; + + % we need to migrate any remnants of the old file naming convention + % for .pqc files. + [pqcPath, oldPqcFile, ~] = fileparts(sample_data{resetIdx(j)}.toolbox_input_file); + oldPqcFile = fullfile(pqcPath, [oldPqcFile, '.pqc']); + if exist(oldPqcFile, 'file') + movefile(oldPqcFile, pqcFile); + end if exist(pqcFile, 'file') delete(pqcFile); diff --git a/GUI/mainWindow.m b/GUI/mainWindow.m index 129c8922d..4edaee5f4 100644 --- a/GUI/mainWindow.m +++ b/GUI/mainWindow.m @@ -254,8 +254,8 @@ function mainWindow(... buttons = findall(tb); zoomoutb = findobj(buttons, 'TooltipString', 'Zoom Out'); - zoominb = findobj(buttons, 'TooltipString', 'Zoom In'); - panb = findobj(buttons, 'TooltipString', 'Pan'); + zoominb = findobj(buttons, 'TooltipString', 'Zoom In (Ctrl+z)'); + panb = findobj(buttons, 'TooltipString', 'Pan (Ctrl+a)'); datacursorb = findobj(buttons, 'TooltipString', 'Data Cursor'); buttons(buttons == tb) = []; @@ -318,11 +318,16 @@ function mainWindow(... set(hToolsLineCastVarNonQC, 'callBack', {@displayLineCastVar, false}); set(hToolsLineCastVarQC, 'callBack', {@displayLineCastVar, true}); end - hHelpMenu = uimenu(fig, 'label', 'Help'); - hHelpWiki = uimenu(hHelpMenu, 'label', 'IMOS Toolbox Wiki'); + hHotKeyMenu = uimenu(fig, 'label', 'Hot Keys'); + uimenu(hHotKeyMenu, 'Label', 'Enable zoom', 'Accelerator', 'z', 'Callback', @(src,evt)zoom(fig, 'on')); + uimenu(hHotKeyMenu, 'Label', 'Enable pan', 'Accelerator', 'a', 'Callback', @(src,evt)pan( fig, 'on')); + uimenu(hHotKeyMenu, 'Label', 'Disable zoom/pan', 'Accelerator', 'q', 'Callback', @disableZoomAndPan); + + hHelpMenu = uimenu(fig, 'label', 'Help'); + hHelpWiki = uimenu(hHelpMenu, 'label', 'IMOS Toolbox Wiki'); %set menu callbacks - set(hHelpWiki, 'callBack', @openWikiPage); + set(hHelpWiki, 'callBack', @openWikiPage); %% Widget Callbacks @@ -634,6 +639,11 @@ function displayLineMooringVar(source,ev, isQC) end +function disableZoomAndPan(source, ev) + pan(fig, 'off'); + zoom(fig, 'off'); +end + function displayLineCastVar(source,ev, isQC) %DISPLAYLINECASTVAR Opens a new window where all the % variables collected by the CTD cast are line-plotted. diff --git a/IMOS/imosParameters.txt b/IMOS/imosParameters.txt index 1348b8106..b2decbf82 100644 --- a/IMOS/imosParameters.txt +++ b/IMOS/imosParameters.txt @@ -133,7 +133,7 @@ SW, 1, surface_downwelling_shortwave_flux_in_air, SWPD, 0, sea_surface_peak_swell_wave_from_direction, degree, clockwise, true north, W, 999999.0, 0.0, 360.0, float SWPD_MAG, 0, sea_surface_peak_swell_wave_from_direction, degree, clockwise, magnetic north, W, 999999.0, 0.0, 360.0, float SWPP, 0, sea_surface_peak_swell_wave_period, Second, , , W, 999999.0, 0.0, 100.0, float -SWSH, 1, sea_surface_swell_wave_significant_height, m, up, sea surface, W, 999999.0, 0.0, 100.0, float +SWSH, 1, sea_surface_swell_wave_significant_height, m, , , W, 999999.0, 0.0, 100.0, float SW_NET, 1, surface_net_upward_shortwave_flux, W m-2, , , F, 999999.0, , , float TAU, 1, magnitude_of_surface_downward_stress, Pascal, , , F, 999999.0, , , float TEMP, 1, sea_water_temperature, degrees_Celsius,, , T, 999999.0, -2.5, 40.0, float @@ -145,7 +145,7 @@ TRAJECTORY, 0, unique_identifier_for_each_trajectory_feature_instance_i UCUR, 1, eastward_sea_water_velocity, m s-1, , , V, 999999.0, -10.0, 10.0, float UCUR_MAG, 0, magnetic_eastward_sea_water_velocity, m s-1, , , V, 999999.0, -10.0, 10.0, float UWND, 1, eastward_wind, m s-1, , , M, 999999.0, , , float -VAVH, 1, sea_surface_wave_significant_height, m, up, sea surface, W, 999999.0, 0.0, 100.0, float +VAVH, 1, sea_surface_wave_significant_height, m, , , W, 999999.0, 0.0, 100.0, float VAVT, 1, sea_surface_wave_zero_upcrossing_period, Second, , , W, 999999.0, 0.0, 100.0, float VBSC, 0, volumetric_backscatter_coefficient, m-1 sr-1, , , E, 999999.0, , , float VCUR, 1, northward_sea_water_velocity, m s-1, , , V, 999999.0, -10.0, 10.0, float @@ -176,16 +176,16 @@ VWND, 1, northward_wind, WCUR, 1, upward_sea_water_velocity, m s-1, , , V, 999999.0, -5.0, 5.0, float WDIR, 1, wind_to_direction, degree, clockwise, true north, M, 999999.0, 0.0, 360.0, float WDIRF_AVG, 1, wind_from_direction, degree, clockwise, true north, M, 999999.0, 0.0, 360.0, float -WHTE, 0, sea_surface_wave_significant_height_of_highest_one_tenth, m, up, sea surface, W, 999999.0, 0.0, 100.0, float -WHTH, 0, sea_surface_wave_significant_height_of_highest_one_third, m, up, sea surface, W, 999999.0, 0.0, 100.0, float +WHTE, 0, sea_surface_wave_significant_height_of_highest_one_tenth, m, , , W, 999999.0, 0.0, 100.0, float +WHTH, 0, sea_surface_wave_significant_height_of_highest_one_third, m, , , W, 999999.0, 0.0, 100.0, float WPFM, 1, sea_surface_wave_mean_period_from_variance_spectral_density_first_frequency_moment, Second, , , W, 999999.0, 0.0, 100.0, float WPMH, 0, sea_surface_wave_zero_crossing_period, Second, , , W, 999999.0, 0.0, 100.0, float WPSM, 1, sea_surface_wave_mean_period_from_variance_spectral_density_second_frequency_moment, Second, , , W, 999999.0, 0.0, 100.0, float WPTE, 0, sea_surface_wave_period_of_highest_one_tenth, Second, , , W, 999999.0, 0.0, 100.0, float WPTH, 0, sea_surface_wave_period_of_highest_one_third, Second, , , W, 999999.0, 0.0, 100.0, float WMPP, 0, sea_surface_wave_maximum_zero_crossing_period, Second, , , W, 999999.0, 0.0, 100.0, float -WMSH, 0, sea_surface_wave_zero_crossing_mean_height, m, up, sea surface, W, 999999.0, 0.0, 100.0, float -WMXH, 0, sea_surface_wave_maximum_height, m, up, sea surface, W, 999999.0, 0.0, 100.0, float +WMSH, 0, sea_surface_wave_zero_crossing_mean_height, m, , , W, 999999.0, 0.0, 100.0, float +WMXH, 0, sea_surface_wave_maximum_height, m, , , W, 999999.0, 0.0, 100.0, float WPDI, 0, sea_surface_wave_from_direction_at_variance_spectral_density_maximum, degree, clockwise, true north, W, 999999.0, 0.0, 360.0, float WPDI_MAG, 0, sea_surface_wave_from_direction_at_variance_spectral_density_maximum, degree, clockwise, magnetic north, W, 999999.0, 0.0, 360.0, float WPDIT, 0, sea_surface_wave_to_direction_at_variance_spectral_density_maximum, degree, clockwise, true north, W, 999999.0, 0.0, 360.0, float @@ -195,12 +195,12 @@ WSPD, 1, wind_speed, WSPD_AVG, 1, wind_speed, m s-1, , , M, 999999.0, , , float WSPD_MIN, 1, wind_speed, m s-1, , , M, 999999.0, , , float WSPD_MAX, 1, wind_speed, m s-1, , , M, 999999.0, , , float -WSSH, 0, sea_surface_wave_spectral_significant_height, m, up, sea surface, W, 999999.0, 0.0, 100.0, float +WSSH, 0, sea_surface_wave_spectral_significant_height, m, , , W, 999999.0, 0.0, 100.0, float WWAV, 1, sea_surface_wind_wave_to_direction, degree, clockwise, true north, W, 999999.0, 0.0, 360.0, float WWDS, 0, sea_surface_wind_wave_directional_spread, degree, clockwise, true north, W, 999999.0, 0.0, 360.0, float WWPD, 0, sea_surface_peak_wind_sea_wave_from_direction, degree, clockwise, true north, W, 999999.0, 0.0, 360.0, float WWPD_MAG, 0, sea_surface_peak_wind_sea_wave_from_direction, degree, clockwise, magnetic north, W, 999999.0, 0.0, 360.0, float WWPP, 0, sea_surface_peak_wind_sea_wave_period, Second, , , W, 999999.0, 0.0, 100.0, float -WWSH, 1, sea_surface_wind_wave_significant_height, m, up, sea surface, W, 999999.0, 0.0, 100.0, float +WWSH, 1, sea_surface_wind_wave_significant_height, m, , , W, 999999.0, 0.0, 100.0, float XCO2_AIR, 1, mole_fraction_of_carbon_dioxide_in_air, 1e-6, , , K, 999999.0, , , float XCO2_WATER, 0, mole_fraction_of_carbon_dioxide_in_sea_water, 1e-6, , , K, 999999.0, , , float \ No newline at end of file diff --git a/NetCDF/exportNetCDF.m b/NetCDF/exportNetCDF.m index 369970c1b..22b788cba 100644 --- a/NetCDF/exportNetCDF.m +++ b/NetCDF/exportNetCDF.m @@ -53,7 +53,7 @@ if ~ischar(dest), error('dest must be a string'); end % check that destination is a directory - [stat atts] = fileattrib(dest); + [stat, atts] = fileattrib(dest); if ~stat || ~atts.directory || ~atts.UserWrite error([dest ' does not exist, is not a directory, or is not writeable']); end @@ -644,6 +644,10 @@ function putAtts(fid, vid, var, template, templateFile, netcdfType, dateFmt, mod % each att is a struct field atts = fieldnames(template); + + % let's process them in the alphabetical order regardless of the case + [~, iSort] = sort(lower(atts)); + atts = atts(iSort); for k = 1:length(atts) name = atts{k}; diff --git a/Parser/SBE19Parse.m b/Parser/SBE19Parse.m index 0fe3e0ade..319e1b4d2 100644 --- a/Parser/SBE19Parse.m +++ b/Parser/SBE19Parse.m @@ -252,7 +252,7 @@ sample_data.variables{end}.name = 'TIME'; sample_data.variables{end}.typeCastFunc = str2func(netcdf3ToMatlabType(imosParameters(sample_data.variables{end}.name, 'type'))); sample_data.variables{end}.data = sample_data.variables{end}.typeCastFunc([descendingTime, ascendingTime]); - sample_data.variables{end}.comment = 'First value over profile measurement'; + sample_data.variables{end}.comment = 'First value over profile measurement.'; sample_data.variables{end+1}.dimensions = dimensions; sample_data.variables{end}.name = 'DIRECTION'; diff --git a/Parser/readXR420.m b/Parser/readXR420.m index b4b0b8f06..8eba09749 100644 --- a/Parser/readXR420.m +++ b/Parser/readXR420.m @@ -178,7 +178,7 @@ sample_data.variables{end}.name = 'TIME'; sample_data.variables{end}.typeCastFunc = str2func(netcdf3ToMatlabType(imosParameters(sample_data.variables{end}.name, 'type'))); sample_data.variables{end}.data = sample_data.variables{end}.typeCastFunc([descendingTime, ascendingTime]); - sample_data.variables{end}.comment = 'First value over profile measurement'; + sample_data.variables{end}.comment = 'First value over profile measurement.'; sample_data.variables{end+1}.dimensions = dimensions; sample_data.variables{end}.name = 'DIRECTION'; diff --git a/Parser/readXR620.m b/Parser/readXR620.m index d185a2cfa..22d614d55 100644 --- a/Parser/readXR620.m +++ b/Parser/readXR620.m @@ -175,7 +175,7 @@ sample_data.variables{end}.name = 'TIME'; sample_data.variables{end}.typeCastFunc = str2func(netcdf3ToMatlabType(imosParameters(sample_data.variables{end}.name, 'type'))); sample_data.variables{end}.data = sample_data.variables{end}.typeCastFunc([descendingTime, ascendingTime]); - sample_data.variables{end}.comment = 'First value over profile measurement'; + sample_data.variables{end}.comment = 'First value over profile measurement.'; sample_data.variables{end+1}.dimensions = dimensions; sample_data.variables{end}.name = 'DIRECTION'; diff --git a/Preprocessing/timeMetaOffsetPP.m b/Preprocessing/timeMetaOffsetPP.m index 8e1c874ea..5538e371c 100644 --- a/Preprocessing/timeMetaOffsetPP.m +++ b/Preprocessing/timeMetaOffsetPP.m @@ -177,6 +177,9 @@ % this set has been deselected if ~sets(k), continue; end + % no offset to be applied on this dataset + if offsets(k) == 0, continue; end + % otherwise apply the offset sample_data{k}.time_deployment_start = ... sample_data{k}.time_deployment_start + (offsets(k) / 24); diff --git a/Preprocessing/timeOffsetPP.m b/Preprocessing/timeOffsetPP.m index 84a345359..340c60717 100644 --- a/Preprocessing/timeOffsetPP.m +++ b/Preprocessing/timeOffsetPP.m @@ -197,6 +197,9 @@ % no time dimension nor variable in this dataset if timeIdx == 0, continue; end + % no offset to be applied on this dataset + if offsets(k) == 0, continue; end + signOffset = sign(offsets(k)); if signOffset >= 0 signOffset = '+'; diff --git a/imosToolbox.m b/imosToolbox.m index 922b950ec..e7213702b 100644 --- a/imosToolbox.m +++ b/imosToolbox.m @@ -73,7 +73,7 @@ function imosToolbox(auto, varargin) end % Set current toolbox version -toolboxVersion = ['2.5.19 - ' computer]; +toolboxVersion = ['2.5.20 - ' computer]; switch auto case 'auto', autoIMOSToolbox(toolboxVersion, varargin{:}); diff --git a/imosToolbox_Linux64.bin b/imosToolbox_Linux64.bin index daca016a4..d12354f1b 100755 Binary files a/imosToolbox_Linux64.bin and b/imosToolbox_Linux64.bin differ diff --git a/imosToolbox_Win32.exe b/imosToolbox_Win32.exe index d383b00d3..eca2a3ed4 100644 Binary files a/imosToolbox_Win32.exe and b/imosToolbox_Win32.exe differ diff --git a/imosToolbox_Win64.exe b/imosToolbox_Win64.exe index 3776a3ad6..6c29c16f7 100644 Binary files a/imosToolbox_Win64.exe and b/imosToolbox_Win64.exe differ