Skip to content

Commit

Permalink
Added ROI info interface which displays statistics about each ROI for…
Browse files Browse the repository at this point in the history
… a given ion image (as well as a second interface for viewing stats for all ion images). Can copy figures to clipboard and export data to CSV.
  • Loading branch information
AlanRace committed Jul 12, 2017
1 parent 6082736 commit 2783966
Show file tree
Hide file tree
Showing 6 changed files with 287 additions and 5 deletions.
Binary file modified lib/JSpectralAnalysis/JSpectralAnalysis.jar
Binary file not shown.
Binary file modified lib/jimzMLParser/jimzMLParser-1.0-SNAPSHOT.jar
Binary file not shown.
21 changes: 17 additions & 4 deletions src/gui/DataViewer.m
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
editRegionOfInterestButton;
saveRegionOfInterestButton;
loadRegionOfInterestButton;
infoRegionOfInterestButton;
selectedROIs;

preprocessingPanel;
Expand Down Expand Up @@ -572,6 +573,11 @@ function loadRegionOfInterest(this)
end
end

function infoRegionOfInterest(this)
roiInfo = RegionOfInterestInfoFigure(this.regionOfInterestList, this.imageList);
roiInfo.selectImageIndex(1);
end

function setRegionOfInterestList(this, regionOfInterestList)
this.regionOfInterestList = regionOfInterestList;

Expand Down Expand Up @@ -1063,11 +1069,17 @@ function createFigure(obj)
'CellSelectionCallback', @obj.selectRegionOfInterest, ...
'Units', 'normalized', 'Position', [0.05 0.05 0.9 0.9]);
obj.editRegionOfInterestButton = uicontrol('Parent', obj.regionOfInterestPanel, 'String', 'Edit', ...
'Units', 'normalized', 'Position', [0.65 0.1 0.3 0.3], 'Callback', @(src, evnt)obj.editRegionOfInterestList());
'Units', 'normalized', 'Position', [0.65 0.1 0.3 0.3], 'Callback', @(src, evnt)obj.editRegionOfInterestList(), ...
'TooltipString', 'Add/Edit regions of interest');
obj.saveRegionOfInterestButton = uicontrol('Parent', obj.regionOfInterestPanel, 'String', 'S', ...
'Units', 'normalized', 'Position', [0.1 0.1 0.1 0.3], 'Callback', @(src, evnt)obj.saveRegionOfInterest());
'Units', 'normalized', 'Position', [0.1 0.1 0.1 0.3], 'Callback', @(src, evnt)obj.saveRegionOfInterest(), ...
'TooltipString', 'Save region of interest list');
obj.loadRegionOfInterestButton = uicontrol('Parent', obj.regionOfInterestPanel, 'String', 'L', ...
'Units', 'normalized', 'Position', [0.1 0.1 0.1 0.05], 'Callback', @(src, evnt)obj.loadRegionOfInterest());
'Units', 'normalized', 'Position', [0.1 0.1 0.1 0.05], 'Callback', @(src, evnt)obj.loadRegionOfInterest(), ...
'TooltipString', 'Load region of interest list');
obj.infoRegionOfInterestButton = uicontrol('Parent', obj.regionOfInterestPanel, 'String', 'i', ...
'Units', 'normalized', 'Position', [0.1 0.1 0.1 0.05], 'Callback', @(src, evnt)obj.infoRegionOfInterest(), ...
'TooltipString', 'Display region of interest details');


% obj.imageAxis = axes('Parent', obj.handle, 'Position', [.25 .62 .7 .3]);
Expand Down Expand Up @@ -1245,9 +1257,10 @@ function sizeChanged(obj)

if(~isempty(panelPosition))
Figure.setObjectPositionInPixels(obj.regionOfInterestTable, [margin, buttonHeight + margin, panelPosition(3) - margin*2, panelPosition(4) - margin*2 - buttonHeight - 20]);
Figure.setObjectPositionInPixels(obj.editRegionOfInterestButton, [panelPosition(3)/2, margin, panelPosition(3)/2 - margin, buttonHeight]);
Figure.setObjectPositionInPixels(obj.editRegionOfInterestButton, [panelPosition(3)*2/3, margin, panelPosition(3)*1/3 - margin, buttonHeight]);
Figure.setObjectPositionInPixels(obj.saveRegionOfInterestButton, [margin, margin, panelPosition(3)/5 - margin*2, buttonHeight]);
Figure.setObjectPositionInPixels(obj.loadRegionOfInterestButton, [margin+panelPosition(3)*1/5, margin, panelPosition(3)/5 - margin*2, buttonHeight]);
Figure.setObjectPositionInPixels(obj.infoRegionOfInterestButton, [margin+panelPosition(3)*2/5, margin, panelPosition(3)/5 - margin*2, buttonHeight]);
end
end

