Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
SpectraViewer-ML/spectraViewer_old.m
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
206 lines (181 sloc)
8.38 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function spectraViewer_old | |
% Viewer for excitation and emission spectra of fluorescent dyes | |
% | |
% Data organization inside spectra files: | |
% All files are expected to be comma separated lists with a header line. | |
% The header line is ignored, data are expected to be (in this order): | |
% Wavelength (abs), Absorption coef, Wavelength (em), Emission coef. | |
% | |
% The file names should contain the best excitation wavelength as the only | |
% number (anywhere within the string). | |
% | |
% Convert Excel files to csv files: | |
% - Make sure the excel sheet uses '.' as a decimal separator. If not, go | |
% to File -> Options -> Advanced -> Editing options -> Use system separator | |
% and change accordingly. Then, go to File -> Export -> Change File Type -> | |
% CSV -> Save as and save file. The region settings of your OS might result | |
% in semicolon-separated lists (instead of comma-separated lists). If so, | |
% go to Windows Start menu - Region and language - Additional settings - | |
% List separator and set it to comma. | |
% | |
% This is a good resource for spectra: https://www.chroma.com/spectra-viewer | |
% | |
% Stephan Junek, 2015 | |
%Find files | |
fn = [dir('*.txt')' dir('*.csv')']; | |
% Sort files according to the wavelength number contained in the file name | |
for f=1:numel(fn) | |
wl(f) = str2double(cell2mat(regexp(fn(f).name,'\d','match'))); | |
spectra(f).wavelength = wl(f); | |
end | |
[sortFn sortIdx] = sort(wl); | |
fn = fn(sortIdx); | |
spectra = spectra(sortIdx); | |
% Import data from files | |
for f = 1:numel(fn) | |
spectra(f).name = fn(f).name; | |
spectra(f).data = readData(fn(f).name); | |
end | |
% Make Gui | |
guiSz = [100 100 1200 600]; | |
gui = figure('Position',guiSz); | |
colorCode = jet(numel(fn)); | |
% Checkboxes for spectra | |
for f = 1:numel(fn) | |
cb_fn(f) = uicontrol('Style','Checkbox','String',spectra(f).name(1:end-4),... | |
'Value',0, 'Position',[10 guiSz(4)-20-f*20 150 18],... | |
'Backgroundcolor',get(gui,'Color'),'Callback',@updateSpectra,... | |
'ForegroundColor',colorCode(f,:)); | |
end | |
% "None" button | |
uicontrol('Style','pushbutton','Position',[10 guiSz(4)-50-f*20 150 18], 'String','None', ... | |
'Callback', @deselect); | |
% Checkboxes for laser lines | |
colorLaserLine = jet(30); | |
colorLUT = linspace(400,700,30); | |
laserlines = [355, 405, 458, 488, 514, 561, 594, 633]; | |
for f = 1:numel(laserlines) | |
cb_ll(f) = uicontrol('Style','Checkbox','String',[num2str(laserlines(f)) ' nm'],... | |
'Value',0, 'Position',[10 guiSz(4)-20-(numel(fn)+3+f)*20 150 18],... | |
'Backgroundcolor',get(gui,'Color'),'Callback',@updateSpectra,... | |
'ForegroundColor',colorLaserLine(find(colorLUT>laserlines(f),1),:)); | |
end | |
% Axes for conventional display of spectra, spectra of deselected dyes will | |
% be made invisible | |
ax(1) = axes('Position',[0.15 0.1 0.55 0.8]); | |
hold on | |
for f = 1:numel(fn) | |
plEx(f) = plot(spectra(f).data(:,1),spectra(f).data(:,2)/max(spectra(f).data(:,2)),'LineStyle','--','Color',colorCode(f,:),'LineWidth',4); | |
plEm(f) = plot(spectra(f).data(:,3),spectra(f).data(:,4)/max(spectra(f).data(:,4)),'Color',colorCode(f,:),'LineWidth',3); | |
end | |
for f = 1:numel(laserlines) | |
plLl(f) = plot(laserlines(f)*[1 1],get(gca,'YLim'),'Color',colorLaserLine(find(colorLUT>laserlines(f),1),:),'LineWidth',2); | |
end | |
set(gca,'YLim',[0 1]); | |
set([plEx plEm plLl], 'Visible','off') | |
xlabel('wavelength [nm]'); | |
% Axes for combined (2D) display of excitation and emission spectra | |
ax(2) = axes('Position',[0.75 0.1 0.2 0.8]); | |
hold all | |
% Calculate matrices (product of exc and em spectra) and display as contour plots | |
% Data will be interpolated to reduce calculation and plotting time | |
wEx = linspace(400,700,100); | |
wEm = linspace(500,800,100); | |
for f = 1:numel(fn) | |
% Make sure no wavelength value appears twice and remove NaN values | |
[c, idx] = unique(spectra(f).data(:,1)); | |
notNaN = ~isnan(spectra(f).data(idx,1)) & ~isnan(spectra(f).data(idx,2)); | |
interEx = interp1(spectra(f).data(idx(notNaN),1),spectra(f).data(idx(notNaN),2),wEx); | |
[c, idx] = unique(spectra(f).data(:,3)); | |
notNaN = ~isnan(spectra(f).data(idx,3)) & ~isnan(spectra(f).data(idx,4)); | |
interEm = interp1(spectra(f).data(idx(notNaN),3),spectra(f).data(idx(notNaN),4),wEm); | |
% Calculate and plot combined spectrum | |
m = repmat(interEx/max(interEx),[100 1]).*repmat(interEm'/max(interEm),[1 100]); | |
[c, pl2d(f)] = contour(wEx,wEm,m,[0.99 0.75 0.5 0.25],'Color',colorCode(f,:),'LineWidth',3); | |
end | |
for f = 1:numel(laserlines) | |
plLl2d(f) = plot(laserlines(f)*[1 1],get(gca,'YLim'),'Color',colorLaserLine(find(colorLUT>laserlines(f),1),:),'LineWidth',2); | |
end | |
set([pl2d plLl2d], 'Visible','off'); | |
xlabel('\lambda_{exc} [nm]'); | |
ylabel('\lambda_{em} [nm]'); | |
set(gca,'YLim',[500 700]); | |
% Callback and helper functions | |
function updateSpectra(varargin) | |
% updates display of spectra | |
checked = find(cell2mat(get(cb_fn,'Value'))); | |
set([plEx plEm pl2d], 'Visible','off'); | |
set([plEx(checked) plEm(checked) pl2d(checked)], 'Visible','on'); | |
legend(pl2d(checked),fn(checked).name); | |
checked = find(cell2mat(get(cb_ll,'Value'))); | |
set([plLl plLl2d], 'Visible','off'); | |
set([plLl(checked) plLl2d(checked)],'Visible','on'); | |
end | |
function deselect(varargin) | |
% Deselect all dyes | |
set(cb_fn,'Value',0); | |
updateSpectra | |
end | |
function out = readData(in) | |
% Import data (adopted from code created by "Import data" button) | |
% Initialize variables. | |
delimiter = ','; | |
startRow = 2; | |
% Read columns of data as strings: | |
% For more information, see the TEXTSCAN documentation. | |
formatSpec = '%s%s%s%s%[^\n\r]'; | |
% Open the text file. | |
fileID = fopen(in,'r'); | |
% Read columns of data according to format string. | |
% This call is based on the structure of the file used to generate this | |
% code. If an error occurs for a different file, try regenerating the code | |
% from the Import Tool. | |
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'HeaderLines' ,startRow-1, 'ReturnOnError', false); | |
% Close the text file. | |
fclose(fileID); | |
% Convert the contents of columns containing numeric strings to numbers. | |
% Replace non-numeric strings with NaN. | |
raw = repmat({''},length(dataArray{1}),length(dataArray)-1); | |
for col=1:length(dataArray)-1 | |
raw(1:length(dataArray{col}),col) = dataArray{col}; | |
end | |
numericData = NaN(size(dataArray{1},1),size(dataArray,2)); | |
for col=[1,2,3,4] | |
% Converts strings in the input cell array to numbers. Replaced non-numeric | |
% strings with NaN. | |
rawData = dataArray{col}; | |
for row=1:size(rawData, 1); | |
% Create a regular expression to detect and remove non-numeric prefixes and | |
% suffixes. | |
regexstr = '(?<prefix>.*?)(?<numbers>([-]*(\d+[\,]*)+[\.]{0,1}\d*[eEdD]{0,1}[-+]*\d*[i]{0,1})|([-]*(\d+[\,]*)*[\.]{1,1}\d+[eEdD]{0,1}[-+]*\d*[i]{0,1}))(?<suffix>.*)'; | |
try | |
result = regexp(rawData{row}, regexstr, 'names'); | |
numbers = result.numbers; | |
% Detected commas in non-thousand locations. | |
invalidThousandsSeparator = false; | |
if any(numbers==','); | |
thousandsRegExp = '^\d+?(\,\d{3})*\.{0,1}\d*$'; | |
if isempty(regexp(thousandsRegExp, ',', 'once')); | |
numbers = NaN; | |
invalidThousandsSeparator = true; | |
end | |
end | |
% Convert numeric strings to numbers. | |
if ~invalidThousandsSeparator; | |
numbers = textscan(strrep(numbers, ',', ''), '%f'); | |
numericData(row, col) = numbers{1}; | |
raw{row, col} = numbers{1}; | |
end | |
catch me | |
end | |
end | |
end | |
% Replace non-numeric cells with NaN | |
R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),raw); % Find non-numeric cells | |
raw(R) = {NaN}; % Replace non-numeric cells | |
% Create output variable | |
out = cell2mat(raw); | |
% Clear temporary variables | |
clearvars filename delimiter startRow formatSpec fileID dataArray ans raw col numericData rawData row regexstr result numbers invalidThousandsSeparator thousandsRegExp me R; | |
end | |
end | |