some housekeeping to tidy up
No files matched your search
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MATLABProject xmlns="http://www.mathworks.com/MATLABProjectFile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"/>
|
||||
@@ -1,188 +0,0 @@
|
||||
function D = IBWread(FN);
|
||||
% IBWread - read Igor wave from IBW file
|
||||
% D = IBWread('Foo.ibw') reads Igor file Foo.ibw into struct D.
|
||||
|
||||
if exist('fullfilename', 'file'), FFN = fullfilename(FN, cd, '.ibw');
|
||||
else, FFN = FN;
|
||||
end
|
||||
|
||||
% read headers
|
||||
[D.binHeader, D.waveHeader, FFN] = readIBWheaders(FN);
|
||||
fid = fopen(FFN,'r');
|
||||
fid = fopen(FFN,'r');
|
||||
% For numeric waves, the type field is interpreted bitwise. One of the following bits, as represented by symbols defined in IgorBin.h, will be set:
|
||||
%
|
||||
% % #define NT_CMPLX 1 % Complex numbers.
|
||||
% % #define NT_FP32 2 % 32 bit fp numbers.
|
||||
% % #define NT_FP64 4 % 64 bit fp numbers.
|
||||
% % #define NT_I8 8 % 8 bit signed integer. Requires Igor Pro 2.0 or later.
|
||||
% % #define NT_I16 0x10 % 16 bit integer numbers. Requires Igor Pro 2.0 or later.
|
||||
% % #define NT_I32 0x20 % 32 bit integer numbers. Requires Igor Pro 2.0 or later.
|
||||
% % #define NT_UNSIGNED 0x40 % Makes above signed integers unsigned. Requires Igor Pro 3.0 or later.
|
||||
% NT_FP64 64-bit floating point (double)
|
||||
% NT_FP32 32-bit floating point (float)
|
||||
% NT_I32 32 bit integer (long)
|
||||
% NT_16 16 bit integer (short)
|
||||
% NT_I8 8 bit integer (char)
|
||||
datatype = D.waveHeader.type;
|
||||
CMPLX = rem(datatype,2);
|
||||
if CMPLX, datatype = datatype-1; end
|
||||
switch datatype,
|
||||
case 0, prec = '*char';
|
||||
case 2, prec = 'single';
|
||||
case 4, prec = 'double';
|
||||
case 8, prec = 'int8';
|
||||
case 16, prec = 'int16';
|
||||
case 32, prec = 'int32';
|
||||
case 64+8, prec = 'uint8';
|
||||
case 64+16, prec = 'uint16';
|
||||
case 64+32, prec = 'uint32';
|
||||
otherwise, error('Invalid numerical datatype.');
|
||||
end
|
||||
|
||||
D.bname = D.waveHeader.bname;
|
||||
% The date/time is store as seconds since midnight, January 1, 1904.
|
||||
D.creationDate = local_igorTime2vec(D.waveHeader.creationDate);
|
||||
D.modDate = local_igorTime2vec(D.waveHeader.creationDate);
|
||||
switch D.binHeader.version,
|
||||
case 2,
|
||||
% The version 2 file has the following general layout.
|
||||
% BinHeader2 structure: 16 bytes
|
||||
% WaveHeader2 structure excluding wData field; 110 bytes
|
||||
% Wave data: Variable size
|
||||
D.Nsam = D.waveHeader.npnts;
|
||||
D.Ndim = 1;
|
||||
% X value for point p = hsA*p + hsB
|
||||
D.dx = D.waveHeader.hsA;
|
||||
D.x0 = D.waveHeader.hsB;
|
||||
D.x1 = D.x0+D.Nsam*D.dx;
|
||||
fseek(fid, 16+110, 'bof');
|
||||
NN = D.Nsam*(1+double(CMPLX)); % if complex, read twice as many numbers
|
||||
D.y = fread(fid, NN, prec);
|
||||
if CMPLX, D.y = D.y(1:2:end) + i*D.y(2:2:end); end; % Re & Im values are interleaved
|
||||
case 5,
|
||||
% The version 5 file has the following general layout.
|
||||
% BinHeader5 structure 64 bytes
|
||||
% WaveHeader5 structure excluding wData field 320 bytes
|
||||
% Wave data Variable size
|
||||
% Optional wave dependency formula Variable size
|
||||
% Optional wave note data Variable size
|
||||
D.Nsam = D.waveHeader.npnts;
|
||||
D.Ndim = sum(D.waveHeader.nDim>0);
|
||||
% X offset & spacing (documentation is obscure)
|
||||
D.dx = D.waveHeader.sfA(1:D.Ndim);
|
||||
D.x0 = D.waveHeader.sfB(1:D.Ndim);
|
||||
D.x1 = nan; % D.x0+D.Nsam*D.dx;
|
||||
fseek(fid, 64+320, 'bof');
|
||||
NN = D.Nsam*(1+double(CMPLX)); % if complex, read twice as many numbers
|
||||
if isequal(0,datatype), % text data
|
||||
% Number of bytes of wave data = wfmSize - (sizeof(WaveHeader5) - 4)
|
||||
NN = D.binHeader.wfmSize-320;
|
||||
D.y = fread(fid, NN, prec)';
|
||||
else, % numerical data
|
||||
D.y = fread(fid, NN, prec);
|
||||
end
|
||||
if CMPLX, D.y = D.y(1:2:end) + i*D.y(2:2:end); end; % Re & Im values are interleaved
|
||||
if ~isempty(D.y) && D.Ndim>1,
|
||||
D.y = reshape(D.y, D.waveHeader.nDim(1:D.Ndim));
|
||||
end
|
||||
end
|
||||
D.WaveNotes = local_readNotes(fid, D.binHeader);
|
||||
if isequal(0,datatype), % partition text data into lines using string indices stored @ eof
|
||||
D = local_partition_text(fid, D);
|
||||
end
|
||||
fseek(fid,0,'eof');
|
||||
D.fileSize = ftell(fid);
|
||||
fclose(fid);
|
||||
|
||||
|
||||
%===============================
|
||||
function DV=local_igorTime2vec(it);
|
||||
% igor time -> date vector a la Matlab
|
||||
% The date/time is store as seconds since midnight, January 1, 1904.
|
||||
Nsec_4year = 126230400;
|
||||
idate_1988 = 21*uint32(Nsec_4year); % # seconds between 1-jan-1904 & 1-jan-1988
|
||||
it = double(it-idate_1988); % smaller numbers-> use ordinary numbers ("doubles")
|
||||
M4 = floor(it/Nsec_4year);
|
||||
YR = double(1988+4*M4);
|
||||
it = double(it-M4*Nsec_4year);
|
||||
last_it = it;
|
||||
while 1, % subtract years as long as they fit
|
||||
s = etime([YR+1 1 1 0 0 0], [YR 1 1 0 0 0]);
|
||||
if it<s, break; end % we went too far
|
||||
YR = YR+1;
|
||||
it = it-s;
|
||||
end
|
||||
MNTH = 1;
|
||||
while 1, % subtract months as long as they fit
|
||||
s = etime([YR MNTH+1 1 0 0 0], [YR MNTH 1 0 0 0]);
|
||||
if it<s, break; end % we went too far
|
||||
MNTH = MNTH+1;
|
||||
it = it-s;
|
||||
end
|
||||
DAY = 1;
|
||||
while 1, % subtract days as long as they fit
|
||||
s = etime([YR MNTH DAY+1 0 0 0], [YR MNTH DAY 0 0 0]);
|
||||
if it<s, break; end % we went too far
|
||||
DAY = DAY+1;
|
||||
it = it-s;
|
||||
end
|
||||
HR = floor(it/60^2); it = it-HR*60^2;
|
||||
MIN = floor(it/60); SEC = it-MIN*60;
|
||||
DV = [YR, MNTH, DAY, HR, MIN, SEC];
|
||||
if ~isequal(last_it, etime(DV, [1988+4*M4 1 1 0 0 0])),
|
||||
error('date error');
|
||||
end
|
||||
|
||||
function Nts = local_readNotes(fid, B);
|
||||
switch B.version,
|
||||
case 2,
|
||||
% BinHeader2 structure 16 bytes
|
||||
% WaveHeader2 structure excluding wData field 110 bytes
|
||||
% Wave data Variable size
|
||||
% 16 bytes of padding 16 bytes
|
||||
dum = fread(fid,16,'char');
|
||||
% Optional wave note data
|
||||
Nts = fread(fid, B.noteSize, '*char').';
|
||||
case 5,
|
||||
% BinHeader5 structure 64 bytes
|
||||
% WaveHeader5 structure excluding wData field 320 bytes
|
||||
% Wave data Variable size
|
||||
% Optional wave dependency formula Variable size
|
||||
dum = fread(fid,B.formulaSize, 'char');
|
||||
% Optional wave note data Variable size
|
||||
Nts = fread(fid, B.noteSize, '*char').';
|
||||
end
|
||||
|
||||
function D = local_partition_text(fid, D);
|
||||
% read sizeindices and chop text accordingly, must be called after reading
|
||||
% notes
|
||||
bH = D.binHeader;
|
||||
% skip other stuff in file
|
||||
% The version 5 file has the following general layout.
|
||||
% BinHeader5 structure 64 bytes
|
||||
% WaveHeader5 structure excluding wData field 320 bytes
|
||||
% Wave data Variable size
|
||||
% Optional wave dependency formula Variable size
|
||||
% Optional wave note data Variable size
|
||||
% Optional extended data units data Variable size
|
||||
% Optional extended dimension units data Variable size
|
||||
% Optional dimension label data Variable size
|
||||
% String indices used for text waves only Variable size
|
||||
dum=fseek(fid, -bH.sIndicesSize, 'eof'); % string indices are last in file; it's easier to refer from end-of-file
|
||||
% bH.sIndicesSize; # bytes of string indices stored for the wave if the wave type is text.
|
||||
% String indices are used to determine the offset in the file and the number of bytes for each element of the text wave.
|
||||
sIdx = [0 fread(fid, bH.sIndicesSize/4, 'uint32').'];
|
||||
for ii=1:numel(sIdx)-1,
|
||||
STR{ii,1} = D.y(sIdx(ii)+1:sIdx(ii+1));
|
||||
end
|
||||
D.y = STR;
|
||||
|
||||
|
||||
% long sIndicesSize; The size of string indicies if this is a text wave.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
function ListFiles = QuickAndDirtyNexafsImport(DataTable)
|
||||
|
||||
|
||||
|
||||
%% QuickAndDirtyNexafsImport
|
||||
%
|
||||
[filePick,pathPick] = uigetfile({'*.h5'},...
|
||||
'Select One or More Files',...
|
||||
'MultiSelect', 'on');
|
||||
% make lists for Nexafs
|
||||
if ischar(filePick)
|
||||
filePick = {filePick};
|
||||
end
|
||||
|
||||
for ii = 1:size(filePick,2)
|
||||
TmpFileList{2}(ii,1) = dir([pathPick filePick{ii}]);
|
||||
end
|
||||
|
||||
|
||||
for ii = 1:size(filePick,2)
|
||||
try
|
||||
TmpImage= h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/spectrum');
|
||||
%else
|
||||
catch
|
||||
try
|
||||
TmpImage = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/scienta spectrum');
|
||||
catch
|
||||
TmpData = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/detector/data');
|
||||
%convert 3 dim matrix to 2 dim matrix
|
||||
for i = 1:size(TmpData,3)%iterations
|
||||
TmpImage(:,i) = TmpData(:,1,(i)); %#ok<*SAGROW>
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
% import Photon Energy (cols)
|
||||
try %general try to ensure that script does not stop upon errors.
|
||||
try
|
||||
TmpXrayEkin = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/energy'); % X-ray excitation energy; Photon energy in eV
|
||||
TmpXrayEkin(TmpXrayEkin==0)=[];
|
||||
catch
|
||||
TmpXrayEkin = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/PhotonEnergy'); % X-ray excitation energy; Photon energy in eV
|
||||
TmpXrayEkin(TmpXrayEkin==0)=[];
|
||||
end
|
||||
% Make unique
|
||||
[TmpFileList{2}(ii).xRayEkin_eV, ind] = unique(TmpXrayEkin);
|
||||
TmpFileList{2}(ii).image = TmpImage(:,ind);
|
||||
% NEXAFS pass energy
|
||||
try
|
||||
tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/PassEnergy'); % in eV
|
||||
TmpFileList{2}(ii).scientaPassEnergy_eV = str2double(tmp(1));
|
||||
catch
|
||||
tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/PassEnergy'); % in eV
|
||||
TmpFileList{2}(ii).scientaPassEnergy_eV = str2double(tmp(1));
|
||||
end
|
||||
% Acquisition mode
|
||||
try
|
||||
TmpFileList{2}(ii).scientaAcquisitionMode = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/AcquisitionMode');
|
||||
catch
|
||||
TmpFileList{2}(ii).scientaAcquisitionMode = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/AcquireMode');
|
||||
end
|
||||
if strcmp(TmpFileList{2}(ii).scientaAcquisitionMode,'Fixed')
|
||||
% NEXAFS kinetic energy window - fixed mode
|
||||
try
|
||||
tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/ScientaCenterEnergy'); % in eV
|
||||
catch
|
||||
tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/CenterEnergy'); % in eV
|
||||
end
|
||||
TmpFileList{2}(ii).scientaEkinRange_eV = [tmp(1)-TmpFileList{2}(ii).scientaPassEnergy_eV/20 tmp(1)+TmpFileList{2}(ii).scientaPassEnergy_eV/20];
|
||||
TmpFileList{2}(ii).scientaEkinStep_eV = NaN;
|
||||
TmpFileList{2}(ii).scientaEkin_eV = linspace(TmpFileList{2}(ii).scientaEkinRange_eV(:,1)...
|
||||
,TmpFileList{2}(ii).scientaEkinRange_eV(:,2),size(TmpFileList{2}(ii).image,1))';
|
||||
else
|
||||
% NEXAFS kinetic energy window - scan mode
|
||||
try
|
||||
tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/ScientaLowEnergy'); % in eV
|
||||
tmp2 = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/ScientaHighEnergy');
|
||||
catch
|
||||
tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/LowEnergy'); % in eV
|
||||
tmp2 = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/HighEnergy');
|
||||
end
|
||||
TmpFileList{2}(ii).scientaEkinRange_eV = [tmp(1) tmp2(1)];
|
||||
try
|
||||
TmpFileList{2}(ii).scientaEkinStep_eV = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/StepSize');
|
||||
catch
|
||||
TmpFileList{2}(ii).scientaEkinStep_eV = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/StepSize');
|
||||
end
|
||||
TmpFileList{2}(ii).scientaEkin_eV = [TmpFileList{2}(ii).scientaEkinRange_eV(:,1):TmpFileList{2}(ii).scientaEkinStep_eV(1):TmpFileList{2}(ii).scientaEkinRange_eV(:,2)]';
|
||||
end
|
||||
catch
|
||||
end
|
||||
end
|
||||
%% Merge lists into one
|
||||
%
|
||||
|
||||
% get index of non-empty structures
|
||||
tf =~cellfun(@isempty,TmpFileList);
|
||||
|
||||
% merge the non-empty list structures into one structure
|
||||
ListFiles = cat(1,TmpFileList{tf});
|
||||
|
||||
% remove lines with empty images
|
||||
for ii = 1:size(ListFiles,1)
|
||||
tmpLogic(ii) = isempty(ListFiles(ii).image);
|
||||
noncells = tmpLogic;
|
||||
end
|
||||
ListFiles(noncells) = [];
|
||||
|
||||
clearvars -except ListFiles DataTable
|
||||
|
||||
|
||||
%%
|
||||
|
||||
|
||||
|
||||
%% Sort by date
|
||||
% rename date fields and delete those fields not needed
|
||||
[ListFiles.lastModifiedDatestr] = ListFiles.date;
|
||||
[ListFiles.lastModifiedDatenum] = ListFiles.datenum;
|
||||
|
||||
% First, we need to convert into a table, because structures can not be sorted:
|
||||
ListFiles = struct2table(ListFiles,'AsArray',true);
|
||||
% Then, we sort the table based on the time (6th column, datenum)
|
||||
ListFiles = sortrows(ListFiles,6);
|
||||
% Then, remove un-needed columns
|
||||
ListFiles = removevars(ListFiles,{'bytes','isdir','date','datenum'});
|
||||
|
||||
% merge tables (append imported data to previous table)
|
||||
if exist("DataTable",'var')
|
||||
ListFiles = outerjoinRowToTable(ListFiles,DataTable);
|
||||
end
|
||||
% Then, we sort the table based on the time (datenum)
|
||||
ListFiles = sortrows(ListFiles,'lastModifiedDatenum');
|
||||
end
|
||||
@@ -1,134 +0,0 @@
|
||||
%% Develpment of hdf export and import
|
||||
%
|
||||
% from table to our instrument hdf structure
|
||||
%% Todo
|
||||
%
|
||||
% * ensure logging of processing in NEXAFS and XPS to select data, make it
|
||||
% usfull for string operations (no cells)
|
||||
% * How to include units and definitions
|
||||
% * Next, make this work for averageded files
|
||||
%%
|
||||
clc
|
||||
% % add some SES data
|
||||
%tmpFileImport = load('../beamtimes/20220828BeamTimeIceNappIss/FileList.mat');
|
||||
% FileList = outerjoinRowToTable(FileList, tmpFileImport.FileList);
|
||||
clearvars tmp*
|
||||
% select only data that has been used,
|
||||
[tmpn1, ~] = cellfun(@size,FileList.spectrum_counts); % spectra have been generated
|
||||
[tmpn2, ~] = cellfun(@size,FileList.spectrum_countsNorm);
|
||||
[tmpn3, ~] = cellfun(@size,FileList.spectrum_countsPerSecond);
|
||||
tmpDataSelection = contains(FileList.sample,lettersPattern) ... % we have added sample notes, so this is data
|
||||
& ~contains(FileList.sample, '(bad data)') & ~contains(FileList.sample, '(no notes)') ...
|
||||
& (tmpn1 > 1 | tmpn2 > 1 | tmpn3 > 1); % has actually been proceesed.
|
||||
|
||||
|
||||
|
||||
tmpUserName = 'ThorstenBR';
|
||||
tmpFileList = FileList(tmpDataSelection,:);
|
||||
% get table variables that are data
|
||||
tmpMissingVariable = ~ismember(tmpFileList.Properties.VariableNames,...
|
||||
[{'image'}; {'spectrum_counts'}; {'spectrum_countsPerSecond'}; {'spectrum_countsNorm'}; {'xRayEkin_eV'}; {'scientaEkin_eV'}; {'imageRoh'}; {'spectrum_countsPerSecondRoh'};{'beamlineInt'}]);
|
||||
tmpVariablesToBeAdded = tmpFileList.Properties.VariableNames(tmpMissingVariable);
|
||||
|
||||
for ij = 1:size(tmpFileList,1)
|
||||
% get file name and "instruement" name
|
||||
tmpPathParts = split(tmpFileList(ij,:).folder,"/");
|
||||
tmpFileName = [tmpPathParts{end-1} tmpUserName '.h5'];
|
||||
tmpTopGroupName = tmpPathParts{end};
|
||||
% write data
|
||||
h5create(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/image'],...
|
||||
size(tmpFileList(ij,:).image{:}));
|
||||
h5write(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/image'],...
|
||||
tmpFileList(ij,:).image{:})
|
||||
if %XPS
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/image'],'label','electron emission intensity');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/image'],'units','XPS (y,x): counts per second vs. electron volt; NEXAFS (y,x,z): counts vs. X-ray photon kinetic energy vs. electron kinetic energy');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/image'],'definition','X-ray excited electron emission');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/image'],'comment','XPS: intensity vs. electron kinetic energy for each sequence iteration; NEXAFS: intensity vs. x-ray photon kinetic energy (non-linear scaling) vs. electron kinetic energy');
|
||||
else %NEXAFS
|
||||
|
||||
end
|
||||
|
||||
try
|
||||
h5create(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_counts'],...
|
||||
size(tmpFileList(ij,:).spectrum_counts{:}));
|
||||
h5write(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_counts'],...
|
||||
tmpFileList(ij,:).spectrum_counts{:})
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_counts'],'label','electron emission intensity');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_counts'],'units','arb. unit');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_counts'],'definition','X-ray excited electron emission');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_counts'],'comment',' ');
|
||||
catch
|
||||
end
|
||||
try
|
||||
h5create(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsPerSecond'],...
|
||||
size(tmpFileList(ij,:).spectrum_countsPerSecond{:}));
|
||||
h5write(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsPerSecond'],...
|
||||
tmpFileList(ij,:).spectrum_countsPerSecond{:})
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsPerSecond'],'label',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsPerSecond'],'units',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsPerSecond'],'definition',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsPerSecond'],'comment',' ');
|
||||
catch
|
||||
end
|
||||
try
|
||||
h5create(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsNorm'],...
|
||||
size(tmpFileList(ij,:).spectrum_countsNorm{:}));
|
||||
h5write(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsNorm'],...
|
||||
tmpFileList(ij,:).spectrum_countsNorm{:})
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsNorm'],'label',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsNorm'],'units',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsNorm'],'definition',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/spectrum_countsNorm'],'comment',' ');
|
||||
catch
|
||||
end
|
||||
try
|
||||
h5create(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/beamlineInt'],...
|
||||
size(tmpFileList(ij,:).beamlineInt{:}));
|
||||
h5write(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/beamlineInt'],...
|
||||
tmpFileList(ij,:).beamlineInt{:})
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/beamlineInt'],'label',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/beamlineInt'],'units',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/beamlineInt'],'definition',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/beamlineInt'],'comment',' ');
|
||||
catch
|
||||
end
|
||||
h5create(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/xRayEkin_eV'],...
|
||||
size(tmpFileList(ij,:).xRayEkin_eV{:}));
|
||||
h5write(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/xRayEkin_eV'],...
|
||||
tmpFileList(ij,:).xRayEkin_eV{:})
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/xRayEkin_eV'],'label',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/xRayEkin_eV'],'units',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/xRayEkin_eV'],'definition',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/xRayEkin_eV'],'comment',' ');
|
||||
|
||||
h5create(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/scientaEkin_eV'],...
|
||||
size(tmpFileList(ij,:).scientaEkin_eV{:}));
|
||||
h5write(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/scientaEkin_eV'],...
|
||||
tmpFileList(ij,:).scientaEkin_eV{:})
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/scientaEkin_eV'],'label',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/scientaEkin_eV'],'units',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/scientaEkin_eV'],'definition',' ');
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:} '/scientaEkin_eV'],'comment',' ');
|
||||
% add attributes
|
||||
tmpCells= []; % create empty array
|
||||
for ii = 1:size(tmpVariablesToBeAdded,2)
|
||||
|
||||
if matches(class(tmpFileList.(tmpVariablesToBeAdded{ii})),'cell')
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:}],tmpVariablesToBeAdded{ii},tmpFileList(ij,:).(tmpVariablesToBeAdded{ii}){:});
|
||||
tmpCells = [tmpCells,', ' tmpVariablesToBeAdded{ii}];
|
||||
else
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:}],tmpVariablesToBeAdded{ii},tmpFileList(ij,:).(tmpVariablesToBeAdded{ii}));
|
||||
end
|
||||
% write variables that were cells to a list; so upon import the
|
||||
% variable type can be set again.
|
||||
h5writeatt(tmpFileName,['/' tmpTopGroupName '/' tmpFileList(ij,:).name{:}],'matlabVariablesThatAreCells',tmpCells);
|
||||
|
||||
end
|
||||
clearvars tmpCells
|
||||
|
||||
|
||||
end
|
||||
disp('*************************************************')
|
||||
disp('* Voila: HDF file(s) written *')
|
||||
disp('*************************************************')
|
||||
@@ -1,473 +0,0 @@
|
||||
function [map,num,typ,scheme] = brewermap(N,scheme)
|
||||
% The complete selection of ColorBrewer colorschemes/palettes (RGB colormaps).
|
||||
%
|
||||
% Returns an RGB colormap from Cynthia Brewer's ColorBrewer 2.0 palettes,
|
||||
% intended for mapping and plots with attractive, distinguishable colors.
|
||||
%
|
||||
%%% Basic Syntax %%%
|
||||
%
|
||||
% brewermap() % print summary
|
||||
% map = brewermap(N,scheme)
|
||||
%
|
||||
%%% Preset Syntax %%%
|
||||
%
|
||||
% old = brewermap(scheme)
|
||||
% map = brewermap()
|
||||
% map = brewermap(N)
|
||||
%
|
||||
% [...,num,typ] = brewermap(...)
|
||||
%
|
||||
%% Colorschemes %%
|
||||
%
|
||||
% This product includes color specifications and designs developed by Cynthia Brewer.
|
||||
% See the ColorBrewer website for further information about each colorscheme,
|
||||
% colour-blind suitability, licensing, and citations: http://colorbrewer.org/
|
||||
% Each colorscheme is defined by a set of hand-picked RGB values (nodes).
|
||||
%
|
||||
% To reverse the colormap sequence prefix the colorscheme name with '-'.
|
||||
%
|
||||
% Diverging | Qualitative | Sequential
|
||||
% ----------|-------------|------------------
|
||||
% BrBG | Accent | Blues PuBuGn
|
||||
% PiYG | Dark2 | BuGn PuRd
|
||||
% PRGn | Paired | BuPu Purples
|
||||
% PuOr | Pastel1 | GnBu RdPu
|
||||
% RdBu | Pastel2 | Greens Reds
|
||||
% RdGy | Set1 | Greys YlGn
|
||||
% RdYlBu | Set2 | OrRd YlGnBu
|
||||
% RdYlGn | Set3 | Oranges YlOrBr
|
||||
% Spectral | | PuBu YlOrRd
|
||||
%
|
||||
% If <N> is greater than the requested colorscheme's defining nodes then:
|
||||
% - Diverging and Sequential colorschemes are interpolated.
|
||||
% - Qualitative colorschemes repeat the nodes (i.e. just like LINES does).
|
||||
% Else:
|
||||
% - Exact values from the ColorBrewer colorschemes are returned.
|
||||
%
|
||||
%% Examples %%
|
||||
%
|
||||
%%% New colors for the COLORMAP example %%%
|
||||
%
|
||||
% >> S = load('spine');
|
||||
% >> image(S.X)
|
||||
% >> colormap(brewermap([],"YlGnBu"))
|
||||
%
|
||||
%%% New colors for the SURF example %%%
|
||||
%
|
||||
% >> [X,Y,Z] = peaks(30);
|
||||
% >> surfc(X,Y,Z)
|
||||
% >> colormap(brewermap([],'RdYlGn'))
|
||||
% >> axis([-3,3,-3,3,-10,5])
|
||||
%
|
||||
%%% Plot a colorscheme's RGB values %%%
|
||||
%
|
||||
% >> rgbplot(brewermap(NaN, '+Blues')) % standard
|
||||
% >> rgbplot(brewermap(NaN, '-Blues')) % reversed
|
||||
%
|
||||
%%% View information about a colorscheme %%%
|
||||
%
|
||||
% >> [~,num,typ] = brewermap(NaN,'Paired')
|
||||
% num = 12
|
||||
% typ = 'Qualitative'
|
||||
%
|
||||
%%% Multi-line plot using matrices %%%
|
||||
%
|
||||
% >> N = 6;
|
||||
% >> axes('ColorOrder',brewermap(N,'Pastel2'),'NextPlot','replacechildren')
|
||||
% >> X = linspace(0,pi*3,1000);
|
||||
% >> Y = bsxfun(@(x,n)n*sin(x+2*n*pi/N), X(:), 1:N);
|
||||
% >> plot(X,Y, 'linewidth',4)
|
||||
%
|
||||
%%% Multi-line plot in a loop %%%
|
||||
%
|
||||
% set(0,'DefaultAxesColorOrder',brewermap(NaN,'Accent'))
|
||||
% N = 6;
|
||||
% X = linspace(0,pi*3,1000);
|
||||
% Y = bsxfun(@(x,n)n*sin(x+2*n*pi/N), X(:), 1:N);
|
||||
% for n = 1:N
|
||||
% plot(X(:),Y(:,n), 'linewidth',4);
|
||||
% hold all
|
||||
% end
|
||||
%
|
||||
%% Input Arguments (**=default) %%
|
||||
%
|
||||
% N = NumericScalar, N>=0, an integer to specify the colormap length.
|
||||
% = []**, map has the same length as MATLAB's inbuilt colormap functions.
|
||||
% = NaN, map is exactly the defining RGB nodes (useful for line ColorOrder).
|
||||
% scheme = CharRowVector or StringScalar, a ColorBrewer colorscheme name.
|
||||
%
|
||||
%% Output Arguments %%
|
||||
%
|
||||
% map = NumericMatrix, size Nx3, a colormap of RGB values between 0 and 1.
|
||||
% num = NumericVector, the number of nodes defining the ColorBrewer colorscheme.
|
||||
% typ = CharRowVector, the colorscheme type: 'Diverging'/'Qualitative'/'Sequential'.
|
||||
%
|
||||
%% Dependencies %%
|
||||
%
|
||||
% * MATLAB R2009a or later.
|
||||
%
|
||||
% See also BREWERMAP_NODES BREWERMAP_VIEW PRESET_COLORMAP CUBEHELIX MAXDISTCOLOR
|
||||
% LBMAP PARULA LINES RGBPLOT COLORMAP COLORBAR PLOT PLOT3 AXES SET CONTOURF
|
||||
persistent bmc scm txt
|
||||
%
|
||||
if isempty(bmc)
|
||||
bmc = bmStruct();
|
||||
end
|
||||
%
|
||||
%% Input Wrangling %%
|
||||
%
|
||||
if nargin==0
|
||||
N = [];
|
||||
end
|
||||
%
|
||||
err = 'First input <N> must be a real positive scalar numeric or [] or NaN.';
|
||||
%
|
||||
if nargout==0 && nargin==0
|
||||
hdr = { 'Type'; 'Scheme'; 'Nodes'};
|
||||
tsn = [{bmc.typ};{bmc.str};{bmc.num}];
|
||||
fprintf('%-12s %-9s %s\n',hdr{:});
|
||||
fprintf('%-12s %-9s %u\n',tsn{:});
|
||||
return
|
||||
elseif isnumeric(N)
|
||||
if isequal(N,[])
|
||||
% Default N is the same as MATLAB colormaps:
|
||||
N = cmDefaultN();
|
||||
else
|
||||
assert(isscalar(N),...
|
||||
'SC:brewermap:N:NotScalarNumeric',err)
|
||||
assert(isnan(N) || isreal(N)&&isfinite(N)&&fix(N)==N&&N>=0,...
|
||||
'SC:brewermap:N:NotWholeRealNotNaN',err)
|
||||
N = double(N);
|
||||
end
|
||||
if nargin<2
|
||||
assert(~isempty(scm),...
|
||||
'SC:colorbrewer:scheme:NotPreset',...
|
||||
'Colorscheme must be preset before this call: BREWERMAP(SCHEME)')
|
||||
scheme = scm;
|
||||
else
|
||||
scheme = bm1s2c(scheme);
|
||||
assert(ischar(scheme)&&ndims(scheme)==2&&size(scheme,1)==1,...
|
||||
'SC:brewermap:scheme:NotText',...
|
||||
'Input <scheme> must be a character vector or a string scalar.') %#ok<ISMAT>
|
||||
end
|
||||
else % preset
|
||||
assert(nargin<2,...
|
||||
'SC:brewermap:WrongArgumentNumber',...
|
||||
'If calling with two inputs then the 1st input must be numeric.')
|
||||
scheme = bm1s2c(N);
|
||||
assert(ischar(scheme)&&ndims(scheme)==2&&size(scheme,1)==1,...
|
||||
'SC:brewermap:N:NotText',...
|
||||
'To preset: the scheme must be a character vector or a string scalar.') %#ok<ISMAT>
|
||||
if strcmpi(scheme,'list')
|
||||
map = {bmc.str};
|
||||
num = [bmc.num];
|
||||
typ = {bmc.typ};
|
||||
return
|
||||
end
|
||||
end
|
||||
%
|
||||
isr = strncmp(scheme,'-',1) || strncmp(scheme,'*',1);
|
||||
isd = strncmp(scheme,'+',1) || isr; % direction
|
||||
ids = strcmpi(scheme(1+isd:end),{bmc.str});
|
||||
assert(any(ids),...
|
||||
'SC:brewermap:scheme:UnknownColorscheme',...
|
||||
'Unknown colorscheme name: "%s"',scheme)
|
||||
%
|
||||
num = bmc(ids).num;
|
||||
typ = bmc(ids).typ;
|
||||
%
|
||||
if ~isnumeric(N) % preset
|
||||
map = txt;
|
||||
txt = N;
|
||||
scm = scheme;
|
||||
return
|
||||
elseif N==0
|
||||
map = nan(0,3);
|
||||
return
|
||||
elseif isnan(N)
|
||||
N = num;
|
||||
end
|
||||
%
|
||||
% Downsample:
|
||||
[idx,itp] = bmIndex(N,num,typ);
|
||||
%
|
||||
map = bmc(ids).rgb(idx,:)/255;
|
||||
%
|
||||
% Interpolate:
|
||||
if itp
|
||||
%
|
||||
% Extrapolate a small amount beyond the end nodes:
|
||||
%ido = linspace(0,num+1,N+2);
|
||||
%ido = ido(2:end-1);
|
||||
% Interpolation completely within the end nodes:
|
||||
ido = linspace(1,num,N);
|
||||
%
|
||||
switch typ
|
||||
case 'Diverging'
|
||||
mid = ceil(num/2);
|
||||
idl = 1:mid;
|
||||
idr = mid:num;
|
||||
map = [...
|
||||
interp1(idl,map(idl,:),ido(ido<=mid),'pchip');...
|
||||
interp1(idr,map(idr,:),ido(ido>mid),'pchip')];
|
||||
case 'Sequential'
|
||||
map = interp1(1:num,map,ido,'pchip');
|
||||
otherwise
|
||||
error('SC:brewermap:Interp:UnknownType','Unknown colorscheme type.')
|
||||
end
|
||||
%
|
||||
end
|
||||
%
|
||||
% Limit output range:
|
||||
map = max(0,min(1,map));
|
||||
%
|
||||
% Reverse row order:
|
||||
if isr
|
||||
map = map(end:-1:1,:);
|
||||
end
|
||||
%
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%brewermap
|
||||
function N = cmDefaultN()
|
||||
% Get the colormap size from the current figure or default colormap.
|
||||
try
|
||||
F = get(groot,'CurrentFigure');
|
||||
catch %#ok<CTCH> pre HG2
|
||||
N = size(get(gcf,'colormap'),1);
|
||||
return
|
||||
end
|
||||
if isempty(F)
|
||||
N = size(get(groot,'DefaultFigureColormap'),1);
|
||||
else
|
||||
N = size(F.Colormap,1);
|
||||
end
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%cmDefaultN
|
||||
function arr = bm1s2c(arr)
|
||||
% If scalar string then extract the character vector, otherwise data is unchanged.
|
||||
if isa(arr,'string') && isscalar(arr)
|
||||
arr = arr{1};
|
||||
end
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bm1s2c
|
||||
function [idx,itp] = bmIndex(N,num,typ)
|
||||
% Ensure exactly the same colors as the online ColorBrewer colorschemes.
|
||||
%
|
||||
switch typ
|
||||
case 'Qualitative'
|
||||
itp = false;
|
||||
idx = 1+mod(0:N-1,num);
|
||||
case 'Diverging'
|
||||
itp = N>num;
|
||||
switch N
|
||||
case 1 % extrapolated
|
||||
idx = 8;
|
||||
case 2 % extrapolated
|
||||
idx = [4,12];
|
||||
case 3
|
||||
idx = [5,8,11];
|
||||
case 4
|
||||
idx = [3,6,10,13];
|
||||
case 5
|
||||
idx = [3,6,8,10,13];
|
||||
case 6
|
||||
idx = [2,5,7,9,11,14];
|
||||
case 7
|
||||
idx = [2,5,7,8,9,11,14];
|
||||
case 8
|
||||
idx = [2,4,6,7,9,10,12,14];
|
||||
case 9
|
||||
idx = [2,4,6,7,8,9,10,12,14];
|
||||
case 10
|
||||
idx = [1,2,4,6,7,9,10,12,14,15];
|
||||
otherwise
|
||||
idx = [1,2,4,6,7,8,9,10,12,14,15];
|
||||
end
|
||||
case 'Sequential'
|
||||
itp = N>num;
|
||||
switch N
|
||||
case 1 % extrapolated
|
||||
idx = 6;
|
||||
case 2 % extrapolated
|
||||
idx = [4,8];
|
||||
case 3
|
||||
idx = [3,6,9];
|
||||
case 4
|
||||
idx = [2,5,7,10];
|
||||
case 5
|
||||
idx = [2,5,7,9,11];
|
||||
case 6
|
||||
idx = [2,4,6,7,9,11];
|
||||
case 7
|
||||
idx = [2,4,6,7,8,10,12];
|
||||
case 8
|
||||
idx = [1,3,4,6,7,8,10,12];
|
||||
otherwise
|
||||
idx = [1,3,4,6,7,8,10,11,13];
|
||||
end
|
||||
otherwise
|
||||
error('SC:brewermap:Index:UnknownType','Unknown colorscheme type.')
|
||||
end
|
||||
%
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bmIndex
|
||||
function bmc = bmStruct()
|
||||
% Return a structure of all colorschemes: name, scheme type, RGB values, number of nodes.
|
||||
% Order: sorted first by <typ>, then case-insensitive sorted by <str>.
|
||||
bmc(35).str = 'YlOrRd';
|
||||
bmc(35).typ = 'Sequential';
|
||||
bmc(35).rgb = [255,255,204;255,255,178;255,237,160;254,217,118;254,204,92;254,178,76;253,141,60;252,78,42;240,59,32;227,26,28;189,0,38;177,0,38;128,0,38];
|
||||
bmc(34).str = 'YlOrBr';
|
||||
bmc(34).typ = 'Sequential';
|
||||
bmc(34).rgb = [255,255,229;255,255,212;255,247,188;254,227,145;254,217,142;254,196,79;254,153,41;236,112,20;217,95,14;204,76,2;153,52,4;140,45,4;102,37,6];
|
||||
bmc(33).str = 'YlGnBu';
|
||||
bmc(33).typ = 'Sequential';
|
||||
bmc(33).rgb = [255,255,217;255,255,204;237,248,177;199,233,180;161,218,180;127,205,187;65,182,196;29,145,192;44,127,184;34,94,168;37,52,148;12,44,132;8,29,88];
|
||||
bmc(32).str = 'YlGn';
|
||||
bmc(32).typ = 'Sequential';
|
||||
bmc(32).rgb = [255,255,229;255,255,204;247,252,185;217,240,163;194,230,153;173,221,142;120,198,121;65,171,93;49,163,84;35,132,67;0,104,55;0,90,50;0,69,41];
|
||||
bmc(31).str = 'Reds';
|
||||
bmc(31).typ = 'Sequential';
|
||||
bmc(31).rgb = [255,245,240;254,229,217;254,224,210;252,187,161;252,174,145;252,146,114;251,106,74;239,59,44;222,45,38;203,24,29;165,15,21;153,0,13;103,0,13];
|
||||
bmc(30).str = 'RdPu';
|
||||
bmc(30).typ = 'Sequential';
|
||||
bmc(30).rgb = [255,247,243;254,235,226;253,224,221;252,197,192;251,180,185;250,159,181;247,104,161;221,52,151;197,27,138;174,1,126;122,1,119;122,1,119;73,0,106];
|
||||
bmc(29).str = 'Purples';
|
||||
bmc(29).typ = 'Sequential';
|
||||
bmc(29).rgb = [252,251,253;242,240,247;239,237,245;218,218,235;203,201,226;188,189,220;158,154,200;128,125,186;117,107,177;106,81,163;84,39,143;74,20,134;63,0,125];
|
||||
bmc(28).str = 'PuRd';
|
||||
bmc(28).typ = 'Sequential';
|
||||
bmc(28).rgb = [247,244,249;241,238,246;231,225,239;212,185,218;215,181,216;201,148,199;223,101,176;231,41,138;221,28,119;206,18,86;152,0,67;145,0,63;103,0,31];
|
||||
bmc(27).str = 'PuBuGn';
|
||||
bmc(27).typ = 'Sequential';
|
||||
bmc(27).rgb = [255,247,251;246,239,247;236,226,240;208,209,230;189,201,225;166,189,219;103,169,207;54,144,192;28,144,153;2,129,138;1,108,89;1,100,80;1,70,54];
|
||||
bmc(26).str = 'PuBu';
|
||||
bmc(26).typ = 'Sequential';
|
||||
bmc(26).rgb = [255,247,251;241,238,246;236,231,242;208,209,230;189,201,225;166,189,219;116,169,207;54,144,192;43,140,190;5,112,176;4,90,141;3,78,123;2,56,88];
|
||||
bmc(25).str = 'Oranges';
|
||||
bmc(25).typ = 'Sequential';
|
||||
bmc(25).rgb = [255,245,235;254,237,222;254,230,206;253,208,162;253,190,133;253,174,107;253,141,60;241,105,19;230,85,13;217,72,1;166,54,3;140,45,4;127,39,4];
|
||||
bmc(24).str = 'OrRd';
|
||||
bmc(24).typ = 'Sequential';
|
||||
bmc(24).rgb = [255,247,236;254,240,217;254,232,200;253,212,158;253,204,138;253,187,132;252,141,89;239,101,72;227,74,51;215,48,31;179,0,0;153,0,0;127,0,0];
|
||||
bmc(23).str = 'Greys';
|
||||
bmc(23).typ = 'Sequential';
|
||||
bmc(23).rgb = [255,255,255;247,247,247;240,240,240;217,217,217;204,204,204;189,189,189;150,150,150;115,115,115;99,99,99;82,82,82;37,37,37;37,37,37;0,0,0];
|
||||
bmc(22).str = 'Greens';
|
||||
bmc(22).typ = 'Sequential';
|
||||
bmc(22).rgb = [247,252,245;237,248,233;229,245,224;199,233,192;186,228,179;161,217,155;116,196,118;65,171,93;49,163,84;35,139,69;0,109,44;0,90,50;0,68,27];
|
||||
bmc(21).str = 'GnBu';
|
||||
bmc(21).typ = 'Sequential';
|
||||
bmc(21).rgb = [247,252,240;240,249,232;224,243,219;204,235,197;186,228,188;168,221,181;123,204,196;78,179,211;67,162,202;43,140,190;8,104,172;8,88,158;8,64,129];
|
||||
bmc(20).str = 'BuPu';
|
||||
bmc(20).typ = 'Sequential';
|
||||
bmc(20).rgb = [247,252,253;237,248,251;224,236,244;191,211,230;179,205,227;158,188,218;140,150,198;140,107,177;136,86,167;136,65,157;129,15,124;110,1,107;77,0,75];
|
||||
bmc(19).str = 'BuGn';
|
||||
bmc(19).typ = 'Sequential';
|
||||
bmc(19).rgb = [247,252,253;237,248,251;229,245,249;204,236,230;178,226,226;153,216,201;102,194,164;65,174,118;44,162,95;35,139,69;0,109,44;0,88,36;0,68,27];
|
||||
bmc(18).str = 'Blues';
|
||||
bmc(18).typ = 'Sequential';
|
||||
bmc(18).rgb = [247,251,255;239,243,255;222,235,247;198,219,239;189,215,231;158,202,225;107,174,214;66,146,198;49,130,189;33,113,181;8,81,156;8,69,148;8,48,107];
|
||||
bmc(17).str = 'Set3';
|
||||
bmc(17).typ = 'Qualitative';
|
||||
bmc(17).rgb = [141,211,199;255,255,179;190,186,218;251,128,114;128,177,211;253,180,98;179,222,105;252,205,229;217,217,217;188,128,189;204,235,197;255,237,111];
|
||||
bmc(16).str = 'Set2';
|
||||
bmc(16).typ = 'Qualitative';
|
||||
bmc(16).rgb = [102,194,165;252,141,98;141,160,203;231,138,195;166,216,84;255,217,47;229,196,148;179,179,179];
|
||||
bmc(15).str = 'Set1';
|
||||
bmc(15).typ = 'Qualitative';
|
||||
bmc(15).rgb = [228,26,28;55,126,184;77,175,74;152,78,163;255,127,0;255,255,51;166,86,40;247,129,191;153,153,153];
|
||||
bmc(14).str = 'Pastel2';
|
||||
bmc(14).typ = 'Qualitative';
|
||||
bmc(14).rgb = [179,226,205;253,205,172;203,213,232;244,202,228;230,245,201;255,242,174;241,226,204;204,204,204];
|
||||
bmc(13).str = 'Pastel1';
|
||||
bmc(13).typ = 'Qualitative';
|
||||
bmc(13).rgb = [251,180,174;179,205,227;204,235,197;222,203,228;254,217,166;255,255,204;229,216,189;253,218,236;242,242,242];
|
||||
bmc(12).str = 'Paired';
|
||||
bmc(12).typ = 'Qualitative';
|
||||
bmc(12).rgb = [166,206,227;31,120,180;178,223,138;51,160,44;251,154,153;227,26,28;253,191,111;255,127,0;202,178,214;106,61,154;255,255,153;177,89,40];
|
||||
bmc(11).str = 'Dark2';
|
||||
bmc(11).typ = 'Qualitative';
|
||||
bmc(11).rgb = [27,158,119;217,95,2;117,112,179;231,41,138;102,166,30;230,171,2;166,118,29;102,102,102];
|
||||
bmc(10).str = 'Accent';
|
||||
bmc(10).typ = 'Qualitative';
|
||||
bmc(10).rgb = [127,201,127;190,174,212;253,192,134;255,255,153;56,108,176;240,2,127;191,91,23;102,102,102];
|
||||
bmc(09).str = 'Spectral';
|
||||
bmc(09).typ = 'Diverging';
|
||||
bmc(09).rgb = [158,1,66;213,62,79;215,25,28;244,109,67;252,141,89;253,174,97;254,224,139;255,255,191;230,245,152;171,221,164;153,213,148;102,194,165;43,131,186;50,136,189;94,79,162];
|
||||
bmc(08).str = 'RdYlGn';
|
||||
bmc(08).typ = 'Diverging';
|
||||
bmc(08).rgb = [165,0,38;215,48,39;215,25,28;244,109,67;252,141,89;253,174,97;254,224,139;255,255,191;217,239,139;166,217,106;145,207,96;102,189,99;26,150,65;26,152,80;0,104,55];
|
||||
bmc(07).str = 'RdYlBu';
|
||||
bmc(07).typ = 'Diverging';
|
||||
bmc(07).rgb = [165,0,38;215,48,39;215,25,28;244,109,67;252,141,89;253,174,97;254,224,144;255,255,191;224,243,248;171,217,233;145,191,219;116,173,209;44,123,182;69,117,180;49,54,149];
|
||||
bmc(06).str = 'RdGy';
|
||||
bmc(06).typ = 'Diverging';
|
||||
bmc(06).rgb = [103,0,31;178,24,43;202,0,32;214,96,77;239,138,98;244,165,130;253,219,199;255,255,255;224,224,224;186,186,186;153,153,153;135,135,135;64,64,64;77,77,77;26,26,26];
|
||||
bmc(05).str = 'RdBu';
|
||||
bmc(05).typ = 'Diverging';
|
||||
bmc(05).rgb = [103,0,31;178,24,43;202,0,32;214,96,77;239,138,98;244,165,130;253,219,199;247,247,247;209,229,240;146,197,222;103,169,207;67,147,195;5,113,176;33,102,172;5,48,97];
|
||||
bmc(04).str = 'PuOr';
|
||||
bmc(04).typ = 'Diverging';
|
||||
bmc(04).rgb = [127,59,8;179,88,6;230,97,1;224,130,20;241,163,64;253,184,99;254,224,182;247,247,247;216,218,235;178,171,210;153,142,195;128,115,172;94,60,153;84,39,136;45,0,75];
|
||||
bmc(03).str = 'PRGn';
|
||||
bmc(03).typ = 'Diverging';
|
||||
bmc(03).rgb = [64,0,75;118,42,131;123,50,148;153,112,171;175,141,195;194,165,207;231,212,232;247,247,247;217,240,211;166,219,160;127,191,123;90,174,97;0,136,55;27,120,55;0,68,27];
|
||||
bmc(02).str = 'PiYG';
|
||||
bmc(02).typ = 'Diverging';
|
||||
bmc(02).rgb = [142,1,82;197,27,125;208,28,139;222,119,174;233,163,201;241,182,218;253,224,239;247,247,247;230,245,208;184,225,134;161,215,106;127,188,65;77,172,38;77,146,33;39,100,25];
|
||||
bmc(01).str = 'BrBG';
|
||||
bmc(01).typ = 'Diverging';
|
||||
bmc(01).rgb = [84,48,5;140,81,10;166,97,26;191,129,45;216,179,101;223,194,125;246,232,195;245,245,245;199,234,229;128,205,193;90,180,172;53,151,143;1,133,113;1,102,94;0,60,48];
|
||||
% Number of nodes:
|
||||
for k = 1:numel(bmc)
|
||||
switch bmc(k).typ
|
||||
case 'Diverging'
|
||||
bmc(k).num = 11;
|
||||
case 'Qualitative'
|
||||
bmc(k).num = size(bmc(k).rgb,1);
|
||||
case 'Sequential'
|
||||
bmc(k).num = 9;
|
||||
otherwise
|
||||
error('SC:brewermap:Struct:UnknownType','Unknown colorscheme type.')
|
||||
end
|
||||
end
|
||||
%
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bmStruct
|
||||
%
|
||||
% Code and Implementation:
|
||||
% Copyright (c) 2014-2025 Stephen Cobeldick
|
||||
% Color Values Only:
|
||||
% Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State University.
|
||||
%
|
||||
% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
% you may not use this file except in compliance with the License.
|
||||
% You may obtain a copy of the License at
|
||||
%
|
||||
% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%
|
||||
% Unless required by applicable law or agreed to in writing, software
|
||||
% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
% See the License for the specific language governing permissions and limitations under the License.
|
||||
%
|
||||
% Redistribution and use in source and binary forms, with or without
|
||||
% modification, are permitted provided that the following conditions are met:
|
||||
%
|
||||
% 1. Redistributions as source code must retain the above copyright notice, this
|
||||
% list of conditions and the following disclaimer.
|
||||
%
|
||||
% 2. The end-user documentation included with the redistribution, if any, must
|
||||
% include the following acknowledgment: "This product includes color
|
||||
% specifications and designs developed by Cynthia Brewer
|
||||
% (http://colorbrewer.org/)." Alternately, this acknowledgment may appear in the
|
||||
% software itself, if and wherever such third-party acknowledgments normally appear.
|
||||
%
|
||||
% 4. The name "ColorBrewer" must not be used to endorse or promote products
|
||||
% derived from this software without prior written permission. For written
|
||||
% permission, please contact Cynthia Brewer at cbrewer@psu.edu.
|
||||
%
|
||||
% 5. Products derived from this software may not be called "ColorBrewer", nor
|
||||
% may "ColorBrewer" appear in their name, without prior written permission of Cynthia Brewer.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%license
|
||||
@@ -1,63 +0,0 @@
|
||||
function brewermap_nodes()
|
||||
% Create a figure showing all ColorBrewer 2.0 colorschemes' defining nodes.
|
||||
%
|
||||
% (c) 2014-2025 Stephen Cobeldick
|
||||
%
|
||||
% View Cynthia Brewer's ColorBrewer 2.0 colorschemes/palettes in a figure:
|
||||
%
|
||||
% * Each row of the figure shows the defining nodes for one colorscheme.
|
||||
% * Text with all colorschemes' names.
|
||||
% * Text with all colorschemes' types (Diverging/Qualitative/Sequential).
|
||||
%
|
||||
%%% Syntax %%%
|
||||
%
|
||||
% brewermap_nodes()
|
||||
%
|
||||
%% Dependencies %%
|
||||
%
|
||||
% * MATLAB R2009a or later.
|
||||
% * brewermap.m <www.mathworks.com/matlabcentral/fileexchange/45208>
|
||||
%
|
||||
% See also BREWERMAP BREWERMAP_VIEW CUBEHELIX MAXDISTCOLOR
|
||||
% LBMAP PARULA LINES RGBPLOT COLORMAP COLORBAR PLOT PLOT3 AXES SET
|
||||
persistent cbh axh
|
||||
%
|
||||
[mcs,nmn,pyt] = brewermap('list');
|
||||
%
|
||||
xmx = max(nmn);
|
||||
ymx = numel(pyt);
|
||||
%
|
||||
if ishghandle(cbh)
|
||||
figure(cbh);
|
||||
delete(axh);
|
||||
else
|
||||
cbh = figure('HandleVisibility','callback', 'IntegerHandle','off',...
|
||||
'NumberTitle','off', 'Name',mfilename,...
|
||||
'MenuBar','figure', 'Toolbar','none', 'Tag',mfilename);
|
||||
set(cbh,'Units','pixels')
|
||||
pos = get(cbh,'Position');
|
||||
pos(1:2) = pos(1:2) - 123;
|
||||
pos(3:4) = max(pos(3:4),[842,532]);
|
||||
set(cbh,'Position',pos)
|
||||
end
|
||||
%
|
||||
axh = axes('Parent',cbh, 'Color','none',...
|
||||
'XTick',0:xmx, 'YTick',0.5:ymx, 'YTickLabel',mcs, 'YDir','reverse');
|
||||
title(axh,'ColorBrewer Color Schemes (brewermap.m)', 'Interpreter','none')
|
||||
xlabel(axh,'Scheme Nodes')
|
||||
ylabel(axh,'Scheme Name')
|
||||
axf = get(axh,'FontName');
|
||||
%
|
||||
for y = 1:ymx
|
||||
N = nmn(y);
|
||||
M = brewermap(N,mcs{y});
|
||||
for x = 1:N
|
||||
patch([x-1,x-1,x,x],[y-1,y,y,y-1],1, 'FaceColor',M(x,:), 'Parent',axh)
|
||||
end
|
||||
text(xmx+0.1,y-0.5,pyt{y}, 'Parent',axh, 'FontName',axf)
|
||||
end
|
||||
%
|
||||
drawnow()
|
||||
%
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%brewermap_nodes
|
||||
@@ -1,408 +0,0 @@
|
||||
function [map,num,typ,scheme] = brewermap_view(N,scheme,isco)
|
||||
% Create an interactive figure for viewing ColorBrewer colormaps. With demo!
|
||||
%
|
||||
% (c) 2014-2025 Stephen Cobeldick
|
||||
%
|
||||
% View Cynthia Brewer's ColorBrewer 2.0 colorschemes/palettes in a figure:
|
||||
%
|
||||
% * Two colorbars give the colorscheme in color and grayscale.
|
||||
% * A button toggles between 3D-cube and 2D-lineplot of the RGB values.
|
||||
% * A button toggles an endless demo cycle through the colorschemes.
|
||||
% * A button reverses the colormap.
|
||||
% * Thirty-five buttons select any ColorBrewer colorscheme.
|
||||
% * Text with the colorscheme's type (Diverging/Qualitative/Sequential).
|
||||
% * Text with the colorscheme's number of nodes (i.e. defining colors).
|
||||
%
|
||||
%%% Syntax %%%
|
||||
%
|
||||
% brewermap_view
|
||||
% brewermap_view(N)
|
||||
% brewermap_view(N,scheme)
|
||||
% brewermap_view(N,scheme,isco)
|
||||
% brewermap_view([],...)
|
||||
% brewermap_view(axes/figure handle array,...) % see "Adjust Colormaps"
|
||||
% [map,num,typ] = brewermap_view(...)
|
||||
%
|
||||
% Calling the function with an output argument blocks MATLAB execution until
|
||||
% the figure is deleted: the final colormap and parameters are then returned.
|
||||
%
|
||||
%% Adjust Colormaps or Colororders of Figures or Axes %%
|
||||
%
|
||||
% For R2014b or later: provide axes or figure handles as the first input
|
||||
% and their COLORMAP will be updated in real-time by BREWERMAP_VIEW.
|
||||
% For R2019b or later: set the 3rd input to TRUE to update COLORORDER.
|
||||
%
|
||||
% >> S = load('spine');
|
||||
% >> image(S.X)
|
||||
% >> brewermap_view(gca) % colormap
|
||||
%
|
||||
% >> plot(rand(5,7))
|
||||
% >> brewermap_view(gca,[],true) % colororder
|
||||
%
|
||||
%% Input Arguments (**=default) %%
|
||||
%
|
||||
% N = NumericScalar, an integer to define the colormap length.
|
||||
% = []**, colormap length of two hundred and fifty-six (256).
|
||||
% = NaN, same length as the defining RGB nodes (useful for Line ColorOrder).
|
||||
% = Array of axes or figure handles. R2014b or later only.
|
||||
% scheme = CharRowVector or StringScalar, a ColorBrewer colorscheme name.
|
||||
% = []** randomly selects a colorscheme.
|
||||
% isco = LogicalScalar, true/false** updates the colororder/colormap of
|
||||
% the provided axes or figure handles. R2019b or later only.
|
||||
%
|
||||
%% Output Arguments (block code execution until figure is closed) %%
|
||||
%
|
||||
% map = NumericMatrix, the colormap defined when the figure is closed.
|
||||
% num = NumericVector, the number of nodes defining the ColorBrewer colorscheme.
|
||||
% typ = CharRowVector, the colorscheme type: 'Diverging'/'Qualitative'/'Sequential'.
|
||||
%
|
||||
%% Dependencies %%
|
||||
%
|
||||
% * MATLAB R2009a or later.
|
||||
% * brewermap.m <www.mathworks.com/matlabcentral/fileexchange/45208>
|
||||
%
|
||||
% See also BREWERMAP BREWERMAP_NODES CUBEHELIX PRESET_COLORMAP MAXDISTCOLOR
|
||||
% RGBPLOT COLORMAP COLORMAPEDITOR COLORBAR UICONTROL ADDLISTENER
|
||||
persistent ax2D ln2D ax3D pt3D txtH is2D cbAx cbIm pTxt pSld bEig bGrp bRev scm isr
|
||||
%
|
||||
new = isempty(ax2D)||~ishghandle(ax2D);
|
||||
dfn = 256;
|
||||
upd = false;
|
||||
upb = false;
|
||||
hgv = [];
|
||||
nmr = dfn;
|
||||
%
|
||||
%% Input Wrangling %%
|
||||
%
|
||||
if nargin>2 && isco
|
||||
% >R2019a only!
|
||||
fnh = @colororder;
|
||||
else % default
|
||||
fnh = @colormap;
|
||||
end
|
||||
%
|
||||
err = 'First input <N> must be a real positive scalar numeric or [] or NaN.';
|
||||
if nargin==0 || isnumeric(N)&&isequal(N,[])
|
||||
N = dfn;
|
||||
elseif isnumeric(N)
|
||||
assert(isscalar(N),'SC:brewermap_view:N:NotScalarNumeric',err)
|
||||
assert(isreal(N)&&isfinite(N)&&fix(N)==N&&N>0||isnan(N),...
|
||||
'SC:brewermap_view:N:NotRealPositiveIntegerNorNaN',err)
|
||||
N = double(N);
|
||||
elseif all(ishghandle(N(:))) % R2014b or later
|
||||
assert(all(isgraphics(N(:),'axes')|isgraphics(N(:),'figure')),...
|
||||
'SC:brewermap_view:N:NotAxesNorFigureHandles',...
|
||||
'First input <N> may be an array of figure or axes handles.')
|
||||
hgv = N(:);
|
||||
nmr = arrayfun(@(h)size(fnh(h),1),hgv);
|
||||
N = nmr(1);
|
||||
else
|
||||
error('SC:brewermap_view:N:UnsupportedInput',err)
|
||||
end
|
||||
%
|
||||
[mcs,nmn,pyt] = brewermap('list');
|
||||
%
|
||||
% Check BREWERMAP output:
|
||||
tmp = find([any(diff(double(char(pyt)),1),2);1]);
|
||||
assert(isequal(tmp,[9;17;35]),'SC:brewermap_view:BREWERMAP:OutputOrder',...
|
||||
'The BREWERMAP function returned an unexpected colorscheme sequence.')
|
||||
%
|
||||
if nargin<2 || isnumeric(scheme)&&isequal(scheme,[])
|
||||
% Default pseudo-random colorscheme:
|
||||
isr = rand(1)>0.5;
|
||||
scm = mcs{1+mod(round(now*1e7),numel(mcs))}; %#ok<TNOW1>
|
||||
else
|
||||
% Parse input colorscheme:
|
||||
scheme = bmv1s2c(scheme);
|
||||
assert(ischar(scheme) && ndims(scheme)==2 && size(scheme,1)==1,...
|
||||
'SC:brewermap_view:scheme:NotCharacterVector',...
|
||||
'Second input <scheme> must be a 1xN char vector.') %#ok<ISMAT>
|
||||
% Check if a reversed colormap was requested:
|
||||
isr = strncmp(scheme,'-',1) || strncmp(scheme,'*',1);
|
||||
isd = strncmp(scheme,'+',1) || isr;
|
||||
scm = scheme(1+isd:end);
|
||||
end
|
||||
%
|
||||
if isnan(N)
|
||||
N = nmn(strcmpi(scm,mcs));
|
||||
end
|
||||
%
|
||||
%% Ensure Figure Exists %%
|
||||
%
|
||||
% LHS and RHS slider bounds/limits, and slider step sizes:
|
||||
lbd = 1;
|
||||
rbd = dfn;
|
||||
stp = [1,10]; % [minor,major]
|
||||
%
|
||||
% Define the 3D cube axis order:
|
||||
xyz = 'RGB'; % specify the order here.
|
||||
[~,xyz] = ismember(xyz,'RGB');
|
||||
%
|
||||
if new % Create a new figure.
|
||||
%
|
||||
% Figure parameters:
|
||||
M = 9; % buttons per column
|
||||
gap = 0.01; % gaps
|
||||
bth = 0.04; % demo button height
|
||||
btw = 0.10; % demo button width
|
||||
bgh = 0.40; % button group height
|
||||
cbw = 0.23; % colorbar width (both together)
|
||||
cbh = 1-3*gap-bth; % colorbar height
|
||||
axh = 1-bgh-2*gap; % axes height
|
||||
axw = 1-cbw-2*gap; % axes width
|
||||
bgw = axw-btw-gap; % button group width
|
||||
%
|
||||
figH = figure('HandleVisibility','callback',...
|
||||
'IntegerHandle','off', 'NumberTitle','off', 'Units','normalized',...
|
||||
'Name','ColorBrewer Interactive ColorScheme Selector',...
|
||||
'MenuBar','figure', 'Toolbar','none', 'Tag',mfilename);
|
||||
%
|
||||
% Add 2D lineplot:
|
||||
ax2D = axes('Parent',figH, 'Position',[gap,bgh+gap,axw,axh], 'Box','on',...
|
||||
'ColorOrder',[1,0,0; 0,1,0; 0,0,1; 0.6,0.6,0.6], 'HitTest','off',...
|
||||
'Visible','off', 'XLim',[0,1], 'YLim',[0,1], 'XTick',[], 'YTick',[]);
|
||||
ln2D = line([0,0,0,0;1,1,1,1],[0,0,0,0;1,1,1,1], 'Parent',ax2D,...
|
||||
'Visible','off', 'Linestyle','-', 'Marker','.');
|
||||
%
|
||||
% Add 3D scatterplot:
|
||||
ax3D = axes('Parent',figH, 'OuterPosition',[0,bgh,axw+2*gap,1-bgh],...
|
||||
'Visible','on', 'XLim',[0,1], 'YLim',[0,1], 'ZLim',[0,1], 'HitTest','on');
|
||||
pt3D = patch('Parent',ax3D, 'XData',[0;1], 'YData',[0;1], 'ZData',[0;1],...
|
||||
'Visible','on', 'LineStyle','none', 'FaceColor','none', 'MarkerEdgeColor','none',...
|
||||
'Marker','o', 'MarkerFaceColor','flat', 'MarkerSize',10, 'FaceVertexCData',[1,1,0;1,0,1]);
|
||||
view(ax3D,3);
|
||||
grid(ax3D,'on')
|
||||
lbl = {'Red','Green','Blue'};
|
||||
xlabel(ax3D,lbl{xyz(1)})
|
||||
ylabel(ax3D,lbl{xyz(2)})
|
||||
zlabel(ax3D,lbl{xyz(3)})
|
||||
%
|
||||
% Add warning text:
|
||||
txtH = text('Parent',ax2D, 'Units','normalized', 'Position',[1,1],...
|
||||
'HorizontalAlignment','right', 'VerticalAlignment','top');
|
||||
%
|
||||
% Add demo button:
|
||||
demo = uicontrol(figH, 'Style','togglebutton', 'Units','normalized',...
|
||||
'Position',[1-cbw/2,1-bth-gap,cbw/2-gap,bth], 'String','Demo',...
|
||||
'Max',1, 'Min',0, 'Callback',@bmvDemo); %#ok<NASGU>
|
||||
% Add 2D/3D button:
|
||||
is2D = uicontrol(figH, 'Style','togglebutton', 'Units','normalized',...
|
||||
'Position',[1-cbw/1,1-bth-gap,cbw/2-gap,bth], 'String','2D / 3D',...
|
||||
'Max',1, 'Min',0, 'Callback',@bmv2D3D);
|
||||
% Add reverse button:
|
||||
bRev = uicontrol(figH, 'Style','togglebutton', 'Units','normalized',...
|
||||
'Position',[bgw+2*gap,bgh-bth,btw,bth], 'String','Reverse',...
|
||||
'Max',1, 'Min',0, 'Callback',@bmvRevM);
|
||||
%
|
||||
% Add colorbars:
|
||||
C(1,1,:) = [1,1,1];
|
||||
cbAx(2) = axes('Parent',figH, 'Visible','off', 'Units','normalized',...
|
||||
'Position',[1-cbw/2,gap,cbw/2-gap,cbh], 'YLim',[0.5,1.5],...
|
||||
'YDir','normal', 'HitTest','off');
|
||||
cbAx(1) = axes('Parent',figH, 'Visible','off', 'Units','normalized',...
|
||||
'Position',[1-cbw/1,gap,cbw/2-gap,cbh], 'YLim',[0.5,1.5],...
|
||||
'YDir','normal', 'HitTest','off');
|
||||
cbIm(2) = image('Parent',cbAx(2), 'CData',C);
|
||||
cbIm(1) = image('Parent',cbAx(1), 'CData',C);
|
||||
%
|
||||
% Add parameter sliders, listeners, and corresponding text:
|
||||
sv = mean([lbd,rbd],2);
|
||||
pTxt = uicontrol(figH,'Style','text', 'Units','normalized',...
|
||||
'Position',[bgw+2*gap,bgh-2*bth-gap,btw,bth], 'String','X');
|
||||
pSld = uicontrol(figH,'Style','slider', 'Units','normalized',...
|
||||
'Position',[bgw+2*gap,gap,btw,bgh-2*bth-gap], 'Min',lbd(1), 'Max',rbd(1),...
|
||||
'SliderStep',stp(1,:)/(rbd(1)-lbd(1)), 'Value',sv(1));
|
||||
addlistener(pSld, 'Value', 'PostSet',@bmvSldr);
|
||||
%
|
||||
% Add colorscheme button group:
|
||||
bGrp = uibuttongroup('Parent',figH, 'BorderType','none', ...
|
||||
'Units','normalized', 'Position',[gap,gap,bgw,bgh-gap]);
|
||||
% Determine button locations:
|
||||
Z = 1:numel(mcs);
|
||||
Z = Z+(Z>17);
|
||||
C = (ceil(Z/M)-1)/4;
|
||||
R = (M-1-mod(Z-1,M))/M;
|
||||
% Add colorscheme buttons to group:
|
||||
for jj = numel(mcs):-1:1
|
||||
bEig(jj) = uicontrol('Parent',bGrp, 'Style','Toggle', 'String',mcs{jj},...
|
||||
'Unit','normalized', 'Position',[C(jj),R(jj),1/4,1/M]);
|
||||
end
|
||||
set(bGrp,'SelectionChangeFcn',@bmvChgS);
|
||||
%
|
||||
end
|
||||
%
|
||||
%% Nested Functions %%
|
||||
%
|
||||
function str = bmvName()
|
||||
% Generate the colorscheme name.
|
||||
pfx = '+-';
|
||||
ids = strcmpi(scm,mcs);
|
||||
if any(ids)
|
||||
str = [pfx(1+isr),mcs{ids}];
|
||||
else % will throw an error in BREWERMAP:
|
||||
str = scm;
|
||||
end
|
||||
end
|
||||
%
|
||||
function bmvUpDt()
|
||||
% Update all graphics objects in the figure.
|
||||
%
|
||||
% Get ColorBrewer colormap and grayscale equivalent:
|
||||
[map,num,typ] = brewermap(N,bmvName());
|
||||
mag = map*[0.298936;0.587043;0.114021];
|
||||
%
|
||||
% Update colorbar values:
|
||||
set(cbAx, 'YLim',[0,abs(N)+(N==0)]+0.5);
|
||||
set(cbIm(1), 'CData',reshape(map,[],1,3))
|
||||
set(cbIm(2), 'CData', repmat(mag,[1,1,3]))
|
||||
%
|
||||
% Update 2D line / 3D patch values:
|
||||
if get(is2D, 'Value')
|
||||
set(ln2D, 'XData',linspace(0,1,abs(N)));
|
||||
set(ln2D,{'YData'},num2cell([map,mag],1).');
|
||||
else % 3D
|
||||
set(pt3D,...
|
||||
'XData',map(:,xyz(1)),...
|
||||
'YData',map(:,xyz(2)),...
|
||||
'ZData',map(:,xyz(3)),...
|
||||
'FaceVertexCData',map)
|
||||
end
|
||||
%
|
||||
% Update reverse button:
|
||||
set(bRev, 'Value',isr)
|
||||
%
|
||||
% Update warning text:
|
||||
str = {[bmvName(),' '];[typ,' '];sprintf('%d Nodes ',num)};
|
||||
set(txtH,'String',str);
|
||||
%
|
||||
% Update parameter value text:
|
||||
set(pTxt(1), 'String',sprintf('N = %.0f',N));
|
||||
%
|
||||
% Update external axes/figure colormaps/colororders:
|
||||
nmr(1) = N;
|
||||
for k = 1:numel(hgv)
|
||||
fnh(hgv(k),brewermap(nmr(k),bmvName()));
|
||||
end
|
||||
%
|
||||
drawnow()
|
||||
end
|
||||
%
|
||||
function bmv2D3D(h,~)
|
||||
% Switch between 2D-line and 3D-cube representation.
|
||||
%
|
||||
if get(h,'Value') % 2D
|
||||
set(ax3D, 'HitTest','off', 'Visible','off')
|
||||
set(ax2D, 'HitTest','on', 'Visible','on')
|
||||
set(pt3D, 'Visible','off')
|
||||
set(ln2D, 'Visible','on')
|
||||
else % 3D
|
||||
set(ax2D, 'HitTest','off', 'Visible','off')
|
||||
set(ax3D, 'HitTest','on', 'Visible','on')
|
||||
set(ln2D, 'Visible','off')
|
||||
set(pt3D, 'Visible','on')
|
||||
end
|
||||
%
|
||||
bmvUpDt();
|
||||
end
|
||||
%
|
||||
function bmvChgS(~,e)
|
||||
% Change the colorscheme.
|
||||
%
|
||||
scm = get(e.NewValue,'String');
|
||||
%
|
||||
bmvUpDt()
|
||||
end
|
||||
%
|
||||
function bmvRevM(h,~)
|
||||
% Reverse the colormap.
|
||||
%
|
||||
isr = logical(get(h,'Value'));
|
||||
%
|
||||
bmvUpDt()
|
||||
end
|
||||
%
|
||||
function bmvSldr(~,~)
|
||||
% Update the slider position.
|
||||
%
|
||||
if ~upd
|
||||
return
|
||||
end
|
||||
%
|
||||
N = round(get(pSld,'Value'));
|
||||
%
|
||||
bmvUpDt()
|
||||
end
|
||||
%
|
||||
function bmvDemo(h,~)
|
||||
% Display all ColorBrewer colorschemes sequentially.
|
||||
%
|
||||
cnt = 0;
|
||||
while ishghandle(h)&&get(h,'Value')
|
||||
cnt = mod(cnt+1,pow2(53));
|
||||
%
|
||||
if mod(cnt,23)<1
|
||||
ids = 1+mod(find(strcmpi(scm,mcs)),numel(mcs));
|
||||
scm = mcs{ids};
|
||||
try %#ok<TRYNC>
|
||||
set(bGrp, 'SelectedObject',bEig(ids));
|
||||
end
|
||||
end
|
||||
%
|
||||
if mod(cnt,69)<1
|
||||
isr = ~isr;
|
||||
end
|
||||
%
|
||||
upb = (upb || N<=1) && N<dfn;
|
||||
N = N - 1 + 2*upb;
|
||||
%
|
||||
% Update slider position:
|
||||
upd = false;
|
||||
try %#ok<TRYNC>
|
||||
set(pSld, 'Value',N)
|
||||
bmvUpDt()
|
||||
end
|
||||
upd = true;
|
||||
%
|
||||
% Faster/slower:
|
||||
pause(0.1);
|
||||
end
|
||||
%
|
||||
end
|
||||
%
|
||||
%% Initialize the Figure %%
|
||||
%
|
||||
set(bGrp,'SelectedObject',bEig(strcmpi(scm,mcs)));
|
||||
set(pSld,'Value',max(lbd,min(rbd,N)));
|
||||
upd = true;
|
||||
bmvUpDt()
|
||||
%
|
||||
if nargout
|
||||
waitfor(ax2D);
|
||||
scheme = bmvName();
|
||||
else
|
||||
clear map
|
||||
end
|
||||
%
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%brewermap_view
|
||||
function arr = bmv1s2c(arr)
|
||||
% If scalar string then extract the character vector, otherwise data is unchanged.
|
||||
if isa(arr,'string') && isscalar(arr)
|
||||
arr = arr{1};
|
||||
end
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bmv1s2c
|
||||
%
|
||||
% Copyright (c) 2014-2025 Stephen Cobeldick
|
||||
%
|
||||
% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
% you may not use this file except in compliance with the License.
|
||||
% You may obtain a copy of the License at
|
||||
%
|
||||
% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%
|
||||
% Unless required by applicable law or agreed to in writing, software
|
||||
% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
% See the License for the specific language governing permissions and limitations under the License.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%license
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
import sys
|
||||
|
||||
input_path = '/Users/bartels-rausch/Documents/GitLab/functionsMatlab/beamtime/nappFileList.m'
|
||||
output_path = '/Users/bartels-rausch/Documents/GitLab/functionsMatlab/beamtime/nappFileList_clean.m'
|
||||
|
||||
try:
|
||||
with open(input_path, 'rb') as f:
|
||||
content = f.read()
|
||||
|
||||
# Try decoding as utf-8, replace errors
|
||||
text = content.decode('utf-8', errors='replace')
|
||||
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
f.write(text)
|
||||
|
||||
print(f"Successfully cleaned file to {output_path}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
@@ -1,831 +0,0 @@
|
||||
function distFig(varargin)
|
||||
% ===== Syntax ============================================================
|
||||
% distFig(...,'Screen',Value)
|
||||
% distFig(...,'Position',Value)
|
||||
%
|
||||
% distFig(...,'Rows',Value)
|
||||
% distFig(...,'Columns',Value)
|
||||
%
|
||||
% distFig(...,'Not',Value)
|
||||
% distFig(...,'Only',Value)
|
||||
% distFig(...,'Offset',Value)
|
||||
%
|
||||
% distFig(...,'Adjust',Value)
|
||||
% distFig(...,'Extra',Value)
|
||||
% distFig(...,'Menu',Value)
|
||||
% distFig(...,'Transpose',Value)
|
||||
% distFig(...,'Simulink',Value)
|
||||
% distFig(...,'Tight',Value)
|
||||
% distFig(...,'Scale',Value)
|
||||
% distFig(...,'ScaleOrigin',Value)
|
||||
% distFig(...,'FreezeSize',Value)
|
||||
% distFig(...,'Order',Value)
|
||||
%
|
||||
% ===== Description =======================================================
|
||||
% distFig(...,'Screen',Value) assigns where the figures will be
|
||||
% distributed.
|
||||
% Synonyms for 'Screen' are 'Scr' and 'S'. Value can be:
|
||||
% 'C' / 'Center' (Default)
|
||||
% 'W' / 'West' / 'L' / 'Left'
|
||||
% 'E' / 'East' / 'R' / 'Right'
|
||||
% 'N' / 'North' / 'T' / 'Top'
|
||||
% 'S' / 'South' / 'B' / 'Bottom'
|
||||
% 'Main' / 'Primary'
|
||||
% 'Ext' / 'External' / 'Secondary'
|
||||
%
|
||||
% distFig(...,'Position',Value) assigns in which part of the screen the
|
||||
% figures will be distributed.
|
||||
% Synonyms for 'Position' are 'Pos' and 'P'. Value can be:
|
||||
% 'C' / 'Center' (Default)
|
||||
% 'W' / 'West' / 'L' / 'Left'
|
||||
% 'E' / 'East' / 'R' / 'Right'
|
||||
% 'N' / 'North' / 'T' / 'Top'
|
||||
% 'S' / 'South' / 'B' / 'Bottom'
|
||||
% 'NW'
|
||||
% 'NE'
|
||||
% 'SW'
|
||||
% 'SE'
|
||||
%
|
||||
% distFig(...,'Rows',Value) assigns how many rows the figures will be
|
||||
% distributed on.
|
||||
% Synonyms for 'Rows' are 'R'. Value can be:
|
||||
% 1...n
|
||||
% 'Auto' / -1
|
||||
% 'Auto' indicates that it automatically calculates the number of required
|
||||
% rows.
|
||||
%
|
||||
% distFig(...,'Columns',Value) assigns how many rows the figures will be
|
||||
% distributed on.
|
||||
% Synonyms for 'Columns' are 'Cols' and 'C'. Value can be:
|
||||
% 1...n
|
||||
% 'Auto' / -1
|
||||
% 'Auto' indicates that it automatically calculates the number of required
|
||||
% columns.
|
||||
%
|
||||
% distFig(...,'Not',Value) excludes specified figures from the distribution
|
||||
% list. Value must be an array with the excluded figure numbers. The
|
||||
% default value is []. The input argument 'gcf' (get current figure) can be
|
||||
% used as well.
|
||||
%
|
||||
% distFig(...,'Only',Value) does only distribute specified figures. Value
|
||||
% must be an array with the figure which will be distributed. The
|
||||
% default value is []. The input argument 'gcf' (get current figure) can be
|
||||
% used as well.
|
||||
%
|
||||
% distFig(...,'Offset',Value) can be used to shift all figures on the
|
||||
% distribution list. Synonyms for 'Offset' is 'O'. Value must be an integer
|
||||
% larger or equal to zero. The default offset value is 0.
|
||||
%
|
||||
% distFig(...,'Adjust',Value) can be used to adjust all figure positions.
|
||||
% For instance, if all figures should be moved 20 pixels to the right,
|
||||
% which is not possible with the other features, Value should be [20,0].
|
||||
% If Value is below 1, the scalars indicate the relative adjustment to the
|
||||
% screen. If the selected monitor is [1920,1080] pixels, a Values of
|
||||
% [0.25,-0.5] moves all figures with [480,540] pixels.
|
||||
% Synonyms for 'Ajust' is 'A'. Value can be:
|
||||
% [Integer,Integer] (In order to adjust by a specific ammount)
|
||||
% [Scalar,Scalar]( < 1) (To adjust a relative ammount of the monitor size)
|
||||
% The default value is [0,0].
|
||||
%
|
||||
% distFig(...,'Extra',Value) is used to handle the extra figures, which
|
||||
% might not fit into 'Rows' * 'Cols'. For instance, 5 figure are to be
|
||||
% distributed on a 2x2 = 4 area. The fifth figure is then places on top of
|
||||
% the first figure if 'Extra' is 'restart'. It can be ignored by setting
|
||||
% 'Extra' to 'ignore', in which the fifth figure will not be distributed.
|
||||
%
|
||||
% distFig(...,'Menu',Value) can be used to modify the menu bar.
|
||||
% Value can be:
|
||||
% 'figure'
|
||||
% 'none'
|
||||
%
|
||||
% distFig(...,'Transpose',Value) can be used to tranpose the order of
|
||||
% distributing. The values must be logical and the default value is false.
|
||||
%
|
||||
% distFig(...,'Simulink',Value) can be used to handle simulink figures.
|
||||
% Value can be:
|
||||
% 'include' (Default)
|
||||
% 'exclude'
|
||||
% 'only'
|
||||
% If value is true, simulink figures will be distributed along with the
|
||||
% other figures. If value if 'exclude' simulink figures will be
|
||||
% excluded from the distribution list. If value is 'only', only the
|
||||
% simulink figures will be distributed and not the ordinary figures.
|
||||
%
|
||||
% distFig(...,'Tight',Value) can be used to stretch the figure to the
|
||||
% border of the figure, so no unnecessary "whitespace" is present.
|
||||
% Value must be logical and the default value if false.
|
||||
%
|
||||
% distFig(...,'Scale',Value) can be used to scale the figure matrix. Both
|
||||
% horizontal and vertical scaling can be applied, but also similar scaling.
|
||||
% Value is a single scalar for similar scaling, but is a 2x1 matrix for
|
||||
% specific scaling in each direction. For instance, distFig('Scale',0.5)
|
||||
% scales all figures by 50% relative to the upper left corner of the
|
||||
% distribution area (Default Scale-origin). distFig('Scale',[0.8,0.4])
|
||||
% scales the figures by 80% and 40% in the horizontal and vertical
|
||||
% directions respectivly relative to the default scale-origin.
|
||||
%
|
||||
% distFig(...,'ScaleOrigin',Value) can be used in combination with the
|
||||
% 'Scale' option. Value is a 2x1 matrix with the origin. If these values
|
||||
% are between 0 and 1 the relative monitor size is used, whereas larger
|
||||
% values should be rounded indicating pixel values. For instance,
|
||||
% distFig('Scale',0.5,'ScaleOrigin',[0.5,1]) scales the figures relative
|
||||
% to the midpoint on the right hand side of the selected monitor. For a
|
||||
% monitor with resolution 1920x1080, this would be equal to
|
||||
% distFig('Scale',0.5,'ScaleOrigin',[1920,960]).
|
||||
% The default scale origin is in the upper left corner of the distribution
|
||||
% area.
|
||||
% Synonyms for 'ScaleOrigin' are 'Origin', 'Orig' and 'Scaleorig'.
|
||||
%
|
||||
% distFig(...,'FreezeSize',Value) can be used to freeze the sizes of the
|
||||
% figures before distribution. Currently, this function anchors the figures
|
||||
% to the upper left corner of the original position, yet keeping the
|
||||
% original size - it does not calculate new positions, so the figures may
|
||||
% overlap.
|
||||
% Synonym for 'FreezeSize' is 'Freeze'.
|
||||
%
|
||||
% distFig(...,'Order',Value) can be used to control the plotting order. For
|
||||
% instance, distFig('Only',[5,6,7,8],'Order',[2,1,4,3]) will plot figure
|
||||
% 5,6,7 and 8 in the order of 6,5,8 and 7. The ordering argument is thus
|
||||
% related to the input of 'Only'.
|
||||
%
|
||||
% ===== Examples ==========================================================
|
||||
% distFig();
|
||||
% This will distribute all open figures on the primary screen in two rows.
|
||||
%
|
||||
% distFig('Screen','Left','Position','Right','Only',[1,2,4])
|
||||
% This will only distribute figure 1, 2 and 4 on the right part of the left
|
||||
% screen.
|
||||
%
|
||||
% distFig('Offset',2,'Not',[1,2])
|
||||
% This will distribute all figure but figure 1 and 2 in the same pattern as
|
||||
% distFig(), but figure 1 and 2 will not be distributed, but instead there will
|
||||
% be blank spots where they would have been distributed.
|
||||
%
|
||||
% ===== Note ==============================================================
|
||||
% If you find any errors or bugs with this version please contact me on
|
||||
% AndersSSimonsen@GMail.com or write a comment on file exchange - then I'll
|
||||
% take a look at it. :)
|
||||
%
|
||||
% This function will only work in MATLAB 2014b and onwards due to the
|
||||
% massive overhaul in the figure handle system - I will not support
|
||||
% previous versions.
|
||||
|
||||
% =========================================================================
|
||||
% ===== Version ===========================================================
|
||||
% =========================================================================
|
||||
|
||||
% Anders Schou Simonsen, AndersSSimonsen@GMail.com
|
||||
% Version 5.5
|
||||
% 31/03-2015
|
||||
|
||||
% =========================================================================
|
||||
% ===== Default values ====================================================
|
||||
% =========================================================================
|
||||
|
||||
Rows = -1;
|
||||
Cols = -1;
|
||||
Scr = 'C';
|
||||
Pos = 'C';
|
||||
Tight = false;
|
||||
Menu = '';
|
||||
Transpose = false;
|
||||
Extra = 'restart';
|
||||
Offset = 0;
|
||||
Not = [];
|
||||
Only = [];
|
||||
Simulink = 'include';
|
||||
Adjust = [0,0];
|
||||
Scale = 1;
|
||||
Scale_Orig = [];
|
||||
FreezeSize = false;
|
||||
Order = [];
|
||||
|
||||
% =========================================================================
|
||||
% ===== Get inputs ========================================================
|
||||
% =========================================================================
|
||||
|
||||
if (mod(nargin,2) ~= 0)
|
||||
error('Uneven number of inputs! Returning...');
|
||||
end
|
||||
|
||||
for i = 1:2:nargin
|
||||
if (ischar(varargin{i+1}))
|
||||
varargin{i+1} = lower(varargin{i+1});
|
||||
end
|
||||
switch lower(varargin{i})
|
||||
case {'scr','screen','s'}
|
||||
% =============================================================
|
||||
Allow = {
|
||||
'C' 'c' 'center' 'main' 'primary'
|
||||
'W' 'w' 'west' 'l' 'left'
|
||||
'E' 'e' 'east' 'r' 'right'
|
||||
'N' 'n' 'north' 't' 'top'
|
||||
'S' 's' 'south' 'b' 'bottom'
|
||||
'Ext' 'ext' 'external' 'secondary' NaN
|
||||
};
|
||||
Trigger = any(strcmp(Allow,varargin{i+1}),2);
|
||||
if (~any(Trigger))
|
||||
warning('Input ''%s'' not recognized for ''%s''!',varargin{i+1},varargin{i});
|
||||
else
|
||||
Scr = Allow{Trigger,1};
|
||||
end
|
||||
case {'pos','position','p'}
|
||||
% =============================================================
|
||||
Allow = {
|
||||
'C' 'c' 'center' NaN NaN
|
||||
'W' 'w' 'west' 'l' 'left'
|
||||
'E' 'e' 'east' 'r' 'right'
|
||||
'N' 'n' 'north' 't' 'top'
|
||||
'S' 's' 'south' 'b' 'bottom'
|
||||
'NW' 'nw' NaN NaN NaN
|
||||
'NE' 'ne' NaN NaN NaN
|
||||
'SW' 'sw' NaN NaN NaN
|
||||
'SE' 'se' NaN NaN NaN
|
||||
};
|
||||
Trigger = any(strcmp(Allow,varargin{i+1}),2);
|
||||
if (~any(Trigger))
|
||||
warning('Input ''%s'' not recognized for ''%s''!',varargin{i+1},varargin{i});
|
||||
else
|
||||
Pos = Allow{Trigger,1};
|
||||
end
|
||||
case {'rows','r'}
|
||||
% =============================================================
|
||||
if (strcmp(varargin{i+1},'auto'))
|
||||
Rows = -1;
|
||||
else
|
||||
if ~((isnumeric(varargin{i+1})) && (mod(varargin{i+1},1) == 0))
|
||||
warning('Input to ''%s'' must be a round numeric value!',varargin{i});
|
||||
else
|
||||
Rows = varargin{i+1};
|
||||
end
|
||||
end
|
||||
case {'cols','columns','c'}
|
||||
% =============================================================
|
||||
if (strcmp(varargin{i+1},'auto'))
|
||||
Cols = -1;
|
||||
else
|
||||
if ~((isnumeric(varargin{i+1})) && (mod(varargin{i+1},1) == 0))
|
||||
warning('Input to ''%s'' must be a round numeric value!',varargin{i});
|
||||
else
|
||||
Cols = varargin{i+1};
|
||||
end
|
||||
end
|
||||
case {'ext','extra'}
|
||||
% =============================================================
|
||||
Allow = {
|
||||
'ignore'
|
||||
'restart'
|
||||
};
|
||||
Trigger = any(strcmp(Allow,varargin{i+1}),2);
|
||||
if (~any(Trigger))
|
||||
warning('Input ''%s'' not recognized for ''%s''!',varargin{i+1},varargin{i});
|
||||
else
|
||||
Extra = Allow{Trigger,1};
|
||||
end
|
||||
case {'menu','bar'}
|
||||
% =============================================================
|
||||
Allow = {
|
||||
'figure'
|
||||
'none'
|
||||
};
|
||||
Trigger = any(strcmp(Allow,varargin{i+1}),2);
|
||||
if (~any(Trigger))
|
||||
warning('Input ''%s'' not recognized for ''%s''!',varargin{i+1},varargin{i});
|
||||
else
|
||||
Menu = Allow{Trigger,1};
|
||||
end
|
||||
case {'transpose'}
|
||||
% =============================================================
|
||||
if (~islogical(varargin{i+1}))
|
||||
warning('Input to ''%s'' must be logical!',varargin{i});
|
||||
else
|
||||
Transpose = varargin{i+1};
|
||||
end
|
||||
case {'offset','o'}
|
||||
% =============================================================
|
||||
if ~((isnumeric(varargin{i+1})) && (mod(varargin{i+1},1) == 0))
|
||||
warning('Input to ''%s'' must be a round numeric value!',varargin{i});
|
||||
else
|
||||
Offset = varargin{i+1};
|
||||
end
|
||||
case {'adjust','a'}
|
||||
% =============================================================
|
||||
if ~(isnumeric(varargin{i+1}))
|
||||
warning('Input to ''%s'' must be numeric!',varargin{i});
|
||||
elseif (numel(varargin{i+1}) ~= 2)
|
||||
warning('Input to ''%s'' must be a (1 x 2) matrix with integers or scalars less than one!',varargin{i});
|
||||
elseif (all(mod(varargin{i+1},1) == 0))
|
||||
Adjust = varargin{i+1};
|
||||
else
|
||||
if (any(varargin{i+1} > 1))
|
||||
warning('Input to ''%s'' must be either integers or scalars less than one!',varargin{i});
|
||||
else
|
||||
Adjust = varargin{i+1};
|
||||
end
|
||||
end
|
||||
case {'not'}
|
||||
% =============================================================
|
||||
if ~((isnumeric(varargin{i+1}) && all(mod(varargin{i+1},1) == 0)) || isobject(varargin{i+1}))
|
||||
warning('Input to ''%s'' must be round numeric values!',varargin{i});
|
||||
else
|
||||
if (isobject(varargin{i+1}))
|
||||
Not = get(varargin{i+1},'Number');
|
||||
if (iscell(Not))
|
||||
Not = cell2mat(Not);
|
||||
end
|
||||
else
|
||||
Not = varargin{i+1};
|
||||
end
|
||||
end
|
||||
case {'only'}
|
||||
% =============================================================
|
||||
if ~((isnumeric(varargin{i+1}) && all(mod(varargin{i+1},1) == 0)) || isobject(varargin{i+1}))
|
||||
warning('Input to ''%s'' must be round numeric values!',varargin{i});
|
||||
else
|
||||
if (isobject(varargin{i+1}))
|
||||
Only = get(varargin{i+1},'Number');
|
||||
if (iscell(Only))
|
||||
Only = cell2mat(Only);
|
||||
end
|
||||
else
|
||||
Only = varargin{i+1};
|
||||
end
|
||||
end
|
||||
case {'simu','simulink'}
|
||||
% =============================================================
|
||||
Allow = {
|
||||
'include' NaN
|
||||
'exclude' 'ignore'
|
||||
'only' NaN
|
||||
};
|
||||
Trigger = any(strcmp(Allow,varargin{i+1}),2);
|
||||
if (~any(Trigger))
|
||||
warning('Input ''%s'' not recognized for ''%s''!',varargin{i+1},varargin{i});
|
||||
else
|
||||
Simulink = Allow{Trigger,1};
|
||||
end
|
||||
case {'tight'}
|
||||
% =============================================================
|
||||
if (~islogical(varargin{i+1}))
|
||||
warning('Input to ''%s'' must be logical!',varargin{i});
|
||||
else
|
||||
Tight = varargin{i+1};
|
||||
end
|
||||
case {'scale'}
|
||||
% =============================================================
|
||||
if (~isnumeric(varargin{i+1}) || (numel(varargin{i+1}) > 2))
|
||||
warning('Input to ''%s'' must be one or two numeric values (x and y scale)!',varargin{i});
|
||||
else
|
||||
Scale = varargin{i+1};
|
||||
end
|
||||
case {'origin','orig','scaleorig','scaleorigin'}
|
||||
% =============================================================
|
||||
if (~isnumeric(varargin{i+1}) || (numel(varargin{i+1}) ~= 2))
|
||||
warning('Input to ''%s'' must be two numeric values (x0 and y0)!',varargin{i});
|
||||
else
|
||||
Scale_Orig = varargin{i+1};
|
||||
end
|
||||
case {'freezesize','freeze'}
|
||||
% =============================================================
|
||||
if (~islogical(varargin{i+1}))
|
||||
warning('Input to ''%s'' must be logical!',varargin{i});
|
||||
else
|
||||
FreezeSize = varargin{i+1};
|
||||
end
|
||||
case {'order'}
|
||||
% =============================================================
|
||||
if ~(isnumeric(varargin{i+1}) && all(mod(varargin{i+1},1) == 0))
|
||||
warning('Input to ''%s'' must be round numeric values!',varargin{i});
|
||||
else
|
||||
Order = varargin{i+1};
|
||||
end
|
||||
otherwise
|
||||
% =============================================================
|
||||
fprintf('Input ''%s'' not recognized!',varargin{i});
|
||||
end
|
||||
end
|
||||
|
||||
% =========================================================================
|
||||
% ===== Constants =========================================================
|
||||
% =========================================================================
|
||||
|
||||
% ===== Limits ============================================================
|
||||
Limits = {...
|
||||
'C' [0,1] [0,1]
|
||||
'W' [0,0.5] [0,1]
|
||||
'E' [0.5,1] [0,1]
|
||||
'N' [0,1] [0.5,1]
|
||||
'NW' [0,0.5] [0.5,1]
|
||||
'NE' [0.5,1] [0.5,1]
|
||||
'S' [0,1] [0,0.5]
|
||||
'SW' [0,0.5] [0,0.5]
|
||||
'SE' [0.5,1] [0,0.5]
|
||||
};
|
||||
|
||||
% ===== Screen angles =====================================================
|
||||
Screens = {...
|
||||
(-pi * 1 / 4) (+pi * 1 / 4) 'E'
|
||||
(-pi * 3 / 4) (-pi * 1 / 4) 'S'
|
||||
(+pi * 1 / 4) (+pi * 3 / 4) 'N'
|
||||
(+pi * 3 / 4) Inf 'W'
|
||||
-Inf (-pi * 3 / 4) 'W'
|
||||
};
|
||||
|
||||
% ===== Taskbar height ====================================================
|
||||
Taskbar_Height = 40;
|
||||
|
||||
% =========================================================================
|
||||
% ===== Figure list =======================================================
|
||||
% =========================================================================
|
||||
|
||||
% ===== All figures =======================================================
|
||||
Fig_Object = findall(0,'type','figure');
|
||||
if (isempty(Fig_Object))
|
||||
fprintf('distFig: No figures to distribute!\n');
|
||||
return;
|
||||
end
|
||||
|
||||
% ===== Remove not visible figures ========================================
|
||||
Visible = arrayfun(@(n) (strcmp(get(Fig_Object(n),'Visible'),'on')),1:numel(Fig_Object));
|
||||
Fig_Object = Fig_Object(Visible);
|
||||
|
||||
% ===== Include simulink figures ==========================================
|
||||
Fig_Number = {Fig_Object.Number};
|
||||
Empty = arrayfun(@(n) (isempty(Fig_Number{n})),1:numel(Fig_Number));
|
||||
Fig_Number(Empty) = {0};
|
||||
Fig_Number = cell2mat(Fig_Number);
|
||||
[~,Index] = sort(get(Fig_Object(Fig_Number == 0),'Name'));
|
||||
Temp = find(Fig_Number == 0);
|
||||
Fig_Number(Temp(Index)) = -(numel(Index):(-1):1);
|
||||
|
||||
% ===== Logical distribution array ========================================
|
||||
Fig_Dist = true(1,numel(Fig_Object));
|
||||
|
||||
% ===== Simulink figures ==================================================
|
||||
if strcmp(Simulink,'exclude')
|
||||
Fig_Dist = (Fig_Number > 0);
|
||||
end
|
||||
if strcmp(Simulink,'only')
|
||||
Fig_Dist = (Fig_Number < 0);
|
||||
end
|
||||
|
||||
% ===== Not ===============================================================
|
||||
Fig_Dist(ismember(Fig_Number,Not)) = false;
|
||||
|
||||
% ===== Only ==============================================================
|
||||
if (~isempty(Only))
|
||||
Fig_Dist(~ismember(Fig_Number,Only)) = false;
|
||||
end
|
||||
|
||||
% ===== Number of figures =================================================
|
||||
nFig_Dist = sum(Fig_Dist);
|
||||
|
||||
% ===== Return ============================================================
|
||||
if (nFig_Dist == 0)
|
||||
return;
|
||||
end
|
||||
|
||||
% =========================================================================
|
||||
% ===== Monitor ===========================================================
|
||||
% =========================================================================
|
||||
|
||||
% ===== Get monitor positions =============================================
|
||||
Monitors = get(0,'MonitorPositions');
|
||||
Monitors_Center = Monitors(:,1:2) + Monitors(:,3:4) / 2;
|
||||
Monitors_Label = cell(size(Monitors,1),1);
|
||||
|
||||
% ===== Center monitor ====================================================
|
||||
Temp = sum(abs(Monitors(:,1:2) - 1),2);
|
||||
Trigger_C = find(Temp == min(Temp));
|
||||
Monitors_Label{Trigger_C} = 'C';
|
||||
|
||||
% ===== External monitors =================================================
|
||||
Dir = Monitors_Center - repmat(Monitors_Center(Trigger_C,:),size(Monitors_Center,1),1);
|
||||
Theta = atan2(Dir(:,2),Dir(:,1));
|
||||
for i = 1:numel(Theta)
|
||||
if (i ~= Trigger_C)
|
||||
Monitors_Label{i} = Screens{(Theta(i) > [Screens{:,1}]) & (Theta(i) <= [Screens{:,2}]),3};
|
||||
end
|
||||
end
|
||||
|
||||
% ===== Select monitor ====================================================
|
||||
Monitor = Monitors(strcmp(Monitors_Label,Scr),:);
|
||||
if (isempty(Monitor))
|
||||
if (strcmp(Scr,'Ext'))
|
||||
if (size(Monitors,1) == 1)
|
||||
warning('No external monitor could be found!');
|
||||
Monitor = Monitors(1,:);
|
||||
else
|
||||
Monitor = Monitors(find(~strcmp(Monitors_Label,'C'),1,'first'),:);
|
||||
end
|
||||
else
|
||||
warning(['Screen ''%s'' could not be found! (Using ''C'' instead)\nThe following monitors were identified: %s.\n'...
|
||||
'If the function cannot find the monitor try and restart MATLAB - this will reset the monitor-matrix, which is being used by the function.'],...
|
||||
Scr,sprintf('%s\b\b\b\b\b',sprintf('''%s'' and ',Monitors_Label{:})));
|
||||
Monitor = Monitors(strcmp(Monitors_Label,'C'),:);
|
||||
if (isempty(Monitor))
|
||||
warning(['distFig cannot find matching monitors - using the first one!',...
|
||||
'\nPlease report this problem to AndersSSimonsen@GMail.com, where you include this matrix:'],0);
|
||||
disp(Monitors);
|
||||
Monitor = Monitors(1,:);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% =========================================================================
|
||||
% ===== Rows and columns ==================================================
|
||||
% =========================================================================
|
||||
|
||||
Limit = Limits(strcmp(Limits(:,1),Pos),:);
|
||||
if ((Rows == (-1)) && (Cols == (-1)))
|
||||
AR_Ideal = 1.2;
|
||||
AR_Mean = Inf;
|
||||
for i = 1:50
|
||||
% ===== Exception =================================================
|
||||
if ((nFig_Dist + Offset) == 4)
|
||||
Rows = 2;
|
||||
Cols = 2;
|
||||
break;
|
||||
end
|
||||
|
||||
% ===== Temporary rows and columns ================================
|
||||
Rows = i;
|
||||
Cols = ceil((nFig_Dist + Offset) / Rows);
|
||||
|
||||
% ===== Sizes =====================================================
|
||||
x = round(linspace(Limit{2}(1),Limit{2}(2),Cols + 1) * Monitor(3)) + 1;
|
||||
y = round(linspace(Limit{3}(1),Limit{3}(2),Rows + 1) * (Monitor(4) - Taskbar_Height)) + Taskbar_Height + 1;
|
||||
clear Size;
|
||||
[Size(:,:,1),Size(:,:,2)] = meshgrid(diff(x),diff(y));
|
||||
|
||||
% ===== Output ====================================================
|
||||
AR_Mean_Prev = AR_Mean;
|
||||
AR_Mean = mean(mean(Size(:,:,1) ./ Size(:,:,2)));
|
||||
if (AR_Mean > AR_Ideal)
|
||||
AR_Error = abs([AR_Ideal - AR_Mean_Prev,AR_Ideal - AR_Mean]);
|
||||
if (AR_Error(1) < AR_Error(2))
|
||||
Rows = i - 1;
|
||||
end
|
||||
Cols = ceil((nFig_Dist + Offset) / Rows);
|
||||
clear Size;
|
||||
break;
|
||||
end
|
||||
end
|
||||
elseif (Rows == (-1))
|
||||
Rows = ceil((nFig_Dist + Offset) / Cols);
|
||||
elseif (Cols == (-1))
|
||||
Cols = ceil((nFig_Dist + Offset) / Rows);
|
||||
end
|
||||
|
||||
% =========================================================================
|
||||
% ===== Location matrix ===================================================
|
||||
% =========================================================================
|
||||
|
||||
Sets = ceil(nFig_Dist / (Rows * Cols) + Offset);
|
||||
Mat = nan(Rows,Cols,Sets);
|
||||
if (Transpose)
|
||||
Mat = permute(Mat,[2,1,3]);
|
||||
end
|
||||
if (isempty(Order))
|
||||
Order = (1:sum(Fig_Dist));
|
||||
end
|
||||
Temp = sort(Fig_Number(Fig_Dist));
|
||||
if (max(Order) > numel(Temp))
|
||||
error('The ordering command is related to the input - not the actual figure numbers! Returning...');
|
||||
end
|
||||
Mat((1:nFig_Dist) + Offset) = Temp(Order);
|
||||
if (Transpose)
|
||||
Mat = permute(Mat,[2,1,3]);
|
||||
end
|
||||
if (strcmp(Extra,'ignore'))
|
||||
Sets = 1;
|
||||
end
|
||||
|
||||
% =========================================================================
|
||||
% ===== Position and size =================================================
|
||||
% =========================================================================
|
||||
|
||||
% ===== Grid ==============================================================
|
||||
x = round(linspace(Limit{2}(1),Limit{2}(2),Cols + 1) * Monitor(3)) + 1;
|
||||
y = round(linspace(Limit{3}(1),Limit{3}(2),Rows + 1) * (Monitor(4) - Taskbar_Height)) + Taskbar_Height + 1;
|
||||
|
||||
% ===== Scale =============================================================
|
||||
if (isempty(Scale_Orig))
|
||||
Scale_Orig = [x(1),y(end)];
|
||||
end
|
||||
if ((all(mod(Scale_Orig,1) == 0)) && (any(Scale_Orig > 1)))
|
||||
ScaleOrig_Pixel = Scale_Orig;
|
||||
else
|
||||
ScaleOrig_Pixel = Monitor(3:4) .* Scale_Orig;
|
||||
end
|
||||
if (numel(Scale) == 1)
|
||||
Scale(2) = Scale(1);
|
||||
end
|
||||
x = (x - ScaleOrig_Pixel(1)) * Scale(1) + ScaleOrig_Pixel(1);
|
||||
y = (y - ScaleOrig_Pixel(2)) * Scale(2) + ScaleOrig_Pixel(2);
|
||||
|
||||
% ===== Positon ===========================================================
|
||||
[FPos(:,:,1),FPos(:,:,2)] = meshgrid(x(1:end-1),y(1:end-1));
|
||||
FPos(:,:,2) = flipud(FPos(:,:,2));
|
||||
FPos(:,:,1) = FPos(:,:,1) + Monitor(1) - 1;
|
||||
FPos(:,:,2) = FPos(:,:,2) + Monitor(2) - 1;
|
||||
|
||||
% ===== Size ==============================================================
|
||||
[Size(:,:,1),Size(:,:,2)] = meshgrid(diff(x),diff(y));
|
||||
|
||||
% ===== Adjust ============================================================
|
||||
if (any(Adjust ~= 0))
|
||||
if (all(mod(Adjust,1) == 0))
|
||||
Adjust_Pixels = Adjust;
|
||||
else
|
||||
Adjust_Pixels = round(Adjust .* (Monitor(3:4) + [0,-Taskbar_Height]));
|
||||
end
|
||||
else
|
||||
Adjust_Pixels = [0,0];
|
||||
end
|
||||
|
||||
% =========================================================================
|
||||
% ===== Distribute figures ================================================
|
||||
% =========================================================================
|
||||
|
||||
for s = 1:Sets
|
||||
for i = 1:size(Mat,1)
|
||||
for j = 1:size(Mat,2)
|
||||
if (~isnan(Mat(i,j,s)))
|
||||
% ===== Position and figure ===============================
|
||||
Pos_Temp = [squeeze(FPos(i,j,:))' + Adjust_Pixels,squeeze(Size(i,j,:))'];
|
||||
gcf_Temp = Fig_Object(Fig_Number == Mat(i,j,s));
|
||||
gca_Temp = get(gcf_Temp,'CurrentAxes');
|
||||
|
||||
% ===== Freeze size =======================================
|
||||
if (FreezeSize)
|
||||
Pos_Orig = get(gcf_Temp,'Position');
|
||||
Pos_Temp(2) = Pos_Temp(2) + Pos_Temp(4) - Pos_Orig(4);
|
||||
Pos_Temp(3:4) = Pos_Orig(3:4);
|
||||
end
|
||||
|
||||
% ===== Focus figures to bring to front ===================
|
||||
figure(gcf_Temp);
|
||||
|
||||
% ===== Set units =========================================
|
||||
if (~isempty(Menu))
|
||||
set(gcf_Temp,'MenuBar',Menu);
|
||||
end
|
||||
if (Mat(i,j,s) < 0)
|
||||
drawnow;
|
||||
end
|
||||
gca_Units_Prev = get(gca_Temp,'Units');
|
||||
gcf_Units_Prev = get(gcf_Temp,'Units');
|
||||
|
||||
% ===== Distribute figure =================================
|
||||
set(gca_Temp,'Units','normalized');
|
||||
set(gcf_Temp,'Units','pixels','OuterPosition',Pos_Temp);
|
||||
set(gcf_Temp,'Units',gcf_Units_Prev);
|
||||
|
||||
% ===== Apply tight =======================================
|
||||
if ((Tight) && (Mat(i,j,s) > 0))
|
||||
drawnow;
|
||||
set(gca_Temp,'Position',[get(gca_Temp,'TightInset') * eye(4,2),1 - get(gca_Temp,'TightInset') * [1,0,1,0;0,1,0,1]']);
|
||||
end
|
||||
set(gca_Temp,'Units',gca_Units_Prev);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% =========================================================================
|
||||
% ===== Check for new updates =============================================
|
||||
% =========================================================================
|
||||
|
||||
% This feature check for a new version of distFig. It is only an attempt,
|
||||
% so it might not work without bugs. It can be disables by setting the
|
||||
% variable below called "Update" to "false" or by deleting this whole
|
||||
% section - this won't affect the rest of the function.
|
||||
%
|
||||
% It generates a .txt file called "distFig_Update.txt" located in the same
|
||||
% folder as distFig.m, which holds the date for the last time the function
|
||||
% checked for updates. In order to not check for updates all the time, the
|
||||
% function only does this ONCE every 7 days (variable "Check_Interval"),
|
||||
% and at max once for every started MATLAB session. Also, it uses appdata,
|
||||
% so if you're using this as well, it might display messages multiple times
|
||||
% within a session, if an update is available, if appdata is deleted.
|
||||
%
|
||||
% The update feature works by scanning the file exchange page for distFig
|
||||
% for a string value called "datePublished", and compares it to the date of
|
||||
% the current version (variable "Date_Current"). If these are not the same,
|
||||
% a hyperlink will be shown to the function page on file exchange page. It
|
||||
% thus depends on a very specific format, which might differ(?) from
|
||||
% different languages - I'm not aware whether this is true, so please
|
||||
% contact me on AndersSSimonsen@GMail.com if you find this to be true, so I
|
||||
% can fix the feature. :)
|
||||
|
||||
% ===== DISABLE THE UPDATE FEATURE BY SETTING THIS VALUE TO false =========
|
||||
Update = true;
|
||||
% ===== DISABLE THE UPDATE FEATURE BY SETTING THIS VALUE TO false =========
|
||||
|
||||
if (Update)
|
||||
try
|
||||
% ===== Initialize ================================================
|
||||
Date_Current = [2015,03,31];
|
||||
Check_Interval = 7;
|
||||
Check = false;
|
||||
|
||||
% ===== Path of update file =======================================
|
||||
Path = mfilename('fullpath');
|
||||
Path = sprintf('%s\\distFig_Update.txt',Path(1:end-numel('\distFig')));
|
||||
|
||||
if (isempty(getappdata(0,'distFig_Update')))
|
||||
% ===== Set appdata ===========================================
|
||||
setappdata(0,'distFig_Update',1);
|
||||
|
||||
% ===== Read update file ======================================
|
||||
File_ID = fopen(Path,'r');
|
||||
Clock = clock;
|
||||
Date_Today = Clock(1:3);
|
||||
if (File_ID == (-1))
|
||||
% ===== Generate update file ==============================
|
||||
File_ID = fopen(Path,'w');
|
||||
fprintf(File_ID,'%d %d %d',Date_Today(1),Date_Today(2),Date_Today(3));
|
||||
fclose(File_ID);
|
||||
Check = true;
|
||||
else
|
||||
% ===== Read last date ====================================
|
||||
Data = textscan(File_ID,'%s','delimiter','');
|
||||
if (strcmp(Data{1},'DISABLE'))
|
||||
Check = false;
|
||||
else
|
||||
Date_Last_Checked = cell2mat(textscan(Data{1}{1},'%f %f %f'));
|
||||
|
||||
% ===== Write new date ================================
|
||||
File_ID = fopen(Path,'w');
|
||||
fprintf(File_ID,'%d %d %d',Date_Today(1),Date_Today(2),Date_Today(3));
|
||||
fclose(File_ID);
|
||||
|
||||
% ===== Check for new updates? ========================
|
||||
Days_Elapsed = etime([Date_Today,zeros(1,3)],[Date_Last_Checked,zeros(1,3)]) / (60^2 * 24);
|
||||
if (Days_Elapsed > Check_Interval)
|
||||
Check = true;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% ===== Check for updates =====================================
|
||||
if (Check)
|
||||
% ===== Read File Exchange date ===========================
|
||||
Data = urlread('http://se.mathworks.com/matlabcentral/fileexchange/37176-distribute-figures');
|
||||
Temp = Data((-1:100) + regexp(Data,'datePublished'));
|
||||
Date_Online = cell2mat(textscan(Temp(26:end),'%f-%f-%f'));
|
||||
|
||||
% ===== New update available? =============================
|
||||
if (~all(Date_Current == Date_Online))
|
||||
setappdata(0,'distFig_Update',2);
|
||||
setappdata(0,'distFig_Online_Date',Date_Online);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% ===== Message ===================================================
|
||||
if (getappdata(0,'distFig_Update') == 2)
|
||||
try
|
||||
% ===== New version =======================================
|
||||
Date_Online = getappdata(0,'distFig_Online_Date');
|
||||
fprintf('New update available for distFig! ');
|
||||
disp('<a href = "http://se.mathworks.com/matlabcentral/fileexchange/37176-distribute-figures">Download here</a>')
|
||||
fprintf('\tCurrent version date:\t%02.0f-%02.0f-%02.0f\n',Date_Current(1),Date_Current(2),Date_Current(3));
|
||||
fprintf('\tOnline version date:\t%02.0f-%02.0f-%02.0f\n',Date_Online(1),Date_Online(2),Date_Online(3));
|
||||
|
||||
% ===== Postpone ==========================================
|
||||
fprintf('Click here to postpone this message for %d days: ',Check_Interval);
|
||||
Command = sprintf([...
|
||||
'setappdata(0,''distFig_Update'',1);',...
|
||||
'fprintf(''distFig update message postponed for %d days!\\n'');'
|
||||
],Check_Interval);
|
||||
disp(sprintf('<a href="matlab:%s">Postpone update message</a>',Command)); %#ok<DSPS>
|
||||
|
||||
% ===== Disable ===========================================
|
||||
fprintf('Click here to disable the update feature forever: ');
|
||||
Command = sprintf([...
|
||||
'File_ID = fopen(''%s'',''w'');',...
|
||||
'fprintf(File_ID,''DISABLE'');',...
|
||||
'fclose(File_ID);',...
|
||||
'setappdata(0,''distFig_Update'',1);',...
|
||||
'fprintf(''distFig update feature disabled!\\n'');'
|
||||
],Path);
|
||||
disp(sprintf('<a href="matlab:%s">Disable update feature</a>',Command)); %#ok<DSPS>
|
||||
catch
|
||||
setappdata(0,'distFig_Update',1);
|
||||
end
|
||||
end
|
||||
catch Error %#ok<NASGU>
|
||||
% ===== Error handling ============================================
|
||||
try
|
||||
Path_Error = [Path(1:end-numel([filesep 'distFig_Update.txt'])), [filesep 'distFig_Error.mat']];
|
||||
fprintf([
|
||||
'There was an error in distFig when checking for updates.',...
|
||||
'\nPlease report this to AndersSSimonsen@GMail.com by sending the error-file "distFig_Error.mat" located in %s. :)\n\n'],Path_Error);
|
||||
AppData = getappdata(0); %#ok<NASGU>
|
||||
save(Path_Error);
|
||||
catch
|
||||
end
|
||||
end
|
||||
end
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 67 KiB |
@@ -1,24 +0,0 @@
|
||||
function PsiFarbe = getPsiColors()
|
||||
% Returns a struct with PSI corporate identity colors.
|
||||
|
||||
% define PSI cooperate identity colours
|
||||
PsiFarbe.hellgrau = [226 226 226]/255;
|
||||
PsiFarbe.mittelgrau = [184 184 184]/255;
|
||||
PsiFarbe.dunkelgrau = [78 78 77]/255;
|
||||
PsiFarbe.blaugrau = [236 236 243]/255; % This is actually not a PSI colour
|
||||
PsiFarbe.gelb = [239 200 37]/255;
|
||||
PsiFarbe.hellorange = [227 164 31]/255;
|
||||
PsiFarbe.dunkelorange = [207 92 22]/255;
|
||||
PsiFarbe.hellrot = [164 36 23]/255;
|
||||
PsiFarbe.dunkelbraun = [114 85 65]/255;
|
||||
PsiFarbe.hellbraun = [127 119 47]/255;
|
||||
PsiFarbe.mittelgruen = [135 150 59]/255;
|
||||
PsiFarbe.hellgruen = [195 214 47]/255;
|
||||
PsiFarbe.dunkelgruen = [72 130 33]/255;
|
||||
PsiFarbe.dunkelrot = [104 47 86]/255;
|
||||
PsiFarbe.dunkelblau = [37 65 108]/255;
|
||||
PsiFarbe.mittelgruenblau = [61 164 168]/255;
|
||||
PsiFarbe.hellblau = [58 162 190]/255;
|
||||
PsiFarbe.mittelblau = [50 118 158]/255;
|
||||
|
||||
end
|
||||
@@ -1,107 +0,0 @@
|
||||
function TableLabViewIss = importLabViewIssfile(filenameOrFolder, dataLines)
|
||||
%IMPORTFILE Import data from a text file or folder
|
||||
% TableLabViewIss = IMPORTFILE(FILENAME) reads data from text
|
||||
% file FILENAME and returns the data as a table.
|
||||
%
|
||||
% TableLabViewIss = IMPORTFILE(FOLDER) reads all .txt files from
|
||||
% FOLDER, merges them into a single table (sorted by datetime).
|
||||
%
|
||||
% TableLabViewIss = IMPORTFILE(FILE, DATALINES) reads data
|
||||
% for the specified row interval(s) of text file FILENAME.
|
||||
%
|
||||
% Example (single file):
|
||||
% TableLabViewIss = importLabViewIssfile("/Users/bartels-rausch/Desktop/17-12-2025_09-14datafile.txt", [2, Inf]);
|
||||
%
|
||||
% Example (folder):
|
||||
% TableLabViewIss = importLabViewIssfile("/Users/bartels-rausch/Desktop/DataFolder");
|
||||
%
|
||||
% See also READTABLE.
|
||||
|
||||
%% Input handling
|
||||
|
||||
% If dataLines is not specified, define defaults
|
||||
if nargin < 2
|
||||
dataLines = [2, Inf];
|
||||
end
|
||||
|
||||
%% Check if input is a file or folder
|
||||
if isfolder(filenameOrFolder)
|
||||
% Process all .txt files in the folder
|
||||
folderPath = filenameOrFolder;
|
||||
fileList = dir(fullfile(folderPath, '*.txt'));
|
||||
|
||||
if isempty(fileList)
|
||||
error('No .txt files found in folder: %s', folderPath);
|
||||
end
|
||||
|
||||
fprintf('Found %d .txt files in folder. Processing...\n', length(fileList));
|
||||
|
||||
% Initialize empty table
|
||||
TableLabViewIss = table();
|
||||
|
||||
% Loop through each file
|
||||
for i = 1:length(fileList)
|
||||
filepath = fullfile(folderPath, fileList(i).name);
|
||||
fprintf(' [%d/%d] Processing: %s\n', i, length(fileList), fileList(i).name);
|
||||
|
||||
% Import this file
|
||||
tbl_temp = importSingleFile(filepath, dataLines);
|
||||
|
||||
% Append to main table
|
||||
if isempty(TableLabViewIss)
|
||||
TableLabViewIss = tbl_temp;
|
||||
else
|
||||
TableLabViewIss = [TableLabViewIss; tbl_temp];
|
||||
end
|
||||
end
|
||||
|
||||
% Sort by datetime
|
||||
[~, sortIdx] = sort(TableLabViewIss.datetime);
|
||||
TableLabViewIss = TableLabViewIss(sortIdx, :);
|
||||
|
||||
fprintf('Merged %d files into single table with %d rows.\n', length(fileList), height(TableLabViewIss));
|
||||
|
||||
else
|
||||
% Process single file
|
||||
TableLabViewIss = importSingleFile(filenameOrFolder, dataLines);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
%% Helper function to import a single file
|
||||
function tbl = importSingleFile(filename, dataLines)
|
||||
% Import options setup
|
||||
opts = delimitedTextImportOptions("NumVariables", 10);
|
||||
|
||||
% Specify range and delimiter
|
||||
opts.DataLines = dataLines;
|
||||
opts.Delimiter = "\t";
|
||||
|
||||
% Specify column names and types
|
||||
opts.VariableNames = ["date_DD_MM_JJJJ_", "time_hh_mm_ss_", "pressure_cell_hPa_", "temperature__C_", "x_mm_", "y_mm_", "z_mm_", "Tsealing__C_", "flowCryo_l_min_", "pOut_hPa_"];
|
||||
opts.VariableTypes = ["datetime", "duration", "double", "double", "double", "double", "double", "double", "double", "double"];
|
||||
|
||||
% Specify file level properties
|
||||
opts.ExtraColumnsRule = "ignore";
|
||||
opts.EmptyLineRule = "read";
|
||||
|
||||
% Specify variable properties
|
||||
opts = setvaropts(opts, "date_DD_MM_JJJJ_", "InputFormat", "dd.MM.yyyy");
|
||||
opts = setvaropts(opts, "time_hh_mm_ss_", "InputFormat", "hh:mm:ss.S");
|
||||
|
||||
% Import the data as regular table
|
||||
tbl = readtable(filename, opts);
|
||||
|
||||
% Merge date + time into a single datetime column
|
||||
tbl.datetime = tbl.date_DD_MM_JJJJ_ + tbl.time_hh_mm_ss_;
|
||||
|
||||
% Set the datetime display format to show date and time
|
||||
tbl.datetime.Format = 'dd.MM.yyyy HH:mm:ss.SSS';
|
||||
|
||||
% Remove the original date and time columns
|
||||
tbl(:, ["date_DD_MM_JJJJ_", "time_hh_mm_ss_"]) = [];
|
||||
|
||||
% Move datetime to be the first column
|
||||
tbl = movevars(tbl, "datetime", "Before", 1);
|
||||
|
||||
end
|
||||
@@ -1,85 +0,0 @@
|
||||
function Table = outerjoinRowToTable(Table,TableRowToBeAdded)
|
||||
%outerjoinRowToTable Adds one row to a table. Variables that are missing in
|
||||
%either the table or the row are added with empty values {' '} for cells
|
||||
%and NaN for doubles. Works with tables that contain both cells and
|
||||
%doubles.
|
||||
%
|
||||
% * Strings in the table are not yet supported.
|
||||
% * The row that is added needs to be formatted as table
|
||||
% * Update 2024: Adds several rows, that is tables
|
||||
% * Update 2026: Handles peakfitting columns with different size.
|
||||
%
|
||||
% T = outerjoinRowToTable(TableToAddTo,RowToBeAdded)
|
||||
%
|
||||
% tmpTableToBeAdded = table({tmpCombined(:,1)},{tmpCombined(:,2)},{'660eV, m50, 092022'},{'#288,#289,#290.ibw'}, ...
|
||||
% 'VariableNames',["bindingEnergy_eV","spectrum_countsNorm","sample","name"]);
|
||||
% SpectrumList = outerjoinRowToTable(SpectrumList,tmpTableToBeAdded);
|
||||
%
|
||||
% Thorsten, December 2023
|
||||
|
||||
% Original Table has more variables
|
||||
if ~all(ismember(Table.Properties.VariableNames,TableRowToBeAdded.Properties.VariableNames))
|
||||
tmpMissingVariable = ~ismember(Table.Properties.VariableNames,TableRowToBeAdded.Properties.VariableNames);
|
||||
tmpVariablesToBeAdded = Table.Properties.VariableNames(tmpMissingVariable);
|
||||
for ii = 1:size(tmpVariablesToBeAdded,2)
|
||||
if matches(class(Table.(tmpVariablesToBeAdded{ii})),'double') || matches(class(Table.(tmpVariablesToBeAdded{ii})),'int32')
|
||||
tmpContentToBeAdded = NaN(size(TableRowToBeAdded,1),size(Table.(tmpVariablesToBeAdded{ii}),2));
|
||||
TableRowToBeAdded = addvars(TableRowToBeAdded,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii});
|
||||
elseif matches(class(Table.(tmpVariablesToBeAdded{ii})),'cell')
|
||||
tmpContentToBeAdded = repmat({' '},size(TableRowToBeAdded,1),size(Table.(tmpVariablesToBeAdded{ii}),2));
|
||||
TableRowToBeAdded = addvars(TableRowToBeAdded,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii});
|
||||
elseif matches(class(Table.(tmpVariablesToBeAdded{ii})),'string')
|
||||
tmpContentToBeAdded = repmat({" "},size(TableRowToBeAdded,1),size(Table.(tmpVariablesToBeAdded{ii}),2));
|
||||
TableRowToBeAdded = addvars(TableRowToBeAdded,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii});
|
||||
end
|
||||
end
|
||||
end
|
||||
% Table to be added has more variables
|
||||
if ~all(ismember(TableRowToBeAdded.Properties.VariableNames,Table.Properties.VariableNames))
|
||||
tmpMissingVariable = ~ismember(TableRowToBeAdded.Properties.VariableNames,Table.Properties.VariableNames);
|
||||
tmpVariablesToBeAdded = TableRowToBeAdded.Properties.VariableNames(tmpMissingVariable);
|
||||
for ii = 1:size(tmpVariablesToBeAdded,2)
|
||||
if matches(class(TableRowToBeAdded.(tmpVariablesToBeAdded{ii})),'double') || matches(class(TableRowToBeAdded.(tmpVariablesToBeAdded{ii})),'int32')
|
||||
tmpContentToBeAdded = NaN(size(Table,1),size(TableRowToBeAdded.(tmpVariablesToBeAdded{ii}),2));
|
||||
Table = addvars(Table,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii});
|
||||
elseif matches(class(TableRowToBeAdded.(tmpVariablesToBeAdded{ii})),'cell')
|
||||
tmpContentToBeAdded = repmat({' '},size(Table,1),size(TableRowToBeAdded.(tmpVariablesToBeAdded{ii}),2));
|
||||
Table = addvars(Table,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii});
|
||||
elseif matches(class(TableRowToBeAdded.(tmpVariablesToBeAdded{ii})),'string')
|
||||
tmpContentToBeAdded = repmat({" "},size(Table,1),size(TableRowToBeAdded.(tmpVariablesToBeAdded{ii}),2));
|
||||
Table = addvars(Table,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii});
|
||||
end
|
||||
end
|
||||
end
|
||||
% Reconcile column widths for peak-fit columns.
|
||||
% These numeric columns can have variable width (one entry per peak),
|
||||
% so a width mismatch is expected when spectra have different numbers
|
||||
% of peaks. Pad the narrower side with NaN.
|
||||
variableWidthColumns = {'peakArea', 'peakPosition', 'peakFWHM', ...
|
||||
'peakBackground', 'peakEta', 'peakShirleyK'};
|
||||
|
||||
for ii = 1:numel(variableWidthColumns)
|
||||
varName = variableWidthColumns{ii};
|
||||
|
||||
if ~ismember(varName, Table.Properties.VariableNames) || ...
|
||||
~ismember(varName, TableRowToBeAdded.Properties.VariableNames)
|
||||
continue
|
||||
end
|
||||
|
||||
widthT = size(Table.(varName), 2);
|
||||
widthR = size(TableRowToBeAdded.(varName), 2);
|
||||
|
||||
if widthT < widthR
|
||||
Table.(varName) = [Table.(varName), ...
|
||||
NaN(height(Table), widthR - widthT)];
|
||||
elseif widthR < widthT
|
||||
TableRowToBeAdded.(varName) = [TableRowToBeAdded.(varName), ...
|
||||
NaN(height(TableRowToBeAdded), widthT - widthR)];
|
||||
end
|
||||
end
|
||||
|
||||
% Ensure matching column order before concatenation
|
||||
TableRowToBeAdded = TableRowToBeAdded(:, Table.Properties.VariableNames);
|
||||
% Add row to table
|
||||
Table = [Table;TableRowToBeAdded];
|
||||
end
|
||||
@@ -1,151 +0,0 @@
|
||||
function plotExportedData(dataDirectory)
|
||||
%plotExportedData Plot all exported ASCII data files in one figure
|
||||
%
|
||||
% This function reads all .txt files from the exported data (created by
|
||||
% exportFigureData) and plots them in a single figure for visual comparison.
|
||||
% File names are parsed to extract axis labels and legend entries.
|
||||
%
|
||||
% SYNTAX:
|
||||
% plotExportedData() % Uses current working directory
|
||||
% plotExportedData(dataDirectory) % Uses specified directory path
|
||||
%
|
||||
% INPUTS:
|
||||
% dataDirectory : char or string (optional)
|
||||
% Path to directory containing exported .txt files.
|
||||
% If omitted, uses current working directory (pwd).
|
||||
%
|
||||
% OUTPUT:
|
||||
% A new figure with all data plotted as lines. Axis labels and legend
|
||||
% entries are reconstructed from the file names.
|
||||
%
|
||||
% NOTES:
|
||||
% - Reads all .txt files in the specified directory
|
||||
% - File name format expected: <FigureTitle>_[<TileTitle>_]<YLabel>_vs_<XLabel>_<LineLabel>.txt
|
||||
% - Plots are created with underscores converted back to spaces for display
|
||||
% - X and Y axis labels are set based on parsed filename
|
||||
% - Legend shows line labels from filenames
|
||||
% - All data is plotted in a single axes for direct visual comparison
|
||||
%
|
||||
% EXAMPLE:
|
||||
% % After running exportFigureData():
|
||||
% plotExportedData()
|
||||
% % or
|
||||
% plotExportedData('../exported_data/')
|
||||
|
||||
% Handle input: use current directory if none provided
|
||||
if nargin == 0 || isempty(dataDirectory)
|
||||
dataDirectory = pwd;
|
||||
end
|
||||
|
||||
% Get all .txt files in the directory
|
||||
fileStruct = dir(fullfile(dataDirectory, '*.txt'));
|
||||
if isempty(fileStruct)
|
||||
warning('plotExportedData:NoFiles', 'No .txt files found in %s', dataDirectory);
|
||||
return;
|
||||
end
|
||||
|
||||
% Create a new figure
|
||||
fig = figure('Name', 'Exported Data Comparison', 'NumberTitle', 'off');
|
||||
ax = axes(fig);
|
||||
hold(ax, 'on');
|
||||
grid(ax, 'on');
|
||||
|
||||
% Storage for axis labels (to ensure consistency)
|
||||
xLabelStr = '';
|
||||
yLabelStr = '';
|
||||
legendEntries = {};
|
||||
|
||||
% Loop over all .txt files
|
||||
for ii = 1:length(fileStruct)
|
||||
fileName = fileStruct(ii).name;
|
||||
filePath = fullfile(dataDirectory, fileName);
|
||||
|
||||
% Read the data
|
||||
try
|
||||
data = readmatrix(filePath);
|
||||
catch ME
|
||||
warning('plotExportedData:ReadFailed', 'Could not read file: %s\n%s', fileName, ME.message);
|
||||
continue;
|
||||
end
|
||||
|
||||
% Check if data has at least 2 columns
|
||||
if size(data, 2) < 2 || size(data, 1) < 1
|
||||
warning('plotExportedData:InvalidData', 'File %s does not have valid X,Y columns', fileName);
|
||||
continue;
|
||||
end
|
||||
|
||||
xData = data(:, 1);
|
||||
yData = data(:, 2);
|
||||
|
||||
% Parse filename to extract labels
|
||||
% Expected format: <FigureTitle>_[<TileTitle>_]<YLabel>_vs_<XLabel>_<LineLabel>.txt
|
||||
|
||||
% Remove .txt extension
|
||||
nameNoExt = fileName(1:end-4);
|
||||
|
||||
% Split by '_vs_' to separate y-axis label from the rest
|
||||
parts = strsplit(nameNoExt, '_vs_');
|
||||
|
||||
if length(parts) >= 2
|
||||
% Extract line label (after _vs_<XLabel>_)
|
||||
rightPart = parts{2}; % <XLabel>_<LineLabel>
|
||||
|
||||
% Find the last underscore to separate XLabel from LineLabel
|
||||
underscores = find(rightPart == '_');
|
||||
if ~isempty(underscores)
|
||||
lastUnderscore = underscores(end);
|
||||
xLabelExtracted = rightPart(1:lastUnderscore-1);
|
||||
lineLabel = rightPart(lastUnderscore+1:end);
|
||||
else
|
||||
xLabelExtracted = rightPart;
|
||||
lineLabel = 'data';
|
||||
end
|
||||
|
||||
% Extract y-axis label (before _vs_)
|
||||
yLabelExtracted = parts{1};
|
||||
|
||||
% Remove figure title (first part before first underscore)
|
||||
% This is tricky, so we'll keep what we have and note it's approximate
|
||||
|
||||
% Convert underscores back to spaces for display
|
||||
xLabelDisplay = strrep(xLabelExtracted, '_', ' ');
|
||||
yLabelDisplay = strrep(yLabelExtracted, '_', ' ');
|
||||
lineLabel = strrep(lineLabel, '_', ' ');
|
||||
|
||||
% Store axis labels (use the first valid ones found)
|
||||
if isempty(xLabelStr)
|
||||
xLabelStr = xLabelDisplay;
|
||||
end
|
||||
if isempty(yLabelStr)
|
||||
yLabelStr = yLabelDisplay;
|
||||
end
|
||||
|
||||
else
|
||||
% Fallback if filename parsing fails
|
||||
lineLabel = nameNoExt;
|
||||
end
|
||||
|
||||
% Plot the data
|
||||
plot(ax, xData, yData, 'DisplayName', lineLabel, 'LineWidth', 1.5, 'Marker', 'o', 'MarkerSize', 4);
|
||||
|
||||
% Store legend entry
|
||||
legendEntries{end+1} = lineLabel;
|
||||
end
|
||||
|
||||
% Set axis labels
|
||||
xlabel(ax, xLabelStr, 'Interpreter', 'none');
|
||||
ylabel(ax, yLabelStr, 'Interpreter', 'none');
|
||||
title(ax, 'Exported Data Comparison', 'Interpreter', 'none');
|
||||
|
||||
% Add legend
|
||||
if ~isempty(legendEntries)
|
||||
legend(ax, legendEntries, 'Interpreter', 'none', 'Location', 'best');
|
||||
end
|
||||
|
||||
% Optimize figure appearance
|
||||
grid(ax, 'on');
|
||||
hold(ax, 'off');
|
||||
|
||||
fprintf('Plotted %d data files from: %s\n', length(fileStruct), dataDirectory);
|
||||
|
||||
end
|
||||
@@ -1,75 +0,0 @@
|
||||
function map = preset_colormap(N,varargin)
|
||||
% Wrapper for any COLORMAP function, to provide preset parameter values.
|
||||
%
|
||||
% (c) 2020-2025 Stephen Cobeldick
|
||||
%
|
||||
%%% Syntax %%%
|
||||
%
|
||||
% preset_colormap(@fun,p1,p2,...,pN) % store function with any parameters
|
||||
% map = preset_colormap(N) % generate colormap
|
||||
% map = preset_colormap % generate colormap
|
||||
%
|
||||
%% Examples %%
|
||||
%
|
||||
% >> preset_colormap(@cubehelix,0.25,-0.67,1.5,1)
|
||||
% >> colormap(preset_colormap)
|
||||
%
|
||||
% >> preset_colormap(5)
|
||||
% ans =
|
||||
% 0 0 0
|
||||
% 0.1055 0.2788 0.4895
|
||||
% 0.1660 0.6705 0.4961
|
||||
% 0.6463 0.8479 0.5076
|
||||
% 1.0000 1.0000 1.0000
|
||||
%
|
||||
% >> preset_colormap(@brewermap,'PuOr')
|
||||
% >> load topo
|
||||
% >> load coast
|
||||
% >> figure
|
||||
% >> worldmap(topo, topolegend)
|
||||
% >> contourfm(topo, topolegend);
|
||||
% >> contourcmap('preset_colormap', 'Colorbar','on', 'Location','horizontal','TitleString','Contour Intervals in Meters');
|
||||
% >> plotm(lat, long, 'k')
|
||||
%
|
||||
%% Dependencies %%
|
||||
%
|
||||
% * MATLAB R2009a or later.
|
||||
%
|
||||
% See also BREWERMAP CUBEHELIX CMOCEAN LBMAP COLORMAP CONTOURCMAP
|
||||
persistent fnh arg
|
||||
%
|
||||
if nargin==0 % Default N same as MATLAB colormaps.
|
||||
N = cmDefaultN();
|
||||
elseif nargin==1 && isnumeric(N)
|
||||
assert(isscalar(N) && isreal(N) && fix(N)==N,...
|
||||
'SC:preset_colormap:N:NotRealScalarNumeric',...
|
||||
'First input <N> must be a real scalar numeric of the colormap size.')
|
||||
N = double(N);
|
||||
else % Store function handle and parameter values.
|
||||
assert(isa(N,'function_handle'),...
|
||||
'SC:preset_colormap:N:NotFunctionHandle',...
|
||||
'First input <N> must be a function handle to a colormap function.')
|
||||
fnh = N;
|
||||
arg = varargin;
|
||||
return
|
||||
end
|
||||
%
|
||||
map = fnh(N,arg{:});
|
||||
%
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%preset_colormap
|
||||
function N = cmDefaultN()
|
||||
% Get the colormap size from the current figure or default colormap.
|
||||
try
|
||||
F = get(groot,'CurrentFigure');
|
||||
catch %#ok<CTCH> pre HG2
|
||||
N = size(get(gcf,'colormap'),1);
|
||||
return
|
||||
end
|
||||
if isempty(F)
|
||||
N = size(get(groot,'DefaultFigureColormap'),1);
|
||||
else
|
||||
N = size(F.Colormap,1);
|
||||
end
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%cmDefaultN
|
||||
@@ -1,52 +0,0 @@
|
||||
function H = readIBWbinheader(FFN);
|
||||
% readIBWbinheader - read BinHeader segment of Igor IBW file
|
||||
% H = readIBWbinheader('foo') reads BinHeader of file Foo.ibw
|
||||
% IBW version 2,5 only
|
||||
MAXDIMS = 4;
|
||||
|
||||
fid = fopen(FFN,'r');
|
||||
H.version = fread(fid,1,'int16');
|
||||
switch H.version,
|
||||
case 2, % typedef struct BinHeader2 {
|
||||
H.wfmSize = fread(fid,1,'uint32'); % long wfmSize; // The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding.
|
||||
H.noteSize = fread(fid,1,'uint32'); % long noteSize; // The size of the note text.
|
||||
H.pictSize = fread(fid,1,'uint32'); % long pictSize; // Reserved. Write zero. Ignore on read.
|
||||
H.checksum = fread(fid,1,'int16'); % short checksum; // Checksum over this header and the wave header.
|
||||
case 5,
|
||||
H.checksum = fread(fid,1,'short');
|
||||
H.wfmSize = fread(fid,1,'long'); % The size of the WaveHeader5 data structure plus the wave data.
|
||||
H.formulaSize = fread(fid,1,'long'); % The size of the dependency formula, if any.
|
||||
H.noteSize = fread(fid,1,'long'); % The size of the note text.
|
||||
H.dataEUnitsSize = fread(fid,1,'long'); % The size of optional extended data units.
|
||||
H.dimEUnitsSize = fread(fid,MAXDIMS,'long'); % The size of optional extended dimension units.
|
||||
H.dimLabelsSize = fread(fid,MAXDIMS,'long'); % The size of optional dimension labels.
|
||||
H.sIndicesSize = fread(fid,1,'long'); ; % The size of string indicies if this is a text wave.
|
||||
H.optionsSize1 = fread(fid,1,'long'); ; % Reserved. Write zero. Ignore on read.
|
||||
H.optionsSize2 = fread(fid,1,'long'); ; % Reserved. Write zero. Ignore on read.
|
||||
otherwise,
|
||||
end % switch H.Version
|
||||
fclose(fid);
|
||||
|
||||
if ~ismember(H.version,[2 5]),
|
||||
error(['Cannot read version ' num2str(H.version) ' IBW files - only versions 2,5 are okay.']);
|
||||
end
|
||||
%==FROM IgorBin.h =====================
|
||||
% #define MAXDIMS 4
|
||||
%
|
||||
% typedef struct BinHeader5 {
|
||||
% short version; // Version number for backwards compatibility.
|
||||
% short checksum; // Checksum over this header and the wave header.
|
||||
% long wfmSize; // The size of the WaveHeader5 data structure plus the wave data.
|
||||
% long formulaSize; // The size of the dependency formula, if any.
|
||||
% long noteSize; // The size of the note text.
|
||||
% long dataEUnitsSize; // The size of optional extended data units.
|
||||
% long dimEUnitsSize[MAXDIMS]; // The size of optional extended dimension units.
|
||||
% long dimLabelsSize[MAXDIMS]; // The size of optional dimension labels.
|
||||
% long sIndicesSize; // The size of string indicies if this is a text wave.
|
||||
% long optionsSize1; // Reserved. Write zero. Ignore on read.
|
||||
% long optionsSize2; // Reserved. Write zero. Ignore on read.
|
||||
% } BinHeader5;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
function [BH, H, FFN] = readIBWheaders(FFN);
|
||||
% readIBWheaders - read BinHeader & WaveHeader segments of Igor IBW file
|
||||
% [BH, WH, FFN] = readIBWheaders('foo') reads BinHeader & WaveHeader of
|
||||
% file Foo.ibw - Versions 2 and 5 only. FFN is full filename.
|
||||
|
||||
% % 1 byte char
|
||||
% % 2 bytes short
|
||||
% % 4 bytes int, long, float, Handle, any kind of pointer
|
||||
% % 8 bytes double
|
||||
MAXDIMS = 4;
|
||||
MAX_WAVE_NAME2 = 18; % Maximum length of wave name in version 1 and 2 files. Does not include the trailing null.
|
||||
MAX_WAVE_NAME5 = 31; % Maximum length of wave name in version 5 files. Does not include the trailing null.
|
||||
MAX_UNIT_CHARS = 3;
|
||||
|
||||
|
||||
BH = readIBWbinheader(FFN);
|
||||
fid = fopen(FFN,'r');
|
||||
switch BH.version
|
||||
case 2,
|
||||
% The version 2 file has the following general layout.
|
||||
% BinHeader2 structure: 16 bytes
|
||||
% WaveHeader2 structure excluding wData field; 110 bytes
|
||||
% Wave data: Variable size
|
||||
fseek(fid,16,'bof'); % start of wave header of IBW vs 2; % struct WaveHeader2 {
|
||||
H.type = fread(fid,1, 'uint16'); % short type; % See types (e.g. NT_FP64) above. Zero for text waves.
|
||||
H.WaveHeader2 = fread(fid,1, 'uint32'); % struct WaveHeader2 **next; // Used in memory only. Write zero. Ignore on read.
|
||||
H.bname = local_char(fread(fid, MAX_WAVE_NAME2+2, 'char')); % char bname[MAX_WAVE_NAME2+2]; // Name of wave plus trailing null.
|
||||
H.whVersion = fread(fid,1, 'uint16'); % short whVersion; // Write 0. Ignore on read.
|
||||
H.srcFldr = fread(fid,1, 'uint16'); % short srcFldr; // Used in memory only. Write zero. Ignore on read.
|
||||
H.fileName = fread(fid,1, 'uint32'); % Handle fileName; // Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
H.dataUnits = local_char(fread(fid, MAX_UNIT_CHARS+1, 'char')); % char dataUnits[MAX_UNIT_CHARS+1]; // Natural data units go here - null if none.
|
||||
H.xUnits = local_char(fread(fid, MAX_UNIT_CHARS+1, 'char')); % char xUnits[MAX_UNIT_CHARS+1]; // Natural x-axis units go here - null if none.
|
||||
%
|
||||
H.npnts = fread(fid,1, 'uint32'); % long npnts; // Number of data points in wave.
|
||||
%
|
||||
H.aModified = fread(fid,1, 'uint16'); % short aModified; // Used in memory only. Write zero. Ignore on read.
|
||||
H.hsA = fread(fid,1, 'double'); % double hsA,hsB; // X value for point p = hsA*p + hsB
|
||||
H.hsB = fread(fid,1, 'double'); % double hsA,hsB; // X value for point p = hsA*p + hsB
|
||||
%
|
||||
H.wModified = fread(fid,1, 'uint16'); % short wModified; // Used in memory only. Write zero. Ignore on read.
|
||||
H.swModified = fread(fid,1, 'uint16'); % short swModified; // Used in memory only. Write zero. Ignore on read.
|
||||
H.fsValid = fread(fid,1, 'uint16'); % short fsValid; // True if full scale values have meaning.
|
||||
H.topFullScale = fread(fid,1, 'double'); % double topFullScale,botFullScale; // The min full scale value for wave.
|
||||
H.botFullScale = fread(fid,1, 'double'); % double topFullScale,botFullScale; // The min full scale value for wave.
|
||||
%
|
||||
H.useBits = fread(fid,1, 'char'); % char useBits; // Used in memory only. Write zero. Ignore on read.
|
||||
H.kindBits = fread(fid,1, 'char'); % char kindBits; // Reserved. Write zero. Ignore on read.
|
||||
H.formula = fread(fid,1, 'uint32'); % void **formula; // Used in memory only. Write zero. Ignore on read.
|
||||
H.depID = fread(fid,1, 'uint32'); % long depID; // Used in memory only. Write zero. Ignore on read.
|
||||
H.creationDate = fread(fid,1, '*uint32'); % unsigned long creationDate; // DateTime of creation. Not used in version 1 files.
|
||||
H.platform = fread(fid,1, 'uint8'); % unsigned char platform; // 0=unspecified, 1=Macintosh, 2=Windows; Added for Igor Pro 5.5.
|
||||
% dummy = fread(fid,1, 'uint8'); % align
|
||||
H.wUnused = fread(fid,1, 'uint8'); % char wUnused[1]; // Reserved. Write zero. Ignore on read.
|
||||
%
|
||||
H.modDate = fread(fid,1, '*uint32'); % unsigned long modDate; // DateTime of last modification.
|
||||
H.waveNoteH = fread(fid,1, 'uint32'); % Handle waveNoteH; // Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
H.wData = fread(fid,4, 'single').'; % float wData[4]; // The start of the array of waveform data.
|
||||
case 5,
|
||||
% The version 5 file has the following general layout.
|
||||
% BinHeader5 structure: 64 bytes
|
||||
% WaveHeader5 structure excluding wData field: 320 bytes
|
||||
% Wave data: Variable size
|
||||
fseek(fid,64,'bof'); % start of wave header of IBW vs 5
|
||||
%
|
||||
H.next = fread(fid,1, 'int32'); % link to next wave in linked list.
|
||||
%
|
||||
H.creationDate = fread(fid,1, 'uint32'); % DateTime of creation.
|
||||
H.modDate = fread(fid,1, 'uint32'); % DateTime of creation.
|
||||
%
|
||||
H.npnts = fread(fid,1, 'int32'); % Total number of points (multiply dimensions up to first zero).
|
||||
H.type = fread(fid,1, 'uint16'); % See types (e.g. NT_FP64) above. Zero for text waves.
|
||||
H.dLock = fread(fid, 1, 'int16'); % Reserved. Write zero. Ignore on read.
|
||||
%
|
||||
H.whpad1 = fread(fid, 6, 'char').'; % Reserved. Write zero. Ignore on read.
|
||||
H.whVersion = fread(fid, 1, 'int16'); % Write 1. Ignore on read.
|
||||
H.bname = local_char(fread(fid, MAX_WAVE_NAME5+1, 'char')); % Name of wave plus trailing null.
|
||||
H.whpad2 = fread(fid, 1, 'int32'); % long Reserved. Write zero. Ignore on read.
|
||||
H.dFolder = fread(fid, 1, 'int32'); % ptr Used in memory only. Write zero. Ignore on read.
|
||||
|
||||
% % Dimensioning info. [0] == rows, [1] == cols etc
|
||||
H.nDim = fread(fid, MAXDIMS, 'int32').'; % long nDim[MAXDIMS] Number of of items in a dimension -- 0 means no data.
|
||||
H.sfA = fread(fid, MAXDIMS, 'double').'; % double sfA[MAXDIMS]; Index value for element e of dimension d = sfA[d]*e + sfB[d].
|
||||
H.sfB = fread(fid, MAXDIMS, 'double').'; % double sfB[MAXDIMS];% double sfB[MAXDIMS];
|
||||
% %
|
||||
% % % SI units
|
||||
H.dataUnits = local_char(fread(fid, MAX_UNIT_CHARS+1, 'char')); % char dataUnits[MAX_UNIT_CHARS+1]; % Natural data units go here - null if none.
|
||||
H.dimUnits = fread(fid, MAXDIMS*(MAX_UNIT_CHARS+1), '*char').'; % % char dimUnits[MAXDIMS][MAX_UNIT_CHARS+1]; % Natural dimension units go here - null if none.
|
||||
% %
|
||||
H.fsValid = fread(fid, 1, 'uint16'); % % short fsValid; % TRUE if full scale values have meaning.
|
||||
H.whpad3 = fread(fid, 1, 'int16'); % % short whpad3; % Reserved. Write zero. Ignore on read.
|
||||
H.topFullScale = fread(fid, 1, 'double');
|
||||
H.botFullScale = fread(fid, 1, 'double'); % % double topFullScale,botFullScale; % The max and max full scale value for wave.
|
||||
% %
|
||||
H.dataEUnits = fread(fid, 1, 'int32'); % % Handle dataEUnits; % Used in memory only. Write zero. Ignore on read.
|
||||
H.dimEUnits = fread(fid, MAXDIMS, 'int32').'; % % Handle dimEUnits[MAXDIMS]; % Used in memory only. Write zero. Ignore on read.
|
||||
H.dimLabels = fread(fid, MAXDIMS, 'int32').'; % % Handle dimLabels[MAXDIMS]; % Used in memory only. Write zero. Ignore on read.
|
||||
% %
|
||||
H.waveNoteH = fread(fid, 1, 'int32'); % % Handle waveNoteH; % Used in memory only. Write zero. Ignore on read.
|
||||
% %
|
||||
H.platform = fread(fid, 1, 'uint8'); % % unsigned char platform; % 0=unspecified, 1=Macintosh, 2=Windows; Added for Igor Pro 5.
|
||||
H.skip_junk________ = fread(fid,80,'char').';
|
||||
% H. = fread(fid, 1, '');
|
||||
% % unsigned char spare[3];
|
||||
% H. = fread(fid, 1, '');
|
||||
% %
|
||||
% H. = fread(fid, 1, '');
|
||||
% % long whUnused[13]; % Reserved. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% %
|
||||
% H. = fread(fid, 1, '');
|
||||
% % long vRefNum, dirID; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% %
|
||||
% H. = fread(fid, 1, '');
|
||||
% % % The following stuff is considered private to Igor.
|
||||
% H. = fread(fid, 1, '');
|
||||
% %
|
||||
% H. = fread(fid, 1, '');
|
||||
% % short aModified; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% % short wModified; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% % short swModified; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% %
|
||||
% H. = fread(fid, 1, '');
|
||||
% % char useBits; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% % char kindBits; % Reserved. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% % void **formula; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% % long depID; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% %
|
||||
% H. = fread(fid, 1, '');
|
||||
% % short whpad4; % Reserved. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% % short srcFldr; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% % Handle fileName; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% %
|
||||
% H. = fread(fid, 1, '');
|
||||
% % long **sIndices; % Used in memory only. Write zero. Ignore on read.
|
||||
% H. = fread(fid, 1, '');
|
||||
% %
|
||||
H.wData = fread(fid, 1, 'single');
|
||||
% % float wData[1]; % The start of the array of data. Must be 64 bit aligned.
|
||||
% H. = fread(fid, 1, '');
|
||||
% };
|
||||
end % switch BH.version
|
||||
H.EOH_pos = ftell(fid);
|
||||
|
||||
|
||||
|
||||
|
||||
fclose(fid);
|
||||
|
||||
%==FROM IgorBin.h =====================
|
||||
% #define MAXDIMS 4
|
||||
|
||||
% % #define MAX_WAVE_NAME5 31 // Maximum length of wave name in version 5 files. Does not include the trailing null.
|
||||
% % #define MAX_UNIT_CHARS 3
|
||||
|
||||
% % #define NT_CMPLX 1 % Complex numbers.
|
||||
% % #define NT_FP32 2 % 32 bit fp numbers.
|
||||
% % #define NT_FP64 4 % 64 bit fp numbers.
|
||||
% % #define NT_I8 8 % 8 bit signed integer. Requires Igor Pro 2.0 or later.
|
||||
% % #define NT_I16 0x10 % 16 bit integer numbers. Requires Igor Pro 2.0 or later.
|
||||
% % #define NT_I32 0x20 % 32 bit integer numbers. Requires Igor Pro 2.0 or later.
|
||||
% % #define NT_UNSIGNED 0x40 % Makes above signed integers unsigned. Requires Igor Pro 3.0 or later.
|
||||
%
|
||||
% struct WaveHeader5 {
|
||||
% struct WaveHeader5 **next; % link to next wave in linked list.
|
||||
%
|
||||
% unsigned long creationDate; % DateTime of creation.
|
||||
% unsigned long modDate; % DateTime of last modification.
|
||||
%
|
||||
% long npnts; % Total number of points (multiply dimensions up to first zero).
|
||||
% short type; % See types (e.g. NT_FP64) above. Zero for text waves.
|
||||
% short dLock; % Reserved. Write zero. Ignore on read.
|
||||
%
|
||||
% char whpad1[6]; % Reserved. Write zero. Ignore on read.
|
||||
% short whVersion; % Write 1. Ignore on read.
|
||||
% char bname[MAX_WAVE_NAME5+1]; % Name of wave plus trailing null.
|
||||
% long whpad2; % Reserved. Write zero. Ignore on read.
|
||||
% struct DataFolder **dFolder; % Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
% % Dimensioning info. [0] == rows, [1] == cols etc
|
||||
% long nDim[MAXDIMS]; % Number of of items in a dimension -- 0 means no data.
|
||||
% double sfA[MAXDIMS]; % Index value for element e of dimension d = sfA[d]*e + sfB[d].
|
||||
% double sfB[MAXDIMS];
|
||||
%
|
||||
% % SI units
|
||||
% char dataUnits[MAX_UNIT_CHARS+1]; % Natural data units go here - null if none.
|
||||
% char dimUnits[MAXDIMS][MAX_UNIT_CHARS+1]; % Natural dimension units go here - null if none.
|
||||
%
|
||||
% short fsValid; % TRUE if full scale values have meaning.
|
||||
% short whpad3; % Reserved. Write zero. Ignore on read.
|
||||
% double topFullScale,botFullScale; % The max and max full scale value for wave.
|
||||
%
|
||||
% Handle dataEUnits; % Used in memory only. Write zero. Ignore on read.
|
||||
% Handle dimEUnits[MAXDIMS]; % Used in memory only. Write zero. Ignore on read.
|
||||
% Handle dimLabels[MAXDIMS]; % Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
% Handle waveNoteH; % Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
% unsigned char platform; % 0=unspecified, 1=Macintosh, 2=Windows; Added for Igor Pro 5.5.
|
||||
% unsigned char spare[3];
|
||||
%
|
||||
% long whUnused[13]; % Reserved. Write zero. Ignore on read.
|
||||
%
|
||||
% long vRefNum, dirID; % Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
% % The following stuff is considered private to Igor.
|
||||
%
|
||||
% short aModified; % Used in memory only. Write zero. Ignore on read.
|
||||
% short wModified; % Used in memory only. Write zero. Ignore on read.
|
||||
% short swModified; % Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
% char useBits; % Used in memory only. Write zero. Ignore on read.
|
||||
% char kindBits; % Reserved. Write zero. Ignore on read.
|
||||
% void **formula; % Used in memory only. Write zero. Ignore on read.
|
||||
% long depID; % Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
% short whpad4; % Reserved. Write zero. Ignore on read.
|
||||
% short srcFldr; % Used in memory only. Write zero. Ignore on read.
|
||||
% Handle fileName; % Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
% long **sIndices; % Used in memory only. Write zero. Ignore on read.
|
||||
%
|
||||
% float wData[1]; % The start of the array of data. Must be 64 bit aligned.
|
||||
% };
|
||||
|
||||
function s=local_char(S);
|
||||
% null-terminated string -> char string
|
||||
S = S(:).';
|
||||
S = S(S~=0);
|
||||
s=char(S);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
function output_table = read_hdf5_as_table(filename,exclude_var_set)
|
||||
% receives a h5 file written with function table2h5.
|
||||
% reduced_var_set (cell of character_vectors), not usable yet.
|
||||
|
||||
|
||||
% Last update: 14.08.2023
|
||||
% By: Juan F. Florez Ospina
|
||||
% Email: juan.florez-ospina@psi.ch
|
||||
|
||||
if ~iscellstr(exclude_var_set)
|
||||
disp("exclude_var_set needs to be a cell of character vectors, e.g, {'var1','var2'} to be excluded.")
|
||||
disp("To proceed, exclude_var_set was set to {}. So vars will be excluded.")
|
||||
exclude_var_set = {};
|
||||
end
|
||||
|
||||
INFO = h5info(filename);
|
||||
num_rows = length(INFO.Groups);
|
||||
|
||||
|
||||
num_attr1 = length(INFO.Groups(1).Datasets);
|
||||
num_attr2 = length(INFO.Groups(1).Attributes);
|
||||
num_cols = num_attr1 + num_attr2;
|
||||
sz = [num_rows,num_cols];
|
||||
|
||||
% Extract group level attributes, they align for all
|
||||
% groups (here denoting measurements/or rows) of the table in filename .h5
|
||||
group_columns = {INFO.Groups(1).Attributes.Name};
|
||||
|
||||
if num_attr1 == 1 && isempty(INFO.Groups(1).Datasets(num_attr1).Attributes)
|
||||
dataset_columns = {};
|
||||
num_attr1 = 0;
|
||||
num_cols = num_cols - 1;
|
||||
else
|
||||
for j = 1 : num_attr1
|
||||
dataset_columns{j} = INFO.Groups(1).Datasets(j).Attributes.Value;
|
||||
end
|
||||
end
|
||||
%TODO: Implement feature to exclude varibales/columns as well as rows at
|
||||
%reading time. This requires propagating modifications
|
||||
% % % Select group and dataset columns to be loaded from hdf5 file, which are
|
||||
% % % those not in the exclude_var_set.
|
||||
% % if ~isempty(exclude_var_set)
|
||||
% % for j = 1 : length(exclude_var_set)
|
||||
% % % keep all vars except exclude_var_set{j}
|
||||
% % var_filter = ~strcmp(exclude_var_set{j},group_columns);
|
||||
% % group_columns = group_columns(var_filter);
|
||||
% % if sum(var_filter) > 0
|
||||
% % exclude_var_set(j) = [];
|
||||
% % end
|
||||
% % end
|
||||
% %
|
||||
% % for j = 1 : length(exclude_var_set)
|
||||
% % % keep all vars except exclude_var_set{j}
|
||||
% % var_filter = ~strcmp(exclude_var_set{j},dataset_columns);
|
||||
% % dataset_columns = dataset_columns(var_filter);
|
||||
% % if sum(var_filter) > 0
|
||||
% % exclude_var_set(j) = [];
|
||||
% % end
|
||||
% % end
|
||||
% % end
|
||||
|
||||
|
||||
% Construct cell array with table data, where each row denotes a group, and
|
||||
% the columns are either datasets or attributes in the given group.
|
||||
tmp = cell(num_rows,num_cols); % {};
|
||||
idx = [];
|
||||
group_columns = {};
|
||||
for i = 1 : num_rows
|
||||
disp(['Begin construction of row:',INFO.Groups(i).Name])
|
||||
|
||||
for j = 1 : num_cols
|
||||
if j <= num_attr1
|
||||
ds_name = [INFO.Groups(i).Name '/' INFO.Groups(i).Datasets(j).Name];
|
||||
|
||||
%disp(ds_name)
|
||||
tmp{i,j} = h5read(filename,ds_name);
|
||||
if i < 2
|
||||
column_idx = str2double(INFO.Groups(i).Datasets(j).Name(3:end));
|
||||
idx = [idx,column_idx];
|
||||
end
|
||||
end
|
||||
if j > num_attr1
|
||||
Name = INFO.Groups(i).Attributes(j-num_attr1).Name;
|
||||
Datatype = INFO.Groups(i).Attributes(j-num_attr1).Datatype.Class;
|
||||
|
||||
% Detect string attributes and convert them to characters.
|
||||
% TODO: extend to other necessary data types.
|
||||
if strcmp(Datatype,'H5T_STRING')
|
||||
convert_func = @(x) convertStringsToChars(x);
|
||||
else % no data type conversion is performed
|
||||
convert_func = @(x) x;
|
||||
end
|
||||
|
||||
tmp{i,j} = convert_func(h5readatt(filename,INFO.Groups(i).Name, Name));
|
||||
if i < 2
|
||||
|
||||
disp(Name)
|
||||
% Split attribute name into column_tag (containing original
|
||||
% column idx) and column_name
|
||||
|
||||
delimiter_idx = find(INFO.Groups(i).Attributes(j-num_attr1).Name=='_');
|
||||
% Left most '_' determines the split location
|
||||
delimiter_idx = delimiter_idx(1);
|
||||
|
||||
column_idx = str2double(Name(5:delimiter_idx-1));
|
||||
group_columns = [group_columns,{Name(delimiter_idx+1:end)}];
|
||||
%disp([Name(5:delimiter_idx-1),'-',column_name])
|
||||
idx = [idx,column_idx];
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
disp(['Ends construction of row:',INFO.Groups(i).Name])
|
||||
|
||||
end
|
||||
|
||||
% Find original ordering of columns by sorting idx in ascending order
|
||||
[~, idx_perm] = sort(idx,'ascend');
|
||||
|
||||
varNames = [dataset_columns,group_columns];
|
||||
|
||||
% Create output_table from cell array using cell2table. This as opposed to
|
||||
% array2table extract the content of its cells, which facilitates filtering
|
||||
% operations based on table columns/vars.
|
||||
|
||||
%output_table = array2table(tmp(:,idx_perm), 'VariableNames', varNames(idx_perm));
|
||||
output_table = cell2table(tmp(:,idx_perm), 'VariableNames', varNames(idx_perm));
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
function tbl = rgaImportData(fullFileName)
|
||||
%RGAIMPORTDATA Import an SRS RGA "Pressure vs Time" scan (.txt) into a table.
|
||||
%
|
||||
% tbl = rgaImportData(fullFileName) reads an RGA ASCII log and returns a
|
||||
% table ready for plotRgaData, with:
|
||||
% datetime - absolute time (start time + Time(s))
|
||||
% time_s - elapsed scan time in seconds
|
||||
% one column per active channel, named <Name>_m<mass> (e.g. Water_m18),
|
||||
% holding the partial pressure in the file's units (usually Torr).
|
||||
%
|
||||
% The scan units and channel metadata are stored in
|
||||
% tbl.Properties.VariableUnits and tbl.Properties.UserData.
|
||||
%
|
||||
% Two quirks of this file format are handled:
|
||||
% * multi-word species names in the channel table (e.g. "Carbn dio")
|
||||
% * adjacent negative values in the data run together with no space
|
||||
% (e.g. "-2.8663e-010-2.3529e-010"); values are recovered by matching
|
||||
% scientific-notation tokens rather than by splitting on whitespace.
|
||||
%
|
||||
% EXAMPLE
|
||||
% tbl = rgaImportData('rga1_Jul_01_2026_08-23-06_AM.txt');
|
||||
% ax = plotRgaData(tbl);
|
||||
%
|
||||
% See also PLOTRGADATA, PLOTCRYODATA
|
||||
|
||||
lines = readlines(fullFileName); % string array, keeps blanks
|
||||
|
||||
%--- Locate the data block header "Time(s) Channel#1 ..." ---
|
||||
iData = find(startsWith(strip(lines),'Time(s)'), 1);
|
||||
if isempty(iData)
|
||||
error('rgaImportData:noData','Could not find the "Time(s)" data header.');
|
||||
end
|
||||
header = lines(1:iData-1); % metadata + channel table
|
||||
|
||||
%--- Start time (absolute) ---
|
||||
iStart = find(startsWith(strip(header),'Start time,'), 1);
|
||||
if isempty(iStart)
|
||||
startStr = strip(header(1)); % fall back to first line
|
||||
else
|
||||
startStr = strip(extractAfter(header(iStart),','));
|
||||
end
|
||||
startStr = regexprep(startStr,'\s+',' '); % collapse the double space
|
||||
startTime = datetime(startStr, ...
|
||||
'InputFormat','MMM d, yyyy h:mm:ss a', 'Locale','en_US');
|
||||
|
||||
%--- Units ---
|
||||
units = 'a.u.';
|
||||
iu = find(startsWith(strip(header),'Units,'), 1);
|
||||
if ~isempty(iu)
|
||||
p = strip(split(header(iu),','));
|
||||
units = char(p(end));
|
||||
end
|
||||
|
||||
%--- Channel definitions (e.g. "1 28.00 Nitrogen 1.00 3 OFF") ---
|
||||
chanPat = '^\s*(\d+)\s+([\d.]+)\s+(.+?)\s+[\d.]+\s+\d+\s+\w+\s*$';
|
||||
tok = regexp(header, chanPat, 'tokens', 'once');
|
||||
tok = tok(~cellfun(@isempty, tok));
|
||||
nCh = numel(tok);
|
||||
if nCh == 0
|
||||
error('rgaImportData:noChannels','No channel definitions found.');
|
||||
end
|
||||
chMass = zeros(nCh,1); chName = strings(nCh,1);
|
||||
for k = 1:nCh
|
||||
chMass(k) = str2double(tok{k}{2});
|
||||
chName(k) = strip(string(tok{k}{3}));
|
||||
end
|
||||
|
||||
%--- Data: time before the comma + N scientific-notation values ---
|
||||
dataLines = lines(iData+1:end);
|
||||
dataLines = dataLines(strlength(strip(dataLines)) > 0);
|
||||
n = numel(dataLines);
|
||||
|
||||
time_s = str2double(extractBefore(dataLines, ','));
|
||||
matches = regexp(dataLines, '[-+]?\d+\.\d+[eE][-+]?\d+', 'match');
|
||||
|
||||
vals = nan(n, nCh);
|
||||
for r = 1:n
|
||||
v = str2double(matches{r});
|
||||
nn = min(numel(v), nCh);
|
||||
vals(r,1:nn) = v(1:nn);
|
||||
end
|
||||
|
||||
%--- Assemble table ---
|
||||
dt = startTime + seconds(time_s);
|
||||
varNames = arrayfun(@(k) matlab.lang.makeValidName( ...
|
||||
sprintf('%s_m%d', chName(k), round(chMass(k)))), 1:nCh, 'UniformOutput', false);
|
||||
|
||||
tbl = table(dt, time_s, 'VariableNames', {'datetime','time_s'});
|
||||
for k = 1:nCh
|
||||
tbl.(varNames{k}) = vals(:,k);
|
||||
end
|
||||
|
||||
tbl.Properties.VariableUnits = [{'', 's'}, repmat({char(units)}, 1, nCh)];
|
||||
tbl.Properties.UserData = struct( ...
|
||||
'units', char(units), 'startTime', startTime, ...
|
||||
'channelName', chName, 'channelMass', chMass);
|
||||
end
|
||||
@@ -1,155 +0,0 @@
|
||||
function success = save_table_as_hdf5(input_table, filename)
|
||||
|
||||
% This function takes input_table (of table type), structured with
|
||||
% Thorsten's FileTable format, and stores it as .h5 file with name
|
||||
% filename. Each row is treated as a group, where columns can be attributes
|
||||
% of the group or datasets inside the group.
|
||||
|
||||
% Last update: 11.08.2023
|
||||
% By: Juan F. Florez Ospina
|
||||
% Email: juan.florez-ospina@psi.ch
|
||||
|
||||
if istable(input_table)
|
||||
|
||||
string_columns = input_table(:,vartype("string")).Properties.VariableNames;
|
||||
input_table = convertvars(input_table,string_columns,'cellstr');
|
||||
% split multicolumn variables
|
||||
input_table = splitvars(input_table);
|
||||
column_names = input_table.Properties.VariableNames;
|
||||
else
|
||||
success = 0;
|
||||
return
|
||||
end
|
||||
|
||||
% Create array with indices of column_names
|
||||
column_names_idx = 1 : length(column_names);
|
||||
|
||||
% Divide input_table into tables with numeric and cellstr variables/columns
|
||||
numeric_table = input_table(:,vartype('numeric')); % group attributes of a timestamped measurement
|
||||
cellstr_table = input_table(:,vartype('cellstr')); % group datasets of a timestamped measurement
|
||||
|
||||
% Record columns/vars original index in reference table
|
||||
numeric_columns = numeric_table.Properties.VariableNames;
|
||||
numeric_columns_idx = argwhere_var_in_varset(numeric_columns,column_names);
|
||||
|
||||
str_columns = cellstr_table.Properties.VariableNames;
|
||||
str_columns_idx = argwhere_var_in_varset(str_columns,column_names);
|
||||
|
||||
% Based on homogeneous columns/cell arrays, we identify the remaining columns
|
||||
% with possibly heterogeneous entries. Ideally, these should store numeric
|
||||
% n-dimensional arrays/datasets.
|
||||
|
||||
rest_columns = {};
|
||||
cntr = 1;
|
||||
for i = 1 : length(input_table.Properties.VariableNames)
|
||||
variable = input_table.Properties.VariableNames{i};
|
||||
|
||||
is_str = sum(strcmp(variable,str_columns))>0;
|
||||
is_num = sum(strcmp(variable,numeric_columns))>0;
|
||||
if ~(is_num || is_str)
|
||||
rest_columns{cntr} = variable;
|
||||
disp(variable)
|
||||
cntr = cntr + 1;
|
||||
end
|
||||
end
|
||||
|
||||
rest_columns_idx = argwhere_var_in_varset(rest_columns,column_names);
|
||||
|
||||
% Create an hdf5 file, where rows are seen as measurements/groups with
|
||||
% attributes given by numeric and str variables and datasets given by the
|
||||
% remaining variables as long as they are numeric n-dimensional arrays.
|
||||
|
||||
cell_table = input_table(:,rest_columns);
|
||||
[rows, cols] = size(input_table);
|
||||
|
||||
for i = 1 : rows
|
||||
group_name = strcat("/MEAS_",string(i),"/");
|
||||
if ~isempty(rest_columns)
|
||||
for j = 1 : length(rest_columns)
|
||||
dataset_name = strcat("DS",string(rest_columns_idx(j)));
|
||||
|
||||
% Some table entries do not provide direct access to the object
|
||||
% of interest, but may contain either {object} or {{object}}.
|
||||
% The following loop solves that problem. TODO: is this generic enough?
|
||||
|
||||
data = cell_table{i,column_names{rest_columns_idx(j)}}{1}; % <=> data = cell_table{i,rest_columns{j}}{1};
|
||||
|
||||
while iscell(data)
|
||||
data = data{1};
|
||||
end
|
||||
% when there is no data, we still need to provide a valid size
|
||||
if ~isempty(data)
|
||||
sz = size(data);
|
||||
else
|
||||
sz = [1,1];
|
||||
end
|
||||
%%%%
|
||||
% Group's dataset: Create dataset of size sz in a certain group
|
||||
h5create(filename, strcat(group_name,dataset_name),sz);
|
||||
% Dataset's attribute: Add attribute with dataset_name equal to column_name
|
||||
attr = "column_name";
|
||||
attr_value = column_names{rest_columns_idx(j)}; % <=> rest_columns{j};
|
||||
h5writeatt(filename,strcat(group_name,dataset_name),attr,attr_value)
|
||||
|
||||
%attr = "column_name_idx";
|
||||
%attr_value = rest_columns_idx(j); % <=> rest_columns{j};
|
||||
%h5writeatt(filename,strcat(group_name,dataset_name),attr,attr_value)
|
||||
|
||||
% Assign 'data' to the dataset. 'data' has to be of admissible type.
|
||||
try
|
||||
h5write(filename,strcat(group_name,dataset_name),data)
|
||||
catch exception
|
||||
disp(exception)
|
||||
%h5write(filename,strcat(group_name,dataset_name),cell_table{i,rest_columns{j}})
|
||||
end
|
||||
end
|
||||
else
|
||||
dataset_name = "DS_EMPTY";
|
||||
sz = [1,1];
|
||||
h5create(filename, strcat(group_name,dataset_name),sz);
|
||||
end
|
||||
|
||||
% Group's attribute: Assign group attributes
|
||||
for attr_idx = 1 : length(numeric_columns)
|
||||
attr = column_names{numeric_columns_idx(attr_idx)};% <=> attr = numeric_columns{attr_idx};
|
||||
attr_value = numeric_table{i,attr};
|
||||
|
||||
column_idx_tag = ['ATTR',num2str(numeric_columns_idx(attr_idx)),'_'];
|
||||
h5writeatt(filename,group_name,[column_idx_tag,attr],attr_value)
|
||||
|
||||
%attr = "column_name_idx";
|
||||
%attr_value = numeric_columns_idx(attr_idx); % <=> rest_columns{j};
|
||||
|
||||
%h5writeatt(filename,group_name,attr,attr_value)
|
||||
end
|
||||
|
||||
for attr_idx = 1 : length(str_columns)
|
||||
|
||||
attr = column_names{str_columns_idx(attr_idx)}; % <=> attr = str_columns{attr_idx}
|
||||
attr_value = cellstr_table{i,attr};
|
||||
|
||||
column_idx_tag = ['ATTR',num2str(str_columns_idx(attr_idx)),'_'];
|
||||
h5writeatt(filename,group_name,[column_idx_tag,attr],attr_value)
|
||||
|
||||
%attr = "column_name_idx";
|
||||
%attr_value = str_columns_idx(attr_idx); % <=> rest_columns{j};
|
||||
|
||||
%h5writeatt(filename,group_name,attr,attr_value)
|
||||
end
|
||||
%h5create(filename,"/g2/DS2",[20 Inf],"Chunksize",[5 5]);
|
||||
end
|
||||
|
||||
success = 1;
|
||||
|
||||
function idx = argwhere_var_in_varset(var,varset)
|
||||
ref_idx = 1 : length(varset);
|
||||
if iscellstr(var)
|
||||
idx = [];
|
||||
for i = 1 : length(var)
|
||||
logical_idx = strcmp(var{i},varset);
|
||||
idx = [idx,ref_idx(logical_idx)];
|
||||
end
|
||||
else
|
||||
logical_idx = strcmp(var,varset);
|
||||
idx = ref_idx(logical_idx);
|
||||
end
|
||||