Expand Down
2 changes: 1 addition & 1 deletion src/gui/MOOGL
Submodule MOOGL updated 1 files
+4 −1 gui/ImageDisplay.m
102 changes: 102 additions & 0 deletions src/gui/RegionOfInterestAllInfoFigure.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
classdef RegionOfInterestAllInfoFigure < Figure

properties (Access = private)
roiList;
imageList;

regionOfInterestTable;
exportButton;
previousPath;
end

methods
function this = RegionOfInterestAllInfoFigure(roiList, imageList)
this.roiList = roiList;
this.imageList = imageList;

this.setTitle('All Region of Interest Details');

this.updateData();
end

function updateData(this)
index = 1;

tableData = {};

for j = 1:length(this.imageList)
image = this.imageList(j);

for i = 1:this.roiList.getSize()
roi = this.roiList.get(i);

tableData{index, 1} = image.description;
tableData{index, 2} = ['<HTML><font color="' roi.getColour().toHex() '">' roi.getName() '</font></HTML>' ];%roi.name;
tableData{index, 3} = mean(image.imageData(roi.pixelSelection));
tableData{index, 4} = std(image.imageData(roi.pixelSelection));
tableData{index, 5} = sum(roi.pixelSelection(:));
tableData{index, 6} = max(image.imageData(roi.pixelSelection));
tableData{index, 7} = min(image.imageData(roi.pixelSelection));

index = index + 1;
end
end

set(this.regionOfInterestTable, 'Data', tableData);
end

function export(this)
[filename, path, filter] = uiputfile({'*.csv', 'CSV File'}, 'Export to CSV', [this.previousPath filesep 'ROIDetails.csv']);

if(filter > 0)
this.previousPath = path;
location = [path filesep filename];

[fid, errmsg] = fopen(location, 'w');

if(fid < 0)
errordlg(errmsg, 'Could not export to CSV');
else
fprintf(fid, 'm/z, ROI, Mean, SD, #Pixels, Max, Min\n');

for j = 1:length(this.imageList)
selectedImage = this.imageList(j);

for i = 1:this.roiList.getSize()
roi = this.roiList.get(i);

fprintf(fid, '%s,%s,%f,%f,%d,%f,%f\n', selectedImage.description, roi.getName(), ...
mean(selectedImage.imageData(roi.pixelSelection)), ...
std(selectedImage.imageData(roi.pixelSelection)), ...
sum(roi.pixelSelection(:)), ...
max(selectedImage.imageData(roi.pixelSelection)), ...
min(selectedImage.imageData(roi.pixelSelection)));
end
end

fclose(fid);
end
end
end
end

methods (Access = protected)
function createFigure(this)
% createFigure Create figure.
%
% createFigure()

createFigure@Figure(this);

columnNames = {'m/z', 'ROI', 'Mean', 'SD', '# Pixels', 'Max', 'Min'};
columnFormat = {'numeric', 'char', 'numeric', 'numeric', 'numeric', 'numeric', 'numeric'};
columnEditable = [false, false, false, false, false, false, false];

this.regionOfInterestTable = uitable('Parent', this.handle, ...
'ColumnName', columnNames, 'ColumnFormat', columnFormat, 'ColumnEditable', columnEditable, ...
'RowName', [], 'Units', 'normalized', 'Position', [0.05 0.15 0.9 0.8]);
this.exportButton = uicontrol('Parent', this.handle, ...
'String', 'Export', 'Units', 'normalized', 'Position', [0.75, 0.05, 0.2, 0.05], 'Callback', @(src, event) this.export());
end
end
end
167 changes: 167 additions & 0 deletions src/gui/RegionOfInterestInfoFigure.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
classdef RegionOfInterestInfoFigure < Figure

properties (Access = private)
roiList;
imageList;

imageListSelection;
allDataButton;
imageDisplay;
roiPlot;
regionOfInterestTable;

previousPath;

copyToClipboardButton;
exportButton;
end

methods
function this = RegionOfInterestInfoFigure(roiList, imageList)
this.roiList = roiList;
this.imageList = imageList;

this.setTitle('Region of Interest Details');
this.updateList();
end

function updateList(this)
set(this.imageListSelection, 'String', {this.imageList.description});

this.imageDisplay.removeAllRegionsOfInterest();

for i = 1:this.roiList.getSize()
roi = this.roiList.get(i);

this.imageDisplay.addRegionOfInterest(roi);
end
end

function selectImageIndex(this, index)
set(this.imageListSelection, 'Value', index);
this.imageSelected([], []);
end

function viewAllData(this)
RegionOfInterestAllInfoFigure(this.roiList, this.imageList);
end

function copyToClipboard(this)
this.setVisibilityForControls('off');
print -clipboard -dmeta
this.setVisibilityForControls('on');
end

function export(this)
selectedValue = get(this.imageListSelection, 'Value');
selectedImage = this.imageList(selectedValue);

[filename, path, filter] = uiputfile({'*.csv', 'CSV File'}, 'Export to CSV', [this.previousPath filesep selectedImage.description '.csv']);

if(filter > 0)
this.previousPath = path;
location = [path filesep filename];

[fid, errmsg] = fopen(location, 'w');

if(fid < 0)
errordlg(errmsg, 'Could not export to CSV');
else
fprintf(fid, 'ROI, Mean, SD, #Pixels, Max, Min\n');

for i = 1:this.roiList.getSize()
roi = this.roiList.get(i);

fprintf(fid, '%s,%f,%f,%d,%f,%f\n', roi.getName(), ...
mean(selectedImage.imageData(roi.pixelSelection)), ...
std(selectedImage.imageData(roi.pixelSelection)), ...
sum(roi.pixelSelection(:)), ...
max(selectedImage.imageData(roi.pixelSelection)), ...
min(selectedImage.imageData(roi.pixelSelection)));
end

fclose(fid);
end
end
end
end

methods (Access = protected)
function setVisibilityForControls(this, visibility)
set(this.imageListSelection, 'Visible', visibility);
set(this.allDataButton, 'Visible', visibility);
set(this.copyToClipboardButton, 'Visible', visibility);
set(this.exportButton, 'Visible', visibility);
end

function imageSelected(this, source, event)
selectedImageIndex = get(this.imageListSelection, 'Value');
selectedImage = this.imageList(selectedImageIndex);

this.imageDisplay.setData(selectedImage);

tableData = {};

colourTable = [];

axes(this.roiPlot);

for i = 1:this.roiList.getSize()
roi = this.roiList.get(i);

colour = [roi.getColour().r roi.getColour().g roi.getColour().b];

if(i == 2)
hold on;
end
bar(i, mean(selectedImage.imageData(roi.pixelSelection)), 'FaceColor', colour ./ 255);

tableData{i, 1} = ['<HTML><font color="' roi.getColour().toHex() '">' roi.getName() '</font></HTML>' ];%roi.name;
tableData{i, 2} = mean(selectedImage.imageData(roi.pixelSelection));
tableData{i, 3} = std(selectedImage.imageData(roi.pixelSelection));
tableData{i, 4} = sum(roi.pixelSelection(:));
tableData{i, 5} = max(selectedImage.imageData(roi.pixelSelection));
tableData{i, 6} = min(selectedImage.imageData(roi.pixelSelection));
end
assignin('base', 'tableData', tableData);
set(this.regionOfInterestTable, 'Data', tableData);

errorbar(1:this.roiList.getSize(), [tableData{:, 2}], [tableData{:, 3}], '.');
set(gca, 'XTickLabel', '')

hold off;
end

function createFigure(this)
% createFigure Create figure.
%
% createFigure()

createFigure@Figure(this);

columnNames = {'ROI', 'Mean', 'SD', '# Pixels', 'Max', 'Min'};
columnFormat = {'char', 'numeric', 'numeric', 'numeric', 'numeric', 'numeric'};
columnEditable = [false, false, false, false, false, false];

this.imageListSelection = uicontrol('Parent', this.handle, 'Style', 'popup', ...
'String', {''}, 'Units', 'normalized', 'Position', [0.05, 0.85, 0.7, 0.1], 'Callback', @(src, event) this.imageSelected(src, event));

this.allDataButton = uicontrol('Parent', this.handle, ...
'String', 'View all data', 'Units', 'normalized', 'Position', [0.75, 0.9, 0.2, 0.05], 'Callback', @(src, event) this.viewAllData());

this.imageDisplay = ImageDisplay(this, Image(1));
set(this.imageDisplay.axisHandle, 'Position', [0.05, 0.5, 0.4, 0.35]);

this.roiPlot = axes(this.handle, 'Units', 'normalized', 'Position', [0.525, 0.525, 0.425, 0.325]);

this.regionOfInterestTable = uitable('Parent', this.handle, ...
'ColumnName', columnNames, 'ColumnFormat', columnFormat, 'ColumnEditable', columnEditable, ...
'RowName', [], 'Units', 'normalized', 'Position', [0.05 0.15 0.9 0.3]);

this.copyToClipboardButton = uicontrol('Parent', this.handle, ...
'String', 'Copy to clipboard', 'Units', 'normalized', 'Position', [0.05, 0.05, 0.2, 0.05], 'Callback', @(src, event) this.copyToClipboard());
this.exportButton = uicontrol('Parent', this.handle, ...
'String', 'Export', 'Units', 'normalized', 'Position', [0.75, 0.05, 0.2, 0.05], 'Callback', @(src, event) this.export());
end
end
end

0 comments on commit 2783966

Please sign in to comment.